Skip to content

Commit a4564a4

Browse files
committed
Clean up CMake and MATLAB/CUDA build system
- Simplifies and unifies CMake setup - Adds developer tools: cppcheck, IWYU, clang-tidy - Enables proper LTO support - Cleans and speeds up CI pipeline - Improves compatibility across Linux, Windows, and macOS - Updates dependencies and fixes MATLAB + CUDA integration - Removes reliance on MATLAB OpenMP, adjusts CUDA/MEX handling - Fixes various typos, warnings, and deployment target issues
1 parent 180beb9 commit a4564a4

40 files changed

+1607
-704
lines changed

.github/workflows/C++.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
name: C++ Build
22

33
on:
4-
push:
5-
branches:
6-
- master
7-
tags:
8-
- v*
94
pull_request:
105
branches:
116
- master

.github/workflows/build_cufinufft_wheels.yml

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
name: Build cufinufft Python wheels
22

3-
on: [push, pull_request]
3+
on:
4+
# Weekly schedule (Sunday 00:00 UTC)
5+
schedule:
6+
- cron: "0 0 * * 0"
7+
8+
# On tag push
9+
push:
10+
tags:
11+
- 'v*'
12+
# Manual trigger (with an optional deploy toggle)
13+
workflow_dispatch:
14+
inputs:
15+
deploy:
16+
description: "Deploy after build?"
17+
type: boolean
18+
required: false
19+
default: false
420

521
jobs:
622
build_wheels:
@@ -17,9 +33,16 @@ jobs:
1733
- uses: ilammy/msvc-dev-cmd@v1
1834
- name: Setup CUDA
1935
if: ${{ matrix.buildplat[0] == 'windows-2022' }}
20-
uses: Jimver/[email protected].21
36+
uses: Jimver/[email protected].24
2137
with:
2238
cuda: '12.4.0'
39+
method: 'network'
40+
linux-local-args: '["--toolkit"]'
41+
log-file-suffix: '${{matrix.os}}-cuda-install.txt'
42+
sub-packages: ${{runner.os == 'Linux' && '["nvcc", "cudart"]' || '["nvcc", "cudart", "cufft", "cufft_dev"]'}}
43+
non-cuda-sub-packages: ${{runner.os == 'Linux' && '["libcufft","libcufft-dev"]' || '[]'}}
44+
use-local-cache: 'false'
45+
use-github-cache: 'false' #it is not working at the moment https://github.com/Jimver/cuda-toolkit/issues/390
2346
- name: Build ${{ matrix.buildplat[1] }} wheels
2447
uses: pypa/[email protected]
2548
with:

.github/workflows/build_finufft_wheels.yml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
name: Build and test finufft Python wheels
22

3-
on: [ push, pull_request ]
3+
on:
4+
# Weekly schedule (Sunday 00:00 UTC)
5+
schedule:
6+
- cron: "0 0 * * 0"
7+
8+
# On tag push
9+
push:
10+
tags:
11+
- 'v*'
12+
# Manual trigger (with an optional deploy toggle)
13+
workflow_dispatch:
14+
inputs:
15+
deploy:
16+
description: "Deploy after build?"
17+
type: boolean
18+
required: false
19+
default: false
20+
421

522
jobs:
623
build_wheels:

.github/workflows/cmake_ci.yml

Lines changed: 123 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,6 @@ name: cmake ci linux macos windows
33
on: [push, pull_request]
44

