Repository navigation
Device ghost-exchange plans, fused block exchanges, single-reduction PCG (CUDA-aware MPI) - #104
Draft
max-models wants to merge 12 commits into
Draft
max-models wants to merge 12 commits into
max-models wants to merge 12 commits into
Conversation
…ommitted) The import of feectools.utilities.cached_launch made feectools.linalg.stencil, and with it the whole package, fail to import. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… per iteration again - _serial_ghost_plan and BlockVector._fused_device_exchange return None on cunumpy's fake CuPy (tests without a GPU), which cannot launch raw kernels: the slice copies and per-block exchanges are used instead. - PCG computes v.p as a device scalar again. With the fused r.r / s.r reduction it makes one host copy per iteration, as on devel-tiny; routing v.p through _inner_products made it two. - Emulation parity: stencil_dot_3d uses warp shuffles, which serial emulation cannot run; it is covered by the GPU parity test. - test_inner_on_device covers pcg_sr. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 16, 2026
Open
The warp-shuffle kernel cannot be emulated one thread at a time, so struphy's tests that emulate every launch on cunumpy's fake CuPy (test_accumulator_matrix_fake_cupy, the polar and end-to-end GPU tests) failed at the first stencil product. On the fake CuPy, StencilMatrix uses the previous one-thread-per-entry kernel (stencil_dot_3d_rows.cu) for device arguments and the usual dispatch for host arguments. test_emulated_stencil_dot_3d_rows compares it with the pyccel kernel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feectools.utilities.cached_launch was imported by stencil.py on this branch but never committed: the .gitignore rule *cache* ignored it (fcd8c8a dropped its use). The rule now has exceptions for this module and its test. A CUDA launch of a cunumpy kernel checks and converts every argument and validates the launch shape; in a Krylov solver axpy and the inner products are launched with the same buffers every iteration. CachedLaunch keys a launch by its buffers (pointer, shape, strides, dtype), the types of its scalars and the launch arguments, prepares it once with the kernel's own checks, and afterwards converts only the scalars (e.g. the axpy coefficient) with the kernel's checkers and launches the compiled kernel. Host calls, cunumpy's fake CuPy, argument objects, explicit streams, debug mode and check_finite go to the wrapped kernel unchanged. The stencil axpy and inner kernels use it again. test_cached_launch checks reuse, scalar conversion, re-preparation for new buffers or launch shapes, the pass-through cases and the bound with a stub kernel (no GPU needed), and that host calls go to the kernel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
GPU and MPI performance work for struphy's CuPy backend. This PR must be merged into
devel-tinybefore the struphy stack that uses it (struphy-hub/struphy#782 bumps the submodule to this branch; it is the first of the stacked PRs struphy-hub/struphy#782 to struphy-hub/struphy#789, which split struphy-hub/struphy#772).Changes
Device ghost exchange
ddm/basic.py: exchange plans built once from per-region indices (_DeviceRegionExchange), and a fused exchange of all blocks of aBlockVector(_FusedDeviceExchange): one message per neighbour and one gather and one scatter kernel for all blocks.blocking_data_exchanger.py,nonblocking_data_exchanger.py: use these plans for device arrays.stencil.py: serial ghost update of vectors and matrices with one kernel on the GPU (_serial_ghost_plan);inner_local/inner_commfor fused reductions.block.py: the exchanges of all blocks are in flight together;BlockLinearOperator.dotwrites the first block of each row directly.Solvers
PConjugateGradientSingleReduction(inverse(A, "pcg_sr", ...), Chronopoulos–Gear): all inner products of an iteration in one reduction, so one Allreduce per iteration instead of two.r·rands·rwith one reduction (_inner_products).Kernels
stencil_dot_3d(CUDA): 8 threads per row, coalesced reads, warp-shuffle sum.IdentityOperator.dotwithout: one copy (the oldout *= 0; out += valso kept NaNs ofout).Fixes added while splitting the struphy branch
stencil.pyimportedfeectools.utilities.cached_launch, which was never committed: the.gitignorerule*cache*ignored it, so the package did not import. It is written new (CachedLaunch: a launch with the same buffers reuses its prepared arguments and launch shape; only scalars such as the axpy coefficient are converted again; host calls, the fake CuPy, argument objects, streams, debug mode andcheck_finitego to the kernel unchanged), with.gitignoreexceptions, and the stencil axpy and inner kernels use it.test_cached_launchchecks it with a stub kernel, without a GPU.test_one_host_copy_per_iterationcaught.v·pis a device scalar again. With the fusedr·r/s·rreduction PCG is back to one copy per iteration, with the same iterates.stencil_dot_3d, because serial emulation cannot run warp shuffles. The GPU parity test covers it.StencilMatrixuses the previous one-thread-per-entry kernel (stencil_dot_3d_rows.cu) for device arguments. Without it, struphy's tests that emulate every launch (accumulation, polar and end-to-end GPU tests) failed at the first stencil product.test_emulated_stencil_dot_3d_rowscompares it with the pyccel kernel.test_inner_on_devicealso coverspcg_sr.Tests
Run on macOS without a GPU, with the cunumpy commit struphy pins (
f996393).feectools/linalg/testsandfeectools/ddmpass, apart from 22 failures thatdevel-tinyshows in the same environment (PETSc and similar setup issues). The same holds fortest_mpi_device.py,test_solvers.pyandtest_block.pyundermpirun -n 2. The fake-CuPy tests show one host copy per iteration forcg,pcg,pcg_srandpbicgstab, with results identical to NumPy. Not tested on a GPU here: the CUDA kernels and the CUDA-aware exchange paths need a run on the cluster.🤖 Generated with Claude Code