Skip to content

feat(distributed): ImplicitGlobalGrid halo backend for multi-node CartesianGrid #46

Description

@kylebeggs

Context

DESIGN.md §10.4 is now resolved: MDLA first (done), ImplicitGlobalGrid.jl for multi-node next.

MDLA is implemented in ext/MatrixFreeOperatorsMDLAExt.jl behind the _dist_scatter! / _dist_reduce! seam and covers single-node multi-GPU with the adjoint carried through. It cannot go multi-node, and it is CUDA-only. IGG is production-proven GPU-aware MPI halo exchange over a Cartesian MPI topology — exactly our uniform CartesianGrid case, multi-node, CPU+GPU.

This issue is to investigate first, then implement — the investigation gate below is real and may change the shape of the implementation.

Scope

  • In: uniform CartesianGrid, multi-node, CPU + GPU, behind the existing distributed seam, as ext/MatrixFreeOperatorsIGGExt.jl. No new core dependency.
  • Out: multi-node AMR (BlockForest). IGG assumes one fixed uniform Cartesian decomposition; the forest's halo_update! is intra-forest and a distributed forest needs a separate answer. Track that separately if/when it comes up.
  • Not adopted: ParallelStencil.jl. We take IGG's halo only. @init_parallel_stencil(backend, precision, ndims) is module-level global state fixed at load, which is incompatible with keeping GPU support in a weak-dep extension; PS also brings no operator algebra, no linear-solve path, and no AMR. Our hot-stencil escape hatch remains KernelAbstractions @kernel (DESIGN §1.A).

Investigation gate (do this first)

IGG owns its own grid construction (init_global_grid) and array allocation (@zeros). The load-bearing question:

Can update_halo! be driven against MFO-owned Field storage, or is only the topology / MPI-Cartesian-communicator part reusable, with the exchange itself written directly on MPI.jl?

Prototype both far enough to answer it before committing to the extension's shape. If only the topology is reusable, the honest outcome may be "depend on MPI.jl directly and borrow IGG's decomposition logic" — which is a fine result for this issue, just a different one.

Secondary questions for the same prototype:

  • How init_global_grid's global state interacts with partition_grid / prepare_distributed, which already compute local-vs-global ranges. One of the two has to own the decomposition; they must not disagree.
  • Whether the adjoint contract survives: _dist_reduce! must remain the exact transpose of _dist_scatter! across ranks, including the ∂/∂κ scatter-add over owned cells. This is the part with no equivalent anywhere in the IGG/PS ecosystem, and it is the easiest thing to get silently wrong.

Calibrate the expected payoff — do not over-invest in overlap

For the driving workload (reaction–diffusion where a large local ODE dominates each node — cardiac monodomain, ~65 states and ~255 exp per node per step) only the scalar field crosses a boundary while the full state churns over the volume. For a 256³ subdomain that is roughly a 2800:1 byte ratio, so even a naive blocking exchange should cost low single-digit percent of a step.

IGG is being adopted for correctness and multi-node CPU+GPU portability, not because the halo is a bottleneck. Get a correct blocking exchange working and measured before reaching for @hide_communication-style overlap. If a benchmark later shows the exchange is actually material, that is the trigger to revisit — not an assumption to build on.

Done when

  • Investigation gate answered and written down (IGG arrays vs. MFO storage)
  • ext/MatrixFreeOperatorsIGGExt.jl implements _dist_scatter! / _dist_reduce!
  • Adjoint identity ⟨Lx,y⟩ = ⟨x,Lᵀy⟩ verified across ranks, not just within one
  • Parameter-gradient (∂/∂κ) parity against the single-rank result
  • Multi-node test gated like test/multigpu (see test(ci): officially instantiate test/multigpu (>=3-GPU distributed tests) #30), skipped by default
  • Halo cost measured on a realistic domain and recorded, so the overlap question is settled by data

🤖 Filed by Claude — Kyle supplied the judgement, I supplied the typing.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions