Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
bd8cd8b
Keep only the hybrid GEMM provider
jtravs Nov 11, 2026
19c17b8
Remove the GEMM microbenchmark
jtravs Nov 11, 2026
f5d4234
Drop IntelLLVM (icpx) support
jtravs Nov 11, 2026
e04648a
Remove the Kokkos Threads host backend option
jtravs Nov 11, 2026
f415464
Build and link no single-precision FFTW
jtravs Nov 11, 2026
5d2539a
Fold the native benchmark scripts into benchmarks/
jtravs Nov 11, 2026
836b93b
Format every tracked native C++ file and regroup includes
jtravs Nov 11, 2026
5145dde
Leave clang-format's RemoveSemicolon off
jtravs Nov 11, 2026
e8a55f7
Format the native C++ files
jtravs Nov 11, 2026
ae2804b
Pin clang-tidy to LLVM 23.1 and add poe tidy-native
jtravs Nov 11, 2026
77be8eb
Add stronger warnings, listed once
jtravs Nov 11, 2026
5202370
Stop the sanitizers at the first report and check view bounds
jtravs Nov 11, 2026
c7bf92a
Add a weekly native deep-check workflow; widen compute-sanitizer
jtravs Nov 11, 2026
e9462fa
Record the removed native build options
jtravs Nov 11, 2026
06fe345
Build SLEEF's header before tidying outside the build
jtravs Nov 11, 2026
3e6b3fa
Refuse a single-value read of a multi-valued stage table
jtravs Nov 11, 2026
2a10abd
Write 1/1 as 1.0 in the Adams divisor tables
jtravs Nov 11, 2026
2abdefc
Hold FFTW plan handles as auto* const
jtravs Nov 11, 2026
02501e5
Keep clang-format from reflowing NOLINT comments
jtravs Nov 11, 2026
a35d19f
Declare every special member of the RAII classes
jtravs Nov 11, 2026
7aeb499
Read optionals the checks cannot prove set through .value()
jtravs Nov 11, 2026
63ae8b3
Name the nanobind exception registrations
jtravs Nov 11, 2026
e15f573
Format the exception registrations
jtravs Nov 11, 2026
5464677
Discard unique_ptr::release explicitly where a capsule owns the storage
jtravs Nov 11, 2026
e87eb62
Enable clang-tidy by whole check families
jtravs Nov 11, 2026
fa66a56
Document the native tooling: what is adopted, scheduled and rejected
jtravs Nov 11, 2026
572f890
Use #ifdef and #ifndef for single-macro conditions
jtravs Nov 11, 2026
f075292
Declare one variable per statement
jtravs Nov 11, 2026
3251c0e
Mark value-returning accessors [[nodiscard]]
jtravs Nov 11, 2026
08b7a8c
Initialise aggregates with designated initialisers
jtravs Nov 11, 2026
eef1956
Call the std::ranges algorithms on whole containers
jtravs Nov 11, 2026
ebf37d1
Copy the Adams rate weights from the vector, not its pointer
jtravs Nov 11, 2026
007ed55
Leave misc-const-correctness off
jtravs Nov 11, 2026
e3cf938
Drop the empty parameter lists of lambdas that take none
jtravs Nov 11, 2026
3928606
Brace both arms of an if-else when one needs braces
jtravs Nov 11, 2026
61659b0
Keep readability-simplify-boolean-expr from applying De Morgan
jtravs Nov 12, 2026
42ded57
Spell cast-initialised locals with auto
jtravs Nov 12, 2026
86b97da
Qualify auto pointers as auto*
jtravs Nov 12, 2026
e24a6a1
Return braced initialisers where the type is the return type
jtravs Nov 12, 2026
5cc4203
Leave readability-use-std-min-max off
jtravs Nov 12, 2026
8126da6
Compare the build record's 0/1 macros with zero
jtravs Nov 12, 2026
998f648
Call void functions and return separately in the band filter dispatch
jtravs Nov 12, 2026
1db5de8
Use std::numbers for sqrt(2) and ln(10)
jtravs Nov 12, 2026
939ed00
Take execution spaces by value where they are stored
jtravs Nov 12, 2026
36643cf
Remove duplicate includes
jtravs Nov 12, 2026
584f15b
Include <numbers> where std::numbers is used
jtravs Nov 12, 2026
68e377d
Compare mixed-sign integers with std::cmp_less
jtravs Nov 12, 2026
dcab1c2
Name declarations' parameters as their definitions do
jtravs Nov 12, 2026
51819a2
Name the unused parameter
jtravs Nov 12, 2026
a9b02a3
Return the GEMM shape policy literal as a string_view
jtravs Nov 12, 2026
dbbbbf9
Write a message with quotes as a raw string literal
jtravs Nov 12, 2026
52554d1
Move each session event into its batch
jtravs Nov 12, 2026
87f3cca
Reserve the test vectors filled in loops
jtravs Nov 12, 2026
024a118
Give general.cpp's file-local helpers internal linkage
jtravs Nov 12, 2026
b0753a6
Let Kokkos views pass by value under performance-unnecessary-value-param
jtravs Nov 12, 2026
3a8e517
Defer the bindings' by-value parameters to their rewrite
jtravs Nov 12, 2026
0492fca
Leave readability-convert-member-functions-to-static off
jtravs Nov 12, 2026
f08863c
Mark the far field's packed-row cascade for bugprone-assignment-in-if…
jtravs Nov 12, 2026
41a9f5e
Keep the tests' fixed random seeds
jtravs Nov 12, 2026
16e435b
Import solprop_native lazily in benchmarks.statistics_cost
jtravs Nov 12, 2026
2f34dc3
Let clang-tidy ignore GCC-only warning flags
jtravs Nov 12, 2026
3fd07c1
Keep the Adams lane passes' integer masks
jtravs Nov 12, 2026
47f7e6f
Mark the deliberate argument orders readability-suspicious-call-argum…
jtravs Nov 12, 2026
6a1ff0b
Release the closed session's rows without a throwing assignment
jtravs Nov 12, 2026
a988876
Form size products in std::size_t
jtravs Nov 12, 2026
a86456f
Name the attempt rows' count before converting it
jtravs Nov 12, 2026
47afb12
Build the coupled-flow test's tables without throwing static initiali…
jtravs Nov 12, 2026
367841e
Test the planned wisdom lines with std::ranges::any_of
jtravs Nov 12, 2026
6b7eb29
Keep the noexcept workspace helpers from allocating
jtravs Nov 12, 2026
5f0abdd
Put column_norms in an anonymous namespace
jtravs Nov 12, 2026
14006e2
Declare the Raman task counts one per statement
jtravs Nov 12, 2026
51abda3
Test the active mask's bytes against zero
jtravs Nov 12, 2026
eb3ad41
Name the integer quotients that feed floating-point values
jtravs Nov 12, 2026
a6c9a38
Form general.cpp's size constants in std::size_t
jtravs Nov 12, 2026
15991c4
Flatten the envelope BLAS guard in the transform policies
jtravs Nov 12, 2026
0b42a12
Close the band statistics' host-only else arms inside their #if
jtravs Nov 12, 2026
864ff6b
Mark general.cpp's coincidental argument names
jtravs Nov 12, 2026
005d5ae
Convert Kokkos's accessibility enum to bool explicitly
jtravs Nov 12, 2026
ccc28d7
Leave the analyser's NewDeleteLeaks check off
jtravs Nov 12, 2026
a80e3f1
Mark the generated source digest's external linkage
jtravs Nov 12, 2026
b4ac85b
Install the pinned clang-tidy on Linux and macOS only
jtravs Nov 12, 2026
3eb5bcd
Time the statistics channel on the former harness's CtC workload
jtravs Nov 12, 2026
4917127
Run poe tidy-native with the pinned clang-tidy the build resolved
jtravs Nov 12, 2026
f38c72e
Refuse multi-valued scalar stage tables when they are loaded
jtravs Nov 12, 2026
a450309
Allow nanobind handles by value instead of a file-wide NOLINT
jtravs Nov 12, 2026
0fdcf73
Find only FFTW's double libraries before Kokkos-FFT
jtravs Nov 12, 2026
5a8eb58
Let the weekly report-only builds warn without failing
jtravs Nov 12, 2026
6fc670e
List the pinned clang-format and clang-tidy in the dependencies
jtravs Nov 12, 2026
3a18591
Run native-deep.yml on a pull request that changes it
jtravs Nov 12, 2026
f9d6b99
Merge origin/main into chore/native-tooling
jtravs Nov 12, 2026
2025943
Take statistics_cost's run options by keyword
jtravs Nov 12, 2026
4393ad8
Preload libstdc++ with ASan in the weekly extension job
jtravs Nov 12, 2026
1bcf6f3
Merge remote-tracking branch 'origin/chore/native-tooling' into refac…
jtravs Nov 12, 2026
d8d3af1
Build native refusal messages with one concatenation helper
jtravs Nov 12, 2026
9b6eec2
Name the build's facts as constants for if constexpr
jtravs Nov 12, 2026
41f53f3
Replace the width switch ladders with dispatch_width
jtravs Nov 12, 2026
f7f5ddc
Forward GeneralState's calls through one with_team
jtravs Nov 12, 2026
1916241
Return nothing from the void workspace forwarders
jtravs Nov 12, 2026
2da322d
Bind the native problem as nested structs filled by one lowering
jtravs Nov 12, 2026
ccf8d8d
Write the native problem's stub as plain attributes
jtravs Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ jobs:
path: wheelhouse
key: >-
native-wheel-v1-${{ matrix.id }}-${{ hashFiles('native/**', '!native/tests/**',
'!native/benchmarks/**', '!native/**/*.md') }}
'!native/**/*.md') }}
- if: steps.cache.outputs.cache-hit != 'true' && runner.os == 'Linux'
name: Install the native toolchain
run: |
Expand Down Expand Up @@ -563,7 +563,7 @@ jobs:
- name: Install the native toolchain
run: |
sudo apt-get update
sudo apt-get install --yes clang-tidy cmake g++-14 libfftw3-dev ninja-build pkg-config
sudo apt-get install --yes cmake g++-14 libfftw3-dev ninja-build pkg-config
- run: uv python install 3.14
- run: uv sync --locked --no-install-package solprop-native
- run: uv run poe check-native
Expand Down Expand Up @@ -608,7 +608,6 @@ jobs:
cmake --preset cuda \
-DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_CUDA_HOST_COMPILER=g++-14 \
-DCUDA_ROOT=/usr/local/cuda-12.8 \
-DSOLPROP_NATIVE_BUILD_BENCHMARKS=OFF \
-DPython_EXECUTABLE="$GITHUB_WORKSPACE/.venv/bin/python"
- name: Compile, tests included
working-directory: native
Expand Down Expand Up @@ -656,7 +655,6 @@ jobs:
cmake --preset hip \
-DCMAKE_CXX_COMPILER="$ROCM_PATH/bin/hipcc" -DCMAKE_PREFIX_PATH="$ROCM_PATH" \
-DCMAKE_CXX_SCAN_FOR_MODULES=OFF -DKokkos_ENABLE_ROCTHRUST=OFF \
-DSOLPROP_NATIVE_BUILD_BENCHMARKS=OFF \
-DPython_EXECUTABLE="$GITHUB_WORKSPACE/.venv/bin/python"
- name: Compile, tests included
working-directory: native
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/cuda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
name: NVIDIA CUDA validation

