You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Carved out of #49 (candidate 1) so it can be tracked as one unit of work.
_forest_sweep_leaves! (src/operators/forest.jl), _forest_adjoint_sweep_leaves!, and the three descriptor loops in _exchange_storage! (src/transfer.jl) are plain serial for loops; on CPU the packed kernels fall back to the same broadcasts. Leaves are disjoint and the exchange phases are ordered to be independent within a phase, so this looks close to embarrassingly parallel. In the Niederer benchmark the reaction term is threaded in example code while diffusion is not, which is a large part of why the two phases scale so differently (#49: diffusion 0.44× on 5.3× fewer cells).
Check first
Whether descriptors within one exchange phase can alias the same destination block. If they can, the threaded sweep needs a partition by destination or atomics; if they cannot, a Threads.@threads over descriptors is enough.
Must not disturb the _exchange_storage! / _bc_storage! rule seams: no allocation inside them, no Field-typed rule arguments.
Acceptance: the examples/niederer_benchmark.jl phase table shows the diffusion phase scaling with -t, and the adjoint sweep keeps ⟨Lx,y⟩ = ⟨x,Lᵀy⟩ bit-for-bit against the serial path.
🤖 Beep boop — Claude split this off #49; Kyle is not forking himself.
Carved out of #49 (candidate 1) so it can be tracked as one unit of work.
_forest_sweep_leaves!(src/operators/forest.jl),_forest_adjoint_sweep_leaves!, and the three descriptor loops in_exchange_storage!(src/transfer.jl) are plain serialforloops; on CPU the packed kernels fall back to the same broadcasts. Leaves are disjoint and the exchange phases are ordered to be independent within a phase, so this looks close to embarrassingly parallel. In the Niederer benchmark the reaction term is threaded in example code while diffusion is not, which is a large part of why the two phases scale so differently (#49: diffusion 0.44× on 5.3× fewer cells).Check first
Whether descriptors within one exchange phase can alias the same destination block. If they can, the threaded sweep needs a partition by destination or atomics; if they cannot, a
Threads.@threadsover descriptors is enough.Constraints
apply!seam); pick once for both single-grid and forest paths._exchange_storage!/_bc_storage!rule seams: no allocation inside them, noField-typed rule arguments.examples/niederer_benchmark.jlphase table shows the diffusion phase scaling with-t, and the adjoint sweep keeps ⟨Lx,y⟩ = ⟨x,Lᵀy⟩ bit-for-bit against the serial path.🤖 Beep boop — Claude split this off #49; Kyle is not forking himself.