Skip to content

ci: enable CUDA test compilation in CI (#22) #166

ci: enable CUDA test compilation in CI (#22)

ci: enable CUDA test compilation in CI (#22) #166

Workflow file for this run

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 }}