# Manual workflow for a self-hosted Linux runner labelled nvidia-gpu, with an NVIDIA
# GPU, the CUDA Toolkit (nvcc, cuFFT, cuBLAS, Compute Sanitizer) and GCC 13 or newer.
# GPU, the CUDA Toolkit 12.8 or newer (nvcc, cuFFT, cuBLAS, Compute Sanitizer) and GCC 14
# or newer (CMakeLists.txt refuses an older host compiler).
# Set the repository variable SOLPROP_NATIVE_CUDA_ARCH to the runner's Kokkos
# architecture (for example AMPERE80, ADA89 or HOPPER90); HOPPER90 is used when unset.
# The repository is public: keep this workflow dispatch-only and never let the
Expand Down Expand Up @@ -58,3 +59,5 @@ jobs:
run: |
compute-sanitizer --tool memcheck --error-exitcode 1 ../.venv/bin/pytest tests/test_numerics.py
compute-sanitizer --tool racecheck --error-exitcode 1 ../.venv/bin/pytest tests/test_numerics.py
compute-sanitizer --tool initcheck --error-exitcode 1 ../.venv/bin/pytest tests/test_numerics.py
compute-sanitizer --tool synccheck --error-exitcode 1 ../.venv/bin/pytest tests/test_numerics.py
204 changes: 204 additions & 0 deletions .github/workflows/native-deep.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
# SPDX-FileCopyrightText: 2026 John C. Travers and contributors
#
# SPDX-License-Identifier: GPL-3.0-or-later

