Repository navigation
GPU stack 7/8: chunked marker loading, row-based weight update, leaner MPI sorting; static field in PushVxB - #788
Open
max-models wants to merge 8 commits into
Conversation
…ng; PushVxB with a static field - Pseudo-random markers are drawn in chunks of 2**20 (was 10000): 16 instead of 1600 iterations for 16M markers, each a few small kernels and a device sync on the GPU. - update_weights finds the rows of the valid markers once and reads the columns it needs, instead of selecting every property with the boolean mask and gathering whole rows. - mpi_sort_markers: the ghost bookkeeping is skipped without sorting boxes (no ghosts can exist); no barriers around the device exchange, which waits for every send and receive; the sorting positions for alpha = 1 are one add instead of five kernels. - PushVxB without a magnetic field variable computes the total field once (no ghost exchange, an MPI synchronization point, before every push). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 16, 2026
max-models
added this pull request to stack #790
October 16, 2026 08:51
…gh gpu-stack-6-marker-layout) # Conflicts: # src/struphy/pic/base.py
…ading-sorting (feectools update)
…ading-sorting (fused gradient)
…ic.mpi_sort_cuda) On the GPU, mpi_sort_markers finds the destination of every marker with one kernel (sort_destinations, mpi_sort_cuda.cu) and counts the markers per destination, instead of a pass over the buffer per direction and per rank; the leaving markers are listed once, stably sorted by destination and gathered once per destination rank. The result is the one of the host path (the same markers in the same columns, the lost markers become holes); the counts are one 8-byte read per rank. STRUPHY_DEVICE_SORT=1/0 forces it on (also on the fake CuPy) or off. On cuda-aware-mpi-fixes Particles._mpi_sort_device imported this module, which was never committed; it is written for the (n_cols, n_markers) buffer of devel (#774, #775). test_mpi_sort_markers_device_kernel_fake_cupy: the kernel (launches emulated) against the NumPy sort, CUDA-aware and staged, periodic and removing boundaries (checked on 2 and 4 ranks). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ading-sorting (feectools update, CachedLaunch)
…gh gpu-stack-6-marker-layout)
…ading-sorting (pcg_sr in the shear Alfven solves)
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.
Part 7 of 8 of the split of #772 (
cuda-aware-mpi-fixes) into stacked PRs. Requires struphy-hub/feectools#104 to be merged into feectoolsdevel-tinyfirst (PR 1 bumps the submodule).Pseudo-random markers are drawn in chunks of
2**20(was 10000): 16 instead of 1600 iterations for 16M markers, each a few small kernels and a device sync on the GPU. The NumPy draws do not depend on the chunk size.update_weightsfinds the indices of the valid markers once and reads only the quantities it needs (xp.takeof one row of the buffer each), instead of a boolean selection per property and a count of the valid markers.mpi_sort_markers: the ghost bookkeeping is skipped without sorting boxes, where no ghosts can exist. There are no barriers around the device exchange, which waits for every send and receive (cunumpy.mpi.exchange). The host path keeps them. The sorting positions foralpha = 1are one add instead of five kernels.PushVxBwithout a magnetic field variable computes the total field once, so there is no ghost exchange (an MPI synchronization point) before every push.Device MPI sort (
Particles._mpi_sort_device,struphy.pic.mpi_sort_cuda): on the GPU one kernel (sort_destinations) finds the destination of every marker and counts the markers per destination, instead of a pass over the buffer per direction and per rank. The leaving markers are listed once, stably sorted by destination and gathered once per destination rank. The result is that of the host path (the same markers in the same columns; lost markers become holes), at the cost of one 8-byte read per rank for the counts.STRUPHY_DEVICE_SORT=1or0forces it on (also on the fake CuPy) or off. The original branch importedmpi_sort_cuda, but it was never committed (and called an undefined_to_numpy_for_kernel), so it is written new here for the(n_cols, n_markers)buffer of devel.test_mpi_sort_markers_device_kernel_fake_cupycompares it with the NumPy sort, CUDA-aware and staged, periodic and removing boundaries, on 2 and 4 ranks.Tests
Local, macOS without a GPU, in a fresh environment with feectools
1d8d47cand the pinned cunumpy, after merging devel (with #774 and #775). The PR passestest_cuda_parity,test_cuda_emulation,test_kernel_backends,test_sorting,test_accum_matrix_cupy,test_preconditioner_cupy,test_poissonandtest_outputon its own. The top of the stack also passes the mass-matrix, preconditioner, Derham-GPU, fused-gradient, Kronecker-block, Poisson, shear Alfvén, post-processing, polar fake-CuPy and allpictests (1477 passed), the examples test for the two profiling cases, the sorting, Poisson and fused-gradient tests undermpirun -n 2, and the device MPI sort on the fake CuPy on 2 and 4 ranks. The Kronecker products match the stencil mass matrices to 5e-16 for M0, M1, M2, M3, Mv, M1n and M2n on a Cuboid, periodic and Dirichlet, on 1 and 2 ranks.Not tested on a GPU here. The CUDA kernels and the device paths need a run on the cluster.
Stack (merge in order)
devel-tiny)devel🤖 Generated with Claude Code