Skip to content

feat(benchmark): add performance report generation and clean output d… #75

feat(benchmark): add performance report generation and clean output d…

feat(benchmark): add performance report generation and clean output d… #75

Workflow file for this run

name: CI
on:
pull_request:
push:
workflow_dispatch:
permissions:
contents: read
jobs:
build:
uses: ./.github/workflows/build-matrix.yml
with:
build_type: Debug
run_tests: true
clang-format-report:
name: clang-format report
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Homebrew
uses: Homebrew/actions/setup-homebrew@main
- name: Install latest clang-format and gersemi (Linuxbrew)
shell: bash
run: |
set -euo pipefail
brew update
brew install clang-format gersemi
brew upgrade clang-format gersemi
echo "$(brew --prefix clang-format)/bin" >> "$GITHUB_PATH"
echo "$(brew --prefix)/bin" >> "$GITHUB_PATH"
clang-format --version
gersemi --version
- name: Check formatting
shell: bash
run: |
set -euo pipefail
mapfile -t files < <(git ls-files \
'*.c' '*.cc' '*.cpp' '*.cxx' '*.h' '*.hpp' '*.hxx' '*.inl')
if [ "${#files[@]}" -eq 0 ]; then
echo "No format-managed files found."
exit 0
fi
clang-format --dry-run --Werror "${files[@]}"
- name: Check CMake formatting
shell: bash
run: |
set -euo pipefail
mapfile -t cmake_files < <(git ls-files \
'CMakeLists.txt' '*.cmake')
if [ "${#cmake_files[@]}" -eq 0 ]; then
echo "No CMake files found."
exit 0
fi
gersemi --check "${cmake_files[@]}"
sanitizer:
name: Sanitizer ${{ matrix.name }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: ASAN+UBSAN+LSAN
build_dir: build/asan
c_flags: -fsanitize=address,undefined,leak -fno-omit-frame-pointer
cxx_flags: -fsanitize=address,undefined,leak -fno-omit-frame-pointer
exe_linker_flags: -fsanitize=address,undefined,leak
shared_linker_flags: -fsanitize=address,undefined,leak
requires_rtsan_probe: false
- name: TSAN
build_dir: build/tsan
c_flags: -fsanitize=thread -fno-omit-frame-pointer
cxx_flags: -fsanitize=thread -fno-omit-frame-pointer
exe_linker_flags: -fsanitize=thread
shared_linker_flags: -fsanitize=thread
requires_rtsan_probe: false
- name: RTSAN
build_dir: build/rtsan
c_flags: -fsanitize=realtime -fno-omit-frame-pointer
cxx_flags: -fsanitize=realtime -fno-omit-frame-pointer
exe_linker_flags: -fsanitize=realtime
shared_linker_flags: -fsanitize=realtime
requires_rtsan_probe: true
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Homebrew
uses: Homebrew/actions/setup-homebrew@main
- name: Install Homebrew packages
shell: bash
run: |
set -euo pipefail
brew update
brew install llvm
echo "$(brew --prefix llvm)/bin" >> "$GITHUB_PATH"
cmake --version
clang --version
- name: Probe realtime sanitizer support
if: matrix.requires_rtsan_probe
id: rtsan-probe
shell: bash
run: |
set -euo pipefail
cat > /tmp/rtsan_probe.cpp << 'EOF'
int main() { return 0; }
EOF
if clang++ -fsanitize=realtime /tmp/rtsan_probe.cpp -o /tmp/rtsan_probe >/dev/null 2>&1; then
echo "supported=true" >> "$GITHUB_OUTPUT"
else
echo "supported=false" >> "$GITHUB_OUTPUT"
fi
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Configure
if: ${{ !matrix.requires_rtsan_probe || steps.rtsan-probe.outputs.supported == 'true' }}
shell: bash
run: |
set -euo pipefail
cmake -B ${{ matrix.build_dir }} -G Ninja \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache \
-DCMAKE_C_FLAGS="${{ matrix.c_flags }}" \
-DCMAKE_CXX_FLAGS="${{ matrix.cxx_flags }}" \
-DCMAKE_EXE_LINKER_FLAGS="${{ matrix.exe_linker_flags }}" \
-DCMAKE_SHARED_LINKER_FLAGS="${{ matrix.shared_linker_flags }}"
- name: Build
if: ${{ !matrix.requires_rtsan_probe || steps.rtsan-probe.outputs.supported == 'true' }}
run: cmake --build ${{ matrix.build_dir }}
- name: Test
if: ${{ !matrix.requires_rtsan_probe || steps.rtsan-probe.outputs.supported == 'true' }}
run: ctest --test-dir ${{ matrix.build_dir }} --output-on-failure
- name: RTSAN unavailable note
if: ${{ matrix.requires_rtsan_probe && steps.rtsan-probe.outputs.supported != 'true' }}
run: |
echo "RTSAN is not supported by this LLVM toolchain; skipping job payload."
benchmark-linux-clang-release:
name: Benchmarks & Profiling
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Homebrew
uses: Homebrew/actions/setup-homebrew@main
- name: Install LLVM and Ninja (Linuxbrew)
shell: bash
run: |
set -euo pipefail
brew update
brew install llvm ninja
echo "$(brew --prefix llvm)/bin" >> "$GITHUB_PATH"
cmake --version
clang --version
- name: Ensure perf is available
shell: bash
run: |
set -euo pipefail
if ! command -v perf >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install -y linux-tools-generic
fi
perf --version
- name: Allow perf profiling (relax perf_event_paranoid)
shell: bash
run: |
set -euo pipefail
sudo sysctl -w kernel.perf_event_paranoid=1
- name: Cache CMake deps
uses: actions/cache@v4
with:
path: |
build/benchmark-release/_deps
key: >-
benchmark-linux-clang-release-${{ hashFiles('CMakeLists.txt', 'cmake/**/*.cmake', 'src/*_bench.cpp') }}
- name: Configure (Release, Clang)
shell: bash
run: |
set -euo pipefail
cmake -B build/benchmark-release -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DENABLE_BENCHMARK_TESTS=ON
- name: Build benchmarks
shell: bash
run: |
set -euo pipefail
cmake --build build/benchmark-release
- name: Run benchmarks
shell: bash
run: |
set -euo pipefail
ctest --test-dir build/benchmark-release --label-regex benchmark --output-on-failure
- name: Upload benchmark and profiling artifacts
uses: actions/upload-artifact@v4
with:
name: benchmark-linux-clang-release-results
path: build/benchmark-release/benchmarks/**
if-no-files-found: error
- name: Clean benchmark output directory
shell: bash
run: rm -rf build/benchmark-release/benchmarks