ci: enable CUDA test compilation in CI (#22) #166
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
| name: CI | |
| on: | |
| push: | |
| branches: [ "main" ] | |
| pull_request: | |
| branches: [ "main" ] | |
| workflow_dispatch: | |
| jobs: | |
| # ─── Static Analysis & Linting ───────────────────────── | |
| static-analysis: | |
| name: Static Analysis (cppcheck) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install cppcheck | |
| run: sudo apt-get update && sudo apt-get install -y cppcheck | |
| - name: Run cppcheck | |
| run: | | |
| cppcheck --enable=warning,performance,portability --suppress=missingIncludeSystem --inconclusive --error-exitcode=1 rippra/src/ rippra/include/ rippra/tests/ | |
| # ─── Formatting Check ──────────────────────────────── | |
| formatting: | |
| name: Code Formatting (clang-format) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install clang-format | |
| run: sudo apt-get update && sudo apt-get install -y clang-format | |
| - name: Check formatting | |
| run: | | |
| # Check only .c/.h files changed in this PR against the base branch. | |
| # Full codebase reformat is a separate follow-up. | |
| BASE="${GITHUB_BASE_REF:-main}" | |
| git fetch origin "$BASE" --depth=1 2>/dev/null || true | |
| CHANGED=$(git diff --name-only "origin/$BASE...HEAD" -- '*.c' '*.h' 2>/dev/null || echo "") | |
| if [ -z "$CHANGED" ]; then | |
| echo "No C/H files changed relative to $BASE." | |
| else | |
| echo "$CHANGED" | xargs clang-format --dry-run --Werror | |
| fi | |
| codeql: | |
| name: CodeQL Security Scan | |
| runs-on: ubuntu-latest | |
| permissions: | |
| security-events: write | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Initialize CodeQL | |
| uses: github/codeql-action/init@v3 | |
| with: | |
| languages: c-cpp | |
| - name: Configure CMake | |
| run: cmake -B build -S . | |
| - name: Build | |
| run: cmake --build build | |
| - name: Perform CodeQL Analysis | |
| uses: github/codeql-action/analyze@v3 | |
| # ─── Linux Build + Tests + ASan ───────────────────────── | |
| linux: | |
| name: Linux Build & Test (ASan/UBSan) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y gcc cmake libomp-dev | |
| - name: Configure CMake with Sanitizers | |
| run: | | |
| cmake -B build -S . \ | |
| -DCMAKE_C_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -g -O2" \ | |
| -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined" | |
| - name: Build | |
| run: cmake --build build -j | |
| - name: Generate synthetic test data | |
| working-directory: rippra | |
| run: | | |
| pip install --quiet numpy | |
| python ml/synthetic_shwfs.py | |
| - name: Run Tests | |
| working-directory: build | |
| run: ctest --output-on-failure | |
| env: | |
| ASAN_OPTIONS: detect_leaks=1 | |
| # ─── Linux Performance Benchmarks ──────────────────────── | |
| benchmarks: | |
| name: Performance Benchmarks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install dependencies | |
| run: sudo apt-get install -y gcc cmake libomp-dev | |
| - name: Configure CMake (Release) | |
| run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DRIPRA_BUILD_BENCHMARKS=ON | |
| - name: Build Benchmarks | |
| run: cmake --build build -j --target benchmark_centroid benchmark_openmp benchmark_e2e | |
| - name: Generate synthetic test data | |
| working-directory: rippra | |
| run: | | |
| pip install --quiet numpy | |
| python ml/synthetic_shwfs.py | |
| - name: Run Benchmarks | |
| working-directory: rippra | |
| run: | | |
| mkdir -p ../benchmark_results | |
| ../build/benchmark_centroid | tee ../benchmark_results/centroid.txt | |
| ../build/benchmark_openmp | tee ../benchmark_results/openmp.txt | |
| ../build/benchmark_e2e | tee ../benchmark_results/e2e.txt | |
| - name: Run OpenMP Scaling Benchmark | |
| working-directory: rippra | |
| run: | | |
| for threads in 1 2 4 8; do | |
| echo "=== OMP_NUM_THREADS=$threads ===" | |
| OMP_NUM_THREADS=$threads ../build/benchmark_openmp 2>&1 | tee -a ../benchmark_results/scaling.txt | |
| echo "" | |
| done | |
| - name: Upload Benchmark Artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: performance-benchmarks | |
| path: benchmark_results/ | |
| # ─── Windows (MinGW) build + test ────────────────────── | |
| windows: | |
| name: Windows Build & Test | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Configure CMake | |
| run: cmake -B build -S . -G "MinGW Makefiles" | |
| - name: Build | |
| run: cmake --build build -j | |
| - name: Generate synthetic test data | |
| working-directory: rippra | |
| run: | | |
| pip install --quiet numpy | |
| python ml/synthetic_shwfs.py | |
| - name: Run Tests | |
| working-directory: build | |
| run: ctest --output-on-failure | |
| # ─── Python ML Validation ─────────────────────────── | |
| python: | |
| name: Python ML Reproducibility | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.10' | |
| - name: Install Python deps | |
| run: pip install --quiet numpy matplotlib scipy onnx onnxscript onnxruntime pandas torch | |
| - name: Generate synthetic test data | |
| working-directory: rippra | |
| run: | | |
| pip install --quiet numpy | |
| python ml/synthetic_shwfs.py | |
| - name: Run complete reproducibility validation | |
| working-directory: rippra | |
| run: python tools/reproduce_all.py | |
| # ─── CUDA Build ─────────────────────────────────────── | |
| cuda: | |
| name: CUDA Build Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install dependencies | |
| run: sudo apt-get update && sudo apt-get install -y gcc cmake libomp-dev | |
| - name: Install CUDA Toolkit | |
| uses: Jimver/cuda-toolkit@v0.2.35 | |
| with: | |
| use-github-cache: false | |
| use-local-cache: false | |
| continue-on-error: true | |
| - name: Configure CMake | |
| run: cmake -B build -S . | |
| - name: Build (all targets, CUDA if available) | |
| run: cmake --build build -j | |
| - name: Generate synthetic test data | |
| working-directory: rippra | |
| run: | | |
| pip install --quiet numpy | |
| python ml/synthetic_shwfs.py | |
| - name: Run CUDA tests (skips gracefully without GPU) | |
| continue-on-error: true | |
| run: ctest --test-dir build -R test_cuda --output-on-failure | |
| publish-package: | |
| name: Publish Docker Image to GHCR | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| needs: [linux, python] | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Lowercase Repository Name | |
| id: string | |
| run: | | |
| echo "repo_name=$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and Push Docker Image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| push: true | |
| tags: | | |
| ghcr.io/${{ steps.string.outputs.repo_name }}:latest | |
| ghcr.io/${{ steps.string.outputs.repo_name }}:${{ github.sha }} |