Skip to content

ci(profile-bench): compile only the modes each matrix job benchmarks - #282

Draft
andrii-lz wants to merge 10 commits into
mainfrom
worktree-profile-bench-per-mode-ci
Draft

ci(profile-bench): compile only the modes each matrix job benchmarks#282
andrii-lz wants to merge 10 commits into
mainfrom
worktree-profile-bench-per-mode-ci

Conversation

@andrii-lz

Copy link
Copy Markdown
Collaborator

Summary

profile-bench.yml's bench matrix jobs all compiled the same full 8-mode profile example binary, even though each job only benchmarks 1-3 of those modes. That single compile unit accounted for ~94 of ~107 seconds of build time (measured locally with cargo build --timings), and it was paid redundantly by every job — twice in most jobs (PR + merge-base builds).

  • Split akita-pcs's blanket profile-ci Cargo feature into 8 per-mode features + a profile-ci-registry marker, so crates/akita-pcs/examples/profile/modes.rs's mode registry only registers (and therefore only monomorphizes) the modes a build actually enables. profile-ci still enables all 8, unchanged for anyone using it directly.
  • Updated each matrix job in profile-bench.yml to build with only the mode-* features its own cases need, with a 3-tier fallback on the merge-base build for commits that predate this change.
  • Fixed a build break the change introduced: unselected mode wrapper functions become genuinely unreferenced in a narrow build, which -D warnings (set globally in this workflow) promotes from dead_code warning to a hard error. Scoped #![allow(dead_code)] to the two affected example files only.
  • Extended scripts/check_profile_ci_features.sh with a per-group coverage check, since CI no longer builds from the umbrella profile-ci feature — a group missing a needed mode-* feature would previously pass this gate and only fail at runtime.
  • Split the one job that spans 3 field types (fp32/fp64/fp128 combined) into one job per field type, since each field type pays its own large fixed monomorphization cost independent of mode count — that job was the long pole keeping overall wall-clock close to the old baseline even after the per-mode split.

Measured impact (local timing, clean builds)

job before after
1-fp128-dense ~107s (shared w/ all) 42.4s
2-fp128-tensor ~107s 43.0s
3-flat-fp32-onehot (new) 47.1s
4-flat-fp64-onehot (new) 47.5s
5-flat-fp128-onehot (new) 48.0s
6-distributed ~107s 43.5s

Max across all jobs (the effective CI wall-clock floor for the bench phase, since jobs run fail-fast: false in parallel) drops from ~107s to ~48s — a ~55% reduction, not just aggregate runner-minutes.

