Skip to content

Cuda 4 device kernels - #88

Draft
max-models wants to merge 4 commits into
devel-tinyfrom
cuda-4-device-kernels
Draft

max-models wants to merge 4 commits into
devel-tinyfrom
cuda-4-device-kernels

Conversation

@max-models

@max-models max-models commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Summary

The main stencil operations now run on the GPU when their data is already there. Before, the data was copied to the host for the Pyccel kernels. A 64×64×32 matvec with degree 3 takes 0.5 ms instead of 165 ms on an H100.

Changes

  • StencilMatrix.dot: a CUDA matvec in feectools/linalg/kernels/device_matvec.py, one thread per output point. It is generated for each dimension (1–3) and dtype (float64, complex128) and cached with cunumpy.CudaKernelVariants. It is used only when the matrix, the input vector and the output vector are all on the device and the matrix uses the precompiled kernel arguments.
  • StencilMatrix.transpose: a CUDA transpose for 3D real matrices in kernels/device_transpose.py, using cunumpy.CudaKernel.
  • StencilVectorSpace.inner: the reduction runs on the device. In the serial case it still returns a NumPy scalar, as the host kernel does.
  • StencilVectorSpace.axpy: a scaled add on the device, including the interface data.
  • Any other case (other dtypes or dimensions, data on the host, the NumPy backend) still uses the host path.
  • New linalg/tests/test_device_matvec.py.

Notes for review

  • _device_matvec_args() caches its result on the matrix, and set_backend() doesn't clear that cache. If a matrix switches to another backend after its first dot, it keeps using the device kernel. The result is still correct, but the backend choice is ignored.

Stack

This is step 4 of 4 for CUDA support. The PRs are stacked, and each one targets devel-tiny, so the diff here also contains the earlier steps. Review only commit 1253695 in this PR, and merge them in order:

  1. Cuda 1 xp arrays #85 — Run feectools with the CuPy backend
  2. Cuda 2 mpi sync #86 — MPI with device buffers
  3. Cuda 3 device binding #87 — Bind each MPI rank to its own GPU
  4. Cuda 4 device kernels #88 — Stencil operations on the device ← this PR

🤖 Generated with Claude Code

max-models and others added 4 commits September 30, 2026 23:53
Make feectools work when cunumpy's backend is CuPy, without any device
kernels yet: kernels that stay on the host still copy their arrays.

- Wrap all Pyccel kernels (stencil, B-splines, field evaluation, DOF
  kernels) in cunumpy.PyccelKernel, so they accept CuPy arrays.
- Keep host-only metadata on NumPy: MPI/index bookkeeping in ddm (cart,
  partition, petsc) and fem.partitioning, Kronecker solver sizes, and
  index arithmetic with Python ints (compute_diag_len, math.prod).
- Stage data for host-only libraries by array, not by global backend:
  LAPACK/SuperLU direct solvers, SciPy FFT, SciPy sparse products.
- Fix calls that ran host kernels on device arrays: the second
  stencil2coo call in StencilMatrix.tosparse and the conjugate transpose.
- Vectorize the construction of the 1D collocation matrices in the
  global projectors (element-wise indexing was a device round trip per
  entry: 334 s of a 348 s Derham setup on the GPU).
- GMRES: take real scalars from CuPy views before modifying them.
- Fix StencilMatrix._update_ghost_regions_serial: the ghost region is
  pads * shifts wide (wrong whenever shifts > 1, on both backends).
- Tests: work with CuPy arrays; skip PETSc tests without petsc4py.

Serial tests pass on both backends (core, ddm, fem, linalg).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Allow MPI on the CuPy backend and make it correct with device buffers
(requires a CUDA-aware MPI library).

- feectools.ddm.mpi no longer disables MPI when ARRAY_BACKEND=cupy; the
  segfaults it guarded against come from MPI libraries that are not
  CUDA-aware.
- Call cunumpy.synchronize_for_mpi before every MPI call on device
  buffers: CuPy kernels run asynchronously and MPI does not know about
  CUDA streams, so a buffer still being written would be sent silently
  wrong. Covers the blocking, non-blocking and interface data exchangers,
  the Allreduce in StencilVectorSpace.inner and the Alltoallv calls of the
  parallel Kronecker solver. Requires cunumpy >= 0.3.0.
- Fix CuPy incompatibilities reached only by the MPI tests: xp.dot/vdot
  on .flat iterators in StencilInterfaceMatrix._dot and the pure-Python
  inner product, and test_cart_1d assigning Python lists to CuPy arrays.
- Add test_mpi_device.py: distributed results against global references,
  and that the exchangers synchronize before MPI.

With 2 MPI ranks and a CUDA-aware Open MPI, all MPI tests in ddm and
linalg pass on both backends; serial tests are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the initialization that always used GPU 0 by
cunumpy.bind_local_device(): each process uses GPU
local_rank % device_count, chosen from the node-local rank that the MPI
launcher exports, and its CUDA context is created before MPI is
initialized (as CUDA-aware MPI requires). No-op on the NumPy backend.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Run the main stencil operations on the GPU when their data is there,
instead of copying it to the host for the Pyccel kernels:

- StencilMatrix.dot: CUDA matvec (feectools.linalg.kernels.device_matvec),
  one thread per output point, generated per dimension (1-3) and dtype
  (float64, complex128) and cached with cunumpy.CudaKernelVariants.
- StencilMatrix.transpose: CUDA transpose for 3D real matrices
  (device_transpose, a cunumpy.CudaKernel).
- StencilVectorSpace.inner: reduction on the device (returns a NumPy
  scalar in the serial case, as the host kernel does).
- StencilVectorSpace.axpy: scaled add on the device.

Other cases (other dtypes, dimensions, backends) keep the host path.
Adds test_device_matvec.py. A 64x64x32 matvec with degree 3 takes
0.5 ms instead of 165 ms on an H100.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant