Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
26d4f3f
Fix/soundness underconstrained chips (#652)
jotabulacios Jun 11, 2026
55e8c7b
fix infra LLVM toolchain for RISC-V asm (#663)
MauroToscano Jun 12, 2026
358e47b
Feat/shrink cpu byte alu (#644)
jotabulacios Jun 12, 2026
abfb0cb
Feat/ecsm accelerator (#657)
jotabulacios Jun 18, 2026
be2de0e
Manual multi-model AI code review (agentic swarm + native Codex/Claud…
MauroToscano Jun 18, 2026
7d8a0fe
feat(cuda): GPU batch inverse (#658)
ColoCarletti Jun 18, 2026
c826eb8
fix(ci): stop AI review matrix from self-cancelling on bot comments (…
MauroToscano Jun 18, 2026
14f66a5
ethrex integration: Crypto-trait guest + synthetic block fixture gene…
ColoCarletti Jun 18, 2026
e366b16
Fix/nightly bench sysroot (#675)
jotabulacios Jun 18, 2026
1a3134d
perf+fix(stark): composition poly is the quotient — (d-1) parts + ver…
diegokingston Jun 22, 2026
1c77707
refactor(stark): make Table.data private; route trace writes through …
MauroToscano Jun 22, 2026
7fb5139
Fix Msb16 LogUp over-send in MUL/DVRM (#701)
jotabulacios Jun 23, 2026
28c1415
refactor(prover): add VM table trace writers (#703)
MauroToscano Jun 23, 2026
8c42a93
fix(ci): AI review — accept /review-ai, raise turn cap, scope agent c…
MauroToscano Jun 23, 2026
263394f
refactor(stark): move inlined tests + trace.rs test helpers into src/…
diegokingston Jun 24, 2026
0cfce83
refactor(ecsm): move inlined tests + reference arithmetic into src/te…
diegokingston Jun 24, 2026
3279243
refactor(math): move test-only FFT helpers into the test tree (#690)
diegokingston Jun 24, 2026
7d7d56c
refactor(prover): move test-only Traces constructors + trim_zero_rows…
diegokingston Jun 24, 2026
d4bb621
Inject LambdaVM crypto into the ethrex guest (#702)
jotabulacios Jun 24, 2026
febd878
infra: add moonmath provider for ai reviews (#708)
JuArce Jun 24, 2026
20061a5
feat(bench): ethrex distinct-transfer benchmark baseline + memory swe…
MauroToscano Jun 24, 2026
03b3461
refactor(make): proper per-file dependency tracking for ASM programs …
Oppen Jun 25, 2026
fdf3bfb
ci(bench): two-tier benchmarking — cheap-tier knobs + on-demand /benc…
MauroToscano Jun 26, 2026
3bb9107
Perf/cpu lde rework (#650)
jotabulacios Jun 26, 2026
be5c4c2
perf(stark): skip fixed 0/1 muls in LogUp fingerprint accumulation (#…
diegokingston Jun 26, 2026
e3dd2d1
perf(stark): fuse composition half-extension onto coset_lde_full (pre…
diegokingston Jun 26, 2026
ae858b8
ci: add gpu benchmarks (#724)
JuArce Jun 29, 2026
38feb15
Continuations (Approach 2): prove executions epoch-by-epoch (#685)
nicole-graus Jun 29, 2026
7974e45
perf/row-major trace LDE for GPU path (#715)
jotabulacios Jun 29, 2026
7f6b85e
refactor(stark): unify & clean up the commitment layer (#735)
diegokingston Jun 29, 2026
f9db93e
Remove unused batched-LDE wrapper functions (#743)
MauroToscano Jun 29, 2026
f4c69b4
ci: rent gpu server with 96GB (#746)
JuArce Jun 30, 2026
ba282a0
fix(test): use row-pair leaves in merkle_root_parity GPU tests (#745)
MauroToscano Jun 30, 2026
912b443
feat: enable recursion (#742)
Oppen Jun 30, 2026
690ab91
fix(ci): run gpu bench with 5 transfers (#752)
JuArce Jun 30, 2026
eb718dc
fix(ci): rent dedicated (gpu_frac=1) host for GPU bench (#754)
JuArce Jun 30, 2026
ebc9302
ci(bench-gpu): cap CPU cores at 32 when picking offer (#755)
JuArce Jun 30, 2026
c85f0e6
feat(cuda): keep LDE and Merkle trees resident on the GPU (#748)
ColoCarletti Jul 1, 2026
5edcc6c
increase gas limit (#765)
jotabulacios Jul 2, 2026
a482ec2
test(recursion): memory-bounded execute/prove smoke tests; wire CI (#…
Oppen Jul 2, 2026
71a99f1
ci/verifier bench (#756)
jotabulacios Jul 2, 2026
b44c615
feat: guest-side step-profiling markers and per-step function histogr…
Oppen Jul 3, 2026
0131c03
feat(stark): single-source constraints — one definition per constrain…
MauroToscano Jul 3, 2026
287aeb0
Fix/verifier bench (#770)
jotabulacios Jul 3, 2026
2aafbc5
Fix(Continuations): Make private input private (#758)
nicole-graus Jul 3, 2026
509fd3f
ci: run tests on GPU server (#747)
JuArce Jul 3, 2026
df6e4bd
feat(prover): Build the LogUp aux trace on the GPU (#762)
ColoCarletti Jul 6, 2026
ce107d0
ci: report gpu-tests as skipped on PRs so the required check can pass…
MauroToscano Jul 6, 2026
291a69a
fix (#780)
ColoCarletti Jul 6, 2026
4f29b70
fix(stark): reject truncated deep_poly_openings instead of panicking …
MauroToscano Jul 6, 2026
85dd86e
Unify bench sign convention so - means faster (#784)
jotabulacios Jul 6, 2026
fbd550c
test(continuation): remove flaky privacy byte-scan test (#789)
MauroToscano Jul 6, 2026
b3f85b7
Feat/fri early termination (#729)
diegokingston Jul 6, 2026
94727c7
flamegraph: fix tail-call misattribution, trie-based fold, addr2line …
Oppen Jul 7, 2026
a5e51d6
perf(prover): faster CPU trace generation (#786)
ColoCarletti Jul 8, 2026
5bbd3f0
Feat/ecsm update (#753)
jotabulacios Jul 13, 2026
3c3b8ad
chore(lint): run clippy with the cuda feature in `make lint` (#805)
MauroToscano Jul 13, 2026
ef109e1
ci: bench workflows queue instead of cancelling each other (#806)
MauroToscano Jul 13, 2026
7dbbb1f
feat(cli): report keccak/ecsm accelerator call counts under `execute …
MauroToscano Jul 13, 2026
a81c44e
feat(stark): GPU constraint/composition evaluation (#798)
MauroToscano Jul 13, 2026
f05a9fc
ci: post recursion guest cycle+accelerator diff (main vs PR) on /benc…
MauroToscano Jul 13, 2026
bdf11c9
feat(stark): full GPU trace residency — skip the round-1 D2H (#799)
MauroToscano Jul 14, 2026
0dba9dc
recursion: supply DECODE/page commitments via private input; bind the…
Oppen Jul 14, 2026
6f3d12d
fix(bench): recursion guest cycles in millions (mawk 32-bit fix) + co…
MauroToscano Jul 14, 2026
8e504da
fix(executor): filter debug-section labels from SymbolTable (#801)
Oppen Jul 14, 2026
b04c808
perf(crypto): wire keccak_permute ecall into merkle/transcript/grindi…
Oppen Jul 14, 2026
c511b31
chore(scripts): delete unused bench_abba_gpu.sh (#812)
MauroToscano Jul 14, 2026
c30ffe5
perf(verifier): verify STARK proofs in place via rkyv (#769)
Oppen Jul 15, 2026
a8a3d87
fix(verifier): guard OOD-table width and drop per-query concat alloca…
MauroToscano Jul 15, 2026
f4a5887
perf(crypto): stream field-element bytes into hashers and transcript …
Oppen Jul 16, 2026
4c108a1
fix(math-cuda): driver-independent cuda builds (cudarc pin + cubin AO…
MauroToscano Jul 16, 2026
18f3b8f
perf(stark): fuse and hoist deep-composition reconstruction for both …
Oppen Jul 16, 2026
a864832
refactor(logup): forward accumulation so acc is the sole next-row OOD…
diegokingston Jul 16, 2026
3be1eed
test(math): pin `stream_bytes` byte parity with `as_bytes` (#832)
MauroToscano Jul 16, 2026
68a120a
perf(syscalls,crypto): in-place keccak sponge + direct finalize + fix…
MauroToscano Jul 17, 2026
2baad17
fix(syscalls): raise the private-input clamp to 512 MiB (#843)
Oppen Jul 17, 2026
6c8a5ba
feat(recursion): supply DECODE/global-memory-genesis roots via privat…
Oppen Jul 17, 2026
3ea4f91
perf(prover): verify continuation proofs in place via rkyv (#845)
Oppen Jul 17, 2026
528a841
bench(recursion): measure the verifier at real query counts, over rea…
Oppen Jul 21, 2026
73aeb41
Avoid wasteful to_affine inversions in ecrecover (#859)
jotabulacios Jul 24, 2026
0893b6b
perf(target): enable unaligned-scalar-mem for riscv64im guests (#864)
diegokingston Jul 27, 2026
55a251f
perf(ecsm): 7.7x faster witness generation (#866)
diegokingston Jul 28, 2026
70a33f9
bench: default CI benches to ethrex 100tx continuations; widen rkyv p…
ColoCarletti Jul 28, 2026
7f0d0dd
perf: build PAGE trace from dense memory store (#858)
ColoCarletti Jul 29, 2026
5fd961a
perf(transcript): direct sponge-squeeze challenges, drop ChaCha20 (⚠️…
diegokingston Jul 29, 2026
e0add1d
fix(bench-verify): Measure each recursion ref's guest cycles with a C…
nicole-graus Jul 29, 2026
fcc4848
Fix /bench-verify and measure continuations (#878)
nicole-graus Jul 30, 2026
d83b4d9
perf(prover): halve GPU continuation proving time (#863)
ColoCarletti Jul 31, 2026
9ccdaf2
perf(programs): build the ethrex guest with thin LTO (#861)
MauroToscano Jul 31, 2026
ce17377
fix(tooling): review fixups for the real ethrex block fixture (#884)
MauroToscano Jul 31, 2026
d0c1d8c
fix(bench): restore /bench-growth rendering, the fixture digest check…
MauroToscano Aug 3, 2026
d161430
Fix /bench-verify target dirs (#882)
jotabulacios Aug 3, 2026
74b6c49
fix(bench): flag /bench comparisons against a noisy baseline instead …
MauroToscano Aug 3, 2026
a1d45e6
bench(gpu): record the host CPU, and stop unrelated comments cancelli…
MauroToscano Aug 3, 2026
6a28012
perf(keccak): inline θ/ρ halfword shifts as μ-gated identities, drop …
MauroToscano Aug 3, 2026
5749a95
perf(prover): device-resident rounds 2-4 and fused NTT for GPU conti…
ColoCarletti Aug 3, 2026
7644043
perf(prover): per-table scheduler with VRAM admission for multi_prove…
ColoCarletti Aug 3, 2026
b082f9f
fix(prover): emit STEP_AIRS_AND_BUS_BALANCE_DONE marker on continuati…
Oppen Aug 4, 2026
8b88a8d
perf(guest): read the private input zero-copy via ef_io::read_input (…
diegokingston Aug 4, 2026
6949ceb
fix(verifier): pin each trace-opening column width to the AIR, not ju…
MauroToscano Aug 7, 2026
483dc6e
fix(page): private-input PAGE OFFSET is unconstrained — forgeable mem…
MauroToscano Aug 7, 2026
58160b6
Feat/hint ecall (#876)
jotabulacios Aug 7, 2026
29ae662
Spec the ECSM affine ecall variant and its IS_AFFINE selector
nicole-graus Aug 11, 2026
3837f1d
Cite the memory-granularity rule and correct the x-only claim
nicole-graus Aug 11, 2026
312e183
Correct the affine prose and document the address-limb and single-cur…
nicole-graus Aug 12, 2026
d898a42
fix(gpu): survive transient VRAM pressure — recover resident-table de…
ColoCarletti Aug 12, 2026
7e65c65
Flag that the exposition's 2p² offset disagrees with the constraint's p²
nicole-graus Aug 12, 2026
ddab868
Correct the operand-overlap rationale and qualify the ecall-number co…
nicole-graus Aug 12, 2026
d52f37d
perf: make bump the default guest allocator (#869)
jotabulacios Aug 13, 2026
ec58a7f
perf(prover): default the cuda table scheduler to K = num_airs (#911)
MauroToscano Aug 18, 2026
cf3b1e9
fix(gpu): recover device-only declines at the remaining cliff sites (…
ColoCarletti Aug 18, 2026
bc3a3c6
ci(bench-gpu): stop building on half-provisioned or bad-RAM boxes (#939)
ColoCarletti Aug 18, 2026
b64b7ae
perf(gpu): grind the proof-of-work nonce on the GPU (#936)
ColoCarletti Aug 21, 2026
884eb45
perf(prover): device-only preprocessed tables and GPU commits for mid…
ColoCarletti Aug 24, 2026
8064a8e
perf(gpu): run DECODE (num_parts=1) DEEP/FRI on device (#946)
ColoCarletti Sep 1, 2026
d6ac910
Merge branch 'main' into spec/ecsm-affine-selector
nicole-graus Sep 9, 2026
88cbeac
Merge branch 'spec/main' into spec/ecsm-affine-selector
nicole-graus Sep 9, 2026
6bcd641
rename from is_affine to is_full_point
nicole-graus Sep 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
46 changes: 46 additions & 0 deletions .github/ai-review/matrix.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"review_lanes": [
{
"id": "glm",
"model": "openrouter/z-ai/glm-5.2",
"prompt": "general",
"variant": "low"
},
{
"id": "kimi",
"model": "openrouter/moonshotai/kimi-k2.7-code",
"prompt": "general",
"variant": "low"
},
{
"id": "nemotron",
"model": "openrouter/nvidia/nemotron-3-ultra-550b-a55b",
"prompt": "general",
"variant": "low"
},
{
"id": "minimax",
"model": "minimax/MiniMax-M3",
"prompt": "general",
"variant": "high"
},
{
"id": "moonmath",
"model": "zro/minimax-m3",
"prompt": "general",
"variant": "low"
}
],
"verifier_lanes": [
{
"id": "deepseek-verifier",
"model": "openrouter/deepseek/deepseek-v4-pro",
"prompt": "verify",
"variant": "low"
}
],
"deduper": {
"model": "openrouter/minimax/minimax-m3",
"variant": "low"
}
}
37 changes: 37 additions & 0 deletions .github/ai-review/prompts/general.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
1. **Safety and security issues** - Label by criticality (Critical/High/Medium/Low)
- Rust: unsafe blocks, error handling, panics, memory safety issues
- GPU/CUDA: device-memory exhaustion or leaks that crash the run, unbounded
allocations, buffer lifetime, host/device synchronization
- VM/executor: instruction semantics, memory access, state transitions,
inconsistent execution/proving behavior

2. **Potential bugs** - Logic errors, edge cases, incorrect behavior, race conditions

3. **Performance issues** - Only significant: e.g. O(n^2) on unbounded input, unnecessary allocations, hot path inefficiencies

4. **Simplicity and readability** - Prefer simple, readable code over clever
abstractions. Cosmetic rewrites are acceptable when they make changed code,
names, comments, or docs easier to understand.
- Dead code: flag functions, branches, CLI paths, or tests the PR leaves
unreachable or unused — call it out so it is removed, not left behind.

Guidelines:
- Be concise and to the point
- Do NOT suggest micro-optimizations, churn, or premature abstractions
- Always prefer simplicity over complexity when performance gains are marginal
- Focus on real issues, not hypothetical improvements
- Be concise and actionable

Environment — review statically with the tools you have:
- This is a static code review in a sandbox. The PR branch is ALREADY checked out in the
working directory and the diff is provided to you — read the changed files and their
dependencies directly. You do not need to (and cannot) fetch anything.
- You MAY use only: reading files, grep, glob, `gh pr view`, `gh pr diff`, `gh pr comment`,
`cargo tree`, `cargo metadata`, `npm list`/`npm ls`, and `forge inspect`. Inline comments
go through the provided inline-comment tool.
- You may NOT build, test, or reach the network: no `cargo build`/`cargo check`/`cargo test`/
`cargo clippy`, no `git fetch`/`git clone`/`git checkout` of other refs. These are blocked
and CI already builds and tests the PR — do not attempt them.
- If a command is denied or fails, do NOT retry it, do NOT try variations to work around the
sandbox, and do NOT report the failure as a review finding. Skip it and continue with the
tools above. Never block or end the review because a command could not run.
10 changes: 10 additions & 0 deletions .github/ai-review/prompts/lanes/verify.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Verify candidate review findings for this PR.

For each candidate, decide whether the finding is supported by the diff and
provided surrounding code. Mark it as:

- `confirmed` when the issue is real and introduced or exposed by this PR
- `rejected` when the claim is wrong, unrelated, or too speculative
- `uncertain` when it may be real but the provided context is insufficient

Prefer rejecting speculative findings. Do not invent new findings in this step.
176 changes: 176 additions & 0 deletions .github/scripts/aggregate_recursion_histogram.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#!/usr/bin/env python3
"""Format the recursion-guest per-function profile as a Markdown PR comment.

`test_recursion_profile_1query`/`_multiquery` print a global top-25 functions
table (folded over all verifier steps, % of total run cycles), followed by
one top-25 table per verifier step (% of that step's own cycles, so the
table shows what dominates *within* the step) — e.g. how much of
`step4:openings` is `keccak`. We parse all of those tables and render them
as Markdown.

Top 25 functions by cycle count (aggregated over their PCs, all steps; % of total cycles):
rank cycles % cum % PCs function
1 5335072 24.95% 24.95% 72 <...>::visit_seq::<...>

Top 25 functions by cycle count — step airs_bus_balance (% of this step's 5129138364 cycles):
rank cycles % cum % PCs function
1 5335072 24.95% 24.95% 72 <...>::visit_seq::<...>

Reads the test's captured output from argv[1]; writes the Markdown body to
argv[2] (or stdout).
"""

import re
import sys
from collections import OrderedDict

# A per-function summary row: rank, cycles, pct%, cum%, pcs, function.
FN_ROW = re.compile(
r"^\s*\d+\s+(\d+)\s+([\d.]+)%\s+([\d.]+)%\s+(\d+)\s+(.*\S)\s*$"
)
HEADER_ROW = re.compile(r"^\s*rank\s+cycles")
GLOBAL_TABLE_START = re.compile(
r"Top \d+ functions by cycle count \(aggregated over their PCs, all steps"
)
STEP_TABLE_START = re.compile(
r"Top \d+ functions by cycle count — step (\S+) \(% of this step's (\d+) cycles\):"
)
TOTAL_CYCLES = re.compile(r"Total cycles\s*:\s*(\d+)")
UNIQUE_PCS = re.compile(r"Unique PCs\s*:\s*(\d+)")
EXEC_TIME = re.compile(r"Exec time\s*:\s*(\S+)")

GLOBAL_KEY = "__global__"


def parse(text):
total_cycles = unique_pcs = exec_time = None
# GLOBAL_KEY -> {"denom": int|None, "rows": [...]}, then one entry per
# step tag in first-seen order.
tables = OrderedDict()
current = None
skip_header = False
for line in text.splitlines():
if total_cycles is None and (m := TOTAL_CYCLES.search(line)):
total_cycles = int(m.group(1))
if unique_pcs is None and (m := UNIQUE_PCS.search(line)):
unique_pcs = int(m.group(1))
if exec_time is None and (m := EXEC_TIME.search(line)):
exec_time = m.group(1)

if GLOBAL_TABLE_START.search(line):
current = GLOBAL_KEY
tables[current] = {"denom": total_cycles, "rows": []}
skip_header = True
continue
if m := STEP_TABLE_START.search(line):
current = m.group(1)
tables[current] = {"denom": int(m.group(2)), "rows": []}
skip_header = True
continue

if current is None:
continue
if skip_header:
# The header row right after a table-start line; anything else
# (e.g. a stray blank line) just ends the table early, which is
# fine — an empty table renders as "no rows".
skip_header = False
if HEADER_ROW.match(line):
continue
if m := FN_ROW.match(line):
tables[current]["rows"].append(
{
"cycles": int(m.group(1)),
"pct": m.group(2),
"cum": m.group(3),
"pcs": int(m.group(4)),
"fn": m.group(5),
}
)
else:
current = None

return total_cycles, unique_pcs, exec_time, tables


def render_table(rows, denom_label):
if not rows:
return "> _no rows_\n"
body = "| Rank | Cycles | % | Cum % | PCs | Function |\n"
body += "|-----:|-------:|--:|------:|----:|----------|\n"
for i, r in enumerate(rows, 1):
body += (
f"| {i} | {r['cycles']:,} | {r['pct']}% | {r['cum']}% | "
f"{r['pcs']} | `{r['fn']}` |\n"
)
last_cum = rows[-1]["cum"]
body += (
f"\n<sub>Each function's cycles are summed over all its program counters "
f"in this table's scope; the top {len(rows)} cover {last_cum}% of "
f"{denom_label}.</sub>\n"
)
return body


def render(total_cycles, unique_pcs, exec_time, tables, title="Recursion guest profile"):
if not tables.get(GLOBAL_KEY, {}).get("rows"):
return (
f"### {title}\n\n"
"> ⚠️ No per-function rows found in the test output — the run may "
"have failed before printing the table. Check the workflow logs.\n"
)

body = f"### {title}\n\n"
if total_cycles is not None:
body += f"**Total cycles:** {total_cycles:,}"
if unique_pcs is not None:
body += f" · **Unique PCs:** {unique_pcs:,}"
if exec_time:
body += f" · **Exec time:** {exec_time}"
body += "\n\n"

global_rows = tables[GLOBAL_KEY]["rows"]
body += f"#### Top {len(global_rows)} functions by cycles (all steps)\n\n"
body += render_table(global_rows, "total cycles")

for step, table in tables.items():
if step == GLOBAL_KEY:
continue
rows, denom = table["rows"], table["denom"]
denom_note = f" of {denom:,} step cycles" if denom is not None else ""
body += (
f"\n<details><summary>Step <code>{step}</code>{denom_note} — "
f"top {len(rows)} functions</summary>\n\n"
)
body += render_table(rows, "this step's cycles")
body += "\n</details>\n"

return body


def main():
import argparse

ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument("log", help="captured test output to parse")
ap.add_argument("-o", "--out", help="write Markdown here instead of stdout")
ap.add_argument(
"-t",
"--title",
default="Recursion guest profile",
help="section heading (e.g. the test/config name)",
)
args = ap.parse_args()

with open(args.log, "r", errors="replace") as f:
text = f.read()
body = render(*parse(text), title=args.title)
if args.out:
with open(args.out, "w") as f:
f.write(body)
else:
sys.stdout.write(body)


if __name__ == "__main__":
main()
Loading
Loading