name: Native deep checks

# Weekly, by hand, and on a pull request that changes this file: the native checks too
# slow for every pull request. Each job reports (an artifact and the job summary) and
# gates nothing.
#
# - coverage: Clang source coverage of the native code over the GoogleTest suite and
# the native pytest suite (SOLPROP_NATIVE_ENABLE_COVERAGE). Its uncovered lines are
# where to look for dead code.
# - extension-asan: the extension itself built with ASan and UBSan and run under the
# native pytest suite, which exercises the nanobind bindings the gate's sanitizer
# stage (GoogleTest only) never reaches.
# - include-cleaner: clang-tidy's misc-include-cleaner over the sources, as a report of
# missing and unused includes.

on:
schedule:
- cron: "17 3 * * 1"
workflow_dispatch:
# A pull request that changes this workflow runs it, so that a change is seen to work
# before the next weekly run (dispatch needs the workflow on the default branch).
pull_request:
paths:
- .github/workflows/native-deep.yml

permissions:
contents: read

concurrency:
group: native-deep-${{ github.ref }}
cancel-in-progress: true

jobs:
coverage:
runs-on: ubuntu-24.04
timeout-minutes: 240
env:
CC: clang-18
CXX: clang++-18
OMP_PROC_BIND: "false"
SOLPROP_NATIVE_THREADS: "2"
UV_NO_SYNC: "1"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
with:
enable-cache: true
- name: Install Clang, its OpenMP runtime and FFTW
run: |
sudo apt-get update
sudo apt-get install --yes clang-18 llvm-18 libomp-18-dev cmake libfftw3-dev ninja-build pkg-config
- run: uv python install 3.14
- run: uv sync --locked --no-install-package solprop-native
- name: Build the instrumented extension and native tests
# FFTW's pthreads library: Ubuntu's OpenMP FFTW links GNU OpenMP, and Clang's
# build runs LLVM's. No vendor BLAS (the reference profile).
# Report-only: a warning from this job's compiler, which no pull-request lane
# builds with, does not stop the report.
env:
CMAKE_ARGS: >-
-DSOLPROP_NATIVE_WARNINGS_AS_ERRORS=OFF
-DSOLPROP_NATIVE_ENABLE_COVERAGE=ON
-DSOLPROP_NATIVE_PROFILE=REFERENCE
-DSOLPROP_NATIVE_FFTW_THREADING=PTHREADS
-DBUILD_TESTING=ON
run: |
uv pip install --no-deps --no-build-isolation -e native \
--config-settings build-dir=build/coverage
- name: GoogleTest suite
continue-on-error: true
env:
LLVM_PROFILE_FILE: ${{ github.workspace }}/profiles/gtest-%p-%m.profraw
run: native/build/coverage/solprop_native_tests
- name: Native pytest suite
continue-on-error: true
working-directory: native
env:
LLVM_PROFILE_FILE: ${{ github.workspace }}/profiles/pytest-%p-%m.profraw
run: uv run pytest -n 2 -p no:cacheprovider
- name: Report
if: always()
run: |
extension=$(uv run python -c "import solprop_native._core as m; print(m.__file__)")
llvm-profdata-18 merge -sparse profiles/*.profraw -o coverage.profdata
objects=("$extension" -object native/build/coverage/solprop_native_tests)
sources=(native/src native/include/solprop_native)
mkdir -p native-coverage
llvm-cov-18 report "${objects[@]}" -instr-profile coverage.profdata "${sources[@]}" \
| tee native-coverage/report.txt
llvm-cov-18 show "${objects[@]}" -instr-profile coverage.profdata "${sources[@]}" \
-format=html -show-line-counts-or-regions -output-dir native-coverage/html
{ echo '## Native source coverage'; echo '```'; tail -n 40 native-coverage/report.txt; echo '```'; } >> "$GITHUB_STEP_SUMMARY"
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: always()
with:
name: native-coverage
path: native-coverage
retention-days: 30

extension-asan:
runs-on: ubuntu-24.04
timeout-minutes: 240
env:
CXX: g++-14
OMP_PROC_BIND: "false"
SOLPROP_NATIVE_THREADS: "2"
UV_NO_SYNC: "1"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
with:
enable-cache: true
- name: Install the native toolchain
run: |
sudo apt-get update
sudo apt-get install --yes cmake g++-14 libfftw3-dev ninja-build pkg-config
- run: uv python install 3.14
- run: uv sync --locked --no-install-package solprop-native
- name: Build the extension with ASan, UBSan and Kokkos bounds checks
env:
CMAKE_ARGS: >-
-DSOLPROP_NATIVE_WARNINGS_AS_ERRORS=OFF
-DSOLPROP_NATIVE_ENABLE_SANITIZERS=ON
-DSOLPROP_NATIVE_PROFILE=REFERENCE
-DKokkos_ENABLE_DEBUG_BOUNDS_CHECK=ON
run: |
uv pip install --no-deps --no-build-isolation -e native \
--config-settings build-dir=build/asan \
--config-settings cmake.build-type=RelWithDebInfo
- name: Native pytest suite under the sanitizers
working-directory: native
# Python is not instrumented, so the ASan runtime is preloaded, with libstdc++
# beside it: ASan resolves __cxa_throw when it starts, and Python loads no C++
# runtime of its own, so without it every C++ exception aborts. CPython's own
# allocations at exit are not leaks of this package. setarch -R: Ubuntu's
# high-entropy ASLR can map a library inside ASan's shadow range. Report-only:
# the summary records the outcome and the log is the artifact.
run: |
set -o pipefail
export LD_PRELOAD="$(g++-14 -print-file-name=libasan.so):$(g++-14 -print-file-name=libstdc++.so)"
export ASAN_OPTIONS=detect_leaks=0:abort_on_error=1
export UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
status=0
setarch "$(uname -m)" -R uv run pytest -n 2 -p no:cacheprovider 2>&1 | tee ../asan.log || status=$?
{ echo '## Native pytest under ASan and UBSan'; echo "exit status ${status}"; echo '```'
grep -E 'ERROR: AddressSanitizer|runtime error|^FAILED|passed|failed' ../asan.log | tail -n 40
echo '```'; } >> "$GITHUB_STEP_SUMMARY"
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: always()
with:
name: native-extension-asan
path: asan.log
retention-days: 30

include-cleaner:
runs-on: ubuntu-24.04
timeout-minutes: 90
env:
CXX: g++-14
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
with:
enable-cache: true
- name: Install the native toolchain
run: |
sudo apt-get update
sudo apt-get install --yes cmake g++-14 libfftw3-dev ninja-build pkg-config
- run: uv python install 3.14
- run: uv sync --locked --no-install-package solprop-native
- name: Configure the cpu-tidy preset (compile commands and generated headers)
working-directory: native
run: |
cmake --preset cpu-tidy -DCMAKE_CXX_COMPILER="$(command -v g++-14)" \
-DPython_EXECUTABLE="$GITHUB_WORKSPACE/.venv/bin/python"
# SLEEF's header comes from its own build.
cmake --build --preset cpu-tidy --target solprop_native_sleef_build
- name: misc-include-cleaner
run: |
build=native/build/presets/cpu-tidy
# The pinned clang-tidy and the arguments the build gives it.
mapfile -t tidy < "$build/clang_tidy_command.txt"
git ls-files -z -- 'native/src/*.cpp' 'native/tests/native/*.cpp' |
xargs -0 -n 1 -P "$(nproc)" "${tidy[@]}" --quiet -p "$build" \
--checks='-*,misc-include-cleaner' --warnings-as-errors='' \
> include-cleaner.txt 2>&1 || true
findings=$(grep -c 'misc-include-cleaner' include-cleaner.txt || true)
echo "## misc-include-cleaner: ${findings} findings" >> "$GITHUB_STEP_SUMMARY"
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: always()
with:
name: native-include-cleaner
path: include-cleaner.txt
retention-days: 30
10 changes: 5 additions & 5 deletions native/benchmarks/size_cliffs.py → benchmarks/size_cliffs.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
cheapest, because fixed per-evaluation costs make small grids dearer per sample.
``--check`` exits non-zero on one. Run on a quiet machine, with the threads pinned::

OMP_PLACES=cores OMP_PROC_BIND=close python native/benchmarks/size_cliffs.py --check
OMP_PLACES=cores OMP_PROC_BIND=close python -m benchmarks.size_cliffs --check
"""

from __future__ import annotations
Expand All @@ -31,6 +31,10 @@
import warnings
from typing import Any, cast

from solprop.driver import Simulation
from solprop.grid import FieldGrid
from solprop.stepper import RungeKutta

FACTORS = (1.0, 1.125, 1.25, 1.375, 1.5, 1.75, 2.0)
LENGTH = 1.5
STEP = LENGTH / 4000
Expand All @@ -39,10 +43,6 @@

def simulation(factor: float, fft_size: str, backend: str, steps: int) -> Any:
"""Return the RDW case on one grid, with `steps` capped Runge-Kutta steps."""
from solprop.driver import Simulation
from solprop.grid import FieldGrid
from solprop.stepper import RungeKutta

grid = FieldGrid.from_limits(
LENGTH, 800e-9, (90e-9, 4e-6), factor * 400e-15, fft_size=fft_size
)
Expand Down
Loading
Loading