test(DON'T MERGE): develop-v2.1.0-rv64#2719
Conversation
resolves int-6773
fix described in anthropics/claude-code-action#944 (comment) also switch to OAuth
I hope this works, but the idea is that stuff merged to develop-v2.0.0-beta will then rebase develop-v2.0.0-rc.1 On main, we do not include develop-v2.0.0-rc.1, so merge to main should set a chain of rebases main -> develop-v2.0.0-beta -> develop-v2.0.0-rc.1
Resolves INT-6673. When any dimension has size of 1, the T6 odometer carry constraint degenerates because "wrap" and "stay" produce the same diff (0), breaking the completeness guarantee of lexicographic enumeration. Add an assert in the Chip constructor to reject this configuration, and a test to verify it panics. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This resolves INT-6777
## Summary - Removed `openvm/` prefix from source paths across 8 documentation files (21 occurrences) - Updated stale `v2-proof-system` repository reference in `docs/crates/recursion/README.md` to reflect the current openvm repo - Updated `stark-backend` path in `docs/crates/recursion/verifier-mapping.md` to link to the [stark-backend GitHub repo](https://github.com/openvm-org/stark-backend) Fixes issues identified in #2553 (comment) ## Test plan - [x] Verified no remaining `openvm/crates/recursion/src/` prefixes exist - [x] Verified no remaining `v2-proof-system` references exist - [x] Verified no remaining `stark-backend/crates/` local path references exist 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Jonathan Wang <jonathanpwang@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This resolves INT-6814
This resolves INT-6828. Now `Eq3bAir` propagates the `row_idx` by the correct amount for each AIR. Note that there is no need for this air to know `air_idx` or anything other than the number of interactions and the `n_lift` for this air, so no new columns are added (but we now do the interaction with proof shape air on the last row of the air instead of the first one).
…2563) ## Summary - Add a `changes` detection job using `dorny/paths-filter@v3` to skip the `lint-cuda` job when no CUDA-related files (`*.cu`, `*.cuh`, `**/cuda/**`, `**/cuda*.rs`, etc.) are modified - Request at least 8 CPUs on the GPU runner (`/cpu=8`) for faster builds - The workflow file and CUDA cache action are also included as triggers so changes to CI itself still run the CUDA lint ## Test plan - [ ] Open a PR that doesn't touch any CUDA files and verify `lint-cuda` is skipped - [ ] Open a PR that touches a `.cu` or `.cuh` file and verify `lint-cuda` runs --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
) Switches guest dependencies that need atomic CAS (`once_cell::race` in the algebra/ecc macros, `spin::Mutex` in `guest-libs/keccak256`) to `portable-atomic` so they compile on stock `riscv64im-unknown-none-elf`, fixing CI failures across the algebra/ecc/pairing/ff_derive/k256/p256/keccak256 guest tests. The stock target's spec declares `atomic-cas: false`, so rustc cfg-gates `AtomicUsize::compare_exchange` out at the language level; `-C passes=lower-atomic` can't help since it acts on LLVM IR after rustc has already rejected the call. rc.1 avoided this on `riscv32im-risc0-zkvm-elf`, which claims CAS support in its spec; we keep guest programs on the stock upstream triple and patch the dependency instead. Switches `once_cell` (and `spin::Mutex` in `guest-libs/keccak256`) to their `portable-atomic` backend, with `portable-atomic` configured to use `critical-section` as its CAS fallback. `critical-section` is a minimal no_std mutual-exclusion interface: exactly one crate in the tree registers an `Impl` via `critical_section::set_impl!`, and every consumer calls `critical_section::with(...)`; without an impl the call panics at runtime. Off-the-shelf impls target interrupt-driven hardware and disable interrupts via CSR reads/writes, which the openvm VM can't transpile (they map to `unimp` and blow up at runtime). `openvm-platform` now registers a no-op impl, sound because the openvm guest is single-threaded, so CAS reduces to a plain load+store with zero CSR emission. A `SAFETY:` comment flags the single-thread invariant. Guest vs host gating now follows one rule across both code and manifests: - `.rs` files: `cfg(openvm_intrinsics)` (set by the guest build rustflags) for openvm-specific code paths, `cfg(not(feature = "std"))` for std-availability (`no_std`), `cfg(target_os = "none")` for runtime-specific attributes (`no_main`, `openvm::entry!` registration). The `no_std` / `no_main` split matches their semantics: std availability is a package decision, entry-point registration is a runtime/target property. - `Cargo.toml` manifests: `cfg(not(target_os = "none"))` for host-only dep gates (Cargo target predicates only accept built-in cfgs, not `openvm_intrinsics`). The `portable-atomic` CAS polyfill keeps the narrower `cfg(all(target_arch = "riscv64", target_os = "none"))` since the `critical-section` backend is arch-specific. - `--check-cfg=cfg(openvm_intrinsics)` added to guest-build rustflags in `crates/toolchain/build/src/lib.rs` so user guest programs never see the unexpected-cfgs warning. - `[workspace.lints.rust]` at the workspace root declares `openvm_intrinsics`; openvm-* crates inherit via `[lints] workspace = true`. Standalone sub-workspaces (tests/programs, book examples) can't inherit, so they declare it explicitly. - `resolver = "2"` on all standalone `[workspace]` sub-workspaces (tests/programs, book examples, cli/tests). Bare `[workspace]` defaulted to v1, which unified proc-macro features into guest builds and dragged `rand_core/std` and `getrandom/std` into the rv64 target. - Cargo.toml host-only dep gates swapped from the stale-on-rv64 `cfg(not(target_os = "zkvm"))` to `cfg(not(target_os = "none"))`. Three cascading rv64-port bugs, only exercised by the `final_exp_hint` tests: - `extensions/pairing/transpiler/src/lib.rs` used `RV32_REGISTER_NUM_LIMBS` (= 4) to compute the phantom's `a`/`b` operand addresses. On rv64 registers live at 8-byte boundaries in `RV64_REGISTER_AS`, so the phantom read zero. Changed to `RV64_REGISTER_NUM_LIMBS`. - `guest-libs/pairing/src/{bn254,bls12_381}/pairing.rs` constructed `(P.as_ptr() as u32, P.len() as u32)` as a fat pointer. The host phantom reads at offsets `0` and `RV64_REGISTER_NUM_LIMBS` (= 8), but the `(u32, u32)` tuple laid fields at offsets 0 and 4. Changed to `(u64, u64)`. - The adjacent `hint_buffer_chunked(ptr, (N * 12 * 2) / 4)` used the rv32 word-size divisor. Changed to `/ openvm_riscv_guest::HINT_WORD_BYTES`. `hint_store_u32!` to `hint_store_u64!` in `algebra/moduli-macros`. New `openvm_riscv_guest::HINT_WORD_BYTES = 8` replaces `/ 4` and `/ 8` magic numbers. Host-side `SqrtHintSubEx` padding bumped from `.take(4)` to `.take(RV64_REGISTER_NUM_LIMBS)` to match the 8-byte guest read. - `rv32`/`riscv32` to `rv64`/`riscv64` across SDK: `Sdk::riscv32()` and `AppConfig::riscv32()` become `riscv64()`, struct fields `rv32i`/`rv32m` become `rv64i`/`rv64m`, `openvm_riscv32.toml` renamed to `openvm_riscv64.toml` with matching TOML keys. Historical `v1.4/` and `v1.5/` snapshots untouched. - `Rv32Modular*`, `Rv32Weierstrass*`, `Rv32Pairing*` imports in failing guest-lib integration tests renamed to `Rv64*`. - `crates/sdk/guest/fib/src/main.rs`: `reveal_u32` to `reveal_u64`, `fibonacci` return type and locals widened from `u32` to `u64`. All 7 book examples were designed as host-run programs with `openvm/std` force-enabled, which dragged std into rv64 guest builds. Per-example: removed `features = ["std"]` from the `openvm` dep, moved `std` behind an example-local `std = ["openvm/std", ...]` feature, added `default-features = false` to transitive std-leakers (`serde`, `num-bigint`, `alloy-primitives`, `openvm-ruint`, `tiny-keccak`, `hex-literal`), and added the `no_main`/`no_std`/`openvm::entry!` guest-program scaffolding. The `i256` example additionally gets `bytes` with the `extra-platforms` feature and `portable-atomic` with `critical-section` on the riscv64-none target, since `alloy-primitives` transitively pulls `bytes` which uses `compare_exchange` directly. The test was passing `["std"]` to enable ff's `BatchInvert` trait via a `#[cfg(feature = "std")]` block in the guest program. On rv64 stock, activating `feature = "std"` at guest level chains through `openvm/std` and tries to link std, which riscv64im-unknown-none-elf doesn't have. Dropped `["std"]` from the test harness call; the std-only inner block is compiled out (the two `BatchInverter::invert_with_*_scratch` paths still run). Generated init file renamed from `openvm_init_batch_inversion_std.rs` to `openvm_init_batch_inversion.rs` to match the new build call. - Deleted `extensions/rv32im/` (empty pre-rv64 leftover) and an untracked stale `extensions/riscv/guest/guest/` copy with the old rv32 hint-store API. - Removed dead duplicate target-cfg block in `extensions/pairing/circuit/Cargo.toml`. - Fixed stale `cfg(target_os = "zkvm")` gate in `examples/keccak/Cargo.toml`. - Removed duplicate `critical_section::set_impl!` in `crates/toolchain/platform/src/heap/embedded.rs`; the canonical no-op impl now lives in `crates/toolchain/platform/src/critical_section.rs`.
Resolves INT-7566. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolves INT-7563.
…, mulh, divrem, jal_lui, jalr, auipc (#2741) Resolves INT-7550. --------- Co-authored-by: Tuanlinh12312 <136139181+Tuanlinh12312@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolves INT-7551.
Resolves INT-7553. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolves INT-7552. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolves INT-7564, INT-7528.
Resolves INT-7554. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves INT-7530.
# fix(v2.1-rv64): convert more rv32 references to rv64
Follow-up cleanup that gets the lint job and the `sha2_bench`
bench-prove run green on the rv64 branch, plus a few non-AOT polish
items called out in review.
## Lint fixes
- `extensions/riscv/circuit/src/auipc/tests.rs` — gate
`RV64_REGISTER_NUM_LIMBS` behind `#[cfg(feature = "cuda")]`; it's only
used inside the CUDA test, so the CPU lint job hit `unused_imports`.
- `crates/continuations/src/tests/e2e.rs` — rename stale
`Rv32DeferralBuilder` / `Rv32DeferralConfig` → `Rv64DeferralBuilder` /
`Rv64DeferralConfig` (3 sites). Fixes the CUDA lint job's `E0432`.
- `crates/sdk/src/tests.rs` — `SdkVmConfig::riscv32()` → `::riscv64()`
plus doc-comment.
- `benchmarks/prove/src/lib.rs` — drop unused `clap::command` import.
- `extensions/riscv/circuit/src/{mul,mul_w,jalr,mulh}/tests.rs` — error
string `"failed to create Rv32IM executor"` → `"Rv64IM executor"`.
## Rename
- `Rv32ModularArithmeticOpcode` → `Rv64ModularArithmeticOpcode` (81
references across `extensions/algebra/{transpiler,circuit}`). Pure
rename, no semantic change.
## Cleanup
- Remove `tmp_convert_to_u8s` and its `// TEMP[jpw]` marker from
`extensions/riscv/circuit/src/adapters/mod.rs` — `pub fn` with zero
in-tree callers.
- `crates/toolchain/openvm/src/io/mod.rs` — replace hardcoded `8` in
`read_vec_by_len` with `openvm_platform::WORD_SIZE`.
## Bug fix
- `crates/toolchain/openvm/src/serde/serializer.rs` — `to_vec` was
calling `Vec::<u64>::with_capacity(size_of_val(value))`, conflating
bytes with u64 elements and over-allocating 8×. Switched to
`size_of_val(value).div_ceil(size_of::<u64>())`. Heap waste only, no
correctness impact.
## Benchmark ELF rebuilds
Rebuilt 16 benchmark guest ELFs as 64-bit RISC-V (the committed binaries
were still 32-bit, which made `sha2_bench` fail with `Error: Not a
64-bit ELF` after the transpiler tightened its check): base64_json,
bincode, bubblesort, ecrecover, fibonacci, fibonacci_iterative,
fibonacci_recursive, keccak256, keccak256_iter, kitchen-sink, pairing,
quicksort, rkyv, sha2_bench, sha256, sha256_iter.
Not rebuilt — `regex`, `revm_transfer`, `revm_snailtracer` — their
dependency closures (`regex-automata`, `tracing-core 0.1.x`) use atomic
CAS methods that the `riscv64im-unknown-none-elf` target doesn't expose.
The existing `portable-atomic` polyfill in `openvm-platform` works for
crates that opt in via a feature flag (`bytes`, `spin`), but neither
failing crate exposes one. Tracking as a separate item.
## Verification
- `cargo +nightly fmt --all -- --check` clean.
- `cargo clippy --workspace --all-targets --tests --features "<CI
feature set>" -- -D warnings` clean.
- `cargo check --workspace --all-targets --tests` clean.
Resolves INT-6048. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Towards INT-6339. AUIPC was zero-extending `pc + (imm << 12)` into the upper 32 bits of rd, but the RV64 spec requires sign extension, causing riscv test `rv64ui-p-auipc` to fail. Add `is_sign_extend` column to constrain the MSB of the 32-bit result and fill the upper 4 bytes accordingly. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Ayush Shukla <ayush@axiom.xyz>
Resolves INT-7594. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolves INT-7610. ## Summary - **Consolidate constants**: Replace bigint's local `CONST_BLOCK_SIZE` with `program::DEFAULT_BLOCK_SIZE`. Remove 59 unused/stale constants from `constants.h` (RV32 legacy, dead sha256/mod_builder/keccak256 entries). - **Remove trace height asserts**: Remove redundant `assert((height & (height - 1)) == 0)` and `assert(height >= d_records.len())` from all 24 CUDA kernel entry points — these invariants are guaranteed by the Rust caller. - **Remove compile-time constants from kernel arguments**: Remove `bitwise_num_bits` parameter from 51 files (CUDA kernels + Rust FFI), hardcoding `RV64_CELL_BITS` into `BitwiseOperationLookup`. Remove `pc_step` from program tracegen, using `DEFAULT_PC_STEP` directly. - **Extract divrem helpers**: Add `limbs_to_u64`/`u64_to_limbs` helpers in `divrem.cuh` to replace inline limb conversion loops. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…named files Upstream #2771 (e11f786) introduced the ColumnsAir trait as required for all AIRs and added StructReflection to corresponding Cols structs. During the rebase, the -X theirs strategy dropped these additions for files our rv64 branch had renamed (Rv32* -> Rv64*) or otherwise modified. Re-applies the derive macros and #[columns_via(...)] attributes so the workspace builds against develop-v2.0.0-rc.1.
…tor script (#2780) ## Summary - Replaces the glibc-derived `memcpy.s` / `memset.s` in `crates/toolchain/openvm/src/` with musl-libc equivalents (MIT-licensed; matches the v2.0.0 lineage). - Adds `scripts/generate_libc_intrinsics.sh` to regenerate both files deterministically from upstream sources. - Fixes an LLVM jump-table label collision that prevented guest binaries with dense user code from linking under fat LTO. ## Why Two problems with the current state: 1. **Licensing**: the existing files were compiled from glibc (LGPL-2.1+) but checked in without a license header or attribution. musl-libc (MIT) is permissive and was the original source used in the v2.0.x branch (`develop-v2.0.0-rc.1`), so switching back is both more permissive and continuity-preserving. 2. **Symbol collision under fat LTO**: the glibc-derived `memcpy.s` defined an orphan jump table `.LJTI0_0` (without a function prefix). LLVM emits the same name for the first jump table of "function 0" in any translation unit, so user code that happens to lower a `match` into a jump table — combined with `lto = "fat"` merging crates into a single LLVM module — causes: ``` error: symbol '.LJTI0_0' is already defined ``` The musl-derived equivalents have no jump table (at `-O3 -funroll-loops`, musl's memcpy unrolls fully), and the generator script prefixes every per-TU local label (`.LBB0_*`, `.LJTI0_*`, `.Lfunc_end0`) with the function name to make any future drift impossible. ## What's in the PR | File | Purpose | |---|---| | `scripts/generate_libc_intrinsics.sh` | Fetches musl sources at a pinned ref, strips `#include` lines, compiles with the recipe `clang -target riscv64 -march=rv64im -O3 -funroll-loops`, applies local-label prefixing, strips `.ident`, normalizes `.file`, and embeds musl `COPYRIGHT` in the file header. Accepts `--musl-ref <tag\|branch\|sha>` and `--clang <path>` with sensible defaults. Idempotent. | | `crates/toolchain/openvm/src/memcpy.s` | Regenerated from musl v1.2.6 (`9fa28ece75d8a2191de7c5bb53bed224c5947417`). | | `crates/toolchain/openvm/src/memset.s` | Regenerated from musl v1.2.6 (`9fa28ece75d8a2191de7c5bb53bed224c5947417`). | | `crates/toolchain/openvm/README.md` | Pointer to the generator. | ## Reproduce ```bash scripts/generate_libc_intrinsics.sh git diff --exit-code crates/toolchain/openvm/src/memcpy.s crates/toolchain/openvm/src/memset.s ``` Should produce no diff on a fresh checkout. The `.ident` directive is stripped during generation, so output bytes are independent of the clang distribution (Homebrew vs Debian vs Apple Clang); the only per-clang-version variation that remains is the `.attribute 5` ISA string (e.g. `"rv64im"` on clang ≤14 vs the canonical `"rv64i2p1_m2p0_zmmul1p0"` on clang ≥16) — same ISA, different recording. ## Test plan - [x] `scripts/generate_libc_intrinsics.sh` reruns produce byte-identical output (idempotent). - [x] Both regenerated files contain no orphan `.LJTI0_*` / `.LBB0_*` / `.Lfunc_end0` labels — every local label is function-prefixed. - [ ] CI on this PR (build, lint, riscv-test-vector, extension-tests). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
723e24c to
16f0404
Compare
|
Claude finished @shuklaayush's task in 5m 42s —— View job Review #19 — RV32→RV64 Migration AuditHEAD: Checklist
SummaryNo new commits since Review #18. HEAD remains at Non-AOT Code: CLEAN ✅All 20+ bugs discovered and fixed across Reviews #1–#18 remain resolved. Verified across:
|
Note: cells_used metrics omitted because CUDA tracegen does not expose unpadded trace heights. Commit: 16f0404 |
93afded to
307dc7e
Compare
f08f0fe to
0110850
Compare
No description provided.