Test plan

  • All 4 (now 6) matrix jobs' exact feature sets build clean under RUSTFLAGS="-D warnings" (matching this workflow's actual flag)
  • Umbrella --features parallel,profile-ci build still produces the same 8-mode registry and builds clean under -D warnings
  • scripts/check_profile_ci_features.sh passes (umbrella coverage + new per-group coverage), including a deliberate-break test confirming the new per-group check catches a missing feature
  • scripts/check_profile_ci_linkage.sh passes against a per-group binary
  • YAML validated with yaml.safe_load
  • Real CI run on this PR (draft — opening to observe actual profile-bench.yml behavior on GitHub's runners)

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Warning

This PR has more than 500 changed lines and does not include a spec.

Large features and architectural changes benefit from a short spec before implementation review.
See CONTRIBUTING.md for the spec workflow.

If this PR is a bug fix, small cleanup, or otherwise does not warrant a spec, feel free to ignore this message.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Documentation blast radius (advisory)

These regions may need doc/spec/book updates based on changed paths.
This is not a merge gate. See docs/documentation.md.

Changed files in this PR: 6

workspace-crates

Workspace membership and public crate surface

Code paths touched:

  • crates/akita-pcs/Cargo.toml

Consider updating:

  • README.md
  • docs/crate-graph.md
  • book/src/how/architecture.md

pcs-umbrella

Public PCS API, examples, integration tests

Code paths touched:

  • crates/akita-pcs/Cargo.toml
  • crates/akita-pcs/examples/profile/modes.rs
  • crates/akita-pcs/examples/profile/workload.rs

Consider updating:

  • book/src/usage/**
  • README.md

ci-tooling

CI workflows and repo scripts

Code paths touched:

  • .github/workflows/profile-bench.yml
  • scripts/check_profile_ci_features.sh

Consider updating:

  • docs/ci-test-timing.md
  • docs/documentation.md
  • specs/ci-test-timing.md

Per-PR checklist: spec Status / acceptance criteria; book owning page; AGENTS.md if contracts changed; archive spec after fold.

@github-actions github-actions Bot added the no-spec PR has no spec file label Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Benchmark Report

  • Latest run: 0bfaabc
  • Message: docs(ci): refresh stale job-split comment for the field-type split
  • Ref: worktree-profile-bench-per-mode-ci
  • Workflow run: run 28902587550 attempt 1
  • Report generated: 2026-07-07T22:26:32Z.
  • Main baseline: a92113f from the merge-base benchmarked on this runner.
  • Previous run: 0ed42ee from the previous PR update with a benchmark artifact.
  • Binary: target/release/examples/profile.
  • Memory: maximum resident set size from /usr/bin/time on the benchmark process.
Status Case Mode Setup Mode Setup s Setup vec MiB Setup NTT MiB Commit s Prove s Verify ms RSS MiB Proof B Grind Σ Grind max Main baseline setup Δ Main baseline commit Δ Main baseline prove Δ Main baseline verify Δ Main baseline proof Δ
ok fp128 dense D64 nv24 np1 dense_fp128_d64 direct 0.134 192.0 480.0 2.485 2.060 17.5 1607.4 89,965 7 0 +1.72% +4.10% -0.27% +0.93% +0.00%
ok fp128 1-of-256 one-hot D64 tensor nv26 np1 onehot_fp128_d64_tensor direct 0.801 1024.0 2560.0 0.127 1.896 44.1 4125.6 90,866 7 0 +0.19% +34.89% -0.79% -1.73% +0.00%
ok fp32 1-of-256 one-hot D128 nv28 np1 onehot_fp32_d128 direct 0.102 54.0 216.0 0.099 2.461 44.4 779.4 86,079 9 1 -0.65% +0.16% +0.44% +0.62% +0.00%
ok fp64 1-of-256 one-hot D128 nv28 np1 onehot_fp64_d128 direct 0.097 80.0 240.0 0.066 1.955 31.9 892.1 90,275 6 0 +2.15% +0.32% +0.42% +0.71% +0.00%
ok fp128 1-of-256 one-hot D64 nv32 np1 onehot_fp128_d64 direct 0.819 1152.0 2880.0 1.529 2.270 26.2 4792.1 90,942 7 0 +0.63% +16.16% -0.74% +1.25% +0.00%
ok fp128 1-of-256 one-hot D64 nv32 np1 onehot_fp128_d64 recursive 1.429 1152.0 2880.0 1.556 2.945 33.0 5270.8 95,021 8 1 +0.52% +19.23% +0.39% -4.62% +0.00%
ok fp128 1-of-256 one-hot D64 nv30 np4 onehot_fp128_d64 direct 0.591 768.0 1920.0 1.520 2.282 26.8 3449.2 90,974 8 1 +0.40% +18.71% +0.24% -1.33% +0.00%
ok fp128 1-of-256 one-hot D64 multi-chunk W2R2 nv32 np1 onehot_fp128_d64_multi_chunk_w2r2 direct 0.983 1536.0 3840.0 0.354 2.234 28.3 6198.8 92,502 7 0 +0.03% -3.08% -0.99% +1.78% +0.00%
ok fp128 1-of-256 one-hot D64 multi-chunk W4R2 nv32 np1 onehot_fp128_d64_multi_chunk_w4r2 direct 0.967 1536.0 3840.0 0.454 3.991 52.0 6706.6 93,625 8 0 -0.59% -3.35% -0.65% -0.52% +0.00%
ok fp128 1-of-256 one-hot D64 multi-chunk W8R2 nv32 np1 onehot_fp128_d64_multi_chunk_w8r2 direct 0.968 1536.0 3840.0 0.561 6.649 76.6 7556.2 94,342 8 0 -0.20% -2.33% +0.57% +0.03% +0.00%

Detailed per-level schedule and proof-size breakdowns are available in the uploaded report.md benchmark artifact.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

CI test timing

  • Report generated: 2026-07-07T22:27:15Z.
  • Source: dfc9e2e on worktree-profile-bench-per-mode-ci.
  • Workflow run: 28902587556.
  • Main baseline: a92113f.
  • Previous run: 352b750.

Run summary

Wall s Main wall s Main Δ Ratio Tests Skipped Failed Status
457.0 445.0 +2.7% 1.03x 1131 0 0 ok

Wall time spans 2 parallel nextest slice shards.

Slowest tests

Rank Duration s Test
1 152.1 akita-config::generated_tables::generated_schedule_tables_match_find_schedule
2 8.9 akita-pcs::akita_e2e::full_d64_snap_regen_prove_verify_nv24
3 7.8 akita-pcs::akita_e2e::batched_onehot_same_point_round_trip
4 5.9 akita-pcs::scheme::tests::onehot::batched_onehot_roundtrip_matches_public_shape_context
5 5.8 akita-pcs::akita_e2e::trace_internalization_rejects_tampered_recursive_fold_handle
6 5.7 akita-pcs::batched_aggregated_e2e::non_zk_aggregated_cases::aggregated_onehot_nv20_batch7
7 5.4 akita-pcs::batched_aggregated_e2e::non_zk_aggregated_cases::aggregated_dense_nv17_batch5
8 5.3 akita-pcs::setup::d128_full::large_setup_batch_passes
9 5.2 akita-pcs::mixed_d_per_level_e2e::mixed_d_per_level_prove_verify_replay_and_malformed_rejections
10 5.2 akita-pcs::mixed_d_per_level_e2e::mixed_d_schedule_with_non_dividing_level_dim_is_rejected
11 5.2 akita-pcs::scheme::tests::batched::batched_verify_accepts_consistent_openings_and_rejects_bad_inputs
12 5.1 akita-pcs::akita_e2e::chunked_multi_chunk_prove_verify
13 4.9 akita-pcs::recursive_setup_e2e::recursive_onehot_cross_mode_rejects_nv20
14 4.8 akita-pcs::batched_aggregated_e2e::aggregated_mixed_dense_and_onehot_under_dense_cfg
15 4.7 akita-pcs::setup::d64_full::large_setup_batch_passes
16 4.7 akita-pcs::setup::d128_full::same_size_passes
17 4.7 akita-pcs::scheme::tests::single::folded_payload_commitments_and_digits_stay_base_field
18 4.5 akita-prover::kernels::linear::tests::chunking::q128_many_blocks_digits_chunk_instead_of_unsafe_block_parallel
19 4.4 akita-pcs::setup::d64_full::large_setup_nv_passes
20 4.4 akita-pcs::scheme::tests::single::fp128_degree_one_batched_proof_roundtrip_is_stable

Regressions vs main

No per-test regressions above the threshold.

New slow tests

No new tests ≥30s vs main baseline.

andrii-lz and others added 10 commits July 7, 2026 15:09
…file modes

Narrow profile-ci-registry builds (one mode-* feature enabled) leave the
other CI wrapper functions and their sole call chains unreferenced, which
-D warnings (set globally in profile-bench.yml) promotes from a warning to
a hard build error. Reachability here is a property of which mode-*
features are enabled, not of the code being actually unused, so allow
dead_code file-wide in the two affected example files.
CI now builds each matrix group from that group's own pcs_mode_features
list, not from the umbrella profile-ci feature. A mode covered by the
umbrella is not necessarily covered by its own group's narrower feature
list, so a missing mode-* feature on a group would previously pass this
gate and only surface as a runtime "unknown mode" failure. Add a per-group
check that every bench case's mode is covered by that same group's
pcs_mode_features.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@andrii-lz
andrii-lz force-pushed the worktree-profile-bench-per-mode-ci branch from 0ed42ee to 0bfaabc Compare July 7, 2026 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-spec PR has no spec file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant