open-standards/.github/workflows/wai-quantum-vector.yml
Transaction Science cb88dd7fa1
All checks were successful
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Successful in 6s
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Successful in 5s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 6s
joule-code conformance gate / Build + round-trip C1-C4 vectors (pull_request) Successful in 3m15s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m33s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m26s
joule-code conformance gate / joule-moq-relay, every target (pull_request) Successful in 2m32s
joule-code conformance gate / joule-moq-ingest, every target (pull_request) Successful in 1m41s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 7s
WAI conformance / does this change touch it (pull_request) Successful in 7s
WAI energy receipts / does this change touch it (pull_request) Successful in 6s
WAI JPEG-AI whole decode (pinned inputs, required) / does this change touch it (pull_request) Successful in 7s
WAI neural sink gates / does this change touch it (pull_request) Successful in 7s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 29s
wai-ops-gpu integer operators on GPUs / does this change touch it (pull_request) Successful in 6s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 7s
wai-quantum CPU vector units / does this change touch it (pull_request) Successful in 6s
wai-quantum studio and desktop / does this change touch it (pull_request) Successful in 6s
WAI mbt2018_mean integer decode (regenerated vectors) / does this change touch it (pull_request) Successful in 8s
wai-quantum WebGPU member / does this change touch it (pull_request) Successful in 8s
wai-quantum CPU vector units / member · vector units, avx2 and avx512 (framework-128gb silicon) (pull_request) Successful in 14s
wai-web wasm32 / does this change touch it (pull_request) Successful in 8s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m41s
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 2m38s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 3m18s
joule-moq-room room service / joule-moq-room, every target (pull_request) Successful in 2m12s
wai-quantum CPU vector units / member · vector unit, rvv 1024-bit (riscv64, emulated) (pull_request) Successful in 29s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 21s
wai-quantum CPU vector units / member · vector unit, sve 128-bit (aarch64, emulated) (pull_request) Successful in 33s
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Successful in 3m28s
wai-quantum CPU vector units / member · vector unit, rvv 128-bit (riscv64, emulated) (pull_request) Successful in 15s
wai-pack / wai-pack · linux (pull_request) Successful in 1m54s
wai-quantum CPU vector units / member · vector unit, avx2 (x86_64 silicon) (pull_request) Successful in 6s
wai-quantum CPU vector units / member · vector unit, sve 2048-bit (aarch64, emulated) (pull_request) Successful in 12s
wai-quantum CPU vector units / member · vector unit, sve 512-bit (aarch64, emulated) (pull_request) Successful in 11s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 5m35s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 6m32s
wai-quantum studio and desktop / studio · browser (pull_request) Successful in 2m48s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 25s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 28s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m23s
wai-quantum WebGPU member / member · DX12 and Vulkan (cbio-windows) (pull_request) Successful in 13m10s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 2m23s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 1m42s
wai-quantum WebGPU member / member · integrated GPU, Vulkan (framework-128gb) (pull_request) Successful in 9m4s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 6m15s
WAI conformance / each feature of the independent verifiers' steps compiles alone (pull_request) Successful in 7m26s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 11m18s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 4m47s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m50s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 15m26s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 9m32s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 26s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 53s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 11m33s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 8m52s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 27s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 17m51s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 7m24s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m30s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 16m37s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 5m56s
wai-quantum CPU vector units / member · vector unit absent (macos) (pull_request) Successful in 14s
wai-quantum WebGPU member / member · discrete GPU, Vulkan (jetson-hub) (pull_request) Successful in 19m39s
wai-pack / wai-pack · macos (pull_request) Successful in 2m41s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 2m28s
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Successful in 10m1s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 1m44s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 2m34s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 46m45s
CI: the avx2 leg declares the units the runner's processor has
The `linux` label now has two runners: jetson-hub, whose processor has
avx2, and framework-128gb-linux (since 2026-10-26), whose processor has
avx512 too. The avx2 leg declared avx2 alone, so on the framework the
engine's probe found avx2 and avx512, the declaration did not match, and
all nine device tests failed (#487's run, task 29781).

On silicon the declaration now comes from the kernel's own flags (avx512f
in /proc/cpuinfo), never from the probe under test, and the leg checks
the avx2 member exactly as before: its 256-bit length, its four bit-exact
certificates and its three killed mutants.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 11:36:49 -04:00

251 lines
13 KiB
YAML

