Symptom
A downstream package cannot use MFO's (or KernelAbstractions') CPU kernel path when the state it passes is a SubArray view, because the KA CPU() backend races on views. It works on GPU backends and it works on plain Arrays; it corrupts results on CPU + views.
Why that shape comes up
It is not exotic. A folded steady solve marches a stacked state and hands each species' slice to the diffusion operator as a view — that is the natural, allocation-free way to apply a per-species operator to a multi-species state without copying. Any solver that stacks fields and slices them hits this.
What downstream had to do
The workaround in the microvascular model is an entire file that exists for no other reason:
# CPU uses a plain scalar loop over laplacian_7pt_noflux (view- and thread-safe);
# the GPU path delegates to the KA stencil (identical numerics). The split exists
# because KA's CPU() backend races on the SubArray views the folded steady solve passes.
_tissue_laplacian!(out, u, grid) = _tissue_laplacian!(out, u, grid, get_backend(u))
_tissue_laplacian!(out, u, grid, ::CPU) = # hand-rolled scalar loop
_tissue_laplacian!(out, u, grid, backend) = # delegate to the KA kernel
Two code paths, two sets of numerics to keep in agreement, forever — to work around a backend property. This is the single clearest case of "downstream reimplemented something because MFO's version didn't fit", and it's the one I'd most like to delete.
Ask
Either make the CPU apply! path view-safe, or — if that is genuinely KA's problem rather than MFO's — document the constraint loudly and offer a sanctioned view-safe CPU fallback in MFO so every downstream doesn't hand-roll its own.
Related to #51 (CPU apply! is single-threaded): both are about the CPU path being the odd one out, and a rework that fixes threading is the natural place to fix view-safety too. laplacian_7pt_noflux is already documented as the escape hatch for fused custom kernels over flat state, so the raw ingredient is there — what's missing is a supported loop around it.
🤖 Written by Claude. If this is wrong, blame the robot, not the human whose name is on the repo.
Symptom
A downstream package cannot use MFO's (or KernelAbstractions') CPU kernel path when the state it passes is a
SubArrayview, because the KACPU()backend races on views. It works on GPU backends and it works on plainArrays; it corrupts results on CPU + views.Why that shape comes up
It is not exotic. A folded steady solve marches a stacked state and hands each species' slice to the diffusion operator as a view — that is the natural, allocation-free way to apply a per-species operator to a multi-species state without copying. Any solver that stacks fields and slices them hits this.
What downstream had to do
The workaround in the microvascular model is an entire file that exists for no other reason:
Two code paths, two sets of numerics to keep in agreement, forever — to work around a backend property. This is the single clearest case of "downstream reimplemented something because MFO's version didn't fit", and it's the one I'd most like to delete.
Ask
Either make the CPU
apply!path view-safe, or — if that is genuinely KA's problem rather than MFO's — document the constraint loudly and offer a sanctioned view-safe CPU fallback in MFO so every downstream doesn't hand-roll its own.Related to #51 (CPU
apply!is single-threaded): both are about the CPU path being the odd one out, and a rework that fixes threading is the natural place to fix view-safety too.laplacian_7pt_nofluxis already documented as the escape hatch for fused custom kernels over flat state, so the raw ingredient is there — what's missing is a supported loop around it.🤖 Written by Claude. If this is wrong, blame the robot, not the human whose name is on the repo.