Skip to content

Add OpenMP pragmas to the stencil and DOF kernels - #103

Merged
spossann merged 3 commits into
devel-tinyfrom
add-openmp-pragmas
Oct 14, 2026
Merged

spossann merged 3 commits into
devel-tinyfrom
add-openmp-pragmas

Conversation

@max-models

@max-models max-models commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Corresponding struphy PR struphy-hub/struphy#757

Add OpenMP pragmas to the kernels struphy runs in its solver loops, and make psydac-accelerate --openmp work.

Kernels

  • #$ omp parallel for collapse(2) over the two outer loops of stencil_dot, stencil_transpose and stencil_axpy (2D and 3D), and of the 3D DOF kernels in feec/dof_kernels.py, so the threads share n1 * n2 rows instead of n1 (enough work for e.g. 256 threads on one rank). In dot and transpose the indices of the first direction are computed inside the i2 loop to make the loops perfectly nested.
  • stencil_inner_3d: one partial sum per pair (i0, i1) with collapse(2); stencil_inner_2d: one per i0 (collapsing would need a work array the size of the vector). The partial sums are added in a fixed order afterwards, instead of an OpenMP reduction. A reduction combines the thread sums in arrival order, so repeated inner products differed in the last bits and CG results were not reproducible (this broke test_inverse_transpose_interaction, which compares two CG runs exactly). The result is now the same for every run and every number of threads; the kernel arguments (shared with the CUDA version) are unchanged.
  • 1D kernels, the legacy matvec/transpose kernels and the field-evaluation kernels are unchanged.

Compilation (accelerate.py)

  • Fix --openmp: the makefile concatenates $(FLAGS)$(FLAGS_openmp) without a space, so pyccel received --compiler-family=GNU--openmp.
  • Switching OpenMP on or off rebuilds all kernels (make -B), since make only tracks source timestamps. The last setting is stored in accelerate/.last_flags_openmp (git-ignored, removed by --cleanup).

Tests

New linalg/tests/test_openmp.py: runs the kernels with 1, 2 and 4 threads in fresh processes, on the CUDA parity cases plus larger grids and the 3D DOF kernels. Results must match the serial Python kernels (rtol=atol=1e-12) and be bitwise identical to the 1-thread compiled result. Skipped unless the kernels were compiled with --openmp.

Validation (GNU Fortran, --openmp)

  • OMP_NUM_THREADS=4: all linalg and feec tests pass (8038 passed), on two consecutive runs, before and after the collapse(2) change.
  • test_openmp.py passes.
  • Switching OpenMP off rebuilds all 19 kernel modules.
  • stencil_dot_3d on a 48³ grid with degree 3: 3.7× faster with 4 threads (outer-loop version, idle machine).

🤖 Generated with Claude Code

@max-models
max-models marked this pull request as ready for review October 13, 2026 15:20
@max-models
max-models requested a review from spossann October 13, 2026 15:20
Comment thread feectools/feec/dof_kernels.py Outdated
Comment thread feectools/linalg/kernels/stencil_dot_2d/stencil_dot_2d_kernels.py Outdated
Parallelizing only the first direction leaves threads idle when n1 is
smaller than the number of threads (e.g. 256 threads on one rank).

- dot and transpose (2D/3D): compute the indices of the first direction
  inside the i2 loop, so the loops over i1 and i2 can be collapsed.
- axpy (2D/3D) and the 3D DOF kernels: collapse(2).
- inner 3D: one partial sum per pair (i0, i1), still added in a fixed
  order, so the result does not depend on the number of threads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@spossann
spossann merged commit 0c548d1 into devel-tiny Oct 14, 2026
9 checks passed
spossann added a commit to struphy-hub/struphy that referenced this pull request Oct 14, 2026
Corresponding feectools PR
struphy-hub/feectools#103

Fix OpenMP directives so all 128 Struphy kernel modules compile with GNU
Fortran using `struphy compile --openmp`, and compile the feectools
kernels with OpenMP as well.

- Repair parallel regions, variable scoping, and accumulation
reductions.
- Give each thread its own mutable spline-evaluation workspace to
prevent data races.
- Force rebuilding when OpenMP settings change, and record compiler
settings only after successful compilation.
- Add CI compilation and numerical regression checks, plus documentation
for thread counts and reduction memory requirements.

## feectools

- `struphy compile --openmp` now passes `--openmp` to
`psydac-accelerate`, so the feectools kernels are threaded too
(previously they were always compiled serially).
- The `feectools` submodule points to the `add-openmp-pragmas` branch
(struphy-hub/feectools#103), which adds OpenMP pragmas to the stencil
`dot`, `transpose`, `axpy` and `inner` kernels (2D/3D) and the 3D DOF
kernels.
- The CI OpenMP step also runs `pytest --pyargs
feectools.linalg.tests.test_openmp`.
- `install.rst` mentions that the feectools kernels are compiled with
OpenMP, and how to run their check.

## Validation

- Fresh OpenMP compilation of all 128 kernel modules.
- Compiled results match serial reference loops with 1, 2, and 4
threads.
- 575 tests passed, including pusher, SPH, compilation, and numerical
parity tests.
- `console/tests/test_compile.py` (16 tests) passes, including the new
check that `--openmp` is forwarded to `psydac-accelerate`.
- Ruff and whitespace checks passed.

Array reductions require temporary output arrays per thread; large
problems may need additional memory and larger stack limits.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Stefan Possanner <stefan.possanner@ipp.mpg.de>
spossann added a commit to struphy-hub/struphy that referenced this pull request Oct 21, 2026
Corresponding feectools PR
struphy-hub/feectools#103

Fix OpenMP directives so all 128 Struphy kernel modules compile with GNU
Fortran using `struphy compile --openmp`, and compile the feectools
kernels with OpenMP as well.

- Repair parallel regions, variable scoping, and accumulation
reductions.
- Give each thread its own mutable spline-evaluation workspace to
prevent data races.
- Force rebuilding when OpenMP settings change, and record compiler
settings only after successful compilation.
- Add CI compilation and numerical regression checks, plus documentation
for thread counts and reduction memory requirements.

## feectools

- `struphy compile --openmp` now passes `--openmp` to
`psydac-accelerate`, so the feectools kernels are threaded too
(previously they were always compiled serially).
- The `feectools` submodule points to the `add-openmp-pragmas` branch
(struphy-hub/feectools#103), which adds OpenMP pragmas to the stencil
`dot`, `transpose`, `axpy` and `inner` kernels (2D/3D) and the 3D DOF
kernels.
- The CI OpenMP step also runs `pytest --pyargs
feectools.linalg.tests.test_openmp`.
- `install.rst` mentions that the feectools kernels are compiled with
OpenMP, and how to run their check.

## Validation

- Fresh OpenMP compilation of all 128 kernel modules.
- Compiled results match serial reference loops with 1, 2, and 4
threads.
- 575 tests passed, including pusher, SPH, compilation, and numerical
parity tests.
- `console/tests/test_compile.py` (16 tests) passes, including the new
check that `--openmp` is forwarded to `psydac-accelerate`.
- Ruff and whitespace checks passed.

Array reductions require temporary output arrays per thread; large
problems may need additional memory and larger stack limits.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Stefan Possanner <stefan.possanner@ipp.mpg.de>
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.

2 participants