55
jobs:
6-
prepare:
7-
runs-on: ubuntu-22.04
8-
outputs:
9-
matrix: ${{ steps.generate_matrix.outputs.matrix }}
10-
steps:
11-
- name: Checkout code
12-
uses: actions/checkout@v4
13-
- name: Generate matrix
14-
id: generate_matrix
15-
run: |
16-
MATRIX=$(python3 ${{ github.workspace }}/.github/workflows/generate_cmake_matrix.py)
17-
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
186
pip-requirements:
197
runs-on: ubuntu-22.04
208
steps:
@@ -23,7 +11,7 @@ jobs:
2311
- name: Set up Python
2412
uses: actions/setup-python@v5
2513
with:
26-
cache : 'pip'
14+
cache: 'pip'
2715
python-version: '3.10'
2816
- name: Generate requirements.txt
2917
run: |
@@ -38,142 +26,193 @@ jobs:
3826
with:
3927
name: requirements
4028
path: requirements.txt
29+
4130
cache:
4231
strategy:
4332
matrix:
44-
os:
45-
- ubuntu-22.04
46-
- windows-2022
33+
os: [ubuntu-22.04, windows-2022]
4734
runs-on: ${{ matrix.os }}
4835
steps:
4936
- name: Checkout code
5037
uses: actions/checkout@v4
5138
- name: create cache directory
52-
run: |
53-
mkdir -p cpm
39+
shell: bash
40+
run: mkdir -p "cpm"
5441
- name: Check if cache exists
5542
id: cache
5643
uses: actions/cache@v4
5744
with:
58-
key: cpm-cache-00-${{ runner.os == 'windows' && 'windows-' || '' }}${{ hashFiles('CMakeLists.txt', 'cmake/*') }}
45+
key: cpm-cache-00-${{ runner.os == 'windows' && 'windows-' || '' }}${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
5946
enableCrossOsArchive: true
6047
path: cpm
61-
- name: Setup Cpp
48+
- name: Setup Cpp (on cache miss)
6249
if: steps.cache.outputs.cache-hit != 'true'
6350
uses: aminya/setup-cpp@v1
6451
with:
65-
cmake : true
66-
- name: Download dependencies in cache linux
52+
cmake: true
53+
- name: Download dependencies in cache (Linux)
6754
if: steps.cache.outputs.cache-hit != 'true' && runner.os == 'Linux'
6855
run: |
69-
cmake -S . -B ./build
56+
cmake -S . -B ./build -DCPM_SOURCE_CACHE="cpm"
7057
rm -rf build
71-
cmake -S . -B ./build -DFINUFFT_USE_DUCC0=ON
72-
env:
73-
CPM_SOURCE_CACHE: cpm
74-
- name: Download dependencies in cache windows
58+
cmake -S . -B ./build -DFINUFFT_USE_DUCC0=ON -DCPM_SOURCE_CACHE="cpm"
59+
- name: Download dependencies in cache (Windows)
7560
if: steps.cache.outputs.cache-hit != 'true' && runner.os != 'Linux'
7661
run: |
77-
cmake -S . -B build
62+
cmake -S . -B build -DCPM_SOURCE_CACHE="cpm"
7863
rm build -r -force
79-
cmake -S . -B build -DFINUFFT_USE_DUCC0=ON
80-
env:
81-
CPM_SOURCE_CACHE: cpm
64+
cmake -S . -B build -DFINUFFT_USE_DUCC0=ON -DCPM_SOURCE_CACHE="cpm"
8265
- name: Cache dependencies
66+
if: steps.cache.outputs.cache-hit != 'true'
8367
uses: actions/cache/save@v4
8468
with:
85-
key: cpm-cache-00-${{ runner.os == 'windows' && 'windows-' || '' }}${{ hashFiles('CMakeLists.txt', 'cmake/*') }}
69+
key: cpm-cache-00-${{ runner.os == 'windows' && 'windows-' || '' }}${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
8670
enableCrossOsArchive: true
8771
path: cpm
72+
8873
cmake-ci:
8974
runs-on: ${{ matrix.os }}
90-
needs: [prepare, cache, pip-requirements]
75+
needs: [cache, pip-requirements]
76+
env:
77+
CMAKE_GENERATOR: Ninja
78+
CPM_SOURCE_CACHE: cpm
79+
CTEST_OUTPUT_ON_FAILURE: "1"
80+
SCCACHE_GHA_ENABLED: "true"
81+
SCCACHE_GHA_VERSION: "0"
82+
CMAKE_C_COMPILER_LAUNCHER: sccache
83+
CMAKE_CXX_COMPILER_LAUNCHER: sccache
84+
CMAKE_CUDA_COMPILER_LAUNCHER: sccache
9185
strategy:
9286
fail-fast: false
93-
matrix: ${{ fromJSON(needs.prepare.outputs.matrix) }}
87+
matrix:
88+
include:
89+
- { os: ubuntu-22.04, toolchain: gcc-10 }
90+
- { os: ubuntu-22.04, toolchain: gcc-11 }
91+
- { os: ubuntu-22.04, toolchain: gcc-12 }
92+
- { os: ubuntu-22.04, toolchain: gcc-13 }
93+
- { os: ubuntu-22.04, toolchain: clang-16 }
94+
- { os: ubuntu-22.04, toolchain: clang-17 }
95+
- { os: ubuntu-22.04, toolchain: clang-18 }
96+
97+
- { os: windows-2022, toolchain: msvc }
98+
- { os: windows-2022, toolchain: clang-19 }
99+
100+
- { os: macos-13, toolchain: llvm }
101+
- { os: macos-13, toolchain: gcc-14 }
102+
- { os: macos-14, toolchain: llvm }
103+
- { os: macos-14, toolchain: gcc-14 }
104+
- { os: macos-15, toolchain: llvm }
105+
# - { os: macos-15, toolchain: gcc-15 } # it is broken at the moment, but it is not caused by finufft
106+
94107
steps:
95108
- name: Checkout code
96109
uses: actions/checkout@v4
110+
97111
- name: Restore Cache
98112
uses: actions/cache/restore@v4
99113
with:
100-
key: cpm-cache-00-${{ runner.os == 'windows' && 'windows-' || '' }}${{ hashFiles('CMakeLists.txt', 'cmake/*') }}
114+
key: cpm-cache-00-${{ runner.os == 'windows' && 'windows-' || '' }}${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
101115
enableCrossOsArchive: true
102116
path: cpm
117+
103118
- name: Download requirements.txt
104119
uses: actions/download-artifact@v4
105120
with:
106121
name: requirements
122+
107123
- name: Run sccache-cache
108124
uses: mozilla-actions/[email protected]
109-
- name: Set caching env vars
110-
run: |
111-
echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV
112-
echo "SCCACHE_GHA_VERSION=0" >> $GITHUB_ENV
113-
- name: Set up sccache on Windows
114-
if: runner.os == 'Windows'
115-
run: Add-Content -Path $env:GITHUB_ENV -Value "SCCACHE_GHA_ENABLED=true"
125+
116126
- name: Setup Cpp
117-
uses: aminya/setup-cpp@v1.1.1
127+
uses: aminya/setup-cpp@v1
118128
with:
119129
compiler: ${{ matrix.toolchain }}
120-
vcvarsall: ${{ contains(matrix.os, 'windows') }}
130+
vcvarsall: true
121131
cmake: true
122132
ninja: true
123-
vcpkg: false
124-
cppcheck: false
125-
clangtidy: false
126-
- name: Set min macOS version and install fftw
127-
if: runner.os == 'macOS'
133+
134+
- name: Install toolchain + FFTW (macOS)
135+
if: startsWith(matrix.os, 'macos-')
128136
run: |
129-
brew install fftw libomp
130-
- name: Install fftw
131-
if: runner.os == 'linux'
137+
export HOMEBREW_NO_ANALYTICS=1 HOMEBREW_NO_INSTALL_CLEANUP=1
138+
brew install libomp fftw
139+
{
140+
echo "LDFLAGS=-L$(brew --prefix libomp)/lib"
141+
echo "CPPFLAGS=-I$(brew --prefix libomp)/include"
142+
echo "LIBRARY_PATH=$(brew --prefix libomp)/lib"
143+
echo "DYLD_LIBRARY_PATH=$(brew --prefix libomp)/lib"
144+
echo "CMAKE_PREFIX_PATH=$(brew --prefix libomp)"
145+
ver="${{ matrix.os }}"; ver="${ver#macos-}"
146+
echo "MACOSX_DEPLOYMENT_TARGET=${ver}.0"
147+
} >> "$GITHUB_ENV"
148+
149+
- name: Install fftw (Linux)
150+
if: runner.os == 'Linux'
132151
run: |
133152
sudo apt update
134153
sudo apt install -y libfftw3-dev
135-
- name: Configure Cmake
136-
run: |
137-
cmake -S . -B ./build -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DCMAKE_BUILD_TYPE:STRING=${{matrix.build_type}} -DFINUFFT_ARCH_FLAGS=${{ matrix.arch_flags }} -DFINUFFT_BUILD_TESTS=ON -DFINUFFT_STATIC_LINKING=${{matrix.finufft_static_linking}} -DFINUFFT_USE_DUCC0=${{ matrix.ducc_fft }} -DFINUFFT_ENABLE_SANITIZERS=${{matrix.build_type == 'Debug'}}
138-
env:
139-
CPM_SOURCE_CACHE: cpm
140-
- name: Build
141-
run: |
142-
cmake --build ./build --config ${{matrix.build_type}}
143-
- name: Test
144-
working-directory: ./build
145-
run: |
146-
ctest -C ${{matrix.build_type}} --output-on-failure
154+
147155
- name: Set up Python
148-
if: matrix.finufft_static_linking == 'off'
149156
uses: actions/setup-python@v5
150157
with:
151158
python-version: '3.10'
152159
cache: 'pip'
153160
cache-dependency-path: requirements.txt
154-
- name: Build Python wheels
155-
if: matrix.finufft_static_linking == 'off'
156-
env:
157-
MACOSX_DEPLOYMENT_TARGET: 13
158-
CPM_SOURCE_CACHE: cpm
159-
shell: bash
161+
162+
- name: Install Python requirements
160163
run: |
161164
python3 -m pip install --upgrade pip
162165
python3 -m pip install -r requirements.txt
163-
python3 -m pip install \
164-
--verbose \
165-
-C cmake.define.CMAKE_BUILD_TYPE=${{ matrix.build_type }} \
166-
-C cmake.define.FINUFFT_ARCH_FLAGS=${{ matrix.arch_flags }} \
167-
-C cmake.define.FINUFFT_USE_DUCC0=${{ matrix.ducc_fft }} \
168-
-C cmake.define.CMAKE_CXX_COMPILER_LAUNCHER=sccache \
169-
-C cmake.define.CMAKE_C_COMPILER_LAUNCHER=sccache \
170-
-C cmake.define.CMAKE_GENERATOR=Ninja \
171-
-C cmake.define.CMAKE_GENERATOR_PLATFORM= \
172-
python/finufft
173-
- name: Test Python package
174-
if: matrix.finufft_static_linking == 'off'
166+
167+
- name: Build and test configurations
168+
shell: bash
175169
run: |
176-
python3 -m pytest python/finufft/test
170+
if [[ "$RUNNER_OS" == "Windows" ]]; then
171+
configs=("build_type=Release ducc_fft=On" "build_type=Debug ducc_fft=On")
172+
else
173+
configs=("build_type=Release ducc_fft=On" "build_type=Release ducc_fft=Off" \
174+
"build_type=Debug ducc_fft=On" "build_type=Debug ducc_fft=Off")
175+
fi
176+
177+
if [[ "${{ matrix.toolchain }}" == "msvc" ]]; then
178+
arch_flags=("/arch:AVX2" "/arch:SSE2" "native")
179+
elif [[ "$RUNNER_OS" == "Linux" ]]; then
180+
arch_flags=("-march=x86-64" "-march=x86-64-v2" "-march=x86-64-v3" "-march=native")
181+
else
182+
arch_flags=("native")
183+
fi
184+
185+
for arch in "${arch_flags[@]}"; do
186+
arch_dir=$(echo "$arch" | tr -c 'A-Za-z0-9' '_')
187+
for cfg in "${configs[@]}"; do
188+
eval "$cfg"
189+
build_dir="build_${build_type}_${ducc_fft}_${arch_dir}"
190+
191+
cmake -E make_directory "$build_dir"
192+
cmake -S . -B "$build_dir" \
193+
-DCMAKE_BUILD_TYPE=$build_type \
194+
-DFINUFFT_ARCH_FLAGS="$arch" \
195+
-DFINUFFT_USE_DUCC0=$ducc_fft \
196+
-DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=Embedded \
197+
-DCMAKE_POLICY_DEFAULT_CMP0141=NEW
198+
# CMake will pick the toolchain set by setup-cpp (and macOS brew block for gcc-14).
199+
200+
cmake --build "$build_dir" --config "$build_type"
201+
(cd "$build_dir" && ctest -C "$build_type")
202+
203+
python3 -m pip install \
204+
--verbose \
205+
-C cmake.define.CMAKE_BUILD_TYPE=$build_type \
206+
-C cmake.define.FINUFFT_ARCH_FLAGS="$arch" \
207+
-C cmake.define.FINUFFT_USE_DUCC0=$ducc_fft \
208+
-C cmake.define.CMAKE_MSVC_DEBUG_INFORMATION_FORMAT=Embedded \
209+
-C cmake.define.CMAKE_POLICY_DEFAULT_CMP0141=NEW \
210+
python/finufft
211+
212+
python3 -m pytest python/finufft/test
213+
done
214+
done
215+
177216
cleanup:
178217
runs-on: ubuntu-22.04
179218
needs: cmake-ci

0 commit comments

Comments
 (0)