name: wai-quantum CPU vector units
# The fabric's CPU vector-unit members: the gate's fixed-point arithmetic in
# the processor's own vector extension, certified bit-exact against the CPU
# reference's pinned corpus digests.
#
# - avx2 on silicon: the x86-64 processor of whichever `linux` runner takes
# the leg. jetson-hub's has avx2 alone; framework-128gb-linux's has avx512
# too, and there the leg declares both, as the kernel reports them, and
# checks the avx2 member as on any other;
# - avx2 and avx512 on silicon together: framework-128gb's processor, which has
# both, one member each;
# - sve and rvv under the host's user-mode emulator (its binfmt handler), at
# several vector lengths each: the scalable kernels set their length per
# pass, and every leg checks the length the member read from the unit is the
# one the emulator was given, so a leg cannot pass at the wrong length;
# - the macOS runner, whose processor has no vector extension these kernels
# use outside streaming mode, finding no member.
#
# Silicon for sve and rvv: a processor with them runs the same tests with no
# emulator declared.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
paths:
- 'wai/wai-quantum/**'
- 'rust-toolchain.toml'
- '.github/workflows/wai-quantum-vector.yml'
schedule:
- cron: '53 6 * * *'
jobs:
# Does this pull request's own diff touch the paths below? This forge matches a
# workflow's `paths:` against the push, so a merge of main into a branch fires the
# workflow whatever the pull request changes; every job here waits on this answer.
# A push to main, a schedule, or anything the script cannot determine answers
# `true` (scripts/pr-touches-paths.py).
relevant:
name: does this change touch it
runs-on: linux-arm64
outputs:
run: ${{ steps.gate.outputs.run }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- id: gate
run: |
set -euo pipefail
r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-quantum-vector.yml \
"${{ github.event.pull_request.base.sha }}" \
"${{ github.event.pull_request.head.sha }}")
echo "this change touches wai-quantum-vector: $r"
echo "run=$r" >> "$GITHUB_OUTPUT"
vector:
name: member · vector unit, ${{ matrix.name }}
needs: relevant
if: needs.relevant.outputs.run == 'true'
runs-on: linux
timeout-minutes: 120
strategy:
fail-fast: false
max-parallel: 1
matrix:
include:
- name: avx2 (x86_64 silicon)
target: x86_64-unknown-linux-gnu
image: ghcr.io/cross-rs/aarch64-unknown-linux-gnu@sha256:7f8308a8734d9fcd2ebbe9a3e4bdea74af293f0799d80c3cc341e340cda49a4c
key: cpu-vector-avx2
bits: 256
emulator: ''
qemu_cpu: ''
- name: sve 128-bit (aarch64, emulated)
target: aarch64-unknown-linux-gnu
image: ghcr.io/cross-rs/aarch64-unknown-linux-gnu@sha256:7f8308a8734d9fcd2ebbe9a3e4bdea74af293f0799d80c3cc341e340cda49a4c
key: cpu-vector-sve
bits: 128
emulator: qemu-user 8.2.2 (the host's binfmt handler)
qemu_cpu: max,sve-default-vector-length=16
- name: sve 512-bit (aarch64, emulated)
target: aarch64-unknown-linux-gnu
image: ghcr.io/cross-rs/aarch64-unknown-linux-gnu@sha256:7f8308a8734d9fcd2ebbe9a3e4bdea74af293f0799d80c3cc341e340cda49a4c
key: cpu-vector-sve
bits: 512
emulator: qemu-user 8.2.2 (the host's binfmt handler)
qemu_cpu: max,sve-default-vector-length=64
- name: sve 2048-bit (aarch64, emulated)
target: aarch64-unknown-linux-gnu
image: ghcr.io/cross-rs/aarch64-unknown-linux-gnu@sha256:7f8308a8734d9fcd2ebbe9a3e4bdea74af293f0799d80c3cc341e340cda49a4c
key: cpu-vector-sve
bits: 2048
emulator: qemu-user 8.2.2 (the host's binfmt handler)
qemu_cpu: max,sve-default-vector-length=256
- name: rvv 128-bit (riscv64, emulated)
target: riscv64gc-unknown-linux-gnu
image: ghcr.io/cross-rs/riscv64gc-unknown-linux-gnu@sha256:67ee97dd4719390d299edfcf39f226360ccfb1539e08b078ec187d4848415794
key: cpu-vector-rvv
bits: 128
emulator: qemu-user 8.2.2 (the host's binfmt handler)
qemu_cpu: rv64,v=true,vlen=128,elen=64
- name: rvv 1024-bit (riscv64, emulated)
target: riscv64gc-unknown-linux-gnu
image: ghcr.io/cross-rs/riscv64gc-unknown-linux-gnu@sha256:67ee97dd4719390d299edfcf39f226360ccfb1539e08b078ec187d4848415794
key: cpu-vector-rvv
bits: 1024
emulator: qemu-user 8.2.2 (the host's binfmt handler)
qemu_cpu: rv64,v=true,vlen=1024,elen=64
container:
image: ${{ matrix.image }}
options: --memory=6g --memory-swap=6g
env:
WAI_QUANTUM_VECTOR_EXPECT: ${{ matrix.key }}
WAI_QUANTUM_VECTOR_EMULATOR: ${{ matrix.emulator }}
# Run test binaries directly, so the host's handler runs them with the
# processor given here, not the image's older emulator.
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER: env
CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_RUNNER: env
steps:
# The image has no Node for a checkout action: the forge's archive of the
# exact commit, its embedded commit id checked.
- name: Fetch the source
shell: bash
run: |
set -euo pipefail
want="${{ github.event.pull_request.head.sha || github.sha }}"
rm -rf src src.tar.gz src.tar && mkdir src
curl -sSf -o src.tar.gz "http://100.64.224.0:3400/Transaction-Science/open-standards/archive/$want.tar.gz"
gzip -dc src.tar.gz > src.tar
got="$(git get-tar-commit-id < src.tar)"
[ "$got" = "$want" ] || { echo "::error::the archive is of $got, not $want"; exit 1; }
tar -xf src.tar -C src --strip-components=1
rm src.tar.gz src.tar
- name: The member's tests
shell: bash
working-directory: src/wai/wai-quantum
run: |
set -euo pipefail
cache=/ci-cache/wai-quantum-vector
mkdir -p "$cache"
exec 9>"$cache/.lock"
flock 9
export RUSTUP_HOME="$cache/rustup" CARGO_HOME="$cache/cargo" CARGO_TARGET_DIR="$cache/target-${{ matrix.target }}"
export PATH="$CARGO_HOME/bin:$PATH"
if ! command -v rustup >/dev/null; then
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --profile minimal --default-toolchain none
fi
rustup toolchain install
rustup target add ${{ matrix.target }}
# The emulated processor, for the test binaries only.
if [ -n "${{ matrix.qemu_cpu }}" ]; then export QEMU_CPU="${{ matrix.qemu_cpu }}"; fi
# Every unit this processor has must be declared, so on silicon the
# declaration comes from the kernel's own flags, not the probe under test.
if [ "${{ matrix.key }}" = cpu-vector-avx2 ] && grep -qw avx512f /proc/cpuinfo; then
export WAI_QUANTUM_VECTOR_EXPECT=cpu-vector-avx2,cpu-vector-avx512
fi
t="--target ${{ matrix.target }} --features quantum_fabric_vector"
cargo test --locked --release -j 6 $t --lib -- quantum_fabric_vector:: 2>&1 | tee "$cache/unit.log"
grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$cache/unit.log" || { echo "::error::no unit test ran"; exit 1; }
report="$(mktemp)"
WAI_QUANTUM_VECTOR_REPORT="$report" cargo test --locked --release -j 6 $t --test vector_member -- --test-threads=1 2>&1 | tee "$cache/device.log"
grep -qE '^test result: ok\. 9 passed; 0 failed' "$cache/device.log" || { echo "::error::not every device test ran and passed"; exit 1; }
cat "$report"
key="${{ matrix.key }}"
grep -qx "vector devices: as declared ($WAI_QUANTUM_VECTOR_EXPECT)" "$report" || { echo "::error::the units found are not the declared ones"; exit 1; }
grep -q "^vector member: key=$key .* bits=${{ matrix.bits }} " "$report" || { echo "::error::the unit's vector length is not ${{ matrix.bits }} bits"; exit 1; }
if [ -n "$WAI_QUANTUM_VECTOR_EMULATOR" ]; then
grep -q "^vector member: key=$key .*emulator:qemu-user" "$report" || { echo "::error::the member does not say it ran under the emulator"; exit 1; }
else
grep -q "^vector member: key=$key .*; silicon;" "$report" || { echo "::error::the member does not say it ran on silicon"; exit 1; }
fi
n="$(grep -c "^vector certified: key=$key .* parity=bit-exact " "$report")"
[ "$n" = 4 ] || { echo "::error::$n of 4 certificates were earned"; exit 1; }
grep -qx "vector mutants: key=$key killed 3 of 3" "$report" || { echo "::error::a kernel mutant survived"; exit 1; }
vector-amd:
name: member · vector units, avx2 and avx512 (framework-128gb silicon)
needs: relevant
if: needs.relevant.outputs.run == 'true'
runs-on: linux-amd
timeout-minutes: 60
env:
CARGO_PROFILE_DEV_DEBUG: '0'
CARGO_BUILD_JOBS: '12'
steps:
- name: Fetch the source
shell: bash
run: |
set -euo pipefail
want="${{ github.event.pull_request.head.sha || github.sha }}"
rm -rf src && mkdir src && cd src
git init -q
# Fetch the commit itself, not the ref. The host names its own route to
# the forge (WAI_FORGE_URL).
git fetch -q --depth 1 "${WAI_FORGE_URL:-http://100.64.224.0:3400}/Transaction-Science/open-standards.git" "$want"
git checkout -q FETCH_HEAD
got="$(git rev-parse HEAD)"
[ "$got" = "$want" ] || { echo "::error::fetched $got, not $want"; exit 1; }
- name: Both units on silicon
shell: bash
working-directory: src/wai/wai-quantum
run: |
set -euo pipefail
export PATH="$HOME/.cargo/bin:$PATH"
export CARGO_TARGET_DIR="$HOME/hw-target/wai-quantum-vector"
# The units this host's processor has, declared here (or by the runner).
export WAI_QUANTUM_VECTOR_EXPECT="${WAI_QUANTUM_AMD_VECTOR_EXPECT:-cpu-vector-avx2,cpu-vector-avx512}"
nice -n 10 cargo test --locked --release --features quantum_fabric_vector --lib -- quantum_fabric_vector:: 2>&1 | tee "$RUNNER_TEMP/unit.log"
grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/unit.log" || { echo "::error::no unit test ran"; exit 1; }
report="$RUNNER_TEMP/vector-report.txt"; : > "$report"
WAI_QUANTUM_VECTOR_REPORT="$report" nice -n 10 cargo test --locked --release --features quantum_fabric_vector --test vector_member -- --test-threads=1 2>&1 | tee "$RUNNER_TEMP/device.log"
grep -qE '^test result: ok\. 9 passed; 0 failed' "$RUNNER_TEMP/device.log" || { echo "::error::not every device test ran and passed"; exit 1; }
cat "$report"
grep -qx "vector devices: as declared ($WAI_QUANTUM_VECTOR_EXPECT)" "$report" || { echo "::error::the units found are not the declared ones"; exit 1; }
for key in ${WAI_QUANTUM_VECTOR_EXPECT//,/ }; do
case "$key" in cpu-vector-avx2) bits=256 ;; cpu-vector-avx512) bits=512 ;; *) echo "::error::no vector length known for $key"; exit 1 ;; esac
grep -q "^vector member: key=$key .* bits=$bits .*; silicon;" "$report" || { echo "::error::$key: not $bits bits on silicon"; exit 1; }
n="$(grep -c "^vector certified: key=$key .* parity=bit-exact " "$report")"
[ "$n" = 4 ] || { echo "::error::$key: $n of 4 certificates were earned"; exit 1; }
grep -qx "vector mutants: key=$key killed 3 of 3" "$report" || { echo "::error::$key: a kernel mutant survived"; exit 1; }
done
vector-absent:
name: member · vector unit absent (macos)
needs: relevant
if: needs.relevant.outputs.run == 'true'
runs-on: macos
timeout-minutes: 60
env:
WAI_QUANTUM_VECTOR_EXPECT: none
steps:
- uses: actions/checkout@v5
# launchd's PATH omits cargo on the macOS host runner.
- name: Put cargo on PATH
shell: bash
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: No vector unit these kernels use, and the member says so
shell: bash
working-directory: wai/wai-quantum
run: |
set -euo pipefail
report="$RUNNER_TEMP/vector-report.txt"; : > "$report"
nice -n 10 cargo test --locked --features quantum_fabric_vector --lib -- quantum_fabric_vector:: 2>&1 | tee "$RUNNER_TEMP/unit.log"
grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/unit.log" || { echo "::error::no unit test ran"; exit 1; }
WAI_QUANTUM_VECTOR_REPORT="$report" nice -n 10 cargo test --locked --features quantum_fabric_vector --test vector_member -- --test-threads=1 2>&1 | tee "$RUNNER_TEMP/device.log"
grep -qE '^test result: ok\. 9 passed; 0 failed' "$RUNNER_TEMP/device.log" || { echo "::error::not every device test ran and passed"; exit 1; }
grep -qx 'vector devices: as declared (none)' "$report" || { echo "::error::the absent case was not established"; exit 1; }