Skip to content

perf(hash): memcpy loads, overlap tails, 4-lane stripes for mh (#211) #809

perf(hash): memcpy loads, overlap tails, 4-lane stripes for mh (#211)

perf(hash): memcpy loads, overlap tails, 4-lane stripes for mh (#211) #809

Workflow file for this run

name: Test
# Branches only — release tags are handled by release.yml. Running this on tag
# pushes fired the full matrix needlessly and broke `trunk check`, which diffs
# against `github.event.before` (the prior tag object, gone after a tag move).
on:
push:
branches: ["**"]
permissions: read-all
jobs:
trunk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Trunk Check
uses: trunk-io/trunk-action@v1
- name: Trunk must not own git hooks
run: |
# Git hooks belong to pre-commit (see .pre-commit-config.yaml); trunk's
# git-hook actions are disabled in .trunk/trunk.yaml so trunk never
# clobbers pre-commit's clang-format run. This can only be checked here:
# a pre-commit hook can't (if trunk owned core.hooksPath, pre-commit
# would never run), and a trunk linter can't (it runs in an isolated
# sandbox blind to the real git config).
# 1) Config invariant: no trunk git-hook action may be enabled.
enabled="$(yq -r '.actions.enabled // [] | .[]' .trunk/trunk.yaml)"
for action in trunk-announce trunk-check-pre-commit trunk-check-pre-push \
trunk-check-pre-push-always trunk-fmt-pre-commit trufflehog-pre-commit; do
if grep -qxF "${action}" <<<"${enabled}"; then
echo "::error::trunk git-hook action '${action}' is enabled in .trunk/trunk.yaml; disable it so pre-commit keeps ownership of git hooks"
exit 1
fi
done
# 2) Runtime truth (when trunk is available): sync hooks, then require
# core.hooksPath not point back into trunk's cache.
if command -v trunk >/dev/null 2>&1; then
trunk git-hooks sync 2>&1 || true
hooks_path="$(git config --get core.hooksPath || true)"
if [[ "${hooks_path}" == *trunk* ]]; then
echo "::error::core.hooksPath is trunk-managed (${hooks_path}); trunk grabbed the git hooks"
exit 1
fi
fi
echo "OK: pre-commit owns git hooks; trunk is not managing them"
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- uses: pre-commit/action@v3.0.1
- uses: pre-commit-ci/lite-action@v1.0.2
if: always()
benchmark:
# Informational only (hence continue-on-error): shared runners are noisy, so
# these numbers are for architecture/compiler shape comparisons (x86_64 gcc
# vs arm64 Apple clang) and gross regressions, not precise gating. Results
# appear in the job log and as a JSON artifact per OS.
continue-on-error: true
strategy:
matrix:
os: [ubuntu-latest, macos-26]
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- uses: bazelbuild/setup-bazelisk@v3
- name: Run hash benchmark
run: |
bazel run -c opt //mbo/hash:hash_benchmark -- \
--benchmark_min_time=0.2s \
--benchmark_repetitions=3 \
--benchmark_report_aggregates_only=true \
--benchmark_out="${GITHUB_WORKSPACE}/hash_benchmark.json" \
--benchmark_out_format=json
- uses: actions/upload-artifact@v4
with:
name: hash-benchmark-${{matrix.os}}
path: hash_benchmark.json
test-gcc:
needs: pre-commit
secrets: inherit
strategy:
matrix:
os: [ubuntu-latest]
compiler: [gcc]
gcc_version: [13, 14]
bazel_config: [asan, cpp23, opt]
# Using `include` does not make the options show up in the generated config names...
exclude:
- bazel_config: asan
gcc_version: 13
- bazel_config: cpp23
gcc_version: 13
uses: ./.github/workflows/test.yml
with:
continue-on-error: false
os: ${{ matrix.os }}
compiler: ${{ matrix.compiler }}
gcc_version: ${{ matrix.gcc_version }}
bazel_config: ${{ matrix.bazel_config }}
test-bcr:
needs: [pre-commit, test-gcc]
secrets: inherit
strategy:
matrix:
os: [ubuntu-latest, macos-26]
compiler: [gcc, native, clang]
gcc_version: [13]
llvm_version: [20.1.8]
bazel_config: [opt]
# Bazel-version compatibility rungs, crossed with the os/compiler combos
# below. 7.2.1 is the earliest 7.x that works: MODULE.bazel uses
# `include()` (added in 7.2.0, so 7.1.x fails with "name 'include' is not
# defined") and the dep `depend_on_what_you_use@0.16.0` declares
# `bazel_compatibility: [>=7.2.1]` (so 7.2.0 is rejected too). Plus the
# latest 8.x (8.7.0), the latest 9.0.x (9.0.2), and the checked-in
# default 9.1.1.
bazel_version: [7.2.1, 8.7.0, 9.0.2, 9.1.1]
exclude:
- os: ubuntu-latest
compiler: native
- os: macos-26
compiler: gcc
uses: ./.github/workflows/test.yml
with:
continue-on-error: false
os: ${{ matrix.os }}
compiler: ${{ matrix.compiler }}
gcc_version: ${{ matrix.gcc_version }}
llvm_version: ${{ matrix.llvm_version }}
bazel_config: ${{ matrix.bazel_config }}
bazel_version: ${{ matrix.bazel_version }}
test-clang:
needs: [pre-commit, test-gcc, test-bcr]
secrets: inherit
strategy:
matrix:
os: [ubuntu-latest, macos-26]
compiler: [clang]
# Hermetic toolchains_llvm clang (independent of the runner's Apple clang).
# Ladder: working default (20), macOS native match (21 = Apple clang 21), newest (22).
# TODO(llvm-23): add 23.x here once released and listed in toolchains_llvm.
llvm_version: [20.1.8, 21.1.8, 22.1.7]
bazel_config: [asan, cpp23, fastbuild, opt]
exclude:
# macOS asan works via toolchains_llvm's @loader_path rpath fix for the
# sanitizer runtime dylib (helly25 fork; upstream PR #767), on LLVM
# 22.1.7. 20.1.8 still hangs in compiler-rt FindDynamicShadowStart on
# macOS 26, so exclude only that combo; macOS asan rides the 22.1.7 rung.
- os: macos-26
llvm_version: 20.1.8
bazel_config: asan
# 20.1.8 is the default pin -> full config coverage
# 21.1.8 less coverage, just check opt
# 22.1.7 keep the complex configs, just drop fastbuild
- llvm_version: 21.1.8
bazel_config: asan
- llvm_version: 21.1.8
bazel_config: cpp23
- llvm_version: 21.1.8
bazel_config: fastbuild
- llvm_version: 22.1.7
bazel_config: fastbuild
uses: ./.github/workflows/test.yml
with:
continue-on-error: true
os: ${{ matrix.os }}
compiler: ${{ matrix.compiler }}
llvm_version: ${{ matrix.llvm_version }}
bazel_config: ${{ matrix.bazel_config }}
done:
needs: [trunk, pre-commit, benchmark, test-gcc, test-clang, test-bcr]
if: always()
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Ensure every job is wired into this gate
env:
NEEDS_JSON: ${{ toJSON(needs) }}
run: |
# Parse the workflow with a real YAML reader (yq) and fail if any
# declared job (other than this gate) is absent from `needs` above, so
# a newly added job cannot silently escape the required gate.
declared="$(yq '.jobs | keys | .[]' .github/workflows/main.yml |
grep -vx done | sort)"
wired="$(jq -r 'keys[]' <<<"${NEEDS_JSON}" | sort)"
missing="$(comm -23 <(printf '%s\n' "${declared}") <(printf '%s\n' "${wired}"))"
if [[ -n "${missing}" ]]; then
echo "Jobs declared in the workflow but missing from done.needs:"
while read -r job; do
echo " - ${job}"
echo "::error title=Gate is missing a job::${job} not in done.needs"
done <<<"${missing}"
exit 1
fi
echo "done covers all $(grep -c . <<<"${declared}") workflow jobs."
- name: Fail if any dependency did not succeed
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1