Showing preview only (2,188K chars total). Download the full file or copy to clipboard to get everything.
Repository: powdr-labs/powdr
Branch: main
Commit: 70a2ad887478
Files: 308
Total size: 30.0 MB
Directory structure:
gitextract_74kaprsg/
├── .config/
│ └── nextest.toml
├── .gitattributes
├── .github/
│ ├── actions/
│ │ ├── init-testing-instance/
│ │ │ └── action.yml
│ │ ├── init-testing-instance-gpu/
│ │ │ └── action.yml
│ │ └── patch-openvm-reth-benchmark/
│ │ └── action.yml
│ ├── runner/
│ │ └── Dockerfile
│ └── workflows/
│ ├── build-cache.yml
│ ├── dead-links.yml
│ ├── nightly-analyze.yml
│ ├── nightly-tests.yml
│ ├── post-merge-tests.yml
│ ├── pr-tests-with-secrets.yml
│ └── pr-tests.yml
├── .gitignore
├── CLAUDE.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── autoprecompile-analyzer/
│ ├── Claude.md
│ └── index.html
├── autoprecompiles/
│ ├── Cargo.toml
│ ├── benches/
│ │ └── optimizer_benchmark.rs
│ ├── scripts/
│ │ ├── plot_effectiveness.py
│ │ ├── rank_apc_candidates.py
│ │ ├── readme.md
│ │ └── requirements.txt
│ ├── src/
│ │ ├── adapter.rs
│ │ ├── blocks/
│ │ │ ├── detection.rs
│ │ │ └── mod.rs
│ │ ├── bus_map.rs
│ │ ├── constraint_optimizer.rs
│ │ ├── empirical_constraints.rs
│ │ ├── equivalence_classes.rs
│ │ ├── evaluation.rs
│ │ ├── execution/
│ │ │ ├── ast.rs
│ │ │ ├── candidates.rs
│ │ │ ├── evaluator.rs
│ │ │ └── mod.rs
│ │ ├── execution_profile.rs
│ │ ├── export.rs
│ │ ├── expression.rs
│ │ ├── expression_conversion.rs
│ │ ├── lib.rs
│ │ ├── low_degree_bus_interaction_optimizer.rs
│ │ ├── memory_optimizer.rs
│ │ ├── optimistic/
│ │ │ ├── algebraic_references.rs
│ │ │ ├── config.rs
│ │ │ ├── execution_constraint_generator.rs
│ │ │ ├── execution_literals.rs
│ │ │ └── mod.rs
│ │ ├── optimizer.rs
│ │ ├── optimizer_documentation.md
│ │ ├── pgo/
│ │ │ ├── cell/
│ │ │ │ ├── mod.rs
│ │ │ │ └── selection.rs
│ │ │ ├── instruction.rs
│ │ │ ├── mod.rs
│ │ │ └── none.rs
│ │ ├── powdr.rs
│ │ ├── range_constraint_optimizer.rs
│ │ ├── stats_logger.rs
│ │ ├── symbolic_machine.rs
│ │ ├── symbolic_machine_generator.rs
│ │ └── trace_handler.rs
│ └── tests/
│ └── optimizer.rs
├── cli-openvm-riscv/
│ ├── Cargo.toml
│ ├── README.md
│ └── src/
│ └── main.rs
├── constraint-solver/
│ ├── Cargo.toml
│ ├── src/
│ │ ├── algebraic_constraint/
│ │ │ ├── mod.rs
│ │ │ └── solve.rs
│ │ ├── bus_interaction_handler.rs
│ │ ├── constraint_system.rs
│ │ ├── effect.rs
│ │ ├── grouped_expression.rs
│ │ ├── indexed_constraint_system.rs
│ │ ├── inliner.rs
│ │ ├── lib.rs
│ │ ├── range_constraint.rs
│ │ ├── reachability.rs
│ │ ├── rule_based_optimizer/
│ │ │ ├── driver.rs
│ │ │ ├── environment.rs
│ │ │ ├── item_db.rs
│ │ │ ├── mod.rs
│ │ │ ├── new_var_generator.rs
│ │ │ ├── rules.rs
│ │ │ ├── tests.rs
│ │ │ └── types.rs
│ │ ├── runtime_constant.rs
│ │ ├── solver/
│ │ │ ├── base.rs
│ │ │ ├── boolean_extractor.rs
│ │ │ ├── constraint_splitter.rs
│ │ │ ├── exhaustive_search.rs
│ │ │ ├── linearizer.rs
│ │ │ └── var_transformation.rs
│ │ ├── solver.rs
│ │ ├── symbolic_expression.rs
│ │ ├── system_splitter.rs
│ │ ├── test_utils.rs
│ │ ├── utils.rs
│ │ └── variable_update.rs
│ └── tests/
│ └── solver.rs
├── expression/
│ ├── Cargo.toml
│ └── src/
│ ├── display.rs
│ ├── lib.rs
│ └── visitors.rs
├── isa-utils/
│ ├── Cargo.toml
│ └── src/
│ └── lib.rs
├── number/
│ ├── Cargo.toml
│ └── src/
│ ├── baby_bear.rs
│ ├── bn254.rs
│ ├── expression_convertible.rs
│ ├── goldilocks.rs
│ ├── koala_bear.rs
│ ├── lib.rs
│ ├── macros.rs
│ ├── mersenne31.rs
│ ├── plonky3_macros.rs
│ ├── serialize.rs
│ └── traits.rs
├── openvm/
│ ├── Cargo.toml
│ ├── build.rs
│ ├── cuda/
│ │ └── src/
│ │ ├── apc_apply_bus.cu
│ │ ├── apc_tracegen.cu
│ │ └── expr_eval.cuh
│ ├── metrics-viewer/
│ │ ├── CLAUDE.md
│ │ ├── index.html
│ │ └── spec.py
│ └── src/
│ ├── air_builder.rs
│ ├── cuda_abi.rs
│ ├── customize_exe.rs
│ ├── empirical_constraints.rs
│ ├── extraction_utils.rs
│ ├── isa.rs
│ ├── lib.rs
│ ├── powdr_extension/
│ │ ├── chip.rs
│ │ ├── executor/
│ │ │ └── mod.rs
│ │ ├── mod.rs
│ │ ├── opcode.rs
│ │ ├── trace_generator/
│ │ │ ├── common.rs
│ │ │ ├── cpu/
│ │ │ │ ├── inventory.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── periphery.rs
│ │ │ ├── cuda/
│ │ │ │ ├── inventory.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── periphery.rs
│ │ │ └── mod.rs
│ │ └── vm.rs
│ ├── program.rs
│ ├── test_utils.rs
│ ├── trace_generation.rs
│ └── utils.rs
├── openvm-bus-interaction-handler/
│ ├── Cargo.toml
│ └── src/
│ ├── bitwise_lookup.rs
│ ├── bus_map.rs
│ ├── lib.rs
│ ├── memory.rs
│ ├── memory_bus_interaction.rs
│ ├── tuple_range_checker.rs
│ └── variable_range_checker.rs
├── openvm-riscv/
│ ├── .gitignore
│ ├── Cargo.toml
│ ├── extensions/
│ │ ├── hints-circuit/
│ │ │ ├── Cargo.toml
│ │ │ └── src/
│ │ │ ├── executors.rs
│ │ │ ├── field10x26_k256.rs
│ │ │ └── lib.rs
│ │ ├── hints-guest/
│ │ │ ├── Cargo.toml
│ │ │ └── src/
│ │ │ └── lib.rs
│ │ └── hints-transpiler/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── lib.rs
│ ├── guest/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-ecc-manual/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-ecc-powdr-affine-hint/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-ecc-projective/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-ecrecover/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-ecrecover-manual/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-hints-test/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-keccak/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-keccak-manual-precompile/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-matmul/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-pairing/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-pairing-manual-precompile/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-sha256/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-sha256-manual-precompile/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-u256/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-u256-manual-precompile/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── scripts/
│ │ ├── basic_metrics.py
│ │ ├── generate_bench_results_readme.py
│ │ ├── metrics_utils.py
│ │ ├── plot_trace_cells.py
│ │ ├── readme.md
│ │ ├── requirements.txt
│ │ └── run_guest_benches.sh
│ ├── src/
│ │ ├── isa/
│ │ │ ├── instruction_formatter.rs
│ │ │ ├── mod.rs
│ │ │ ├── opcode.rs
│ │ │ ├── symbolic_instruction_builder.rs
│ │ │ └── trace_generator/
│ │ │ ├── common.rs
│ │ │ ├── cpu.rs
│ │ │ ├── cuda.rs
│ │ │ └── mod.rs
│ │ └── lib.rs
│ └── tests/
│ ├── apc_builder_complex.rs
│ ├── apc_builder_pseudo_instructions.rs
│ ├── apc_builder_single_instructions.rs
│ ├── apc_builder_superblocks.rs
│ ├── apc_reth_op_bug.cbor
│ ├── apc_snapshots/
│ │ ├── complex/
│ │ │ ├── aligned_memcpy.txt
│ │ │ ├── copy_byte.txt
│ │ │ ├── guest_top_block.txt
│ │ │ ├── load_two_bytes_compare.txt
│ │ │ ├── load_two_bytes_compare_unsigned.txt
│ │ │ ├── many_stores_relative_to_same_register.txt
│ │ │ ├── memcpy_block.txt
│ │ │ ├── rotate.txt
│ │ │ ├── stack_accesses.txt
│ │ │ ├── store_to_same_memory_address.txt
│ │ │ └── unaligned_memcpy.txt
│ │ ├── pseudo_instructions/
│ │ │ ├── beqz.txt
│ │ │ ├── bgez.txt
│ │ │ ├── bgtz.txt
│ │ │ ├── blez.txt
│ │ │ ├── bltz.txt
│ │ │ ├── bnez.txt
│ │ │ ├── j.txt
│ │ │ ├── jr.txt
│ │ │ ├── load_immediate.txt
│ │ │ ├── mv.txt
│ │ │ ├── neg.txt
│ │ │ ├── not.txt
│ │ │ ├── ret.txt
│ │ │ ├── seqz.txt
│ │ │ ├── sgtz.txt
│ │ │ ├── sltz.txt
│ │ │ └── snez.txt
│ │ ├── single_instructions/
│ │ │ ├── single_add_1.txt
│ │ │ ├── single_and_0.txt
│ │ │ ├── single_beq.txt
│ │ │ ├── single_bge.txt
│ │ │ ├── single_bgeu.txt
│ │ │ ├── single_blt.txt
│ │ │ ├── single_bltu.txt
│ │ │ ├── single_bne.txt
│ │ │ ├── single_div.txt
│ │ │ ├── single_divu.txt
│ │ │ ├── single_loadb.txt
│ │ │ ├── single_loadb_imm0.txt
│ │ │ ├── single_loadb_x0.txt
│ │ │ ├── single_loadbu.txt
│ │ │ ├── single_loadh.txt
│ │ │ ├── single_loadhu.txt
│ │ │ ├── single_loadw.txt
│ │ │ ├── single_mul.txt
│ │ │ ├── single_rem.txt
│ │ │ ├── single_remu.txt
│ │ │ ├── single_sll.txt
│ │ │ ├── single_sll_by_8.txt
│ │ │ ├── single_sra.txt
│ │ │ ├── single_srl.txt
│ │ │ ├── single_storeb.txt
│ │ │ ├── single_storeh.txt
│ │ │ ├── single_storew.txt
│ │ │ ├── single_sub.txt
│ │ │ └── single_xor.txt
│ │ └── superblocks/
│ │ ├── beq0_fallthrough.txt
│ │ ├── beq0_jump.txt
│ │ ├── beq_fallthrough.txt
│ │ ├── beq_jump.txt
│ │ └── many_blocks.txt
│ ├── common/
│ │ └── mod.rs
│ ├── keccak_apc_pre_opt.cbor
│ ├── machine_extraction.rs
│ └── openvm_constraints.txt
├── riscv-elf/
│ ├── Cargo.toml
│ └── src/
│ ├── bin/
│ │ └── elf-labels.rs
│ ├── debug_info.rs
│ ├── lib.rs
│ └── rv64.rs
├── riscv-types/
│ ├── Cargo.toml
│ └── src/
│ └── lib.rs
├── rust-toolchain.toml
├── scripts/
│ ├── analyze_nightly.py
│ └── update-dep.sh
└── syscalls/
├── Cargo.toml
└── src/
└── lib.rs
================================================
FILE CONTENTS
================================================
================================================
FILE: .config/nextest.toml
================================================
# Profiles to fail after a timeout, but continue with the other tests
[profile.quick-10]
slow-timeout = { period = "10s", terminate-after = 1 }
fail-fast = false
[profile.quick-30]
slow-timeout = { period = "30s", terminate-after = 1 }
fail-fast = false
[profile.quick-60]
slow-timeout = { period = "60s", terminate-after = 1 }
fail-fast = false
================================================
FILE: .gitattributes
================================================
**/*.asm linguist-language=Rust
**/*.pil linguist-language=Rust
================================================
FILE: .github/actions/init-testing-instance/action.yml
================================================
name: "Init testing instance"
description: "Initialises a testing instance with all required tools and fetches the precomputed tests archive named `tests_archive_cpu`"
runs:
using: "composite"
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Download build artifacts (CPU)
uses: actions/download-artifact@v4
with:
name: tests_archive_cpu
- name: Install Rust toolchain nightly-2025-05-14 (with clippy and rustfmt)
shell: bash
run: rustup toolchain install nightly-2025-05-14 --component clippy,rustfmt,rust-src
- name: Install riscv target
shell: bash
run: rustup target add riscv32imac-unknown-none-elf --toolchain nightly-2025-10-01
- name: Install test dependencies
shell: bash
run: sudo apt-get update && sudo apt-get install -y binutils-riscv64-unknown-elf lld
- name: Install Rust deps
shell: bash
run: rustup install nightly-2025-10-01 --component rust-src
- name: Install Rust deps
shell: bash
run: rustup install nightly-2025-02-14 --component rust-src
- name: Install OpenVM guest toolchain (nightly-2025-08-02)
shell: bash
run: |
rustup toolchain install nightly-2025-08-02
rustup component add rust-src --toolchain nightly-2025-08-02
- uses: taiki-e/install-action@nextest
================================================
FILE: .github/actions/init-testing-instance-gpu/action.yml
================================================
name: "Init testing instance (GPU)"
description: "Initialises a testing instance with all required tools and fetches the precomputed tests archive named `tests_archive_gpu`"
runs:
using: "composite"
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Download build artifacts (GPU)
uses: actions/download-artifact@v4
with:
name: tests_archive_gpu
- name: Install Rust toolchain nightly-2025-05-14 (with clippy and rustfmt)
shell: bash
run: rustup toolchain install nightly-2025-05-14 --component clippy,rustfmt,rust-src
- name: Install riscv target
shell: bash
run: rustup target add riscv32imac-unknown-none-elf --toolchain nightly-2025-10-01
# TODO: runner on our GPU server has no sudo access, so we manually installed these; uncomment these once we have proper runners
# - name: Install test dependencies
# shell: bash
# run: sudo apt-get update && sudo apt-get install -y binutils-riscv64-unknown-elf lld
- name: Install Rust deps
shell: bash
run: rustup install nightly-2025-10-01 --component rust-src
- name: Install Rust deps
shell: bash
run: rustup install nightly-2025-02-14 --component rust-src
- name: Install OpenVM guest toolchain (nightly-2025-08-02)
shell: bash
run: |
rustup toolchain install nightly-2025-08-02
rustup component add rust-src --toolchain nightly-2025-08-02
- uses: taiki-e/install-action@nextest
================================================
FILE: .github/actions/patch-openvm-reth-benchmark/action.yml
================================================
name: "Patch openvm-reth-benchmark"
description: "Checks out powdr-labs/openvm-reth-benchmark at a fixed ref and patches it to use local powdr crates"
runs:
using: "composite"
steps:
- name: Checkout openvm-reth-benchmark
uses: actions/checkout@v4
with:
repository: powdr-labs/openvm-reth-benchmark
# Set once here — no inputs required elsewhere
# Should always point to the latest main commit
ref: 4a697fec23cb00849039f0bcaab5432929e05b38
path: openvm-reth-benchmark
- name: Patch openvm-reth-benchmark to use local powdr
shell: bash
run: |
cd openvm-reth-benchmark
mkdir -p .cargo
cat <<'EOF' > .cargo/config.toml
[patch."https://github.com/powdr-labs/powdr.git"]
powdr-openvm-riscv = { path = "../openvm-riscv" }
powdr-openvm = { path = "../openvm" }
powdr-riscv-elf = { path = "../riscv-elf" }
powdr-number = { path = "../number" }
powdr-autoprecompiles = { path = "../autoprecompiles" }
powdr-openvm-riscv-hints-circuit = { path = "../openvm-riscv/extensions/hints-circuit" }
EOF
================================================
FILE: .github/runner/Dockerfile
================================================
#
# Runner for powdr github actions.
# We don't automate runner token generation yet. This image should be used as follows:
# - generate a runner token in github (valid for ~1h)
# - build the docker image passing the token as argument:
# docker buildx build -t github-runner --build-arg TOKEN=THE_GENERATED_TOKEN .
# - this will create an image already registered it with github
# - the container will start the runner (./run.sh) by default.
# this base image was taken from the Dockerfile in the github runner repo
FROM mcr.microsoft.com/dotnet/runtime-deps:6.0-jammy AS build
ARG RUNNER_VERSION=2.319.1
RUN apt-get update && apt install -y curl \
sudo \
libicu70 \
liblttng-ust1 \
libkrb5-3 \
zlib1g \
libssl3 \
git \
build-essential \
clang-15 \
nlohmann-json3-dev \
libpqxx-dev \
nasm \
libgmp-dev \
uuid-dev \
zstd
RUN adduser --disabled-password --uid 1001 runner \
&& usermod -aG sudo runner \
&& echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers \
&& echo "Defaults env_keep += \"DEBIAN_FRONTEND\"" >> /etc/sudoers
USER runner
WORKDIR /home/runner
RUN curl -f -L -o runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz \
&& tar xzf ./runner.tar.gz \
&& rm runner.tar.gz
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s - -y
ARG TOKEN
RUN test -n "$TOKEN" || (echo "must set github runner TOKEN: --build-arg TOKEN=XXX" && false)
RUN ./config.sh --name arch-server --work work --replace --url https://github.com/powdr-labs/powdr --token ${TOKEN}
# anything that should be in the PATH of the runner must be setup here
ENV PATH="/home/runner/.cargo/bin:$PATH"
CMD ["./run.sh"]
================================================
FILE: .github/workflows/build-cache.yml
================================================
name: Generate rust cache for PR builds
on:
workflow_dispatch:
schedule:
- cron: '0 2 * * *' # run at 2 AM UTC
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: warp-ubuntu-2404-x64-4x
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Save date of cache build
run: mkdir target && date -R -u > target/cache-build-date.txt
- name: Save commit hash of cache build
run: git rev-parse HEAD > target/cache-commit-hash.txt
##### The block below is shared between cache build and PR build workflows #####
- name: Install Rust toolchain nightly-2025-10-01 (with clippy and rustfmt)
run: rustup toolchain install nightly-2025-10-01 --component clippy,rustfmt
- name: Install Rust toolchain
run: rustup toolchain install nightly-2025-02-14 --component rust-src
- name: Install Rust toolchain 1.90 (stable)
run: rustup toolchain install 1.90
- name: Set cargo to perform shallow clones
run: echo "CARGO_NET_GIT_FETCH_WITH_CLI=true" >> $GITHUB_ENV
- name: Format
run: cargo fmt --all --check --verbose
- name: Cargo check with Rust 1.90 (default features)
run: cargo +1.90 check --all-targets
- name: Lint no default features
run: cargo clippy --all --all-targets --no-default-features --profile pr-tests --verbose -- -D warnings
- name: Build
run: cargo build --all-targets --features metrics --all --profile pr-tests --verbose
###############################################################################
- name: Delete the old cache
uses: WarpBuilds/cache@v1
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
Cargo.lock
key: ${{ runner.os }}-cargo-pr-tests
delete-cache: true
- name: ⚡ Save rust cache
uses: WarpBuilds/cache/save@v1
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
Cargo.lock
key: ${{ runner.os }}-cargo-pr-tests
================================================
FILE: .github/workflows/dead-links.yml
================================================
name: Check markdown links
on: [pull_request, merge_group]
jobs:
markdown-link-check:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: gaurav-nelson/github-action-markdown-link-check@v1
with:
use-quiet-mode: 'no'
use-verbose-mode: 'yes'
================================================
FILE: .github/workflows/nightly-analyze.yml
================================================
name: Nightly Regression Analysis
on:
workflow_dispatch:
workflow_run:
workflows: ["Nightly tests"]
types:
- completed
jobs:
analyze:
runs-on: ubuntu-latest
# Only run if nightly tests completed successfully or failed (not skipped/cancelled)
if: >-
${{
github.event_name == 'workflow_dispatch' ||
github.event.workflow_run.conclusion == 'success' ||
github.event.workflow_run.conclusion == 'failure'
}}
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install pandas
- name: Run regression analysis
id: analysis
run: |
# Run analysis and capture stdout (report) separately from stderr (logs)
set +e
python ./scripts/analyze_nightly.py --regression-threshold 2 > analysis_report.md
EXIT_CODE=$?
set -e
# Set outputs for later steps
echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT
# Save report as output (using delimiter for multiline)
{
echo "report<<EOF"
cat analysis_report.md
echo "EOF"
} >> $GITHUB_OUTPUT
# Print report to logs as well
cat analysis_report.md
- name: Generate job summary
run: cat analysis_report.md >> $GITHUB_STEP_SUMMARY
- name: Check for regressions
if: ${{ steps.analysis.outputs.exit_code == '1' }}
run: echo "::warning::Performance regressions detected! See job summary for details."
- name: Check for errors
if: ${{ steps.analysis.outputs.exit_code == '2' }}
run: echo "::warning::Errors occurred during analysis. See job summary for details."
- name: Send report to Matrix
uses: fadenb/matrix-chat-message@v0.0.6
with:
homeserver: ${{ secrets.MATRIX_HOMESERVER }}
token: ${{ secrets.MATRIX_ACCESS_TOKEN }}
channel: ${{ secrets.MATRIX_ROOM_ID }}
message: |
${{ steps.analysis.outputs.report }}
[View workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
================================================
FILE: .github/workflows/nightly-tests.yml
================================================
name: Nightly tests
on:
workflow_dispatch:
schedule:
- cron: "0 23 * * *" # run at 11pm UTC
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: "-C target-cpu=native"
RUST_BACKTRACE: 1
JEMALLOC_SYS_WITH_MALLOC_CONF: "retain:true,background_thread:true,metadata_thp:always,dirty_decay_ms:10000,muzzy_decay_ms:10000,abort_conf:true"
POWDR_OPENVM_SEGMENT_DELTA: 50000
jobs:
bench:
runs-on: warp-ubuntu-2404-x64-4x
permissions:
contents: write
deployments: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: ⚡ Restore rust cache
id: cache
uses: WarpBuilds/cache/restore@v1
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
Cargo.lock
key: ${{ runner.os }}-cargo-pr-tests
- name: Install Rust toolchain nightly-2025-10-01 (with clippy and rustfmt)
run: rustup toolchain install nightly-2025-10-01 --component clippy,rustfmt,rust-src
- name: Install Rust toolchain 1.90
run: rustup toolchain install 1.90
- name: Install riscv target
run: rustup target add riscv32imac-unknown-none-elf --toolchain nightly-2025-10-01
- name: Install test dependencies
run: sudo apt-get update && sudo apt-get install -y binutils-riscv64-unknown-elf lld
- name: Run benchmarks
# we add `|| exit 1` to make sure the step fails if `cargo bench` fails
run: cargo bench --workspace --features "metrics" -- --output-format bencher | tee output.txt || exit 1
- name: Store benchmark result
uses: benchmark-action/github-action-benchmark@v1
with:
name: Benchmarks
tool: "cargo"
output-file-path: output.txt
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: true
alert-threshold: "120%"
comment-on-alert: true
summary-always: true
test_apc:
runs-on: server-dev
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: ⚡ Cache rust
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-release-apc-${{ hashFiles('**/Cargo.toml') }}
- name: Build
run: cargo build --release -p powdr-openvm
- name: Install cargo openvm
# Rust 1.90 is needed by fresher versions of dependencies of cargo-openvm.
run: |
rustup toolchain install 1.90
cargo +1.90 install --git 'http://github.com/powdr-labs/openvm.git' --rev "v1.4.2-powdr-rc.4" --locked cargo-openvm
- name: Setup python venv
run: |
python3 -m venv .venv
source .venv/bin/activate
pip install -r openvm-riscv/scripts/requirements.txt
pip install -r autoprecompiles/scripts/requirements.txt
- name: Remove old results if present
run: |
rm -rf results
mkdir -p results
- name: Run guest benchmarks
run: |
source .venv/bin/activate
bash ./openvm-riscv/scripts/run_guest_benches.sh
- name: Patch benchmark
uses: ./.github/actions/patch-openvm-reth-benchmark
- name: Run reth benchmark
run: |
source .venv/bin/activate
cd openvm-reth-benchmark
RES_DIR=reth
mkdir -p $RES_DIR
echo "export RPC_1=${{ secrets.RPC_1 }}" >> .env
# prove with no APCs
./run.sh --apc 0 --mode prove-stark || exit 1
# remove apc cache to not interfere with the next runs
rm -rf apc-cache
echo "Finished proving with no APCs"
mv metrics.json $RES_DIR/apc000.json
python ../openvm-riscv/scripts/plot_trace_cells.py -o $RES_DIR/trace_cells_apc000.png $RES_DIR/apc000.json > $RES_DIR/trace_cells_apc000.txt
# prove with 3 APCs
./run.sh --apc 3 --mode prove-stark || exit 1
# remove apc cache to not interfere with the next runs
rm -rf apc-cache
echo "Finished proving with 3 APCs"
mv metrics.json $RES_DIR/apc003.json
python ../openvm-riscv/scripts/plot_trace_cells.py -o $RES_DIR/trace_cells_apc003.png $RES_DIR/apc003.json > $RES_DIR/trace_cells_apc003.txt
# prove with 10 APCs
./run.sh --apc 10 --mode prove-stark || exit 1
# remove apc cache to not interfere with the next runs
rm -rf apc-cache
echo "Finished proving with 10 APCs"
mv metrics.json $RES_DIR/apc010.json
python ../openvm-riscv/scripts/plot_trace_cells.py -o $RES_DIR/trace_cells_apc010.png $RES_DIR/apc010.json > $RES_DIR/trace_cells_apc010.txt
# prove with 30 APCs
./run.sh --apc 30 --mode prove-stark || exit 1
# remove apc cache to not interfere with the next runs
rm -rf apc-cache
echo "Finished proving with 30 APCs"
mv metrics.json $RES_DIR/apc030.json
python ../openvm-riscv/scripts/plot_trace_cells.py -o $RES_DIR/trace_cells_apc030.png $RES_DIR/apc030.json > $RES_DIR/trace_cells_apc030.txt
# prove with 100 APCs, recording mem usage
psrecord --include-children --interval 1 --log $RES_DIR/psrecord.csv --log-format csv --plot $RES_DIR/psrecord.png "./run.sh --apc 100 --mode prove-stark" || exit 1
# remove apc cache to not interfere with the next runs
rm -rf apc-cache
echo "Finished proving with 100 APCs"
mv metrics.json $RES_DIR/apc100.json
python ../openvm-riscv/scripts/plot_trace_cells.py -o $RES_DIR/trace_cells_apc100.png $RES_DIR/apc100.json > $RES_DIR/trace_cells_apc100.txt
# The APC candidates would be the same for all runs, so just keep the last one
mv apcs/apc_candidates.json $RES_DIR/apc_candidates.json
python ../openvm-riscv/scripts/basic_metrics.py summary-table --csv $RES_DIR/apc000.json $RES_DIR/apc003.json $RES_DIR/apc010.json $RES_DIR/apc030.json $RES_DIR/apc100.json > $RES_DIR/basic_metrics.csv
python ../openvm-riscv/scripts/basic_metrics.py plot $RES_DIR/apc000.json $RES_DIR/apc003.json $RES_DIR/apc010.json $RES_DIR/apc030.json $RES_DIR/apc100.json -o $RES_DIR/proof_time_breakdown.png
python ../openvm-riscv/scripts/basic_metrics.py combine $RES_DIR/apc000.json $RES_DIR/apc003.json $RES_DIR/apc010.json $RES_DIR/apc030.json $RES_DIR/apc100.json > $RES_DIR/combined_metrics.json
python ../autoprecompiles/scripts/plot_effectiveness.py $RES_DIR/apc_candidates.json --output $RES_DIR/effectiveness.png
mv $RES_DIR ../results/
- name: Save revisions and run info
run: |
echo "openvm-reth-benchmark: $(git -C openvm-reth-benchmark rev-parse HEAD)" > results/run.txt
echo "powdr: $(git rev-parse HEAD)" >> results/run.txt
echo "run: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" >> results/run.txt
- name: upload result artifacts
uses: actions/upload-artifact@v4
with:
name: bench-results
path: |
results/*
- name: get the date/time
id: date
run: echo "value=$(date +'%Y-%m-%d-%H%M')" >> $GITHUB_OUTPUT
- name: Generate bench results README
run: |
python3 ./openvm-riscv/scripts/generate_bench_results_readme.py \
./results \
"${{ steps.date.outputs.value }}" \
--output ./results/readme.md
- name: commit to bench results
uses: peaceiris/actions-gh-pages@v4
with:
personal_token: ${{ secrets.BENCH_RESULTS_TOKEN }}
external_repository: powdr-labs/bench-results
publish_dir: ./results
destination_dir: results/${{ steps.date.outputs.value }}/
keep_files: true
enable_jekyll: true
test_apc_gpu:
runs-on: [self-hosted, gpu-shared]
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: ⚡ Cache rust
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-release-apc-gpu-${{ hashFiles('**/Cargo.toml') }}
- name: Install cargo openvm
# Rust 1.90 is needed by fresher versions of dependencies of cargo-openvm.
run: |
rustup toolchain install 1.90
cargo +1.90 install --git 'http://github.com/powdr-labs/openvm.git' --rev "v1.4.2-powdr-rc.4" --locked cargo-openvm
- name: Setup python venv
run: |
python3 -m venv .venv
source .venv/bin/activate
pip install -r openvm-riscv/scripts/requirements.txt
pip install -r autoprecompiles/scripts/requirements.txt
- name: Remove old results if present
run: |
rm -rf results
mkdir -p results
- name: Patch benchmark
uses: ./.github/actions/patch-openvm-reth-benchmark
- name: Run reth benchmark (GPU)
run: |
source .venv/bin/activate
cd openvm-reth-benchmark
RES_DIR=reth_gpu
mkdir -p $RES_DIR
echo "export RPC_1=${{ secrets.RPC_1 }}" >> .env
# prove with no APCs
./run.sh --cuda --apc 0 --mode prove-stark || exit 1
# remove apc cache to not interfere with the next runs
rm -rf apc-cache
echo "Finished proving with no APCs"
mv metrics.json $RES_DIR/apc000.json
python ../openvm-riscv/scripts/plot_trace_cells.py -o $RES_DIR/trace_cells_apc000.png $RES_DIR/apc000.json > $RES_DIR/trace_cells_apc000.txt
# prove with 10 APCs
./run.sh --cuda --apc 10 --mode prove-stark || exit 1
# remove apc cache to not interfere with the next runs
rm -rf apc-cache
echo "Finished proving with 10 APCs"
mv metrics.json $RES_DIR/apc010.json
python ../openvm-riscv/scripts/plot_trace_cells.py -o $RES_DIR/trace_cells_apc010.png $RES_DIR/apc010.json > $RES_DIR/trace_cells_apc010.txt
# prove with 30 APCs
./run.sh --cuda --apc 30 --mode prove-stark || exit 1
# remove apc cache to not interfere with the next runs
rm -rf apc-cache
echo "Finished proving with 30 APCs"
mv metrics.json $RES_DIR/apc030.json
python ../openvm-riscv/scripts/plot_trace_cells.py -o $RES_DIR/trace_cells_apc030.png $RES_DIR/apc030.json > $RES_DIR/trace_cells_apc030.txt
# The APC candidates would be the same for all runs, so just keep the last one
mv apcs/apc_candidates.json $RES_DIR/apc_candidates.json
python ../openvm-riscv/scripts/basic_metrics.py summary-table --csv $RES_DIR/apc000.json $RES_DIR/apc010.json $RES_DIR/apc030.json > $RES_DIR/basic_metrics.csv
python ../openvm-riscv/scripts/basic_metrics.py plot $RES_DIR/apc000.json $RES_DIR/apc010.json $RES_DIR/apc030.json -o $RES_DIR/proof_time_breakdown.png
python ../openvm-riscv/scripts/basic_metrics.py combine $RES_DIR/apc000.json $RES_DIR/apc010.json $RES_DIR/apc030.json > $RES_DIR/combined_metrics.json
python ../autoprecompiles/scripts/plot_effectiveness.py $RES_DIR/apc_candidates.json --output $RES_DIR/effectiveness.png
mv $RES_DIR ../results/
- name: Save revisions and run info
run: |
echo "openvm-reth-benchmark: $(git -C openvm-reth-benchmark rev-parse HEAD)" > results/run.txt
echo "powdr: $(git rev-parse HEAD)" >> results/run.txt
echo "run: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" >> results/run.txt
- name: upload result artifacts
uses: actions/upload-artifact@v4
with:
name: bench-results-gpu
path: |
results/*
- name: get the date/time
id: date
run: echo "value=$(date +'%Y-%m-%d-%H%M')" >> $GITHUB_OUTPUT
- name: Generate bench results README
run: |
python3 ./openvm-riscv/scripts/generate_bench_results_readme.py \
./results \
"${{ steps.date.outputs.value }}-gpu" \
--output ./results/readme.md
- name: commit to bench results
uses: peaceiris/actions-gh-pages@v4
with:
personal_token: ${{ secrets.BENCH_RESULTS_TOKEN }}
external_repository: powdr-labs/bench-results
publish_dir: ./results
destination_dir: results/${{ steps.date.outputs.value }}-gpu/
keep_files: true
enable_jekyll: true
================================================
FILE: .github/workflows/post-merge-tests.yml
================================================
name: Post-merge APC tests
on:
workflow_dispatch:
push:
branches:
- main
paths:
- "**.rs"
- "**.toml"
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: "-C target-cpu=native"
RUST_BACKTRACE: 1
JEMALLOC_SYS_WITH_MALLOC_CONF: "retain:true,background_thread:true,metadata_thp:always,dirty_decay_ms:10000,muzzy_decay_ms:10000,abort_conf:true"
POWDR_OPENVM_SEGMENT_DELTA: 50000
jobs:
test_guests_apc:
runs-on: server-dev
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: ⚡ Cache rust
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-release-apc-${{ hashFiles('**/Cargo.toml') }}
- name: Build
run: cargo build --release -p powdr-openvm
- name: Install cargo openvm
# Rust 1.90 is needed by fresher versions of dependencies of cargo-openvm.
run: |
rustup toolchain install 1.90
cargo +1.90 install --git 'http://github.com/powdr-labs/openvm.git' --rev "v1.4.2-powdr-rc.4" --locked cargo-openvm
- name: Run keccak with 100 APCs
run: /usr/bin/time -v cargo run --bin powdr_openvm_riscv -r prove guest-keccak --input 10000 --autoprecompiles 100 --recursion
- name: Run ECC with 100 APCs
run: /usr/bin/time -v cargo run --bin powdr_openvm_riscv -r prove guest-ecc-powdr-affine-hint --input 20 --autoprecompiles 100 --recursion
- name: Run ecrecover with 100 APCs
run: /usr/bin/time -v cargo run --bin powdr_openvm_riscv -r prove guest-ecrecover --input 20 --autoprecompiles 100 --recursion
- name: Patch benchmark
uses: ./.github/actions/patch-openvm-reth-benchmark
- name: Run reth benchmark
run: |
cd openvm-reth-benchmark
RES_DIR=reth
mkdir -p $RES_DIR
echo "export RPC_1=${{ secrets.RPC_1 }}" >> .env
# prove with 100 APCs
/usr/bin/time -v ./run.sh --apc 100 --mode prove-stark || exit 1
echo "Finished proving with 100 APCs"
- name: Save revisions and run info
run: |
echo "openvm-reth-benchmark: $(git -C openvm-reth-benchmark rev-parse HEAD)" > run.txt
echo "powdr: $(git rev-parse HEAD)" >> run.txt
echo "run: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" >> run.txt
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: bench-results
path: |
run.txt
================================================
FILE: .github/workflows/pr-tests-with-secrets.yml
================================================
name: PR tests (with secrets)
# This workflow uses pull_request_target to allow external PRs to access secrets
# after a maintainer approves the workflow run
#
# SECURITY NOTE: This workflow intentionally checks out untrusted code from PRs
# to run tests with secrets. This is safe because:
# 1. GitHub requires maintainer approval before running for external contributors
# 2. The workflow code itself (this file) is controlled and runs from base branch
# 3. We only run predefined build/test commands, not arbitrary PR code
# 4. Cache poisoning risk is acceptable for these specific test jobs
on:
# also allow this to be run manually (so we can test changes to the workflow in a branch)
workflow_dispatch:
pull_request_target:
types: [opened, synchronize, reopened]
# cancel any previous running workflows for the same branch
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
# Minimal permissions for security
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
POWDR_OPENVM_SEGMENT_DELTA: 50000
jobs:
test_apc_reth_compilation:
runs-on: warp-ubuntu-2404-x64-8x
steps:
# IMPORTANT: Checkout the PR head, not the base branch
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
submodules: recursive
- name: ⚡ Cache rust
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.toml') }}
- name: Build
run: cargo build --release -p powdr-openvm
- name: Install cargo openvm
# Rust 1.90 is needed by fresher versions of dependencies of cargo-openvm.
run: |
rustup toolchain install 1.90
cargo +1.90 install --git 'http://github.com/powdr-labs/openvm.git' --rev "v1.4.2-powdr-rc.4" --locked cargo-openvm
- name: Patch benchmark
uses: ./.github/actions/patch-openvm-reth-benchmark
- name: Run small execution test with APCs
run: |
cd openvm-reth-benchmark
echo "export RPC_1=${{ secrets.RPC_1 }}" >> .env
PGO_TYPE="instruction" /usr/bin/time -v ./run.sh --apc 10 --mode compile
# Check that reth commit is on main.
# Do that after the actual test so that the step above passes when checking that a
# reth PR commit works with a powdr PR.
- name: Verify openvm-reth-benchmark ref is on main
shell: bash
run: |
cd openvm-reth-benchmark
if [ "$(git rev-parse --is-shallow-repository)" = "true" ]; then
git fetch --quiet --unshallow origin main
else
git fetch --quiet origin main
fi
if ! git merge-base --is-ancestor HEAD origin/main; then
echo "Pinned ref is not in origin/main history."
echo "HEAD: $(git rev-parse HEAD)"
echo "origin/main: $(git rev-parse origin/main)"
exit 1
fi
test_apc_reth_app_proof:
runs-on: warp-ubuntu-2404-x64-32x
steps:
# IMPORTANT: Checkout the PR head, not the base branch
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
submodules: recursive
- name: ⚡ Cache rust
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-release-apc-reth-app-proof-${{ hashFiles('**/Cargo.toml') }}
- name: Build
run: cargo build --release -p powdr-openvm
- name: Install cargo openvm
# Rust 1.90 is needed by fresher versions of dependencies of cargo-openvm.
run: |
rustup toolchain install 1.90
cargo +1.90 install --git 'http://github.com/powdr-labs/openvm.git' --rev "v1.4.2-powdr-rc.4" --locked cargo-openvm
- name: Setup python venv
run: |
python3 -m venv .venv
source .venv/bin/activate
pip install -r openvm-riscv/scripts/requirements.txt
pip install -r autoprecompiles/scripts/requirements.txt
- name: Patch benchmark
uses: ./.github/actions/patch-openvm-reth-benchmark
- name: Run reth benchmark
run: |
source .venv/bin/activate
cd openvm-reth-benchmark
RES_DIR=reth
mkdir -p $RES_DIR
echo "export RPC_1=${{ secrets.RPC_1 }}" >> .env
# prove with 3 APCs
APC=3 ./run.sh --mode prove-app || exit 1
echo "Finished proving with 3 APCs"
================================================
FILE: .github/workflows/pr-tests.yml
================================================
name: PR tests
on:
workflow_dispatch:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
merge_group:
push:
branches:
- main
# cancel any previous running workflows for the same branch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
env:
CARGO_TERM_COLOR: always
POWDR_OPENVM_SEGMENT_DELTA: 50000
jobs:
build_cpu:
runs-on: warp-ubuntu-2404-x64-8x
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: ⚡ Restore rust cache
id: cache
uses: WarpBuilds/cache/restore@v1
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
Cargo.lock
key: ${{ runner.os }}-cargo-pr-tests
- name: Date of the restored cache
run: cat target/cache-build-date.txt
continue-on-error: true
- name: Check out cache commit state and update mtime accordingly.
run: git checkout "$(cat target/cache-commit-hash.txt || echo 'f02fd626e2bb9e46a22ea1cda96b4feb5c6bda43')" && git ls-files -z | xargs -0 -n1 touch -d "Fri, 18 Apr 2025 03:30:58 +0000" && git checkout HEAD@{1}
##### The block below is shared between cache build and PR build workflows #####
- name: Install Rust toolchain nightly-2025-10-01 (with clippy and rustfmt)
run: rustup toolchain install nightly-2025-10-01 --component clippy,rustfmt
- name: Install Rust toolchain 1.90 (stable)
run: rustup toolchain install 1.90
- name: Set cargo to perform shallow clones
run: echo "CARGO_NET_GIT_FETCH_WITH_CLI=true" >> $GITHUB_ENV
- name: Format
run: cargo fmt --all --check --verbose
- name: Cargo check with Rust 1.90 (default features)
run: cargo +1.90 check --all-targets
- name: Lint no default features
run: cargo clippy --all --all-targets --features metrics --profile pr-tests --verbose -- -D warnings
- name: Build (CPU)
run: cargo build --all-targets --features metrics --all --profile pr-tests --verbose
###############################################################################
- uses: taiki-e/install-action@nextest
- name: Create tests archive (CPU)
run: cargo nextest archive --archive-file tests_cpu.tar.zst --cargo-profile pr-tests --workspace --no-default-features
- name: Upload build artifacts (CPU)
uses: actions/upload-artifact@v4
with:
name: tests_archive_cpu
path: |
tests_cpu.tar.zst
test_quick_cpu:
needs: build_cpu
runs-on: ubuntu-24.04
strategy:
matrix:
test:
- "1"
- "2"
- "3"
- "4"
- "5"
- "6"
- "7"
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Init testing instance
uses: ./.github/actions/init-testing-instance
- name: Run default tests
run: cargo nextest run --archive-file tests_cpu.tar.zst --workspace-remap . --verbose --partition count:"${{ matrix.test }}"/7 --no-tests=warn
test_medium_cpu:
needs: build_cpu
runs-on: warp-ubuntu-2404-x64-16x
strategy:
matrix:
test:
- "1"
- "2"
- "3"
- "4"
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Init testing instance
uses: ./.github/actions/init-testing-instance
- name: Run medium tests (ignored tests except large ones)
run: cargo nextest run --archive-file tests_cpu.tar.zst --workspace-remap . --verbose --partition count:"${{ matrix.test }}"/7 --test-threads=4 -E 'not (test(_large))' --run-ignored only --no-tests=warn
test_large_cpu:
needs: build_cpu
runs-on: warp-ubuntu-2404-x64-32x
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Init testing instance
uses: ./.github/actions/init-testing-instance
- name: Run large tests
run: cargo nextest run --archive-file tests_cpu.tar.zst --workspace-remap . --verbose -E 'test(_large)' --run-ignored only --no-tests=warn
udeps_cpu:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install nightly toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
- name: Install cargo-udeps
run: cargo install cargo-udeps --locked
- name: Run cargo-udeps (CPU)
run: cargo udeps --all-targets
# NOTE: test_apc_reth_compilation has been moved to pr-tests-with-secrets.yml
# This job requires secrets.RPC_1 and uses pull_request_target to work with external PRs
build_gpu:
if: github.event.pull_request.draft != true
runs-on: [self-hosted, gpu-shared]
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: Install Rust toolchain nightly-2025-10-01 (with clippy and rustfmt)
run: rustup toolchain install nightly-2025-10-01 --component clippy,rustfmt
- name: Install Rust toolchain 1.90 (stable)
run: rustup toolchain install 1.90
- name: Set cargo to perform shallow clones
run: echo "CARGO_NET_GIT_FETCH_WITH_CLI=true" >> $GITHUB_ENV
- name: Format
run: cargo fmt --all --check --verbose
- name: Cargo check with Rust 1.90 (all features)
run: cargo +1.90 check --all-targets
- name: Lint no default features
run: cargo clippy --all --all-targets --features cuda,metrics,aot --profile pr-tests --verbose -- -D warnings
- name: Build (GPU)
run: cargo build --all-targets --features cuda,metrics,aot --all --profile pr-tests --verbose
- uses: taiki-e/install-action@nextest
- name: Create tests archive (GPU, features=cuda)
run: cargo nextest archive --archive-file tests_gpu.tar.zst --cargo-profile pr-tests --workspace --package powdr-openvm-riscv --features cuda
- name: Upload build artifacts (GPU)
uses: actions/upload-artifact@v4
with:
name: tests_archive_gpu
path: |
tests_gpu.tar.zst
test_quick_gpu:
if: github.event.pull_request.draft != true
needs: build_gpu
runs-on: [self-hosted, gpu-shared]
timeout-minutes: 30
# TODO: we only have one runner on our GPU server, so can't partition yet; uncomment these once we have proper runners
# strategy:
# matrix:
# test:
# - "1"
# - "2"
# - "3"
# - "4"
# - "5"
# - "6"
# - "7"
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Init testing instance (GPU)
uses: ./.github/actions/init-testing-instance-gpu
- name: Run quick GPU tests from powdr-openvm-riscv only
run: cargo nextest run --archive-file tests_gpu.tar.zst --workspace-remap . --verbose --no-tests=warn
# run: cargo nextest run --archive-file tests_gpu.tar.zst --workspace-remap . --verbose --partition count:"${{ matrix.test }}"/7 --no-tests=warn
# NOTE: test_apc_reth_app_proof has been moved to pr-tests-with-secrets.yml
# This job requires secrets.RPC_1 and uses pull_request_target to work with external PRs
================================================
FILE: .gitignore
================================================
# Generated by Cargo
# will have compiled files and executables
/target/
# Cargo configuration
/.cargo/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
cargo_target/
riscv/tests/riscv_data/**/target
================================================
FILE: CLAUDE.md
================================================
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
powdr is a zkVM enhancement toolkit that provides autoprecompiles (automated synthesis of guest-specific precompiles) and a constraint solver. The codebase is tightly integrated with OpenVM and stark-backend from powdr-labs forks, providing autoprecompiles for the RISC-V zkVM OpenVM.
## Build Commands
```bash
# Build the workspace (CPU)
cargo build --all-targets --features metrics
# Build with GPU support
cargo build --all-targets --features cuda,metrics
# Check compilation
cargo check --all-targets
# Format code
cargo fmt --all
# Lint
cargo clippy --all --all-targets --features metrics -- -D warnings
```
## Testing
Always use `--release` for test runs. Use the `quick-10` profile as the default — it times out tests after 10s and continues. Check which tests timed out; only re-run them individually (without the quick profile) if you have good reason to believe your diff could affect them. All tests are run on CI anyway.
```bash
# Run all tests (default, with 10s timeout per test)
cargo nextest run --release --profile quick-10
# Run a single test
cargo nextest run --release <test_name>
# Run ignored (longer) tests
cargo nextest run --release --run-ignored only
# Run only large tests
cargo nextest run --release -E 'test(_large)' --run-ignored only
# Run tests in specific package
cargo nextest run --release -p powdr-openvm
# Available quick profiles (timeout per test, slow tests deprioritized):
# --profile quick-10 (10s timeout, good default)
# --profile quick-30 (30s timeout)
# --profile quick-60 (60s timeout)
```
## CLI Usage
The main CLI is `powdr_openvm_riscv` (in `cli-openvm-riscv/`):
```bash
# Compile a guest program with autoprecompiles
cargo run -p cli-openvm -- compile guest-keccak --autoprecompiles 10 --pgo instruction --input 100
# Execute a compiled program
cargo run -p cli-openvm -- execute guest-keccak --autoprecompiles 10 --input 100
# Prove (generate ZK proof)
cargo run -p cli-openvm -- prove guest-keccak --autoprecompiles 1 --input 10
# Mock prove (debug mode, verifies constraints without full proof)
cargo run -p cli-openvm -- prove guest-keccak --mock --autoprecompiles 1 --input 10
```
## Architecture
### Core Crates
- **autoprecompiles** (`autoprecompiles/`): The main precompile synthesis engine. Analyzes basic blocks of agnostic assembly instructions and synthesizes optimized circuits (APCs - Autoprecompiles). Key modules:
- `optimizer.rs`: Constraint optimization pipeline
- `constraint_optimizer.rs`: Eliminates redundant constraints
- `symbolic_machine_generator.rs`: Converts instruction sequences to symbolic machines
- `pgo/`: Profile-guided optimization for APC selection
- **constraint-solver** (`constraint-solver/`): Algebraic constraint analysis and solving. Provides:
- `grouped_expression.rs`: Expression representation for efficient manipulation
- `indexed_constraint_system.rs`: Efficient constraint system indexing
- `range_constraint.rs`: Range analysis for variables
- `inliner.rs`: Constraint inlining with degree bounds
- **openvm** (`openvm/`): OpenVM integration layer. Connects powdr optimizations to the OpenVM zkVM:
- `customize_exe.rs`: Modifies OpenVM executables to use APCs
- `powdr_extension/`: OpenVM circuit extension for APCs
- `trace_generation.rs`: Generates execution traces for proving
### Supporting Crates
- **expression** (`expression/`): Core algebraic expression types (`AlgebraicExpression`, operators)
- **number** (`number/`): Field element abstractions
- **riscv-elf** (`riscv-elf/`): ELF file parsing for RISC-V binaries
- **cli-openvm** (`cli-openvm/`): Command-line interface
### Guest Programs
Example guest programs in `openvm/guest-*` directories (keccak, sha256, ecc, pairing, etc.) are used for testing and benchmarking.
## Key Concepts
- **APC (Autoprecompile)**: An optimized circuit for a basic block of assembly instructions (often RISC-V)
- **PGO (Profile-Guided Optimization)**: Uses execution profiling to select which basic blocks to optimize
- `PgoConfig::Cell`: Optimizes based on total cell count savings
- `PgoConfig::Instruction`: Optimizes based on instruction execution frequency
- **Symbolic Machine**: Intermediate representation of constraints and bus interactions
- **Bus Interactions**: Communication between different chips/machines in the OpenVM architecture
## Coding Guidelines
### Coding Style
- Write idiomatic Rust code. Follow Rust conventions and best practices, and keep the style similar to existing code in the repository.
- Try to minimize code, reusing existing functions and modules where possible.
- Keep diffs small and focused. Avoid unrelated changes, unnecessary refactoring, or adding comments to unchanged code.
- Use builder pattern with `with_*` methods for structs with optional configuration.
### Before Returning to User
Always run these checks before claiming work is complete:
1. Format code
2. Check clippy
3. Run relevant tests and / or end-to-end tests using the CLI
### Git Workflow
- Use `git push origin <branchname>`
- Never use `git add .` - explicitly add modified files only
### PR Workflow
Use the GitHub CLI to interact with GitHub, for example:
- Create PR (always use --draft): `gh pr create --repo https://github.com/powdr-labs/powdr --base main --draft --title "..." --body "..."`
- Check CI status: `gh pr checks --repo https://github.com/powdr-labs/powdr <pr-number>`
- View PR comments: `gh pr view --repo https://github.com/powdr-labs/powdr <pr-number> --comments`
- View review comments on code: `gh api repos/powdr-labs/powdr/pulls/<pr-number>/comments`
================================================
FILE: Cargo.toml
================================================
[workspace]
resolver = "2"
members = [
"number",
"constraint-solver",
"expression",
"riscv-elf",
"riscv-types",
"isa-utils",
"syscalls",
"autoprecompiles",
"openvm",
"openvm-bus-interaction-handler",
"openvm-riscv",
"cli-openvm-riscv",
"openvm-riscv/extensions/hints-guest",
"openvm-riscv/extensions/hints-transpiler",
"openvm-riscv/extensions/hints-circuit",
]
exclude = ["riscv-runtime"]
[workspace.package]
version = "0.1.4"
edition = "2021"
license = "MIT"
homepage = "https://powdr.org"
repository = "https://github.com/powdr-labs/powdr"
[workspace.dependencies]
# workspace crates
powdr-constraint-solver = { path = "./constraint-solver", version = "0.1.4" }
powdr-isa-utils = { path = "./isa-utils", version = "0.1.4" }
powdr-expression = { path = "./expression", version = "0.1.4" }
powdr-number = { path = "./number", version = "0.1.4" }
powdr-riscv-elf = { path = "./riscv-elf", version = "0.1.4" }
powdr-riscv-types = { path = "./riscv-types", version = "0.1.4" }
powdr-syscalls = { path = "./syscalls", version = "0.1.4" }
powdr-autoprecompiles = { path = "./autoprecompiles", version = "0.1.4" }
powdr-openvm-riscv = { path = "./openvm-riscv", version = "0.1.4" }
powdr-openvm-bus-interaction-handler = { path = "./openvm-bus-interaction-handler", version = "0.1.4" }
powdr-openvm = { path = "./openvm", version = "0.1.4" }
powdr-openvm-riscv-hints-guest = { path = "./openvm-riscv/extensions/hints-guest", version = "0.1.4" }
powdr-openvm-riscv-hints-transpiler = { path = "./openvm-riscv/extensions/hints-transpiler", version = "0.1.4" }
powdr-openvm-riscv-hints-circuit = { path = "./openvm-riscv/extensions/hints-circuit", version = "0.1.4" }
# openvm
openvm = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-build = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-rv32im-circuit = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-rv32im-transpiler = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-rv32im-guest = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4", default-features = false }
openvm-transpiler = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-circuit = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-circuit-derive = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-circuit-primitives = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-circuit-primitives-derive = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-instructions = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-instructions-derive = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-sdk = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4", default-features = false, features = [
"parallel",
"jemalloc",
"nightly-features",
"evm-prove",
] }
openvm-ecc-circuit = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-ecc-transpiler = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-keccak256-circuit = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-keccak256-transpiler = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-sha256-circuit = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-sha256-transpiler = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-algebra-circuit = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-algebra-transpiler = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-bigint-circuit = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-bigint-transpiler = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-pairing-circuit = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-pairing-transpiler = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-native-circuit = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4", default-features = false }
openvm-native-recursion = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4", default-features = false }
openvm-platform = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
openvm-custom-insn = { git = "https://github.com/powdr-labs/openvm.git", tag = "v1.4.2-powdr-rc.4" }
# stark-backend
openvm-stark-sdk = { git = "https://github.com/powdr-labs/stark-backend.git", rev = "v1.2.2-powdr-2026-03-20", default-features = false, features = [
"parallel",
"jemalloc",
"nightly-features",
] }
openvm-stark-backend = { git = "https://github.com/powdr-labs/stark-backend.git", rev = "v1.2.2-powdr-2026-03-20", default-features = false, features = [
"parallel",
"jemalloc",
] }
openvm-cuda-backend = { git = "https://github.com/powdr-labs/stark-backend.git", rev = "v1.2.2-powdr-2026-03-20", default-features = false }
openvm-cuda-builder = { git = "https://github.com/powdr-labs/stark-backend.git", rev = "v1.2.2-powdr-2026-03-20", default-features = false }
openvm-cuda-common = { git = "https://github.com/powdr-labs/stark-backend.git", rev = "v1.2.2-powdr-2026-03-20", default-features = false }
# external dependencies
num-traits = "0.2.19"
itertools = "0.14"
derive_more = { version = "2", features = ["full"] }
log = "0.4.27"
serde = "1.0.228"
tracing = "0.1.40"
eyre = "0.6.12"
serde_cbor = "0.11.2"
metrics = "0.23.0"
derivative = "2.2.0"
serde_json = "^1.0.140"
# dev dependencies
test-log = "0.2.19"
pretty_assertions = "1.4.1"
env_logger = "0.11.8"
[profile.pr-tests]
inherits = "dev"
opt-level = 3
debug = "line-tables-only"
debug-assertions = true
overflow-checks = true
panic = 'unwind'
incremental = true # This is true because target is cached
codegen-units = 256
[profile.release-with-debug]
inherits = "release"
debug = true
[workspace.lints.clippy]
print_stdout = "deny"
uninlined_format_args = "deny"
iter_over_hash_type = "deny"
# Uncomment both patches below for local stark-backend and openvm.
# The local openvm also needs to have stark-backend patched so all types match.
# [patch."https://github.com/powdr-labs/stark-backend.git"]
# openvm-stark-sdk = { path = "../stark-backend/crates/stark-sdk", default-features = false }
# openvm-stark-backend = { path = "../stark-backend/crates/stark-backend", default-features = false }
# openvm-cuda-backend = { path = "../stark-backend/crates/cuda-backend", default-features = false }
# openvm-cuda-builder = { path = "../stark-backend/crates/cuda-builder", default-features = false }
# openvm-cuda-common = { path = "../stark-backend/crates/cuda-common", default-features = false }
# [patch."https://github.com/powdr-labs/openvm.git"]
# openvm = { path = "../openvm/crates/toolchain/openvm" }
# openvm-build = { path = "../openvm/crates/toolchain/build" }
# openvm-rv32im-circuit = { path = "../openvm/extensions/rv32im/circuit/" }
# openvm-rv32im-transpiler = { path = "../openvm/extensions/rv32im/transpiler" }
# openvm-rv32im-guest = { path = "../openvm/extensions/rv32im/guest" }
# openvm-transpiler = { path = "../openvm/crates/toolchain/transpiler" }
# openvm-circuit = { path = "../openvm/crates/vm" }
# openvm-circuit-derive = { path = "../openvm/crates/vm/derive" }
# openvm-circuit-primitives = { path = "../openvm/crates/circuits/primitives" }
# openvm-circuit-primitives-derive = { path = "../openvm/crates/circuits/primitives/derive" }
# openvm-instructions = { path = "../openvm/crates/toolchain/instructions" }
# openvm-instructions-derive = { path = "../openvm/crates/toolchain/instructions/derive" }
# openvm-sdk = { path = "../openvm/crates/sdk" }
# openvm-ecc-circuit = { path = "../openvm/extensions/ecc/circuit" }
# openvm-ecc-transpiler = { path = "../openvm/extensions/ecc/transpiler" }
# openvm-keccak256-circuit = { path = "../openvm/extensions/keccak256/circuit" }
# openvm-keccak256-transpiler = { path = "../openvm/extensions/keccak256/transpiler" }
# openvm-sha256-circuit = { path = "../openvm/extensions/sha256/circuit" }
# openvm-sha256-transpiler = { path = "../openvm/extensions/sha256/transpiler" }
# openvm-algebra-circuit = { path = "../openvm/extensions/algebra/circuit" }
# openvm-algebra-transpiler = { path = "../openvm/extensions/algebra/transpiler" }
# openvm-bigint-circuit = { path = "../openvm/extensions/bigint/circuit" }
# openvm-bigint-transpiler = { path = "../openvm/extensions/bigint/transpiler" }
# openvm-pairing-circuit = { path = "../openvm/extensions/pairing/circuit" }
# openvm-pairing-transpiler = { path = "../openvm/extensions/pairing/transpiler" }
# openvm-native-circuit = { path = "../openvm/extensions/native/circuit" }
# openvm-native-recursion = { path = "../openvm/extensions/native/recursion" }
# openvm-platform = { path = "../openvm/crates/toolchain/platform" }
# openvm-custom-insn = { path = "../openvm/crates/toolchain/custom_insn" }
================================================
FILE: LICENSE-APACHE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: LICENSE-MIT
================================================
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
<p align="center">
<img src="assets/powdr_wires.png" width="600">
</p>
# powdr
[](https://matrix.to/#/#powdr:matrix.org)
[](https://twitter.com/powdr_labs)<!-- markdown-link-check-disable-line -->
> WARNING: This codebase is experimental and has not been audited. DO NOT USE FOR PRODUCTION!
If you have any questions or want to contribute, feel free to write us in our [Matrix Chat](https://matrix.to/#/#powdr:matrix.org).
*powdr* provides state-of-the-art performance and security to zkVMs, enhancing them with compiler-based techniques including static analysis and formal verification.
The main components are:
- [Autoprecompiles](https://www.powdr.org/blog/auto-acc-circuits): automated synthesis of guest-specific precompiles.
- Constraint Solver: compile-time solver used to detect potential optimizations and security issues.
- powdr-OpenVM: powdr extensions for [OpenVM](https://github.com/openvm-org/openvm/).
## powdr-legacy
The previous versions of powdr are now archived in the [powdr-legacy](https://github.com/powdr-labs/powdr-legacy) repository.
It contains all previous crates regarding provers, powdr-asm, powdr-pil, powdrVM, stdlib circuits and RISC-V support.
### Project structure
For an overview of the project structure, run:
```
cargo doc --workspace --no-deps --open
```
## Contributing
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as below, without any additional terms or conditions.
## License
This project is licensed under either of
<!-- markdown-link-check-disable -->
- [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) ([`LICENSE-APACHE`](LICENSE-APACHE))
- [MIT license](https://opensource.org/licenses/MIT) ([`LICENSE-MIT`](LICENSE-MIT))
<!-- markdown-link-check-enable -->
at your option.
================================================
FILE: autoprecompile-analyzer/Claude.md
================================================
# APC Effectiveness Analyzer
Single-page web app for visualizing Automatic Precompile (APC) candidate effectiveness in zkVM systems. Port of `plot_effectiveness.py` from powdr.
## Project Structure
```
index.html # SPA with embedded JS/CSS (~2000 lines)
CLAUDE.md # This file
```
## Data Format
Current version:
**Version 4** (current): Each APC is a *superblock* composed of one or more basic blocks.
```json
{
"version": 4,
"apcs": [{
"execution_frequency": 50000,
"original_blocks": [
{ "start_pc": 12345, "instructions": ["instr1", "instr2"] },
{ "start_pc": 12360, "instructions": ["instr3"] }
],
"stats": {
"before": { "main_columns": 100, "constraints": 200, "bus_interactions": 50 },
"after": { "main_columns": 50, "constraints": 100, "bus_interactions": 25 }
},
"width_before": 100,
"value": 5000,
"cost_before": 1000.0,
"cost_after": 500.0,
}],
"labels": { "2099200": ["memset"], "2099448": ["memcpy"] }
}
```
All older formats are normalized to `original_blocks` on load:
- **Versions 2 & 3**: `original_block: { start_pc, instructions }` → wrapped in a 1-element array
- **Version 1** (no `version` field): `original_block` with `statements` → `original_blocks[0]` with `instructions`
- **Version 0** (bare array): same as v1 without wrapper, no labels
**Visualization model**: A block's identity is its `block_id` — a comma-separated list of hex PCs (e.g., `0x3000,0x3050`). `start_pc` is the first basic block's PC (used for sorting/display). Multiple blocks may share the same basic block PC.
## Testing
Start server:
```bash
python3 -m http.server 8000 &
```
Test URL with real data (~11,300 APCs):
```
http://localhost:8000/?data=https%3A%2F%2Fgithub.com%2Fpowdr-labs%2Fbench-results%2Fblob%2Fgh-pages%2Fresults%2F2026-01-27-0453%2Freth%2Fapc_candidates.json
```
Verify:
- Data loads (GitHub URLs auto-convert to raw)
- Bar chart shows ~3.28x mean effectiveness
- Value-cost plot reaches ~80% savings at 1000 APCs
- Labels table expands with function names
- Block selection syncs across all views
Cache-bust: append `&_t=1` to URL.
## URL Parameters
```
?data=<url> # Data source (required to load data)
&plot=value-cost # Show value-cost plot (omit for default bar chart)
&block=0x2008f8 # Select block by PC address (hex)
```
Example - jump directly to value-cost plot with a block selected:
```
http://localhost:8000/?data=<url>&plot=value-cost&block=0x200af0
```
URL updates automatically as you interact with the app, enabling easy sharing of specific views.
## Development Notes
**D3.js chart redraw**: Charts are fully recreated on metric switch. Ensure `.remove()` is called on exit selections to prevent memory leaks.
**State persistence**: `selectedBlock` must survive metric changes. Check selection still exists in new processed data.
**GitHub URL conversion**: `loadFromUrl()` has regex converting blob URLs to raw URLs. Brittle - test after GitHub URL format changes.
**Grouping threshold**: Blocks <0.1% of total cells grouped as "Other". Hardcoded in `createChart()`.
**Weighted mean**: `sum(effectiveness * traceCells) / sum(traceCells)` - weights by trace cells, not block count.
### Common Errors
- **CORS**: GitHub blob URLs must convert to raw URLs
- **D3 selections**: Use enter/update/exit patterns; don't forget `.remove()`
- **Event handlers**: Remove old handlers when recreating charts
- **Test with full dataset**: ~11K items, not small test data
================================================
FILE: autoprecompile-analyzer/index.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>APC Effectiveness Analyzer</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.copy-icon:hover { color: white !important; }
.copy-icon .copy-check { display: none; }
.copy-icon .copy-default { display: inline; }
.copy-icon.copied .copy-check { display: inline; }
.copy-icon.copied .copy-default { display: none; }
.copy-icon.copied { color: #7ee787 !important; }
</style>
<!-- D3.js -->
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
body {
background-color: #f8f9fa;
}
.drop-zone {
border: 3px dashed #dee2e6;
border-radius: 10px;
padding: 40px;
text-align: center;
cursor: pointer;
transition: all 0.3s;
background-color: white;
}
.drop-zone:hover,
.drop-zone.dragover {
border-color: #0d6efd;
background-color: #e7f1ff;
}
.chart-container {
background-color: white;
border-radius: 10px;
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.bar-highlight {
stroke: #ffc10755 !important;
stroke-width: 2 !important;
}
.bar-selected {
stroke: #ffc107 !important;
stroke-width: 4 !important;
}
.code-panel-container {
position: relative;
}
.sticky-label-header {
position: sticky;
top: 0;
z-index: 100;
background-color: #e3f2fd;
border-left: 4px solid #2196f3;
padding: 8px 10px;
font-weight: bold;
color: #1565c0;
font-family: 'Courier New', monospace;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
display: none;
cursor: pointer;
transition: background-color 0.2s;
}
.sticky-label-header.active {
display: block;
}
.sticky-label-header:hover {
background-color: #bbdefb;
}
.code-panel {
font-family: 'Courier New', monospace;
background-color: #f8f9fa;
border-radius: 5px;
padding: 15px;
max-height: 500px;
overflow-y: auto;
position: relative;
}
.label-line {
background-color: #e3f2fd;
border-left: 4px solid #2196f3;
padding: 8px 10px;
margin: 15px 0 5px 0;
font-weight: bold;
color: #1565c0;
}
.label-name {
font-size: 11px;
word-break: break-all;
line-height: 1.4;
}
.labels-table {
width: 100%;
margin-top: 10px;
font-size: 12px;
}
.labels-table th {
cursor: pointer;
user-select: none;
padding: 8px;
background-color: #f8f9fa;
border-bottom: 2px solid #dee2e6;
position: relative;
}
.labels-table th:hover {
background-color: #e9ecef;
}
.labels-table th.sorted-asc::after {
content: ' ▲';
font-size: 10px;
}
.labels-table th.sorted-desc::after {
content: ' ▼';
font-size: 10px;
}
.labels-table td {
padding: 8px;
border-bottom: 1px solid #dee2e6;
}
.labels-table tbody tr {
cursor: pointer;
}
.labels-table tbody tr:hover {
background-color: #f8f9fa;
}
.label-cell {
max-width: 400px;
word-break: break-all;
font-family: 'Courier New', monospace;
font-size: 11px;
}
.collapsible-header {
cursor: pointer;
user-select: none;
display: flex;
align-items: center;
gap: 10px;
}
.collapsible-header:hover {
opacity: 0.8;
}
.collapse-icon {
transition: transform 0.3s;
font-size: 14px;
}
.collapse-icon.collapsed {
transform: rotate(-90deg);
}
.labels-table-wrapper {
max-height: 300px;
overflow-y: auto;
border: 1px solid #dee2e6;
border-radius: 5px;
}
.label-row {
position: relative;
}
.expand-icon {
display: inline-block;
width: 16px;
transition: transform 0.2s;
cursor: pointer;
}
.expand-icon.expanded {
transform: rotate(90deg);
}
.blocks-detail-row {
background-color: #f8f9fa;
}
.blocks-detail-row td:nth-child(2) {
padding-left: 30px !important;
}
.blocks-detail-row:hover {
background-color: #e9ecef;
}
.code-block {
border: 1px solid #dee2e6;
border-radius: 3px;
margin: 10px 0;
padding: 10px;
background-color: white;
}
.code-block-header {
font-weight: bold;
margin-bottom: 5px;
color: #495057;
font-size: 12px;
}
.code-block.selected {
border-color: #ffc107;
background-color: #fff9e6;
box-shadow: 0 0 5px rgba(255, 193, 7, 0.3);
}
.code-line {
margin: 2px 0;
padding: 2px 5px;
cursor: pointer;
}
.code-line:hover {
background-color: #e9ecef;
}
.code-line.highlighted {
background-color: #fff3cd;
}
.tooltip {
position: absolute;
text-align: left;
padding: 10px;
font: 12px sans-serif;
background: rgba(0, 0, 0, 0.85);
color: white;
border-radius: 5px;
pointer-events: none;
z-index: 1000;
}
.bar {
stroke: black;
stroke-width: 0.5;
opacity: 0.8;
cursor: pointer;
}
.bar:hover {
opacity: 1;
}
.mean-line {
stroke: red;
stroke-width: 2;
stroke-dasharray: 5, 5;
opacity: 0.7;
}
.grid line {
stroke: #e0e0e0;
stroke-opacity: 0.7;
}
.grid path {
stroke-width: 0;
}
</style>
</head>
<body>
<nav class="navbar navbar-dark bg-primary">
<div class="container-fluid">
<span class="navbar-brand mb-0 h1" id="pageTitle" style="cursor: pointer;">APC Effectiveness Analyzer</span>
<span class="text-white small ms-auto text-end" id="dataSourceDisplay"
style="display:none; flex:1 1 auto; max-width:calc(100vw - 220px); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; font-family: 'Courier New', monospace;"></span>
</div>
</nav>
<div class="container mt-4">
<!-- File Upload Section -->
<div id="uploadSection" class="row mb-4">
<div class="col-12">
<div class="drop-zone" id="dropZone">
<h4>Drop JSON file here or click to upload</h4>
<p class="text-muted">Upload APC candidates JSON file</p>
<input type="file" id="fileInput" accept=".json" style="display: none;">
</div>
<div class="mt-3">
<div class="input-group">
<span class="input-group-text">Or paste URL:</span>
<input type="text" id="urlInput" class="form-control"
placeholder="https://example.com/data.json or GitHub link">
<button class="btn btn-primary" id="loadUrlBtn">Load from URL</button>
</div>
<small class="text-muted">Supports direct JSON URLs and GitHub file links</small>
</div>
</div>
</div>
<!-- Main App Section (hidden initially) -->
<div id="appSection" style="display: none;">
<div class="row">
<!-- Left column: plot + labels + code -->
<div class="col-12 col-lg-9">
<div id="vizSection">
<div class="row">
<div class="col-12">
<div class="chart-container">
<ul class="nav nav-pills mb-3" id="chartTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="tab-effectiveness"
type="button">Effectiveness by Basic Block</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="tab-secondary" type="button">Saved proving cost
vs added verifier cost</button>
</li>
</ul>
<div id="chartTabEffectiveness">
<div id="chart"></div>
</div>
<div id="chartTabSecondary" style="display: none;">
<div id="chartValueCost"></div>
</div>
</div>
</div>
</div>
<!-- Labels Summary Section -->
<div class="row mt-4" id="labelsSummarySection" style="display: none;">
<div class="col-12">
<div class="chart-container">
<div class="collapsible-header" id="labelsHeader">
<span class="collapse-icon collapsed">▼</span>
<h5 style="margin: 0;">Labels</h5>
</div>
<div id="labelsContent" style="display: none; margin-top: 10px;">
<div class="labels-table-wrapper">
<div id="labelsTableContainer"></div>
</div>
</div>
</div>
</div>
</div>
<!-- Code Panel Section -->
<div class="row mt-4">
<div class="col-12">
<div class="chart-container">
<h5>Program Code</h5>
<div class="code-panel-container">
<div id="stickyLabelHeader" class="sticky-label-header"></div>
<div id="codePanel" class="code-panel">
<span class="text-muted">No data loaded</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Right column: controls -->
<div class="col-12 col-lg-3">
<div id="infoSection" class="mb-4" style="display: none;">
<div class="chart-container">
<h5>Info</h5>
<p class="text-muted small" id="plotInfoText" style="margin-bottom: 0;">
</p>
</div>
</div>
<div id="controlsSection" class="mb-4" style="display: none;">
<div class="chart-container">
<div class="row g-3">
<div class="col-12">
<label for="effectivenessType" class="form-label">Cost Metric:</label>
<select id="effectivenessType" class="form-select">
<option value="cost" selected>Total Cost</option>
<option value="main_columns">Main Columns</option>
<option value="constraints">Constraints</option>
<option value="bus_interactions">Bus Interactions</option>
</select>
</div>
<div class="col-12">
<label for="pcSearch" class="form-label">Block ID:</label>
<div class="input-group">
<input type="text" id="pcSearch" class="form-control">
<button class="btn btn-primary" id="pcSearchBtn">Go</button>
</div>
</div>
</div>
</div>
</div>
<div id="selectedBlockSection" class="mb-4" style="display: none;">
<div class="chart-container">
<h5>Selected Block</h5>
<div class="mb-2">
<span id="codeBlockInfo" class="text-muted">Click on a bar or code line to select a
block</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
let currentData = null;
let currentLabels = {};
let chart = null;
let selectedBlock = null;
let lastData = null;
let lastMeanEffectiveness = null;
// File handling
const dropZone = document.getElementById('dropZone');
const fileInput = document.getElementById('fileInput');
const uploadSection = document.getElementById('uploadSection');
const appSection = document.getElementById('appSection');
const controlsSection = document.getElementById('controlsSection');
const vizSection = document.getElementById('vizSection');
const effectivenessType = document.getElementById('effectivenessType');
const pageTitle = document.getElementById('pageTitle');
const dataSourceDisplay = document.getElementById('dataSourceDisplay');
const pcSearch = document.getElementById('pcSearch');
const pcSearchBtn = document.getElementById('pcSearchBtn');
const tabEffectiveness = document.getElementById('tab-effectiveness');
const tabSecondary = document.getElementById('tab-secondary');
const chartTabEffectiveness = document.getElementById('chartTabEffectiveness');
const chartTabSecondary = document.getElementById('chartTabSecondary');
const plotInfoText = document.getElementById('plotInfoText');
// Plot point sizing (value-cost plot)
const POINT_RADIUS = 3;
const HOVER_RADIUS = 6;
const SELECTED_RADIUS = 6;
const DATA_DISPLAY_MAX = 70;
const DATA_DISPLAY_HEAD = 35;
const DATA_DISPLAY_TAIL = 35;
function shortenUrl(urlText) {
if (urlText.length <= DATA_DISPLAY_MAX) return urlText;
return `${urlText.slice(0, DATA_DISPLAY_HEAD)}...${urlText.slice(-DATA_DISPLAY_TAIL)}`;
}
function updateDataSourceDisplay(source) {
if (source) {
const displayText = shortenUrl(source.replace(/^https?:\/\//i, ''));
const href = source;
dataSourceDisplay.innerHTML = `Data: <a href="${href}" target="_blank" rel="noopener noreferrer" style="color: white; text-decoration: underline;">${displayText}</a>`
+ ` <svg class="copy-icon" onclick="navigator.clipboard.writeText('${href.replace(/'/g, "\\'")}').then(() => { this.classList.add('copied'); this.setAttribute('title','Copied!'); setTimeout(() => { this.classList.remove('copied'); this.setAttribute('title','Copy data URL'); }, 2000); })" `
+ `title="Copy data URL" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" style="margin-left:0.4rem; cursor:pointer; color:rgba(255,255,255,0.7); vertical-align:middle;">`
+ `<path class="copy-default" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25z"/>`
+ `<path class="copy-default" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25z"/>`
+ `<path class="copy-check" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"/>`
+ `</svg>`;
dataSourceDisplay.style.display = 'inline';
} else {
dataSourceDisplay.innerHTML = '';
dataSourceDisplay.style.display = 'none';
}
}
// Drop zone events
dropZone.addEventListener('click', () => fileInput.click());
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('dragover');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('dragover');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('dragover');
const files = e.dataTransfer.files;
if (files.length > 0) {
handleFile(files[0]);
}
});
fileInput.addEventListener('change', (e) => {
if (e.target.files.length > 0) {
handleFile(e.target.files[0]);
}
});
// URL loading functionality
const urlInput = document.getElementById('urlInput');
const loadUrlBtn = document.getElementById('loadUrlBtn');
tabEffectiveness.addEventListener('click', () => {
tabEffectiveness.classList.add('active');
tabSecondary.classList.remove('active');
chartTabEffectiveness.style.display = 'block';
chartTabSecondary.style.display = 'none';
updateInfoText();
if (lastData) {
const totalBefore = lastData.reduce((sum, d) => sum + d.metric_before, 0);
createChart(lastData, totalBefore, lastMeanEffectiveness || 0);
} else if (currentData) {
updateVisualization();
}
const newUrl = new URL(window.location);
newUrl.searchParams.delete('plot');
window.history.replaceState({}, document.title, newUrl);
});
tabSecondary.addEventListener('click', () => {
tabSecondary.classList.add('active');
tabEffectiveness.classList.remove('active');
chartTabEffectiveness.style.display = 'none';
chartTabSecondary.style.display = 'block';
updateInfoText();
if (lastData) {
createValueCostPlot(lastData);
} else if (currentData) {
createValueCostPlot(processData());
}
const newUrl = new URL(window.location);
newUrl.searchParams.set('plot', 'value-cost');
window.history.replaceState({}, document.title, newUrl);
});
loadUrlBtn.addEventListener('click', loadFromUrl);
urlInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
loadFromUrl();
}
});
async function loadFromUrl() {
const url = urlInput.value.trim();
if (!url) {
alert('Please enter a URL');
return;
}
// Convert GitHub URLs to raw URLs
let fetchUrl = url;
if (url.includes('github.com') && !url.includes('raw.githubusercontent.com')) {
// Convert github.com/user/repo/blob/branch/file to raw.githubusercontent.com/user/repo/branch/file
fetchUrl = url.replace('github.com', 'raw.githubusercontent.com').replace('/blob/', '/');
}
try {
loadUrlBtn.disabled = true;
loadUrlBtn.textContent = 'Loading...';
const response = await fetch(fetchUrl);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const text = await response.text();
try {
const jsonData = JSON.parse(text);
loadData(jsonData);
updateDataSourceDisplay(url);
uploadSection.style.display = 'none';
appSection.style.display = 'block';
controlsSection.style.display = 'block';
vizSection.style.display = 'block';
updateVisualization();
// Update URL to include the data parameter
const newUrl = new URL(window.location);
newUrl.searchParams.set('data', url);
window.history.replaceState({}, document.title, newUrl);
} catch (parseError) {
alert('Error parsing JSON from URL: ' + parseError.message);
}
} catch (error) {
alert('Error loading URL: ' + error.message);
} finally {
loadUrlBtn.disabled = false;
loadUrlBtn.textContent = 'Load from URL';
}
}
effectivenessType.addEventListener('change', () => {
if (currentData) {
const selectedId = selectedBlock ? selectedBlock.block_id : null;
updateVisualization();
// Restore selection if it exists
if (selectedId) {
const data = processData();
const block = data.find(d => d.block_id === selectedId);
if (block) {
selectBlock(block);
}
}
}
});
// PC search functionality
pcSearchBtn.addEventListener('click', searchForPC);
pcSearch.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
searchForPC();
}
});
function searchForPC() {
if (!currentData) {
alert('Please load data first');
return;
}
const input = pcSearch.value.trim();
if (!input) {
// Empty input means unselect
selectBlock(null);
return;
}
// Parse hex (0x...) or decimal
let pcValue;
if (input.toLowerCase().startsWith('0x')) {
pcValue = parseInt(input, 16);
} else {
pcValue = parseInt(input, 10);
}
if (isNaN(pcValue)) {
alert('Invalid PC address. Please enter a valid hex (0x...) or decimal number.');
return;
}
// Find the superblock that contains this PC in any of its basic blocks
// Each instruction is 4 bytes, so PC advances by 4
const data = processData();
const block = data.find(d => {
if (d.is_other) return false; // Skip "Other" grouped blocks
return d.original_blocks.some(b => {
const endPc = b.start_pc + b.instructions.length * 4;
return pcValue >= b.start_pc && pcValue < endPc;
});
});
if (block) {
selectBlock(block);
} else {
alert(`No block found containing PC: 0x${pcValue.toString(16)} (${pcValue})`);
}
}
pageTitle.addEventListener('click', () => {
currentData = null;
currentLabels = {};
selectedBlock = null;
uploadSection.style.display = 'block';
appSection.style.display = 'none';
controlsSection.style.display = 'none';
document.getElementById('selectedBlockSection').style.display = 'none';
document.getElementById('infoSection').style.display = 'none';
vizSection.style.display = 'none';
fileInput.value = '';
urlInput.value = '';
updateDataSourceDisplay('');
// Clear URL parameters when returning to upload screen
window.history.replaceState({}, document.title, window.location.pathname);
});
// Check for URL parameter on page load
window.addEventListener('DOMContentLoaded', () => {
const urlParams = new URLSearchParams(window.location.search);
const dataUrl = urlParams.get('url') || urlParams.get('data');
const plotParam = urlParams.get('plot');
if (dataUrl) {
urlInput.value = dataUrl;
loadFromUrl();
}
if (plotParam === 'value-cost') {
tabSecondary.click();
} else {
updateInfoText();
}
});
function handleFile(file) {
if (!file.name.endsWith('.json')) {
alert('Please upload a JSON file');
return;
}
const reader = new FileReader();
reader.onload = (e) => {
try {
const jsonData = JSON.parse(e.target.result);
loadData(jsonData);
updateDataSourceDisplay('');
uploadSection.style.display = 'none';
appSection.style.display = 'block';
controlsSection.style.display = 'block';
vizSection.style.display = 'block';
updateVisualization();
} catch (error) {
alert('Error parsing JSON file: ' + error.message);
}
};
reader.readAsText(file);
}
function updateApcDataV1(apc) {
// Normalize old single-block format into original_blocks array
apc.original_blocks = [{
start_pc: apc.original_block.start_pc,
instructions: apc.original_block.statements,
}];
return apc;
}
// json is a direct list of APCs
function loadDataV0(jsonData) {
return { data: jsonData.map(updateApcDataV1), labels: {} };
}
// json with APCs and labels but no version
function loadDataV1(jsonData) {
return { data: jsonData.apcs.map(updateApcDataV1), labels: jsonData.labels };
}
// json in version 2 or 3. The difference is that the `apc_candidate_file` field doesn't exist,
// which is not used in the visualization anyway, so we can use the same loader for both versions.
function loadDataV2V3(jsonData) {
const apcs = jsonData.apcs.map(apc => {
apc.original_blocks = [apc.original_block];
return apc;
});
return { data: apcs, labels: jsonData.labels };
}
// json in version 4: original_blocks is a list of BasicBlocks (may be more than one).
function loadDataV4(jsonData) {
return { data: jsonData.apcs, labels: jsonData.labels };
}
function loadData(jsonData) {
// Handle backward compatibility with older json formats
let result;
if (Array.isArray(jsonData)) {
result = loadDataV0(jsonData);
} else if (!('version' in jsonData)) {
result = loadDataV1(jsonData);
} else {
switch (jsonData.version) {
case 2: result = loadDataV2V3(jsonData); break;
case 3: result = loadDataV2V3(jsonData); break;
case 4: result = loadDataV4(jsonData); break;
default: throw new Error(`Unsupported version: ${jsonData.version}`);
}
}
currentData = result.data;
currentLabels = result.labels;
// Show right-side panes when data is loaded
document.getElementById('selectedBlockSection').style.display = 'block';
document.getElementById('infoSection').style.display = 'block';
controlsSection.style.display = 'block';
updateInfoText();
}
function getMetricValues(item, effType) {
switch (effType) {
case 'cost':
return { before: item.cost_before, after: item.cost_after };
case 'main_columns':
return { before: item.stats.before.main_columns, after: item.stats.after.main_columns };
case 'constraints':
return { before: item.stats.before.constraints, after: item.stats.after.constraints };
case 'bus_interactions':
return { before: item.stats.before.bus_interactions, after: item.stats.after.bus_interactions };
default:
throw new Error(`Unknown effectiveness type: ${effType}`);
}
}
function calculateEffectiveness(item, effType) {
const { before, after } = getMetricValues(item, effType);
return before / after;
}
function formatMetric(count) {
if (count >= 1e9) {
return (count / 1e9).toFixed(1) + 'B';
} else if (count >= 1e6) {
return (count / 1e6).toFixed(1) + 'M';
} else if (count >= 1e3) {
return (count / 1e3).toFixed(1) + 'K';
} else {
return count.toFixed(0);
}
}
function processData() {
const effType = effectivenessType.value;
const processed = currentData.map(item => {
const { before, after } = getMetricValues(item, effType);
const metric_before = before * item.execution_frequency;
const metric_after = after * item.execution_frequency;
const value = (before - after) * item.execution_frequency;
const density = metric_after > 0 ? value / after : 0;
const lastBlock = item.original_blocks[item.original_blocks.length - 1];
const block_pcs = item.original_blocks.map(b => b.start_pc);
return {
start_pc: item.original_blocks[0].start_pc,
block_id: block_pcs.map(pc => '0x' + pc.toString(16)).join(','),
block_pcs,
original_blocks: item.original_blocks,
end_pc: lastBlock.start_pc + lastBlock.instructions.length * 4,
effectiveness: before / after,
instructions: item.original_blocks.reduce((sum, b) => sum + b.instructions.length, 0),
software_version_cells: metric_before, // alias used throughout charting
metric_before,
metric_after,
metric_before_raw: before,
metric_after_raw: after,
value,
density,
width_before: item.width_before,
execution_frequency: item.execution_frequency,
statements: item.original_blocks.flatMap(b => b.instructions), // flat list for legacy uses
stats_after: item.stats.after // Keep APC stats
};
});
// Sort by metric_before (matches Python)
processed.sort((a, b) => b.metric_before - a.metric_before);
return processed;
}
function updateVisualization() {
const data = processData();
const totalBefore = data.reduce((sum, d) => sum + d.metric_before, 0);
const totalAfter = data.reduce((sum, d) => sum + d.metric_after, 0);
// Calculate weighted mean (weight by cost after, matches Python)
const meanEffectiveness = totalAfter > 0
? data.reduce((sum, d) => sum + d.effectiveness * d.metric_after, 0) / totalAfter
: 0;
lastData = data;
lastMeanEffectiveness = meanEffectiveness;
// Create visualizations
createChart(data, totalBefore, meanEffectiveness);
if (chartTabSecondary.style.display !== 'none') {
createValueCostPlot(data);
}
// Show all code in the code panel
showAllCode();
// Create labels summary table if there are labels
createLabelsSummary();
// Check for block parameter in URL and select it
const urlParams = new URLSearchParams(window.location.search);
const blockParam = urlParams.get('block');
if (blockParam) {
// blockParam is a comma-separated list of hex PCs (block_id)
const block = data.find(d => d.block_id === blockParam);
if (block) {
selectBlock(block);
}
}
}
function aggregateLabelData() {
const effType = effectivenessType.value;
const labelStats = {};
// Sort blocks by PC to process them in order
const sortedBlocks = [...currentData].sort((a, b) =>
a.original_blocks[0].start_pc - b.original_blocks[0].start_pc
);
// Track current active label(s)
let currentActiveLabels = [];
// Iterate through all blocks in PC order
sortedBlocks.forEach(item => {
// Check all basic block PCs for label matches
const matchingPcKey = item.original_blocks
.map(b => b.start_pc.toString())
.find(key => currentLabels[key] && currentLabels[key].length > 0);
// Check if this block starts a new label
if (matchingPcKey) {
currentActiveLabels = currentLabels[matchingPcKey];
// Initialize label stats if needed
currentActiveLabels.forEach(label => {
if (!labelStats[label]) {
labelStats[label] = {
label: label,
pc: item.original_blocks[0].start_pc,
blocks: [],
totalTraceCells: 0,
totalCostBefore: 0,
totalCostAfter: 0
};
}
});
}
// Assign this block to all current active labels
currentActiveLabels.forEach(label => {
labelStats[label].blocks.push(item);
// Add trace cells (same as x-axis in chart)
labelStats[label].totalTraceCells += item.width_before * item.execution_frequency;
// Aggregate costs based on effectiveness type
switch (effType) {
case 'cost':
labelStats[label].totalCostBefore += item.cost_before;
labelStats[label].totalCostAfter += item.cost_after;
break;
case 'main_columns':
labelStats[label].totalCostBefore += item.stats.before.main_columns;
labelStats[label].totalCostAfter += item.stats.after.main_columns;
break;
case 'constraints':
labelStats[label].totalCostBefore += item.stats.before.constraints;
labelStats[label].totalCostAfter += item.stats.after.constraints;
break;
case 'bus_interactions':
labelStats[label].totalCostBefore += item.stats.before.bus_interactions;
labelStats[label].totalCostAfter += item.stats.after.bus_interactions;
break;
}
});
});
// Calculate effectiveness for each label (weighted by cost)
const labelArray = Object.values(labelStats).map(stat => {
// Process and sort blocks
const processedBlocks = stat.blocks.map(block => ({
pc: block.original_blocks[0].start_pc,
block_pcs: block.original_blocks.map(b => b.start_pc),
traceCells: block.width_before * block.execution_frequency,
effectiveness: calculateEffectiveness(block, effType),
instructions: block.original_blocks.reduce((sum, b) => sum + b.instructions.length, 0)
}));
// Sort blocks by the same criteria as the current label sort
sortBlocksInLabel(processedBlocks);
return {
label: stat.label,
pc: stat.pc,
traceCells: stat.totalTraceCells,
costBefore: stat.totalCostBefore,
costAfter: stat.totalCostAfter,
effectiveness: stat.totalCostBefore / stat.totalCostAfter,
blockCount: stat.blocks.length,
blocks: processedBlocks
};
});
return labelArray;
}
function createValueCostPlot(data) {
const container = document.getElementById('chartValueCost');
if (!container) return;
d3.select(container).selectAll('*').remove();
// Sort by density (value / cost_after)
const sorted = [...data].sort((a, b) => b.density - a.density);
if (sorted.length === 0) {
container.innerHTML = '<span class="text-muted">No data available for value-cost plot.</span>';
return;
}
// Build cumulative arrays (cost scaled by execution frequency)
let cumulativeCost = 0;
let cumulativeValue = 0;
let cumulativeBefore = 0;
const series = sorted.map((d, idx) => {
cumulativeCost += d.metric_after_raw;
cumulativeValue += d.value;
cumulativeBefore += d.metric_before;
return { x: cumulativeCost, y: cumulativeValue, beforeCum: cumulativeBefore, block: d, idx };
});
const totalSoftwareCost = data.reduce((sum, d) => sum + d.metric_before, 0);
const margin = { top: 20, right: 20, bottom: 40, left: 60 };
const containerWidth = container.clientWidth || 300;
const width = containerWidth - margin.left - margin.right;
const height = 270 - margin.top - margin.bottom;
// Avoid log(0): start domain at min positive cost
const minCost = d3.min(series, d => d.x) || 1;
const maxCost = d3.max(series, d => d.x) || minCost;
const xScale = d3.scaleLog()
.domain([Math.max(1, minCost), maxCost])
.range([0, width]);
const yScale = d3.scaleLinear()
.domain([0, Math.max(d3.max(series, d => d.y), totalSoftwareCost)])
.range([height, 0]);
const svg = d3.select(container)
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// Hover guide lines
const guideH = svg.append('line')
.attr('stroke', '#bbbbbb')
.attr('stroke-dasharray', '4 4')
.attr('stroke-width', 1)
.style('display', 'none');
const guideV = svg.append('line')
.attr('stroke', '#bbbbbb')
.attr('stroke-dasharray', '4 4')
.attr('stroke-width', 1)
.style('display', 'none');
const guideHText = svg.append('text')
.style('fill', '#555')
.style('font-size', '11px')
.style('display', 'none');
const guideVText = svg.append('text')
.style('fill', '#555')
.style('font-size', '11px')
.style('display', 'none');
const line = d3.line()
.x(d => xScale(d.x))
.y(d => yScale(d.y))
.curve(d3.curveLinear);
// Background for deselect on click (send behind everything)
svg.append('rect')
.attr('width', width)
.attr('height', height)
.attr('fill', 'transparent')
.attr('pointer-events', 'all')
.on('click', () => selectBlock(null))
.lower();
svg.append('path')
.datum(series)
.attr('fill', 'none')
.attr('stroke', '#0d6efd')
.attr('stroke-width', 2)
.attr('d', line);
// Horizontal lines at percentages of total software cost (upper bound)
if (totalSoftwareCost > 0) {
const percentages = [0.2, 0.4, 0.6, 0.8, 1.0];
percentages.forEach(pct => {
const yVal = totalSoftwareCost * pct;
svg.append('line')
.attr('x1', 0)
.attr('x2', width)
.attr('y1', yScale(yVal))
.attr('y2', yScale(yVal))
.attr('stroke', '#888')
.attr('stroke-dasharray', '4 4')
.attr('stroke-width', pct === 1 ? 1.5 : 1);
const label = pct === 1
? `Software cost: ${formatMetric(yVal)}`
: `${Math.round(pct * 100)}%`;
svg.append('text')
.attr('x', 5)
.attr('y', yScale(yVal) - 6)
.attr('text-anchor', 'start')
.style('fill', '#666')
.style('font-size', '11px')
.text(label);
});
}
// Point labels for selected counts (powers of 10 and 3×powers of 10)
const refCounts = [];
const maxCount = series.length;
for (let p = 0; Math.pow(10, p) <= maxCount; p++) {
const pow = Math.pow(10, p);
if (p > 0) {
refCounts.push(pow);
}
const three = 3 * pow;
if (three <= maxCount) refCounts.push(three);
}
const labelYOffset = 14;
refCounts.forEach((count, idx) => {
if (count > series.length || count < 1) return;
const point = series[count - 1];
svg.append('text')
.attr('x', xScale(point.x))
.attr('y', yScale(point.y) - labelYOffset)
.attr('text-anchor', 'middle')
.style('fill', '#555')
.style('font-size', '11px')
.text(`${count} APCs`);
});
// Tooltip
const tooltip = d3.select('body').append('div')
.attr('class', 'tooltip')
.style('opacity', 0);
// Secondary hover line text
const guideHText2 = svg.append('text')
.style('fill', '#555')
.style('font-size', '11px')
.style('display', 'none');
const baseColor = '#0d6efd';
const hoverColor = '#0b5ed7';
const selectedColor = '#d32f2f';
// Points
svg.selectAll('.value-point')
.data(series)
.enter()
.append('circle')
.attr('class', 'value-point')
.attr('cx', d => xScale(d.x))
.attr('cy', d => yScale(d.y))
.attr('r', POINT_RADIUS)
.attr('fill', baseColor)
.attr('stroke', baseColor)
.attr('stroke-width', 1)
.on('mouseover', function (event, d) {
const isSelected = selectedBlock && !selectedBlock.is_other && selectedBlock.block_id === d.block.block_id;
d3.select(this)
.attr('r', isSelected ? SELECTED_RADIUS : HOVER_RADIUS)
.attr('fill', isSelected ? selectedColor : hoverColor)
.attr('stroke', isSelected ? selectedColor : hoverColor);
tooltip.transition().duration(200).style('opacity', 0.9);
tooltip.html(blockTooltipHtml(d.block))
.style('left', (event.pageX + 10) + 'px')
.style('top', (event.pageY + 10) + 'px');
// Guides
guideH
.attr('x1', 0)
.attr('x2', width)
.attr('y1', yScale(d.y))
.attr('y2', yScale(d.y))
.style('display', 'block');
guideV
.attr('x1', xScale(d.x))
.attr('x2', xScale(d.x))
.attr('y1', 0)
.attr('y2', height)
.style('display', 'block');
const pctSaved = totalSoftwareCost > 0 ? (d.y / totalSoftwareCost * 100) : 0;
const pctAccel = totalSoftwareCost > 0 ? (d.beforeCum / totalSoftwareCost * 100) : 0;
const reductionFactor = (100 - pctSaved) > 0 ? (100 / (100 - pctSaved)) : Infinity;
const isFirstHalf = xScale(d.x) < (width / 2);
// Horizontal labels: right side for first half, left side for second half
const hLabelX = isFirstHalf ? width - 5 : 5;
const hAnchor = isFirstHalf ? 'end' : 'start';
guideHText
.attr('x', hLabelX)
.attr('y', yScale(d.y) - 6)
.attr('text-anchor', hAnchor)
.style('display', 'block')
.text(`Accelerated prover cost: ${formatMetric(d.beforeCum)} (${pctAccel.toFixed(1)}%)`);
guideHText2
.attr('x', hLabelX)
.attr('y', yScale(d.y) + 14)
.attr('text-anchor', hAnchor)
.style('display', 'block')
.text(`Saved prover cost: ${formatMetric(d.y)} (${pctSaved.toFixed(1)}%, ${reductionFactor === Infinity ? '∞' : reductionFactor.toFixed(2) + 'x'} reduction)`);
guideVText
.attr('x', isFirstHalf ? xScale(d.x) + 4 : xScale(d.x) - 4)
.attr('y', 20)
.attr('text-anchor', isFirstHalf ? 'start' : 'end')
.style('display', 'block')
.text(`Verifier cost: ${formatMetric(d.x)} · APCs: ${d.idx + 1}`);
})
.on('mouseout', function () {
tooltip.transition().duration(300).style('opacity', 0);
updateValueCostPointStyles();
guideH.style('display', 'none');
guideV.style('display', 'none');
guideHText.style('display', 'none');
guideHText2.style('display', 'none');
guideVText.style('display', 'none');
})
.on('click', function (event, d) {
event.stopPropagation();
selectBlock(d.block);
});
// Apply selection styling initially
updateValueCostPointStyles();
// Axes
svg.append('g')
.attr('transform', `translate(0,${height})`)
.call(d3.axisBottom(xScale).ticks(5, "~s"));
svg.append('g')
.call(d3.axisLeft(yScale).ticks(5).tickFormat(formatMetric));
// Labels
svg.append('text')
.attr('transform', `translate(${width / 2}, ${height + margin.bottom - 5})`)
.style('text-anchor', 'middle')
.text('Added verifier cost (log)');
svg.append('text')
.attr('transform', 'rotate(-90)')
.attr('y', 0 - margin.left + 15)
.attr('x', 0 - (height / 2))
.style('text-anchor', 'middle')
.text('Saved prover cost');
}
function sortBlocksInLabel(blocks) {
// Sort blocks by trace cells (descending) by default
blocks.sort((a, b) => {
const column = currentLabelSort.column;
let aVal, bVal;
switch (column) {
case 'traceCells':
aVal = a.traceCells;
bVal = b.traceCells;
break;
case 'effectiveness':
aVal = a.effectiveness;
bVal = b.effectiveness;
break;
case 'pc':
aVal = a.pc;
bVal = b.pc;
break;
case 'blockCount':
// For blockCount, sort by traceCells instead
aVal = a.traceCells;
bVal = b.traceCells;
break;
default:
aVal = a.traceCells;
bVal = b.traceCells;
}
if (currentLabelSort.direction === 'asc') {
return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
} else {
return aVal > bVal ? -1 : aVal < bVal ? 1 : 0;
}
});
}
let currentLabelSort = { column: 'traceCells', direction: 'desc' };
function createLabelsSummary() {
const labelsSummarySection = document.getElementById('labelsSummarySection');
const labelsTableContainer = document.getElementById('labelsTableContainer');
// Check if there are any labels
if (Object.keys(currentLabels).length === 0) {
labelsSummarySection.style.display = 'none';
return;
}
const labelData = aggregateLabelData();
if (labelData.length === 0) {
labelsSummarySection.style.display = 'none';
return;
}
labelsSummarySection.style.display = 'block';
// Set up collapsible behavior (only once)
const labelsHeader = document.getElementById('labelsHeader');
const labelsContent = document.getElementById('labelsContent');
const collapseIcon = labelsHeader.querySelector('.collapse-icon');
// Remove old listener if exists and add new one
labelsHeader.replaceWith(labelsHeader.cloneNode(true));
const newLabelsHeader = document.getElementById('labelsHeader');
const newCollapseIcon = newLabelsHeader.querySelector('.collapse-icon');
newLabelsHeader.addEventListener('click', function () {
const content = document.getElementById('labelsContent');
const icon = this.querySelector('.collapse-icon');
if (content.style.display === 'none') {
content.style.display = 'block';
icon.classList.remove('collapsed');
} else {
content.style.display = 'none';
icon.classList.add('collapsed');
}
});
// Sort data
sortLabelData(labelData, currentLabelSort.column, currentLabelSort.direction);
// Get metric name for column header
const effType = effectivenessType.options[effectivenessType.selectedIndex].text;
// Create table
let tableHtml = `
<table class="table labels-table">
<thead>
<tr>
<th style="width: 30px;"></th>
<th data-column="pc">PC</th>
<th data-column="label">Label</th>
<th data-column="blockCount">Blocks</th>
<th data-column="traceCells">Trace Cells</th>
<th data-column="effectiveness">Effectiveness (${effType})</th>
</tr>
</thead>
<tbody>
`;
labelData.forEach((row, idx) => {
const labelId = `label-${idx}`;
tableHtml += `
<tr class="label-row" data-pc="${row.pc}" data-label-id="${labelId}">
<td><span class="expand-icon">►</span></td>
<td>0x${row.pc.toString(16)}</td>
<td class="label-cell">${escapeHtml(row.label)}</td>
<td>${row.blockCount}</td>
<td>${formatMetric(row.traceCells)}</td>
<td>${row.effectiveness.toFixed(2)}</td>
</tr>
`;
// Add blocks as separate rows
row.blocks.forEach(block => {
tableHtml += `
<tr class="blocks-detail-row" id="${labelId}-detail-${block.pc}" style="display: none;" data-block-pc="${block.pc}" data-label-id="${labelId}">
<td></td>
<td>0x${block.pc.toString(16)}</td>
<td>...</td>
<td></td>
<td>${formatMetric(block.traceCells)}</td>
<td>${block.effectiveness.toFixed(2)}</td>
</tr>
`;
});
});
tableHtml += `
</tbody>
</table>
`;
labelsTableContainer.innerHTML = tableHtml;
// Add sort indicators
document.querySelectorAll('.labels-table th').forEach(th => {
const column = th.getAttribute('data-column');
th.classList.remove('sorted-asc', 'sorted-desc');
if (column === currentLabelSort.column) {
th.classList.add(`sorted-${currentLabelSort.direction}`);
}
});
// Add click handlers for sorting
document.querySelectorAll('.labels-table th').forEach(th => {
th.addEventListener('click', function () {
const column = this.getAttribute('data-column');
if (currentLabelSort.column === column) {
// Toggle direction
currentLabelSort.direction = currentLabelSort.direction === 'asc' ? 'desc' : 'asc';
} else {
// New column, default to descending
currentLabelSort.column = column;
currentLabelSort.direction = 'desc';
}
createLabelsSummary();
});
});
// Add click handlers for label rows (expand/collapse)
document.querySelectorAll('.label-row').forEach(tr => {
const expandIcon = tr.querySelector('.expand-icon');
const labelId = tr.getAttribute('data-label-id');
// Click on expand icon or first cell to expand
const expandCell = tr.querySelector('td:first-child');
expandCell.addEventListener('click', function (e) {
e.stopPropagation();
// Find all detail rows for this label
const detailRows = document.querySelectorAll(`[data-label-id="${labelId}"].blocks-detail-row`);
const isExpanded = expandIcon.classList.contains('expanded');
if (isExpanded) {
detailRows.forEach(row => row.style.display = 'none');
expandIcon.classList.remove('expanded');
} else {
detailRows.forEach(row => row.style.display = 'table-row');
expandIcon.classList.add('expanded');
}
});
// Click on rest of row to select first block
tr.addEventListener('click', function (e) {
if (e.target.closest('td:first-child')) return; // Ignore if clicking expand cell
const pc = parseInt(this.getAttribute('data-pc'));
const data = processData();
const block = data.find(d => d.block_pcs && d.block_pcs.includes(pc));
if (block) {
selectBlock(block);
}
});
});
// Add click handlers for individual block rows
document.querySelectorAll('.blocks-detail-row').forEach(tr => {
tr.addEventListener('click', function () {
const pc = parseInt(this.getAttribute('data-block-pc'));
const data = processData();
const block = data.find(d => d.block_pcs && d.block_pcs.includes(pc));
if (block) {
selectBlock(block);
}
});
});
}
function sortLabelData(data, column, direction) {
data.sort((a, b) => {
let aVal = a[column];
let bVal = b[column];
// Special handling for label (case-insensitive string sort)
if (column === 'label') {
aVal = aVal.toLowerCase();
bVal = bVal.toLowerCase();
}
if (direction === 'asc') {
return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
} else {
return aVal > bVal ? -1 : aVal < bVal ? 1 : 0;
}
});
}
function blockTooltipHtml(b) {
if (b.is_other) {
return `<strong>Other (${b.count} APCs)</strong><br/>` +
`Execution frequency: ${formatMetric(b.execution_frequency)}<br/>` +
`Cost (software version): ${formatMetric(b.software_version_cells)}<br/>` +
`Cost (accelerated): ${formatMetric(b.metric_after || 0)}<br/>` +
`Effectiveness: ${b.effectiveness.toFixed(2)}<br/>` +
`Verifier cost (accelerated): n/a<br/>` +
`APC size (total): ${b.stats_after.main_columns || 'N/A'} cols, ${b.stats_after.bus_interactions || 'N/A'} bus, ${b.stats_after.constraints || 'N/A'} constraints`;
}
const pcsDisplay = b.block_pcs.length === 1
? `0x${b.start_pc.toString(16)}`
: b.block_pcs.map(pc => '0x' + pc.toString(16)).join(', ');
return `<strong>PC: ${pcsDisplay}</strong><br/>` +
`Execution frequency: ${formatMetric(b.execution_frequency)}<br/>` +
`Instructions: ${b.instructions}<br/>` +
`Cost (software version): ${formatMetric(b.metric_before)}<br/>` +
`Cost (accelerated): ${formatMetric(b.metric_after)}<br/>` +
`Effectiveness: ${b.effectiveness.toFixed(2)}<br/>` +
`Verifier cost (accelerated): ${formatMetric(b.metric_after_raw)}<br/>` +
`Density (saved cost / verifier cost): ${formatMetric(b.density)}<br/>` +
`APC size: ${b.stats_after.main_columns} cols, ${b.stats_after.bus_interactions} bus, ${b.stats_after.constraints} constraints`;
}
function highlightElements(blockId, isHover = true) {
// Highlight corresponding bar
d3.selectAll('.bar')
.classed('bar-highlight', d => d.block_id === blockId);
}
function clearHighlights() {
d3.selectAll('.bar').classed('bar-highlight', false);
}
function updateBarSelection() {
if (!selectedBlock || selectedBlock.is_other) return;
d3.selectAll('.bar')
.classed('bar-selected', d => d.block_id === selectedBlock.block_id);
}
function updateInfoText() {
if (!plotInfoText) return;
const showingEffectiveness = chartTabSecondary.style.display === 'none';
if (showingEffectiveness) {
plotInfoText.innerHTML = 'The plot shows each basic block, sorted the proving cost it causes in the software execution:<br>• The <strong>width</strong> corresponds to its cost before acceleration.<br>• The <strong>height</strong> shows the factor by which the cost is reduced after acceleration.';
} else {
plotInfoText.innerHTML = 'The plot shows the trade-off between added verifier cost and saved proving cost for accelerating basic blocks:<br>• The <strong>x-axis</strong> shows the cumulative verifier cost of accelerated blocks. APCs are added by decreasing density, i.e., the saved proving cost divided by the added verification cost.<br>• The <strong>y-axis</strong> shows the cumulative saved cost achieved by accelerating those blocks.';
}
}
function updateValueCostPointStyles() {
const baseColor = '#0d6efd';
const selectedColor = '#d32f2f';
d3.selectAll('.value-point').each(function (d) {
const isSelected = selectedBlock && !selectedBlock.is_other && selectedBlock.block_id === d.block.block_id;
d3.select(this)
.attr('fill', isSelected ? selectedColor : baseColor)
.attr('stroke', isSelected ? selectedColor : baseColor)
.attr('stroke-width', 1)
.attr('r', isSelected ? SELECTED_RADIUS : POINT_RADIUS);
});
}
function selectBlock(blockData) {
// Clear previous selection
d3.selectAll('.bar').classed('bar-selected', false);
// Set new selection
selectedBlock = blockData;
// Update URL
const newUrl = new URL(window.location);
if (blockData && !blockData.is_other) {
// Highlight selected bar
d3.selectAll('.bar')
.classed('bar-selected', d => d.block_id === blockData.block_id);
// Update URL with block parameter (block_id is comma-separated hex PCs)
newUrl.searchParams.set('block', blockData.block_id);
// Update the PC search input field with the entry PC
pcSearch.value = '0x' + blockData.start_pc.toString(16);
} else {
// Clear block parameter if deselecting or selecting "Other"
newUrl.searchParams.delete('block');
// Clear the PC search input field
pcSearch.value = '';
}
window.history.replaceState({}, document.title, newUrl);
// Update code panel selection
updateCodePanelSelection(blockData);
// Update value-cost plot point styling
updateValueCostPointStyles();
// Update bar selection styling (for re-rendered charts)
updateBarSelection();
}
function showAllCode() {
const codePanel = document.getElementById('codePanel');
// Get all blocks sorted by start_pc
const allBlocks = processData().sort((a, b) => a.start_pc - b.start_pc);
let codeHtml = '';
allBlocks.forEach((block, index) => {
if (block.is_other) return; // Skip "Other" grouped blocks
// Check for gap between previous superblock and current superblock
if (index > 0) {
const prevBlock = allBlocks[index - 1];
if (!prevBlock.is_other) {
const prevBlockEnd = prevBlock.end_pc;
const gap = block.start_pc - prevBlockEnd;
const missingInstructions = gap / 4;
if (missingInstructions > 0) {
codeHtml += `
<div style="padding: 10px; margin: 10px 0; background-color: #f0f0f0; border-left: 3px solid #999; font-style: italic; color: #666;">
... ${missingInstructions} instruction${missingInstructions !== 1 ? 's' : ''} not shown (0x${prevBlockEnd.toString(16)} - 0x${(block.start_pc - 4).toString(16)}) ...
</div>
`;
}
}
}
// Check all basic block PCs for labels
let labelData = '';
for (const basicBlock of block.original_blocks) {
const pcKey = basicBlock.start_pc.toString();
if (currentLabels[pcKey] && currentLabels[pcKey].length > 0) {
const labels = currentLabels[pcKey];
const labelsHtml = labels.map(label =>
`<div class="label-name">${escapeHtml(label)}</div>`
).join('');
labelData = JSON.stringify(labels);
codeHtml += `
<div class="label-line" data-pc="${block.start_pc}" data-labels='${labelData}'>
${labelsHtml}
</div>
`;
break; // Use first matching label for the sticky header
}
}
const blockId = `block-${block.block_pcs.join('_')}`;
const pcsText = block.block_pcs.length === 1
? `PC: 0x${block.start_pc.toString(16)}`
: `PCs: ${block.block_pcs.map(pc => '0x' + pc.toString(16)).join(', ')}`;
const headerText = `${pcsText} | Cost (software): ${formatMetric(block.metric_before)} | Effectiveness: ${block.effectiveness.toFixed(2)} | Instructions: ${block.instructions}`;
// Render each basic block as a sub-section within the superblock
const linesHtml = block.original_blocks.map((basicBlock, bbIdx) => {
const subHeader = block.original_blocks.length > 1
? `<div style="padding: 2px 8px; font-size: 0.8em; color: #888; border-top: 1px dashed #ccc; margin-top: 2px;">basic block 0x${basicBlock.start_pc.toString(16)}</div>`
: '';
const instrs = basicBlock.instructions.map((stmt, idx) =>
`<div class="code-line" data-pc="${basicBlock.start_pc}" data-line="${idx}">${escapeHtml(stmt)}</div>`
).join('');
return subHeader + instrs;
}).join('');
codeHtml += `
<div class="code-block" id="${blockId}" data-pc="${block.start_pc}" data-labels='${labelData}'>
<div class="code-block-header">${headerText}</div>
${linesHtml}
</div>
`;
});
codePanel.innerHTML = codeHtml;
// Add click handlers to code lines
document.querySelectorAll('.code-line').forEach(line => {
line.addEventListener('click', function () {
const pc = parseInt(this.getAttribute('data-pc'));
const blockData = allBlocks.find(b => b.block_pcs && b.block_pcs.includes(pc));
if (blockData) {
selectBlock(blockData);
}
});
});
// Set up scroll listener to update sticky header
updateStickyLabel();
codePanel.removeEventListener('scroll', updateStickyLabel);
codePanel.addEventListener('scroll', updateStickyLabel);
// Set up click handler for sticky header
const stickyHeader = document.getElementById('stickyLabelHeader');
if (stickyHeader) {
stickyHeader.removeEventListener('click', handleStickyLabelClick);
stickyHeader.addEventListener('click', handleStickyLabelClick);
}
}
function handleStickyLabelClick() {
const stickyHeader = document.getElementById('stickyLabelHeader');
const pc = stickyHeader.getAttribute('data-pc');
if (pc) {
const pcValue = parseInt(pc);
const data = processData();
const block = data.find(d => d.block_pcs && d.block_pcs.includes(pcValue));
if (block) {
selectBlock(block);
}
}
}
function updateStickyLabel() {
const codePanel = document.getElementById('codePanel');
const stickyHeader = document.getElementById('stickyLabelHeader');
if (!codePanel || !stickyHeader) return;
// Find the first visible block or label
const scrollTop = codePanel.scrollTop;
const panelTop = codePanel.getBoundingClientRect().top;
// Get all blocks and labels
const elements = codePanel.querySelectorAll('.label-line, .code-block');
let currentLabels = null;
let currentPc = null;
for (let i = 0; i < elements.length; i++) {
const element = elements[i];
const elementTop = element.offsetTop;
// If this element is past our scroll position, use the previous label
if (elementTop > scrollTop) {
break;
}
// Check if this element has labels
const labelsAttr = element.getAttribute('data-labels');
if (labelsAttr && labelsAttr !== '""' && labelsAttr !== '') {
try {
currentLabels = JSON.parse(labelsAttr);
currentPc = element.getAttribute('data-pc');
} catch (e) {
// Ignore parse errors
}
}
}
// Update sticky header
if (currentLabels && currentLabels.length > 0 && currentPc) {
const labelHtml = currentLabels.map(label =>
`<div class="label-name">${escapeHtml(label)}</div>`
).join('');
stickyHeader.innerHTML = labelHtml;
stickyHeader.setAttribute('data-pc', currentPc);
stickyHeader.classList.add('active');
} else {
stickyHeader.classList.remove('active');
stickyHeader.removeAttribute('data-pc');
}
}
function updateCodePanelSelection(blockData) {
const codeInfo = document.getElementById('codeBlockInfo');
// Remove all previous selections
document.querySelectorAll('.code-block').forEach(block => {
block.classList.remove('selected');
});
document.querySelectorAll('.code-line').forEach(line => {
line.classList.remove('highlighted');
});
if (!blockData) {
codeInfo.innerHTML = '<span class="text-muted">Click on a bar or code line to select a block</span>';
return;
}
codeInfo.innerHTML = blockTooltipHtml(blockData);
if (blockData.is_other) return;
// Highlight the selected superblock
const blockElement = document.getElementById(`block-${blockData.block_pcs.join('_')}`);
if (blockElement) {
blockElement.classList.add('selected');
// Highlight all lines in this block
blockElement.querySelectorAll('.code-line').forEach(line => {
line.classList.add('highlighted');
});
// Scroll within the code panel only, not the whole page
const codePanel = document.getElementById('codePanel');
const blockTop = blockElement.offsetTop;
codePanel.scrollTo({ top: blockTop, behavior: 'smooth' });
}
}
function clearCode() {
// Only clear if there's no selected block
if (!selectedBlock) {
document.getElementById('codeBlockInfo').innerHTML = '<span class="text-muted">Click on a bar or code line to select a block</span>';
showAllCode();
}
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function createChart(data, totalCells, meanEffectiveness) {
// Clear existing chart
d3.select('#chart').selectAll('*').remove();
// Set dimensions and margins
const margin = { top: 40, right: 120, bottom: 60, left: 80 };
const containerWidth = document.getElementById('chart').clientWidth || 1200;
const width = containerWidth - margin.left - margin.right;
const height = 270 - margin.top - margin.bottom;
// Group small blocks (< 0.1% threshold)
const threshold = totalCells * 0.001;
const largeBlocks = data.filter(d => d.software_version_cells >= threshold);
const smallBlocks = data.filter(d => d.software_version_cells < threshold);
let plotData = [...largeBlocks];
if (smallBlocks.length > 0) {
const otherCells = smallBlocks.reduce((sum, d) => sum + d.software_version_cells, 0);
const otherEffectiveness = smallBlocks.reduce((sum, d) => sum + d.effectiveness * d.software_version_cells, 0) / otherCells;
const otherExecFreq = smallBlocks.reduce((sum, d) => sum + d.execution_frequency, 0);
const otherStatsAfter = smallBlocks.reduce((acc, d) => {
if (d.stats_after) {
acc.main_columns = (acc.main_columns || 0) + d.stats_after.main_columns;
acc.bus_interactions = (acc.bus_interactions || 0) + d.stats_after.bus_interactions;
acc.constraints = (acc.constraints || 0) + d.stats_after.constraints;
}
return acc;
}, {});
plotData.push({
effectiveness: otherEffectiveness,
software_version_cells: otherCells,
execution_frequency: otherExecFreq,
instructions: -1,
is_other: true,
count: smallBlocks.length,
statements: [], // No individual statements for grouped blocks
stats_after: otherStatsAfter
});
}
// Calculate positions
let xPos = 0;
plotData.forEach(d => {
d.x = xPos;
d.width = d.software_version_cells;
xPos += d.width;
});
// Create SVG
const svg = d3.select('#chart')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.on('click', function (event) {
// If clicking on the background (not a bar), deselect
if (event.target.tagName === 'svg') {
selectBlock(null);
}
})
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// Add background rect to capture clicks
svg.append('rect')
.attr('width', width)
.attr('height', height)
.style('fill', 'none')
.style('pointer-events', 'all')
.on('click', function (event) {
event.stopPropagation();
selectBlock(null);
});
// Create scales
const xScale = d3.scaleLinear()
.domain([0, totalCells])
.range([0, width]);
// Calculate 99th percentile effectiveness by trace cells
// Sort by effectiveness ascending
const sortedByEffectiveness = [...plotData].sort((a, b) => a.effectiveness - b.effectiveness);
// Find the effectiveness value at 99th percentile weighted by trace cells
let cumulativeCells = 0;
const p99Threshold = totalCells * 0.99;
let maxEffectivenessP99 = 0;
for (const d of sortedByEffectiveness) {
cumulativeCells += d.software_version_cells;
maxEffectivenessP99 = d.effectiveness;
if (cumulativeCells >= p99Threshold) {
break;
}
}
// Use 99th percentile for y-axis scaling
const yScale = d3.scaleLinear()
.domain([0, maxEffectivenessP99 * 1.1])
.range([height, 0]);
// Color scale for instructions (log scale)
const validInstructions = plotData.filter(d => !d.is_other && d.instructions > 0).map(d => d.instructions);
const instrMin = d3.min(validInstructions) || 1;
const instrMax = d3.max(validInstructions) || instrMin;
const colorScale = d3.scaleSequentialLog()
.domain([instrMin, instrMax])
.interpolator(d3.interpolateRdYlGn);
// Add grid
svg.append('g')
.attr('class', 'grid')
.attr('transform', `translate(0,${height})`)
.call(d3.axisBottom(xScale)
.tickSize(-height)
.tickFormat(''));
svg.append('g')
.attr('class', 'grid')
.call(d3.axisLeft(yScale)
.tickSize(-width)
.tickFormat(''));
// Create tooltip
const tooltip = d3.select('body').append('div')
.attr('class', 'tooltip')
.style('opacity', 0);
// Add bars
svg.selectAll('.bar')
.data(plotData)
.enter().append('rect')
.attr('class', 'bar')
.attr('x', d => xScale(d.x))
.attr('y', d => Math.max(0, yScale(d.effectiveness)))
.attr('width', d => xScale(d.width) - xScale(0))
.attr('height', d => height - Math.max(0, yScale(d.effectiveness)))
.style('fill', d => d.is_other ? 'lightgray' : colorScale(d.instructions))
.on('mouseover', function (event, d) {
// Show tooltip
tooltip.transition()
.duration(200)
.style('opacity', .9);
const content = blockTooltipHtml(d);
tooltip.html(content)
.style('left', (event.pageX - 50) + 'px')
.style('top', (event.pageY + 20) + 'px');
// Highlight elements (but don't change code on hover if something is selected)
if (!d.is_other) {
highlightElements(d.block_id, true);
}
})
.on('mouseout', function (d) {
// Hide tooltip
tooltip.transition()
.duration(500)
.style('opacity', 0);
// Clear highlights
clearHighlights();
})
.on('click', function (event, d) {
event.stopPropagation();
// Select this superblock on click
selectBlock(d);
});
// Note: Selection is handled in the selectBlock function after chart is created
// Add "Other" label for wide enough other blocks
plotData.filter(d => d.is_other && d.width > totalCells * 0.02).forEach(d => {
svg.append('text')
.attr('x', xScale(d.x + d.width / 2))
.attr('y', yScale(d.effectiveness / 2))
.attr('text-anchor', 'middle')
.attr('font-size', '10px')
.attr('font-weight', 'bold')
.text(`Other (${d.count} APCs)`);
});
// Add mean line
svg.append('line')
.attr('class', 'mean-line')
.attr('x1', 0)
.attr('x2', width)
.attr('y1', yScale(meanEffectiveness))
.attr('y2', yScale(meanEffectiveness));
// Add axes
svg.append('g')
.attr('transform', `translate(0,${height})`)
.call(d3.axisBottom(xScale)
.tickFormat(d => formatMetric(d)));
svg.append('g')
.call(d3.axisLeft(yScale));
// Add labels
const effType = effectivenessType.options[effectivenessType.selectedIndex].text;
svg.append('text')
.attr('transform', 'rotate(-90)')
.attr('y', 0 - margin.left)
.attr('x', 0 - (height / 2))
.attr('dy', '1em')
.style('text-anchor', 'middle')
.text('Effectiveness');
svg.append('text')
.attr('transform', `translate(${width / 2}, ${height + margin.bottom})`)
.style('text-anchor', 'middle')
.text(`Cumulative ${effType.toLowerCase()} before (software version)`);
// Add title
svg.append('text')
.attr('x', width / 2)
.attr('y', 0 - margin.top / 2)
.attr('text-anchor', 'middle')
.style('font-size', '16px')
.style('font-weight', 'bold')
.text(`Effectiveness by Basic Block (reduction in ${effType})`);
// Add mean text box
svg.append('rect')
.attr('x', 5)
.attr('y', 5)
.attr('width', 80)
.attr('height', 25)
.style('fill', 'wheat')
.style('opacity', 0.8)
.style('stroke', 'gray')
.style('stroke-width', 1)
.style('rx', 3);
svg.append('text')
.attr('x', 45)
.attr('y', 22)
.attr('text-anchor', 'middle')
.style('font-size', '12px')
.text(`Mean: ${meanEffectiveness.toFixed(2)}`);
// Add color legend
if (validInstructions.length > 0) {
const legendWidth = 20;
const legendHeight = 200;
const legendScale = d3.scaleLinear()
.domain([Math.log10(instrMin), Math.log10(instrMax)])
.range([legendHeight, 0]);
const legendAxis = d3.axisRight(legendScale)
.ticks(5)
.tickFormat(d => Math.pow(10, d).toFixed(0));
const legend = svg.append('g')
.attr('transform', `translate(${width + 40}, ${height / 2 - legendHeight / 2})`);
// Create gradient
const gradientId = 'instruction-gradient';
const gradient = svg.append('defs')
.append('linearGradient')
.attr('id', gradientId)
.attr('x1', '0%')
.attr('y1', '100%')
.attr('x2', '0%')
.attr('y2', '0%');
const steps = 20;
for (let i = 0; i <= steps; i++) {
const t = i / steps;
const value = instrMin * Math.pow(instrMax / instrMin, t);
gradient.append('stop')
.attr('offset', `${t * 100}%`)
.style('stop-color', colorScale(value));
}
legend.append('rect')
.attr('width', legendWidth)
.attr('height', legendHeight)
.style('fill', `url(#${gradientId})`);
legend.append('g')
.attr('transform', `translate(${legendWidth}, 0)`)
.call(legendAxis);
legend.append('text')
.attr('transform', `rotate(90)`)
.attr('y', -legendWidth - 30)
.attr('x', legendHeight / 2)
.style('text-anchor', 'middle')
.style('font-size', '12px')
.text('Instructions (log)');
}
// Apply selection styling if a block is already selected
updateBarSelection();
}
</script>
</body>
</html>
================================================
FILE: autoprecompiles/Cargo.toml
================================================
[package]
name = "powdr-autoprecompiles"
version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
[dependencies]
powdr-expression.workspace = true
powdr-number.workspace = true
powdr-constraint-solver.workspace = true
itertools.workspace = true
log.workspace = true
num-traits.workspace = true
serde.workspace = true
tracing.workspace = true
tracing-subscriber = { version = "0.3.17", features = ["std", "env-filter"] }
serde_json.workspace = true
rayon = "1.10.0"
strum = { version = "0.27.0", features = ["derive"] }
priority-queue = "2.7.0"
metrics.workspace = true
deepsize2 = "0.1.0"
derive_more.workspace = true
derivative.workspace = true
[dev-dependencies]
expect-test = "1.5.1"
flate2 = "1.1.2"
powdr-openvm-bus-interaction-handler.workspace = true
test-log.workspace = true
criterion = { version = "0.4", features = ["html_reports"] }
[package.metadata.cargo-udeps.ignore]
development = ["env_logger"]
[lints]
workspace = true
[lib]
bench = false # See https://github.com/bheisler/criterion.rs/issues/458
[[bench]]
name = "optimizer_benchmark"
harness = false
================================================
FILE: autoprecompiles/benches/optimizer_benchmark.rs
================================================
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use powdr_autoprecompiles::{
bus_map::BusMap,
export::{ApcWithBusMap, SimpleInstruction},
optimizer::optimize,
Apc, ColumnAllocator, DegreeBound,
};
use powdr_number::BabyBearField;
use powdr_openvm_bus_interaction_handler::{
bus_map::OpenVmBusType, memory_bus_interaction::OpenVmMemoryBusInteraction,
OpenVmBusInteractionHandler,
};
type TestApc = Apc<BabyBearField, SimpleInstruction<BabyBearField>, (), ()>;
const DEFAULT_DEGREE_BOUND: DegreeBound = DegreeBound {
identities: 3,
bus_interactions: 2,
};
/// Benching the `test_optimize` test
fn optimize_keccak_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("optimize-keccak");
group.sample_size(10);
let file = std::fs::File::open("tests/keccak_apc_pre_opt.json.gz").unwrap();
let reader = flate2::read::GzDecoder::new(file);
let apc: ApcWithBusMap<TestApc, BusMap<OpenVmBusType>> =
serde_json::from_reader(reader).unwrap();
group.bench_function("optimize", |b| {
b.iter_batched(
|| {
(
apc.apc.machine.clone(),
ColumnAllocator::from_max_poly_id_of_machine(&apc.apc.machine),
)
},
|(machine, column_allocator)| {
optimize::<_, _, _, OpenVmMemoryBusInteraction<_, _>>(
black_box(machine),
OpenVmBusInteractionHandler::default(),
DEFAULT_DEGREE_BOUND,
&apc.bus_map,
column_allocator,
&mut Default::default(),
)
.unwrap()
},
criterion::BatchSize::SmallInput,
);
});
group.finish();
}
criterion_group!(benches, optimize_keccak_benchmark);
criterion_main!(benches);
================================================
FILE: autoprecompiles/scripts/plot_effectiveness.py
================================================
#!/usr/bin/env python3
import json
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import argparse
def load_apc_data(json_path, effectiveness_type='cost'):
"""Load APC candidates and compute effectiveness."""
with open(json_path, 'r') as f:
data = json.load(f)["apcs"]
def get_before_after_cost(item, eff_type):
if eff_type == 'cost':
return (item['cost_before'], item['cost_after'])
elif eff_type == 'main_columns':
return (item['stats']['before']['main_columns'], item['stats']['after']['main_columns'])
elif eff_type == 'constraints':
return (item['stats']['before']['constraints'], item['stats']['after']['constraints'])
elif eff_type == 'bus_interactions':
return (item['stats']['before']['bus_interactions'], item['stats']['after']['bus_interactions'])
else:
raise ValueError(f"Unknown effectiveness type: {eff_type}")
rows = []
for item in data:
cost_before, cost_after = get_before_after_cost(item, effectiveness_type)
rows.append({
'start_pcs': [b['start_pc'] for b in item['original_blocks']],
'cost_before': cost_before * item['execution_frequency'],
'cost_after': cost_after * item['execution_frequency'],
'effectiveness': cost_before / cost_after,
'instructions': sum(len(b['instructions']) for b in item['original_blocks']),
})
return pd.DataFrame(rows)
def format_cell_count(count):
"""Format cell count with appropriate units."""
if count >= 1e9:
return f"{count/1e9:.1f}B"
elif count >= 1e6:
return f"{count/1e6:.1f}M"
elif count >= 1e3:
return f"{count/1e3:.1f}K"
else:
return f"{count:.0f}"
def plot_effectiveness(json_path, filename=None, effectiveness_type='cost'):
"""Generate bar plot of effectiveness data."""
df = load_apc_data(json_path, effectiveness_type)
total_cost_before = df['cost_before'].sum()
total_cost_after = df['cost_after'].sum()
# Print top 10 basic blocks
top10 = df.nlargest(10, 'cost_before')[['start_pcs', 'cost_before', 'effectiveness', 'instructions']]
print(top10)
top10['cost_before'] = top10['cost_before'].apply(format_cell_count)
top10.columns = ['Start PCs', 'Cost before', 'Effectiveness', 'Instructions']
print(f"\nTop 10 Basic Blocks by {effectiveness_type}:")
print(top10.to_string(index=False))
print()
# Calculate weighted mean effectiveness, corresponding to the overall effectiveness
# assuming that all basic blocks are accelerated.
mean_effectiveness = (df['effectiveness'] * df['cost_after']).sum() / total_cost_after
print(f"Mean effectiveness: {mean_effectiveness:.2f}")
# Separate large and small APCs (< 0.1% threshold)
threshold = total_cost_before * 0.001
df_large = df[df['cost_before'] >= threshold].copy()
df_small = df[df['cost_before'] < threshold]
# Sort large APCs by cost
df_large = df_large.sort_values('cost_before', ascending=False)
# Create 'Other' entry if there are small APCs
if len(df_small) > 0:
other_cost = df_small['cost_before'].sum()
other_effectiveness = (df_small['effectiveness'] * df_small['cost_before']).sum() / other_cost
other_row = pd.DataFrame([{
'effectiveness': other_effectiveness,
'cost_before': other_cost,
'instructions': -1, # Special marker for Other
'is_other': True
}])
df_plot = pd.concat([df_large.assign(is_other=False), other_row], ignore_index=True)
else:
df_plot = df_large.assign(is_other=False)
# Create plot
fig, ax = plt.subplots(figsize=(12, 6))
# Set up color mapping with log scale
valid_instructions = df_plot[~df_plot['is_other']]['instructions']
if len(valid_instructions) > 0:
norm = mcolors.LogNorm(vmin=valid_instructions.min(), vmax=valid_instructions.max())
cmap = plt.cm.RdYlGn # Red-Yellow-Green colormap
# Plot bars
x_pos = 0
for idx, row in df_plot.iterrows():
width = row['cost_before']
if row.get('is_other', False):
color = 'lightgray'
else:
color = cmap(norm(row['instructions']))
ax.bar(x_pos + width/2, row['effectiveness'], width=width,
color=color, edgecolor='black', linewidth=0.5, alpha=0.8)
# Label 'Other' box if it's wide enough
if row.get('is_other', False) and width > total_cost_before * 0.02: # Only label if > 2% of total width
ax.text(x_pos + width/2, row['effectiveness']/2,
f'Other\n({len(df_small)} APCs)',
ha='center', va='center', fontsize=10,
color='black', weight='bold')
x_pos += width
# Formatting
ax.set_xlabel('Cumulative cost before (software version)', fontsize=12)
ax.set_ylabel('Effectiveness', fontsize=12)
ax.set_title(f"Effectiveness by Basic Block (reduction in {effectiveness_type})", fontsize=14)
ax.grid(True, alpha=0.3, axis='y')
ax.axhline(mean_effectiveness, color='red', linestyle='--', linewidth=2, alpha=0.7)
# Format x-axis
ax.set_xlim(0, total_cost_before)
x_ticks = ax.get_xticks()
ax.set_xticklabels([format_cell_count(x) for x in x_ticks])
# Add colorbar for instruction count
if len(valid_instructions) > 0:
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cbar = plt.colorbar(sm, ax=ax, pad=0.02)
cbar.set_label('Instructions (log scale)', rotation=270, labelpad=20)
# Add mean text
ax.text(0.02, 0.97, f'Mean: {mean_effectiveness:.2f}',
transform=ax.transAxes, fontsize=10, verticalalignment='top',
bbox=dict(boxstyle='round,pad=0.5', facecolor='wheat', alpha=0.8))
plt.tight_layout()
# Save or show
if filename:
plt.savefig(filename, dpi=300, bbox_inches='tight')
else:
plt.show()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Plot effectiveness analysis from APC candidates JSON file.")
parser.add_argument("json_path", help="Path to the APC candidates JSON file")
parser.add_argument("-o", "--output", help="Optional file name to save the plot", default=None)
parser.add_argument("-e", "--effectiveness",
choices=['cost', 'main_columns', 'constraints', 'bus_interactions'],
default='cost',
help="Type of effectiveness calculation (default: cost_before/cost_after)")
args = parser.parse_args()
plot_effectiveness(args.json_path, args.output, args.effectiveness)
================================================
FILE: autoprecompiles/scripts/rank_apc_candidates.py
================================================
#!/usr/bin/env python3
"""
Simple APC Candidates JSON Parser
This script parses the apc_candidates.json file and extracts key information
in a concise format.
"""
import json
import sys
import argparse
from pathlib import Path
from tabulate import tabulate
def main():
"""Parse APC candidates and show key information."""
parser = argparse.ArgumentParser(description="Parse APC candidates and show key information.")
parser.add_argument("json_file", help="Path to the APC candidates JSON file")
parser.add_argument("-o", "--output", help="Output file (default: stdout)", default=None)
args = parser.parse_args()
json_file = Path(args.json_file)
output_file = args.output
if not json_file.exists():
print(f"Error: File {json_file} not found!")
sys.exit(1)
try:
with open(json_file, 'r') as f:
data = json.load(f)["apcs"]
except Exception as e:
print(f"Error reading file: {e}")
sys.exit(1)
# Capture output to write to file
output_lines = []
# Process and calculate densitys for each candidate
candidates_with_densitys = []
for i, candidate in enumerate(data):
start_pcs = [b["start_pc"] for b in candidate["original_blocks"]]
freq = candidate["execution_frequency"]
num_instructions = sum(len(b["instructions"]) for b in candidate["original_blocks"])
# Get optimization stats
before_constraints = candidate["stats"]["before"]["constraints"]
after_constraints = candidate["stats"]["after"]["constraints"]
before_main_columns = candidate["stats"]["before"]["main_columns"]
after_main_columns = candidate["stats"]["after"]["main_columns"]
before_bus_interactions = candidate["stats"]["before"]["bus_interactions"]
after_bus_interactions = candidate["stats"]["after"]["bus_interactions"]
value = candidate["value"]
cost_before = candidate["cost_before"]
cost_after = candidate["cost_after"]
# Calculate improvements as factors (before/after ratios)
cost_improvement_factor = cost_before / cost_after
constraint_improvement_factor = before_constraints / after_constraints
main_columns_improvement_factor = before_main_columns / after_main_columns
bus_interactions_improvement_factor = before_bus_interactions / after_bus_interactions
# Calculate density used for ranking candidates
density = value / cost_after
candidates_with_densitys.append({
'index': i + 1,
'start_pcs': start_pcs,
'freq': freq,
'num_instructions': num_instructions,
'before_constraints': before_constraints,
'after_constraints': after_constraints,
'before_main_columns': before_main_columns,
'after_main_columns': after_main_columns,
'before_bus_interactions': before_bus_interactions,
'after_bus_interactions': after_bus_interactions,
'cost_improvement_factor': cost_improvement_factor,
'constraint_improvement_factor': constraint_improvement_factor,
'main_columns_improvement_factor': main_columns_improvement_factor,
'bus_interactions_improvement_factor': bus_interactions_improvement_factor,
'value': value,
'cost_before': cost_before,
'cost_after': cost_after,
'density': density,
})
# Sort by descending density
candidates_with_densitys.sort(key=lambda x: x['density'], reverse=True)
# Summary statistics (moved to top)
output_lines.append("")
output_lines.append("=" * 120)
output_lines.append(f"SUMMARY STATISTICS OVER ALL APC CANDIDATES")
output_lines.append("=" * 120)
total_candidates = len(data)
total_instructions = sum(len(b["instructions"]) for c in data for b in c["original_blocks"])
total_cost_before = sum(c["cost_before"] for c in data)
total_cost_after = sum(c["cost_after"] for c in data)
total_cost_improvement_factor = total_cost_before / total_cost_after
total_before_constraints = sum(c["stats"]["before"]["constraints"] for c in data)
total_after_constraints = sum(c["stats"]["after"]["constraints"] for c in data)
total_constraint_improvement_factor = total_before_constraints / total_after_constraints
total_before_main_columns = sum(c["stats"]["before"]["main_columns"] for c in data)
total_after_main_columns = sum(c["stats"]["after"]["main_columns"] for c in data)
main_columns_improvement_factor = total_before_main_columns / total_after_main_columns
total_before_bus_interactions = sum(c["stats"]["before"]["bus_interactions"] for c in data)
total_after_bus_interactions = sum(c["stats"]["after"]["bus_interactions"] for c in data)
total_bus_interactions_improvement_factor = total_before_bus_interactions / total_after_bus_interactions
output_lines.append(f"# of APC Candidates: {total_candidates}")
output_lines.append(f"Sum of Instructions: {total_instructions}")
output_lines.append(f"Average Instructions per APC Candidate: {total_instructions / total_candidates:.1f}")
output_lines.append("")
output_lines.append(f"Sum of Cost: {total_cost_before} → {total_cost_after} ({total_cost_improvement_factor:.2f}x reduction)")
output_lines.append(f"Sum of Main Columns: {total_before_main_columns} → {total_after_main_columns} ({main_columns_improvement_factor:.2f}x reduction)")
output_lines.append(f"Sum of Constraints: {total_before_constraints} → {total_after_constraints} ({total_constraint_improvement_factor:.2f}x reduction)")
output_lines.append(f"Sum of Bus Interactions: {total_before_bus_interactions} → {total_after_bus_interactions} ({total_bus_interactions_improvement_factor:.2f}x reduction)")
# Statement count distribution
stmt_dist = {}
for c in data:
stmt_count = sum(len(b["instructions"]) for b in c["original_blocks"])
stmt_dist[stmt_count] = stmt_dist.get(stmt_count, 0) + 1
output_lines.append("")
output_lines.append("# of Instructions Distribution:")
stmt_table_data = []
for stmt_count in sorted(stmt_dist.keys()):
count = stmt_dist[stmt_count]
percentage = (count / total_candidates) * 100
stmt_table_data.append([stmt_count, count, f"{percentage:.1f}%"])
stmt_table_headers = ["Instructions", "# of Candidates", "Percentage"]
stmt_table_output = tabulate(stmt_table_data, headers=stmt_table_headers, tablefmt="grid")
output_lines.append(stmt_table_output)
# Frequency distribution
freq_dist = {}
for c in data:
freq = c["execution_frequency"]
freq_dist[freq] = freq_dist.get(freq, 0) + 1
output_lines.append("")
output_lines.append("Execution Frequency Distribution:")
freq_table_data = []
for freq in sorted(freq_dist.keys()):
count = freq_dist[freq]
percentage = (count / total_candidates) * 100
freq_table_data.append([f"{freq}x", count, f"{percentage:.1f}%"])
freq_table_headers = ["Frequency", "# of Candidates", "Percentage"]
freq_table_output = tabulate(freq_table_data, headers=freq_table_headers, tablefmt="grid")
output_lines.append(freq_table_output)
# Show sorted candidates by density using tabulate
output_lines.append("")
output_lines.append("=" * 120)
output_lines.append("APC CANDIDATES RANKED BY DENSITY (VALUE / COST_AFTER)")
output_lines.append("=" * 120)
# Prepare table data for tabulate
table_headers = [
"Rank", "Start PCs", "# of Instr", "Freq", "Value", "Cost Before -> After (Redux)",
"Density", "Main Cols Before -> After (Redux)",
"Constraints Before -> After (Redux)", "Bus Int Before -> After (Redux)"
]
table_data = []
for i, candidate in enumerate(candidates_with_densitys):
row = [
i + 1,
str(candidate['start_pcs']),
candidate['num_instructions'],
f"{candidate['freq']}x",
f"{candidate['value']:.0f}",
f"{candidate['cost_before']:.0f} -> {candidate['cost_after']:.0f} ({candidate['cost_improvement_factor']:.1f}x)",
f"{candidate['density']:.2f}",
f"{candidate['before_main_columns']} -> {candidate['after_main_columns']} ({candidate['main_columns_improvement_factor']:.1f}x)",
f"{candidate['before_constraints']} -> {candidate['after_constraints']} ({candidate['constraint_improvement_factor']:.1f}x)",
f"{candidate['before_bus_interactions']} -> {candidate['after_bus_interactions']} ({candidate['bus_interactions_improvement_factor']:.1f}x)"
]
table_data.append(row)
# Generate table using tabulate
table_output = tabulate(table_data, headers=table_headers, tablefmt="grid")
output_lines.append(table_output)
# Write output to file or stdout
try:
if output_file:
with open(output_file, 'w') as f:
for line in output_lines:
f.write(line + '\n')
print(f"Output written to: {output_file}")
else:
# Write to stdout
for line in output_lines:
print(line)
except Exception as e:
print(f"Error writing to output file: {e}")
# Fallback to console output
for line in output_lines:
print(line)
if __name__ == "__main__":
main()
================================================
FILE: autoprecompiles/scripts/readme.md
================================================
### Scripts
Set up (from the project root):
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r autoprecompiles/scripts/requirements.txt
```
================================================
FILE: autoprecompiles/scripts/requirements.txt
================================================
pandas
matplotlib
================================================
FILE: autoprecompiles/src/adapter.rs
================================================
use powdr_constraint_solver::constraint_system::BusInteractionHandler;
use std::collections::BTreeMap;
use std::hash::Hash;
use std::{fmt::Display, sync::Arc};
use powdr_number::FieldElement;
use serde::{Deserialize, Serialize};
use crate::blocks::{detect_superblocks, ExecutionBlocks, SuperBlock};
use crate::empirical_constraints::EmpiricalConstraints;
use crate::evaluation::EvaluationResult;
use crate::execution::{ExecutionState, OptimisticConstraint, OptimisticConstraints};
use crate::execution_profile::ExecutionProfile;
use crate::{
blocks::{BasicBlock, Instruction, Program},
constraint_optimizer::IsBusStateful,
memory_optimizer::MemoryBusInteraction,
range_constraint_optimizer::RangeConstraintHandler,
Apc, InstructionHandler, PowdrConfig, VmConfig,
};
#[derive(Serialize, Deserialize)]
pub struct ApcWithStats<F, I, A, V, S> {
apc: Arc<Apc<F, I, A, V>>,
stats: S,
evaluation_result: EvaluationResult,
}
impl<F, I, A, V, S> ApcWithStats<F, I, A, V, S> {
pub fn new(apc: Arc<Apc<F, I, A, V>>, stats: S, evaluation_result: EvaluationResult) -> Self {
Self {
apc,
stats,
evaluation_result,
}
}
#[allow(clippy::type_complexity)]
pub fn into_parts(self) -> (Arc<Apc<F, I, A, V>>, S, EvaluationResult) {
(self.apc, self.stats, self.evaluation_result)
}
pub fn apc(&self) -> &Apc<F, I, A, V> {
&self.apc
}
pub fn stats(&self) -> &S {
&self.stats
}
pub fn evaluation_result(&self) -> EvaluationResult {
self.evaluation_result
}
}
pub trait PgoAdapter {
type Adapter: Adapter;
fn filter_blocks_and_create_apcs_with_pgo(
&self,
blocks: Vec<AdapterBasicBlock<Self::Adapter>>,
config: &PowdrConfig,
vm_config: AdapterVmConfig<Self::Adapter>,
labels: BTreeMap<u64, Vec<String>>,
empirical_constraints: EmpiricalConstraints,
) -> Vec<AdapterApcWithStats<Self::Adapter>> {
let blocks = if let Some(prof) = self.execution_profile() {
detect_superblocks(config, &prof.pc_list, blocks)
} else {
let superblocks = blocks
.into_iter()
.map(SuperBlock::from)
// filter invalid APC candidates
.filter(|sb| sb.instructions().count() > 1)
.collect();
ExecutionBlocks::new_without_pgo(superblocks)
};
self.create_apcs_with_pgo(blocks, config, vm_config, labels, empirical_constraints)
}
fn create_apcs_with_pgo(
&self,
exec_blocks: AdapterExecutionBlocks<Self::Adapter>,
config: &PowdrConfig,
vm_config: AdapterVmConfig<Self::Adapter>,
labels: BTreeMap<u64, Vec<String>>,
empirical_constraints: EmpiricalConstraints,
) -> Vec<AdapterApcWithStats<Self::Adapter>>;
fn execution_profile(&self) -> Option<&ExecutionProfile> {
None
}
fn pc_execution_count(&self, pc: u64) -> Option<u32> {
self.execution_profile()
.and_then(|prof| prof.pc_count.get(&pc).cloned())
}
}
pub trait Adapter: Sized
where
Self::InstructionHandler:
InstructionHandler<Field = Self::Field, Instruction = Self::Instruction>,
{
type Field: Serialize + for<'de> Deserialize<'de> + Send + Sync + Clone;
type PowdrField: FieldElement;
type InstructionHandler: InstructionHandler + Sync;
type BusInteractionHandler: BusInteractionHandler<Self::PowdrField>
+ Clone
+ IsBusStateful<Self::PowdrField>
+ RangeConstraintHandler<Self::PowdrField>
+ Sync;
type Program: Program<Self::Instruction> + Send;
type Instruction: Instruction<Self::Field> + Serialize + for<'de> Deserialize<'de> + Send + Sync;
type MemoryBusInteraction<V: Ord + Clone + Eq + Display + Hash>: MemoryBusInteraction<
Self::PowdrField,
V,
>;
type CustomBusTypes: Clone
+ Display
+ Sync
+ Eq
+ PartialEq
+ Serialize
+ for<'de> Deserialize<'de>;
type ApcStats: Send + Sync;
type AirId: Eq + Hash + Send + Sync;
type ExecutionState: ExecutionState;
fn into_field(e: Self::PowdrField) -> Self::Field;
fn from_field(e: Self::Field) -> Self::PowdrField;
/// Given the autoprecompile and the original instructions, return the stats
fn apc_stats(
apc: Arc<AdapterApc<Self>>,
instruction_handler: &Self::InstructionHandler,
) -> Self::ApcStats;
fn is_branching(instr: &Self::Instruction) -> bool;
fn is_allowed(instr: &Self::Instruction) -> bool;
}
pub type AdapterApcWithStats<A> = ApcWithStats<
<A as Adapter>::Field,
<A as Adapter>::Instruction,
<<A as Adapter>::ExecutionState as ExecutionState>::RegisterAddress,
<<A as Adapter>::ExecutionState as ExecutionState>::Value,
<A as Adapter>::ApcStats,
>;
pub type ApcStats<A> = <A as Adapter>::ApcStats;
pub type AdapterApc<A> = Apc<
<A as Adapter>::Field,
<A as Adapter>::Instruction,
<<A as Adapter>::ExecutionState as ExecutionState>::RegisterAddress,
<<A as Adapter>::ExecutionState as ExecutionState>::Value,
>;
pub type AdapterApcOverPowdrField<A> = Apc<
<A as Adapter>::PowdrField,
<A as Adapter>::Instruction,
<<A as Adapter>::ExecutionState as ExecutionState>::RegisterAddress,
<<A as Adapter>::ExecutionState as ExecutionState>::Value,
>;
pub type AdapterVmConfig<'a, A> = VmConfig<
'a,
<A as Adapter>::InstructionHandler,
<A as Adapter>::BusInteractionHandler,
<A as Adapter>::CustomBusTypes,
>;
pub type AdapterExecutionState<A> = <A as Adapter>::ExecutionState;
pub type AdapterOptimisticConstraints<A> = OptimisticConstraints<
<<A as Adapter>::ExecutionState as ExecutionState>::RegisterAddress,
<<A as Adapter>::ExecutionState as ExecutionState>::Value,
>;
pub type AdapterOptimisticConstraint<A> = OptimisticConstraint<
<<A as Adapter>::ExecutionState as ExecutionState>::RegisterAddress,
<<A as Adapter>::ExecutionState as ExecutionState>::Value,
>;
pub type AdapterBasicBlock<A> = BasicBlock<<A as Adapter>::Instruction>;
pub type AdapterSuperBlock<A> = SuperBlock<<A as Adapter>::Instruction>;
pub type AdapterExecutionBlocks<A> = ExecutionBlocks<<A as Adapter>::Instruction>;
================================================
FILE: autoprecompiles/src/blocks/detection.rs
================================================
use std::collections::BTreeSet;
use crate::{
adapter::Adapter,
blocks::{BasicBlock, Program},
};
/// Collects basic blocks from a program
pub fn collect_basic_blocks<A: Adapter>(
program: &A::Program,
jumpdest_set: &BTreeSet<u64>,
) -> Vec<BasicBlock<A::Instruction>> {
let mut blocks = Vec::new();
let mut curr_block = BasicBlock {
start_pc: program.instruction_index_to_pc(0),
instructions: Vec::new(),
};
for (i, instr) in program.instructions().enumerate() {
let is_target = jumpdest_set.contains(&program.instruction_index_to_pc(i));
let is_branching = A::is_branching(&instr);
let is_allowed = A::is_allowed(&instr);
// If this opcode cannot be in an apc, we make sure it's alone in a BB.
if !is_allowed {
// If not empty, push the current block.
if !curr_block.instructions.is_empty() {
blocks.push(curr_block);
}
// Push the instruction itself
blocks.push(BasicBlock {
start_pc: program.instruction_index_to_pc(i),
instructions: vec![instr.clone()],
});
// Skip the instruction and start a new block from the next instruction.
curr_block = BasicBlock {
start_pc: program.instruction_index_to_pc(i + 1),
instructions: Vec::new(),
};
} else {
// If the instruction is a target, we need to close the previous block
// as is if not empty and start a new block from this instruction.
if is_target {
if !curr_block.instructions.is_empty() {
blocks.push(curr_block);
}
curr_block = BasicBlock {
start_pc: program.instruction_index_to_pc(i),
instructions: Vec::new(),
};
}
curr_block.instructions.push(instr.clone());
// If the instruction is a branch, we need to close this block
// with this instruction and start a new block from the next one.
if is_branching {
blocks.push(curr_block); // guaranteed to be non-empty because an instruction was just pushed
curr_block = BasicBlock {
start_pc: program.instruction_index_to_pc(i + 1),
instructions: Vec::new(),
};
}
}
}
if !curr_block.instructions.is_empty() {
blocks.push(curr_block);
}
tracing::info!(
"Got {} basic blocks from `collect_basic_blocks`",
blocks.len()
);
blocks
}
================================================
FILE: autoprecompiles/src/blocks/mod.rs
================================================
use std::{
collections::{BTreeMap, HashMap},
fmt::Display,
};
use itertools::Itertools;
use rayon::iter::{
IndexedParallelIterator, IntoParallelIterator, IntoParallelRefIterator, ParallelIterator,
};
use serde::{Deserialize, Serialize};
/// Tools to detect basic blocks in a program
mod detection;
pub use detection::collect_basic_blocks;
use crate::PowdrConfig;
#[derive(Debug, Serialize, Deserialize, Clone)]
/// A sequence of instructions starting at a given PC.
pub struct BasicBlock<I> {
/// The program counter of the first instruction in this block.
pub start_pc: u64,
pub instructions: Vec<I>,
}
impl<I: PcStep> BasicBlock<I> {
/// Returns an iterator over the program counters of the instructions in this block.
pub fn pcs(&self) -> impl Iterator<Item = u64> + '_ {
(0..self.instructions.len()).map(move |i| self.start_pc + (i as u64 * I::pc_step() as u64))
}
/// Returns an iterator over the program counters of the instructions in this block.
pub fn instructions(&self) -> impl Iterator<Item = (u64, &I)> + '_ {
self.instructions
.iter()
.enumerate()
.map(|(index, i)| (self.start_pc + (index as u64 * I::pc_step() as u64), i))
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
/// A sequence of basic blocks that can be made into an autoprecompile.
/// A single basic block is represented as a SuperBlock with one element.
pub struct SuperBlock<I> {
blocks: Vec<BasicBlock<I>>,
}
impl<I> From<BasicBlock<I>> for SuperBlock<I> {
fn from(basic_block: BasicBlock<I>) -> Self {
SuperBlock {
blocks: vec![basic_block],
}
}
}
impl<I> From<Vec<BasicBlock<I>>> for SuperBlock<I> {
fn from(blocks: Vec<BasicBlock<I>>) -> Self {
assert!(!blocks.is_empty());
SuperBlock { blocks }
}
}
impl<I> SuperBlock<I> {
pub fn is_basic_block(&self) -> bool {
self.blocks.len() == 1
}
pub fn try_as_basic_block(&self) -> Option<&BasicBlock<I>> {
if self.is_basic_block() {
Some(&self.blocks[0])
} else {
None
}
}
}
impl<I> SuperBlock<I> {
/// Sequence of basic block start PCs, uniquely identifies this superblock
pub fn start_pcs(&self) -> Vec<u64> {
self.blocks.iter().map(|b| b.start_pc).collect()
}
/// For each basic block in the superblock, returns the index of its first instruction
/// (within the superblock's flat instruction list) together with the block's start PC.
pub fn instruction_indexed_start_pcs(&self) -> Vec<(usize, u64)> {
let mut idx = 0;
self.blocks
.iter()
.map(|b| {
let elem = (idx, b.start_pc);
idx += b.instructions.len();
elem
})
.collect()
}
/// Sequence of basic blocks composing this superblock
pub fn blocks(&self) -> impl Iterator<Item = &BasicBlock<I>> {
self.blocks.iter()
}
/// Apply fn to every instruction in this superblock, returning a new superblock with the transformed instructions.
pub fn map_instructions<F, I2>(self, f: F) -> SuperBlock<I2>
where
F: Fn(I) -> I2 + Clone,
{
SuperBlock {
blocks: self
.blocks
.into_iter()
.map(|b| BasicBlock {
start_pc: b.start_pc,
instructions: b.instructions.into_iter().map(f.clone()).collect(),
})
.collect(),
}
}
}
impl<I: PcStep> SuperBlock<I> {
/// Returns an iterator over the program counters of the instructions in this block.
pub fn pcs(&self) -> impl Iterator<Item = u64> + '_ {
self.blocks.iter().flat_map(BasicBlock::pcs)
}
/// Sequence of instructions across all basic blocks in this superblock
pub fn instructions(&self) -> impl Iterator<Item = (u64, &I)> {
self.blocks.iter().flat_map(BasicBlock::instructions)
}
/// Parallel iterator over instructions across all basic blocks in this superblock
pub fn par_instructions(&self) -> impl IndexedParallelIterator<Item = (u64, &I)>
where
I: Sync,
{
// note: we need collect_vec() because parallel flat_map does not implement IndexedParallelIterator
self.instructions().collect_vec().into_par_iter()
}
}
impl<I: Display> Display for SuperBlock<I> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(bb) = self.try_as_basic_block() {
return bb.fmt(f);
}
writeln!(f, "SuperBlock(")?;
let mut insn_idx = 0;
for block in &self.blocks {
writeln!(f, " pc: {}, statements: [", block.start_pc)?;
for instr in block.instructions.iter() {
writeln!(f, " instr {insn_idx:>3}: {instr}")?;
insn_idx += 1;
}
write!(f, " ],")?;
}
write!(f, ")")
}
}
impl<I: Display> Display for BasicBlock<I> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "BasicBlock(start_pc: {}, statements: [", self.start_pc)?;
for (i, instr) in self.instructions.iter().enumerate() {
writeln!(f, " instr {i:>3}: {instr}")?;
}
write!(f, "])")
}
}
pub trait Program<I: PcStep> {
/// Returns the base program counter.
fn base_pc(&self) -> u64;
/// Converts an instruction index to a program counter.
fn instruction_index_to_pc(&self, idx: usize) -> u64 {
self.base_pc() + (idx as u64 * I::pc_step() as u64)
}
/// Returns an iterator over the instructions in the program.
fn instructions(&self) -> Box<dyn Iterator<Item = I> + '_>;
/// Returns the number of instructions in the program.
fn length(&self) -> u32;
}
pub trait PcStep {
fn pc_step() -> u32;
}
pub trait Instruction<T>: Clone + Display + PcStep {
/// Returns a list of concrete values that the LHS of the PC lookup should be assigned to.
fn pc_lookup_row(&self, pc: u64) -> Vec<T>;
}
/// A sequence of basic blocks seen in the execution, identified by their start PCs.
/// A run is interrupted by an invalid APC block (i.e., single instruction).
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct
gitextract_74kaprsg/
├── .config/
│ └── nextest.toml
├── .gitattributes
├── .github/
│ ├── actions/
│ │ ├── init-testing-instance/
│ │ │ └── action.yml
│ │ ├── init-testing-instance-gpu/
│ │ │ └── action.yml
│ │ └── patch-openvm-reth-benchmark/
│ │ └── action.yml
│ ├── runner/
│ │ └── Dockerfile
│ └── workflows/
│ ├── build-cache.yml
│ ├── dead-links.yml
│ ├── nightly-analyze.yml
│ ├── nightly-tests.yml
│ ├── post-merge-tests.yml
│ ├── pr-tests-with-secrets.yml
│ └── pr-tests.yml
├── .gitignore
├── CLAUDE.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── autoprecompile-analyzer/
│ ├── Claude.md
│ └── index.html
├── autoprecompiles/
│ ├── Cargo.toml
│ ├── benches/
│ │ └── optimizer_benchmark.rs
│ ├── scripts/
│ │ ├── plot_effectiveness.py
│ │ ├── rank_apc_candidates.py
│ │ ├── readme.md
│ │ └── requirements.txt
│ ├── src/
│ │ ├── adapter.rs
│ │ ├── blocks/
│ │ │ ├── detection.rs
│ │ │ └── mod.rs
│ │ ├── bus_map.rs
│ │ ├── constraint_optimizer.rs
│ │ ├── empirical_constraints.rs
│ │ ├── equivalence_classes.rs
│ │ ├── evaluation.rs
│ │ ├── execution/
│ │ │ ├── ast.rs
│ │ │ ├── candidates.rs
│ │ │ ├── evaluator.rs
│ │ │ └── mod.rs
│ │ ├── execution_profile.rs
│ │ ├── export.rs
│ │ ├── expression.rs
│ │ ├── expression_conversion.rs
│ │ ├── lib.rs
│ │ ├── low_degree_bus_interaction_optimizer.rs
│ │ ├── memory_optimizer.rs
│ │ ├── optimistic/
│ │ │ ├── algebraic_references.rs
│ │ │ ├── config.rs
│ │ │ ├── execution_constraint_generator.rs
│ │ │ ├── execution_literals.rs
│ │ │ └── mod.rs
│ │ ├── optimizer.rs
│ │ ├── optimizer_documentation.md
│ │ ├── pgo/
│ │ │ ├── cell/
│ │ │ │ ├── mod.rs
│ │ │ │ └── selection.rs
│ │ │ ├── instruction.rs
│ │ │ ├── mod.rs
│ │ │ └── none.rs
│ │ ├── powdr.rs
│ │ ├── range_constraint_optimizer.rs
│ │ ├── stats_logger.rs
│ │ ├── symbolic_machine.rs
│ │ ├── symbolic_machine_generator.rs
│ │ └── trace_handler.rs
│ └── tests/
│ └── optimizer.rs
├── cli-openvm-riscv/
│ ├── Cargo.toml
│ ├── README.md
│ └── src/
│ └── main.rs
├── constraint-solver/
│ ├── Cargo.toml
│ ├── src/
│ │ ├── algebraic_constraint/
│ │ │ ├── mod.rs
│ │ │ └── solve.rs
│ │ ├── bus_interaction_handler.rs
│ │ ├── constraint_system.rs
│ │ ├── effect.rs
│ │ ├── grouped_expression.rs
│ │ ├── indexed_constraint_system.rs
│ │ ├── inliner.rs
│ │ ├── lib.rs
│ │ ├── range_constraint.rs
│ │ ├── reachability.rs
│ │ ├── rule_based_optimizer/
│ │ │ ├── driver.rs
│ │ │ ├── environment.rs
│ │ │ ├── item_db.rs
│ │ │ ├── mod.rs
│ │ │ ├── new_var_generator.rs
│ │ │ ├── rules.rs
│ │ │ ├── tests.rs
│ │ │ └── types.rs
│ │ ├── runtime_constant.rs
│ │ ├── solver/
│ │ │ ├── base.rs
│ │ │ ├── boolean_extractor.rs
│ │ │ ├── constraint_splitter.rs
│ │ │ ├── exhaustive_search.rs
│ │ │ ├── linearizer.rs
│ │ │ └── var_transformation.rs
│ │ ├── solver.rs
│ │ ├── symbolic_expression.rs
│ │ ├── system_splitter.rs
│ │ ├── test_utils.rs
│ │ ├── utils.rs
│ │ └── variable_update.rs
│ └── tests/
│ └── solver.rs
├── expression/
│ ├── Cargo.toml
│ └── src/
│ ├── display.rs
│ ├── lib.rs
│ └── visitors.rs
├── isa-utils/
│ ├── Cargo.toml
│ └── src/
│ └── lib.rs
├── number/
│ ├── Cargo.toml
│ └── src/
│ ├── baby_bear.rs
│ ├── bn254.rs
│ ├── expression_convertible.rs
│ ├── goldilocks.rs
│ ├── koala_bear.rs
│ ├── lib.rs
│ ├── macros.rs
│ ├── mersenne31.rs
│ ├── plonky3_macros.rs
│ ├── serialize.rs
│ └── traits.rs
├── openvm/
│ ├── Cargo.toml
│ ├── build.rs
│ ├── cuda/
│ │ └── src/
│ │ ├── apc_apply_bus.cu
│ │ ├── apc_tracegen.cu
│ │ └── expr_eval.cuh
│ ├── metrics-viewer/
│ │ ├── CLAUDE.md
│ │ ├── index.html
│ │ └── spec.py
│ └── src/
│ ├── air_builder.rs
│ ├── cuda_abi.rs
│ ├── customize_exe.rs
│ ├── empirical_constraints.rs
│ ├── extraction_utils.rs
│ ├── isa.rs
│ ├── lib.rs
│ ├── powdr_extension/
│ │ ├── chip.rs
│ │ ├── executor/
│ │ │ └── mod.rs
│ │ ├── mod.rs
│ │ ├── opcode.rs
│ │ ├── trace_generator/
│ │ │ ├── common.rs
│ │ │ ├── cpu/
│ │ │ │ ├── inventory.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── periphery.rs
│ │ │ ├── cuda/
│ │ │ │ ├── inventory.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── periphery.rs
│ │ │ └── mod.rs
│ │ └── vm.rs
│ ├── program.rs
│ ├── test_utils.rs
│ ├── trace_generation.rs
│ └── utils.rs
├── openvm-bus-interaction-handler/
│ ├── Cargo.toml
│ └── src/
│ ├── bitwise_lookup.rs
│ ├── bus_map.rs
│ ├── lib.rs
│ ├── memory.rs
│ ├── memory_bus_interaction.rs
│ ├── tuple_range_checker.rs
│ └── variable_range_checker.rs
├── openvm-riscv/
│ ├── .gitignore
│ ├── Cargo.toml
│ ├── extensions/
│ │ ├── hints-circuit/
│ │ │ ├── Cargo.toml
│ │ │ └── src/
│ │ │ ├── executors.rs
│ │ │ ├── field10x26_k256.rs
│ │ │ └── lib.rs
│ │ ├── hints-guest/
│ │ │ ├── Cargo.toml
│ │ │ └── src/
│ │ │ └── lib.rs
│ │ └── hints-transpiler/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── lib.rs
│ ├── guest/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-ecc-manual/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-ecc-powdr-affine-hint/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-ecc-projective/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-ecrecover/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-ecrecover-manual/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-hints-test/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-keccak/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-keccak-manual-precompile/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-matmul/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-pairing/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-pairing-manual-precompile/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-sha256/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-sha256-manual-precompile/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-u256/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── guest-u256-manual-precompile/
│ │ ├── Cargo.toml
│ │ ├── openvm.toml
│ │ └── src/
│ │ └── main.rs
│ ├── scripts/
│ │ ├── basic_metrics.py
│ │ ├── generate_bench_results_readme.py
│ │ ├── metrics_utils.py
│ │ ├── plot_trace_cells.py
│ │ ├── readme.md
│ │ ├── requirements.txt
│ │ └── run_guest_benches.sh
│ ├── src/
│ │ ├── isa/
│ │ │ ├── instruction_formatter.rs
│ │ │ ├── mod.rs
│ │ │ ├── opcode.rs
│ │ │ ├── symbolic_instruction_builder.rs
│ │ │ └── trace_generator/
│ │ │ ├── common.rs
│ │ │ ├── cpu.rs
│ │ │ ├── cuda.rs
│ │ │ └── mod.rs
│ │ └── lib.rs
│ └── tests/
│ ├── apc_builder_complex.rs
│ ├── apc_builder_pseudo_instructions.rs
│ ├── apc_builder_single_instructions.rs
│ ├── apc_builder_superblocks.rs
│ ├── apc_reth_op_bug.cbor
│ ├── apc_snapshots/
│ │ ├── complex/
│ │ │ ├── aligned_memcpy.txt
│ │ │ ├── copy_byte.txt
│ │ │ ├── guest_top_block.txt
│ │ │ ├── load_two_bytes_compare.txt
│ │ │ ├── load_two_bytes_compare_unsigned.txt
│ │ │ ├── many_stores_relative_to_same_register.txt
│ │ │ ├── memcpy_block.txt
│ │ │ ├── rotate.txt
│ │ │ ├── stack_accesses.txt
│ │ │ ├── store_to_same_memory_address.txt
│ │ │ └── unaligned_memcpy.txt
│ │ ├── pseudo_instructions/
│ │ │ ├── beqz.txt
│ │ │ ├── bgez.txt
│ │ │ ├── bgtz.txt
│ │ │ ├── blez.txt
│ │ │ ├── bltz.txt
│ │ │ ├── bnez.txt
│ │ │ ├── j.txt
│ │ │ ├── jr.txt
│ │ │ ├── load_immediate.txt
│ │ │ ├── mv.txt
│ │ │ ├── neg.txt
│ │ │ ├── not.txt
│ │ │ ├── ret.txt
│ │ │ ├── seqz.txt
│ │ │ ├── sgtz.txt
│ │ │ ├── sltz.txt
│ │ │ └── snez.txt
│ │ ├── single_instructions/
│ │ │ ├── single_add_1.txt
│ │ │ ├── single_and_0.txt
│ │ │ ├── single_beq.txt
│ │ │ ├── single_bge.txt
│ │ │ ├── single_bgeu.txt
│ │ │ ├── single_blt.txt
│ │ │ ├── single_bltu.txt
│ │ │ ├── single_bne.txt
│ │ │ ├── single_div.txt
│ │ │ ├── single_divu.txt
│ │ │ ├── single_loadb.txt
│ │ │ ├── single_loadb_imm0.txt
│ │ │ ├── single_loadb_x0.txt
│ │ │ ├── single_loadbu.txt
│ │ │ ├── single_loadh.txt
│ │ │ ├── single_loadhu.txt
│ │ │ ├── single_loadw.txt
│ │ │ ├── single_mul.txt
│ │ │ ├── single_rem.txt
│ │ │ ├── single_remu.txt
│ │ │ ├── single_sll.txt
│ │ │ ├── single_sll_by_8.txt
│ │ │ ├── single_sra.txt
│ │ │ ├── single_srl.txt
│ │ │ ├── single_storeb.txt
│ │ │ ├── single_storeh.txt
│ │ │ ├── single_storew.txt
│ │ │ ├── single_sub.txt
│ │ │ └── single_xor.txt
│ │ └── superblocks/
│ │ ├── beq0_fallthrough.txt
│ │ ├── beq0_jump.txt
│ │ ├── beq_fallthrough.txt
│ │ ├── beq_jump.txt
│ │ └── many_blocks.txt
│ ├── common/
│ │ └── mod.rs
│ ├── keccak_apc_pre_opt.cbor
│ ├── machine_extraction.rs
│ └── openvm_constraints.txt
├── riscv-elf/
│ ├── Cargo.toml
│ └── src/
│ ├── bin/
│ │ └── elf-labels.rs
│ ├── debug_info.rs
│ ├── lib.rs
│ └── rv64.rs
├── riscv-types/
│ ├── Cargo.toml
│ └── src/
│ └── lib.rs
├── rust-toolchain.toml
├── scripts/
│ ├── analyze_nightly.py
│ └── update-dep.sh
└── syscalls/
├── Cargo.toml
└── src/
└── lib.rs
SYMBOL INDEX (2247 symbols across 159 files)
FILE: autoprecompiles/benches/optimizer_benchmark.rs
type TestApc (line 15) | type TestApc = Apc<BabyBearField, SimpleInstruction<BabyBearField>, (), ...
constant DEFAULT_DEGREE_BOUND (line 17) | const DEFAULT_DEGREE_BOUND: DegreeBound = DegreeBound {
function optimize_keccak_benchmark (line 23) | fn optimize_keccak_benchmark(c: &mut Criterion) {
FILE: autoprecompiles/scripts/plot_effectiveness.py
function load_apc_data (line 9) | def load_apc_data(json_path, effectiveness_type='cost'):
function format_cell_count (line 39) | def format_cell_count(count):
function plot_effectiveness (line 50) | def plot_effectiveness(json_path, filename=None, effectiveness_type='cos...
FILE: autoprecompiles/scripts/rank_apc_candidates.py
function main (line 16) | def main():
FILE: autoprecompiles/src/adapter.rs
type ApcWithStats (line 23) | pub struct ApcWithStats<F, I, A, V, S> {
function new (line 29) | pub fn new(apc: Arc<Apc<F, I, A, V>>, stats: S, evaluation_result: Evalu...
function into_parts (line 38) | pub fn into_parts(self) -> (Arc<Apc<F, I, A, V>>, S, EvaluationResult) {
function apc (line 42) | pub fn apc(&self) -> &Apc<F, I, A, V> {
function stats (line 46) | pub fn stats(&self) -> &S {
function evaluation_result (line 50) | pub fn evaluation_result(&self) -> EvaluationResult {
type PgoAdapter (line 55) | pub trait PgoAdapter {
method filter_blocks_and_create_apcs_with_pgo (line 58) | fn filter_blocks_and_create_apcs_with_pgo(
method create_apcs_with_pgo (line 81) | fn create_apcs_with_pgo(
method execution_profile (line 90) | fn execution_profile(&self) -> Option<&ExecutionProfile> {
method pc_execution_count (line 94) | fn pc_execution_count(&self, pc: u64) -> Option<u32> {
type Adapter (line 100) | pub trait Adapter: Sized
method into_field (line 130) | fn into_field(e: Self::PowdrField) -> Self::Field;
method from_field (line 132) | fn from_field(e: Self::Field) -> Self::PowdrField;
method apc_stats (line 135) | fn apc_stats(
method is_branching (line 140) | fn is_branching(instr: &Self::Instruction) -> bool;
method is_allowed (line 142) | fn is_allowed(instr: &Self::Instruction) -> bool;
type AdapterApcWithStats (line 145) | pub type AdapterApcWithStats<A> = ApcWithStats<
type ApcStats (line 152) | pub type ApcStats<A> = <A as Adapter>::ApcStats;
type AdapterApc (line 153) | pub type AdapterApc<A> = Apc<
type AdapterApcOverPowdrField (line 159) | pub type AdapterApcOverPowdrField<A> = Apc<
type AdapterVmConfig (line 165) | pub type AdapterVmConfig<'a, A> = VmConfig<
type AdapterExecutionState (line 171) | pub type AdapterExecutionState<A> = <A as Adapter>::ExecutionState;
type AdapterOptimisticConstraints (line 172) | pub type AdapterOptimisticConstraints<A> = OptimisticConstraints<
type AdapterOptimisticConstraint (line 176) | pub type AdapterOptimisticConstraint<A> = OptimisticConstraint<
type AdapterBasicBlock (line 180) | pub type AdapterBasicBlock<A> = BasicBlock<<A as Adapter>::Instruction>;
type AdapterSuperBlock (line 181) | pub type AdapterSuperBlock<A> = SuperBlock<<A as Adapter>::Instruction>;
type AdapterExecutionBlocks (line 182) | pub type AdapterExecutionBlocks<A> = ExecutionBlocks<<A as Adapter>::Ins...
FILE: autoprecompiles/src/blocks/detection.rs
function collect_basic_blocks (line 9) | pub fn collect_basic_blocks<A: Adapter>(
FILE: autoprecompiles/src/blocks/mod.rs
type BasicBlock (line 21) | pub struct BasicBlock<I> {
function pcs (line 29) | pub fn pcs(&self) -> impl Iterator<Item = u64> + '_ {
function instructions (line 34) | pub fn instructions(&self) -> impl Iterator<Item = (u64, &I)> + '_ {
type SuperBlock (line 45) | pub struct SuperBlock<I> {
function from (line 50) | fn from(basic_block: BasicBlock<I>) -> Self {
function from (line 58) | fn from(blocks: Vec<BasicBlock<I>>) -> Self {
function is_basic_block (line 65) | pub fn is_basic_block(&self) -> bool {
function try_as_basic_block (line 69) | pub fn try_as_basic_block(&self) -> Option<&BasicBlock<I>> {
function start_pcs (line 80) | pub fn start_pcs(&self) -> Vec<u64> {
function instruction_indexed_start_pcs (line 86) | pub fn instruction_indexed_start_pcs(&self) -> Vec<(usize, u64)> {
function blocks (line 99) | pub fn blocks(&self) -> impl Iterator<Item = &BasicBlock<I>> {
function map_instructions (line 104) | pub fn map_instructions<F, I2>(self, f: F) -> SuperBlock<I2>
function pcs (line 123) | pub fn pcs(&self) -> impl Iterator<Item = u64> + '_ {
function instructions (line 128) | pub fn instructions(&self) -> impl Iterator<Item = (u64, &I)> {
function par_instructions (line 133) | pub fn par_instructions(&self) -> impl IndexedParallelIterator<Item = (u...
method fmt (line 143) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
method fmt (line 162) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type Program (line 171) | pub trait Program<I: PcStep> {
method base_pc (line 173) | fn base_pc(&self) -> u64;
method instruction_index_to_pc (line 176) | fn instruction_index_to_pc(&self, idx: usize) -> u64 {
method instructions (line 181) | fn instructions(&self) -> Box<dyn Iterator<Item = I> + '_>;
method length (line 184) | fn length(&self) -> u32;
type PcStep (line 187) | pub trait PcStep {
method pc_step (line 188) | fn pc_step() -> u32;
method pc_step (line 436) | fn pc_step() -> u32 {
type Instruction (line 191) | pub trait Instruction<T>: Clone + Display + PcStep {
method pc_lookup_row (line 193) | fn pc_lookup_row(&self, pc: u64) -> Vec<T>;
type ExecutionBasicBlockRun (line 199) | pub struct ExecutionBasicBlockRun(pub Vec<u64>);
type BlockAndStats (line 202) | pub struct BlockAndStats<I> {
type ExecutionBlocks (line 209) | pub struct ExecutionBlocks<I> {
function new_without_pgo (line 218) | pub fn new_without_pgo(blocks: Vec<SuperBlock<I>>) -> Self {
function find_non_overlapping (line 231) | pub fn find_non_overlapping<T: Eq>(haystack: &[T], needle: &[T]) -> Vec<...
function detect_execution_bb_runs (line 248) | fn detect_execution_bb_runs<I>(
function count_superblocks_in_run (line 294) | fn count_superblocks_in_run(
function count_superblocks_in_execution (line 312) | fn count_superblocks_in_execution(
function detect_superblocks (line 339) | pub fn detect_superblocks<I: Clone + PcStep>(
type TestInstruction (line 433) | struct TestInstruction;
function test_find_non_overlapping (line 442) | fn test_find_non_overlapping() {
function test_superblocks_in_run (line 450) | fn test_superblocks_in_run() {
function test_detect_superblocks_counts_and_execution_runs (line 470) | fn test_detect_superblocks_counts_and_execution_runs() {
FILE: autoprecompiles/src/bus_map.rs
type BusType (line 5) | pub enum BusType<C> {
function fmt (line 19) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type BusMap (line 31) | pub struct BusMap<C> {
function from_id_type_pairs (line 37) | pub fn from_id_type_pairs(pairs: impl IntoIterator<Item = (u64, BusType<...
function bus_type (line 51) | pub fn bus_type(&self, bus_id: u64) -> BusType<C> {
function all_types_by_id (line 58) | pub fn all_types_by_id(&self) -> &BTreeMap<u64, BusType<C>> {
function get_bus_id (line 63) | pub fn get_bus_id(&self, bus_type: &BusType<C>) -> Option<u64> {
FILE: autoprecompiles/src/constraint_optimizer.rs
type Error (line 33) | pub enum Error {
method from (line 38) | fn from(err: powdr_constraint_solver::solver::Error) -> Self {
function optimize_constraints (line 50) | pub fn optimize_constraints<
function substitute_bus_interaction_fields (line 157) | fn substitute_bus_interaction_fields<P: FieldElement, V: Ord + Clone + E...
function trivial_simplifications (line 182) | pub fn trivial_simplifications<P: FieldElement, V: Ord + Clone + Eq + Ha...
function solver_based_optimization (line 209) | fn solver_based_optimization<T: FieldElement, V: Clone + Ord + Hash + Di...
function try_replace_by_number (line 264) | fn try_replace_by_number<T: FieldElement, V: Clone + Ord + Hash + Display>(
function remove_free_variables (line 286) | fn remove_free_variables<T: FieldElement, V: Clone + Ord + Eq + Hash + D...
function can_always_be_satisfied_via_free_variable (line 368) | fn can_always_be_satisfied_via_free_variable<
function remove_disconnected_columns (line 397) | pub fn remove_disconnected_columns<T: FieldElement, V: Clone + Ord + Eq ...
function variables_in_stateful_bus_interactions (line 431) | fn variables_in_stateful_bus_interactions<'a, P: FieldElement, V: Ord + ...
function remove_trivial_constraints (line 445) | fn remove_trivial_constraints<P: FieldElement, V: PartialEq + Clone + Ha...
function remove_equal_bus_interactions (line 454) | fn remove_equal_bus_interactions<P: FieldElement, V: Ord + Clone + Eq + ...
type IsBusStateful (line 471) | pub trait IsBusStateful<T: FieldElement> {
method is_stateful (line 475) | fn is_stateful(&self, bus_id: T) -> bool;
function remove_redundant_constraints (line 479) | fn remove_redundant_constraints<P: FieldElement, V: Clone + Ord + Hash +...
function remove_duplicate_factors (line 537) | fn remove_duplicate_factors<P: FieldElement, V: Clone + Ord + Hash + Dis...
function remove_unreferenced_derived_variables (line 562) | fn remove_unreferenced_derived_variables<P: FieldElement, V: Clone + Ord...
FILE: autoprecompiles/src/empirical_constraints.rs
type EmpiricalConstraints (line 25) | pub struct EmpiricalConstraints {
method combine_with (line 60) | pub fn combine_with(&mut self, other: EmpiricalConstraints) {
method for_block (line 98) | pub fn for_block<I: PcStep>(&self, block: &SuperBlock<I>) -> BlockEmpi...
method apply_pc_threshold (line 143) | pub fn apply_pc_threshold(self) -> Self {
type BlockEmpiricalConstraints (line 38) | pub struct BlockEmpiricalConstraints {
method filtered (line 171) | pub fn filtered(self, predicate: impl Fn(&BlockCell) -> bool) -> Self {
type DebugInfo (line 50) | pub struct DebugInfo {
method combine_with (line 219) | pub fn combine_with(&mut self, other: DebugInfo) {
method take (line 227) | pub fn take(&mut self) -> Self {
function merge_maps (line 236) | fn merge_maps<K: Ord, V: Eq + Debug>(map1: &mut BTreeMap<K, V>, map2: BT...
type BlockCell (line 250) | pub struct BlockCell {
method new (line 258) | pub fn new(instruction_idx: usize, column_idx: usize) -> Self {
type ConstraintGenerator (line 267) | pub struct ConstraintGenerator<'a, A: Adapter> {
function new (line 280) | pub fn new(
function get_algebraic_reference (line 292) | fn get_algebraic_reference(&self, block_cell: &BlockCell) -> AlgebraicRe...
function generate_constraints (line 305) | pub fn generate_constraints(&self) -> Vec<EqualityConstraint<A::PowdrFie...
function range_constraints (line 317) | fn range_constraints(&self) -> Vec<EqualityConstraint<A::PowdrField>> {
function equivalence_constraints (line 343) | fn equivalence_constraints(&self) -> Vec<EqualityConstraint<A::PowdrFiel...
type EqualityExpression (line 365) | pub enum EqualityExpression<T> {
function from (line 371) | fn from(expr: EqualityExpression<T>) -> Self {
type EqualityConstraint (line 380) | pub struct EqualityConstraint<T> {
function from (line 386) | fn from(constraint: EqualityConstraint<T>) -> Self {
FILE: autoprecompiles/src/equivalence_classes.rs
type EquivalenceClass (line 10) | pub type EquivalenceClass<T> = BTreeSet<T>;
type Partition (line 19) | pub struct Partition<T> {
method serialize (line 28) | fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Er...
function deserialize (line 35) | fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D:...
function from_iter (line 46) | fn from_iter<I: IntoIterator<Item = C>>(iter: I) -> Self {
function to_classes (line 73) | pub fn to_classes(&self) -> Vec<Vec<T>> {
function intersect_many (line 85) | pub fn intersect_many(partitions: impl IntoIterator<Item = Self>) -> Self {
function intersected_with (line 97) | pub fn intersected_with(self, other: Self) -> Self {
function combine (line 117) | pub fn combine(mut self, other: Self) -> Self {
function map_elements (line 131) | pub fn map_elements<T2: Eq + Hash + Clone, F: Fn(T) -> T2>(self, f: F) -...
constant CHUNK_SIZE (line 147) | const CHUNK_SIZE: usize = 64;
function parallel_intersect (line 154) | pub fn parallel_intersect(partitions: impl IndexedParallelIterator<Item ...
method eq (line 176) | fn eq(&self, other: &Self) -> bool {
function to_canonical (line 185) | fn to_canonical(&self) -> BTreeSet<BTreeSet<T>> {
function partition (line 197) | fn partition(sets: Vec<Vec<u32>>) -> Partition<u32> {
function test_intersect_partitions (line 202) | fn test_intersect_partitions() {
function test_default_partition_yields_no_classes (line 233) | fn test_default_partition_yields_no_classes() {
function test_map_elements (line 241) | fn test_map_elements() {
function test_map_elements_panics_on_collision (line 253) | fn test_map_elements_panics_on_collision() {
function test_combine (line 259) | fn test_combine() {
function test_combine_panics_on_collision (line 269) | fn test_combine_panics_on_collision() {
FILE: autoprecompiles/src/evaluation.rs
type AirStats (line 12) | pub struct AirStats {
method new (line 24) | pub fn new<F>(machine: &SymbolicMachine<F>) -> Self {
method sum (line 45) | fn sum<I: Iterator<Item = AirStats>>(iter: I) -> AirStats {
type Output (line 34) | type Output = AirStats;
method add (line 35) | fn add(self, rhs: AirStats) -> AirStats {
type EvaluationResult (line 52) | pub struct EvaluationResult {
function evaluate_apc (line 63) | pub fn evaluate_apc<A: Adapter>(
method fmt (line 82) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function render_stat (line 94) | fn render_stat(before: usize, after: usize) -> String {
FILE: autoprecompiles/src/execution/ast.rs
type OptimisticConstraint (line 10) | pub struct OptimisticConstraint<A, V> {
function children (line 16) | fn children(&self) -> Box<dyn Iterator<Item = &OptimisticExpression<A, V...
function children_mut (line 20) | fn children_mut(&mut self) -> Box<dyn Iterator<Item = &mut OptimisticExp...
method unique_references (line 32) | fn unique_references(&'a self) -> impl Iterator<Item = OptimisticLiteral...
function all_children (line 46) | fn all_children(&self) -> Box<dyn Iterator<Item = &OptimisticExpression<...
type OptimisticExpression (line 52) | pub enum OptimisticExpression<A, V> {
function children (line 58) | fn children(&self) -> Box<dyn Iterator<Item = &OptimisticExpression<A, V...
type LocalOptimisticLiteral (line 70) | pub enum LocalOptimisticLiteral<A> {
function from (line 77) | fn from(value: LocalOptimisticLiteral<A>) -> Self {
type LocalFetch (line 88) | pub enum LocalFetch<A> {
function get (line 94) | pub fn get<E: ExecutionState<RegisterAddress = A>>(&self, state: &E) -> ...
type Fetch (line 105) | pub struct Fetch<A> {
function from (line 111) | fn from(value: OptimisticLiteral<A>) -> Self {
type OptimisticLiteral (line 122) | pub struct OptimisticLiteral<A> {
FILE: autoprecompiles/src/execution/candidates.rs
type ApcCandidates (line 12) | pub struct ApcCandidates<E: ExecutionState, A, S> {
type ApcCall (line 21) | pub struct ApcCall<S> {
function new (line 31) | pub fn new(apcs: Vec<A>) -> Self {
function check_conditions (line 40) | pub fn check_conditions(&mut self, state: &E, snapshot_callback: impl Fn...
function abort_in_progress (line 73) | pub fn abort_in_progress(&mut self) -> Vec<usize> {
function extract_calls (line 81) | pub fn extract_calls(&mut self) -> Vec<ApcCall<S>> {
function try_insert (line 157) | pub fn try_insert(
function candidate_range (line 178) | fn candidate_range(candidate: &ApcCandidate<E, S>) -> (usize, usize) {
function ranges_overlap (line 189) | fn ranges_overlap((start_a, end_a): (usize, usize), (start_b, end_b): (u...
type CandidateRank (line 195) | struct CandidateRank {
method cmp (line 205) | fn cmp(&self, other: &Self) -> Ordering {
method partial_cmp (line 214) | fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
type ApcCandidate (line 220) | struct ApcCandidate<E: ExecutionState, S> {
type Clocked (line 233) | struct Clocked<S> {
function new (line 239) | fn new(global_clk: usize, snapshot: S) -> Self {
type Apc (line 248) | pub trait Apc<E: ExecutionState> {
method optimistic_constraints (line 250) | fn optimistic_constraints(&self) -> &OptimisticConstraints<E::Register...
method cycle_count (line 253) | fn cycle_count(&self) -> usize;
method priority (line 256) | fn priority(&self) -> usize;
type CandidateStatus (line 260) | enum CandidateStatus<E: ExecutionState, S> {
type TestApc (line 274) | struct TestApc {
method a (line 281) | fn a(len: usize) -> Self {
method p (line 288) | fn p(mut self, priority: usize) -> Self {
method c (line 293) | fn c(mut self, optimistic_constraints: OptimisticConstraints<(), usize...
method cycle_count (line 304) | fn cycle_count(&self) -> usize {
method priority (line 308) | fn priority(&self) -> usize {
method optimistic_constraints (line 312) | fn optimistic_constraints(&self) -> &OptimisticConstraints<(), usize> {
function a (line 299) | fn a(len: usize) -> TestApc {
type TestExecutionState (line 318) | struct TestExecutionState {
method incr (line 324) | fn incr(&mut self) {
method jump (line 328) | fn jump(&mut self, pc: usize) {
method snapshot (line 333) | fn snapshot(&self) -> TestSnapshot {
type RegisterAddress (line 341) | type RegisterAddress = ();
type Value (line 343) | type Value = usize;
method value_limb (line 345) | fn value_limb(_: Self::Value, _: usize) -> Self::Value {
method pc (line 349) | fn pc(&self) -> Self::Value {
method reg (line 353) | fn reg(&self, _address: &Self::RegisterAddress) -> Self::Value {
method global_clk (line 357) | fn global_clk(&self) -> usize {
type TestSnapshot (line 363) | struct TestSnapshot {
function s (line 367) | fn s(instret: usize) -> TestSnapshot {
type TestVm (line 371) | struct TestVm {
method try_add_candidate (line 377) | fn try_add_candidate(&mut self, apc_id: usize) -> Result<(), Optimisti...
method incr (line 383) | fn incr(&mut self) -> Vec<ApcCall<TestSnapshot>> {
method jump (line 390) | fn jump(&mut self, pc: usize) -> Vec<ApcCall<TestSnapshot>> {
method count_done (line 397) | fn count_done(&self) -> usize {
method count_in_progress (line 405) | fn count_in_progress(&self) -> usize {
method new (line 413) | fn new(apcs: impl IntoIterator<Item = TestApc>) -> Self {
function single_candidate (line 422) | fn single_candidate() {
function single_candidate_final_state_failure (line 444) | fn single_candidate_final_state_failure() {
function two_candidates_same_length (line 466) | fn two_candidates_same_length() {
function superblock_success (line 492) | fn superblock_success() {
function superblock_failure (line 525) | fn superblock_failure() {
function superblock_failure_keeps_non_overlapping_calls (line 565) | fn superblock_failure_keeps_non_overlapping_calls() {
function two_candidates_different_start (line 622) | fn two_candidates_different_start() {
function abort_in_progress_returns_shorter_candidate (line 657) | fn abort_in_progress_returns_shorter_candidate() {
function abort_in_progress_after_segment_end_picks_shorter_candidate (line 690) | fn abort_in_progress_after_segment_end_picks_shorter_candidate() {
function jump_back_and_readd_candidate_does_not_overlap (line 726) | fn jump_back_and_readd_candidate_does_not_overlap() {
FILE: autoprecompiles/src/execution/evaluator.rs
type OptimisticConstraints (line 18) | pub struct OptimisticConstraints<A, V> {
function empty (line 26) | pub fn empty() -> Self {
function from_constraints (line 35) | pub fn from_constraints(constraints: Vec<OptimisticConstraint<A, V>>) ->...
type OptimisticConstraintEvaluator (line 90) | pub struct OptimisticConstraintEvaluator<A, V> {
type OptimisticConstraintFailed (line 98) | pub struct OptimisticConstraintFailed;
method default (line 101) | fn default() -> Self {
function new (line 107) | pub fn new() -> Self {
function instruction_index (line 114) | pub fn instruction_index(&self) -> usize {
function try_next_execution_step (line 119) | pub fn try_next_execution_step<E>(
type StepOptimisticConstraintEvaluator (line 170) | struct StepOptimisticConstraintEvaluator<'a, E: ExecutionState> {
function new (line 176) | fn new(
function evaluate_constraint (line 193) | fn evaluate_constraint(&self, c: &OptimisticConstraint<E::RegisterAddres...
function evaluate_expression (line 197) | fn evaluate_expression(
function evaluate_literal (line 209) | fn evaluate_literal(&self, l: &OptimisticLiteral<E::RegisterAddress>) ->...
function fetch (line 221) | fn fetch(&self, f: &Fetch<E::RegisterAddress>) -> E::Value {
type TestExecutionState (line 236) | struct TestExecutionState<const LIMB_WIDTH: usize> {
type RegisterAddress (line 242) | type RegisterAddress = u8;
type Value (line 244) | type Value = u8;
method pc (line 246) | fn pc(&self) -> Self::Value {
method reg (line 250) | fn reg(&self, address: &Self::RegisterAddress) -> Self::Value {
method value_limb (line 254) | fn value_limb(value: Self::Value, limb_index: usize) -> Self::Value {
method global_clk (line 258) | fn global_clk(&self) -> usize {
type SingleLimbExecutionState (line 264) | type SingleLimbExecutionState = TestExecutionState<8>;
function literal (line 266) | fn literal(instr_idx: usize, val: LocalOptimisticLiteral<u8>) -> Optimis...
function literal_expr (line 270) | fn literal_expr(
function mem (line 278) | fn mem(instr_idx: usize, addr: u8) -> OptimisticExpression<u8, u8> {
function mem_limb (line 282) | fn mem_limb(instr_idx: usize, addr: u8, limb_index: usize) -> Optimistic...
function pc (line 289) | fn pc(instr_idx: usize) -> OptimisticExpression<u8, u8> {
function value (line 293) | fn value(value: u8) -> OptimisticExpression<u8, u8> {
function eq (line 297) | fn eq(
function equality_constraints (line 304) | fn equality_constraints() -> OptimisticConstraints<u8, u8> {
function cross_step_memory_constraint (line 312) | fn cross_step_memory_constraint() -> OptimisticConstraints<u8, u8> {
function cross_step_pc_constraint (line 316) | fn cross_step_pc_constraint() -> OptimisticConstraints<u8, u8> {
function initial_to_final_constraint (line 320) | fn initial_to_final_constraint(final_instr_idx: usize) -> OptimisticCons...
function constraints_succeed_when_all_states_match (line 325) | fn constraints_succeed_when_all_states_match() {
function checks_equality_constraints (line 344) | fn checks_equality_constraints() {
function reuses_values_from_previous_steps (line 364) | fn reuses_values_from_previous_steps() {
function detects_mismatch_for_stored_values (line 381) | fn detects_mismatch_for_stored_values() {
function compares_program_counter_across_steps (line 398) | fn compares_program_counter_across_steps() {
function links_initial_and_final_state (line 424) | fn links_initial_and_final_state() {
function compares_memory_to_literal_value (line 465) | fn compares_memory_to_literal_value() {
function accesses_register_limbs (line 490) | fn accesses_register_limbs() {
FILE: autoprecompiles/src/execution/mod.rs
type ExecutionState (line 10) | pub trait ExecutionState {
method pc (line 33) | fn pc(&self) -> Self::Value;
method value_limb (line 35) | fn value_limb(value: Self::Value, limb_index: usize) -> Self::Value;
method reg (line 38) | fn reg(&self, address: &Self::RegisterAddress) -> Self::Value;
method global_clk (line 41) | fn global_clk(&self) -> usize;
FILE: autoprecompiles/src/execution_profile.rs
type ExecutionProfile (line 18) | pub struct ExecutionProfile {
function execution_profile (line 27) | pub fn execution_profile<A: Adapter>(
type PgoData (line 70) | struct PgoData {
method record_u64 (line 76) | fn record_u64(&mut self, field: &tracing::field::Field, value: u64) {
method record_debug (line 84) | fn record_debug(&mut self, _: &TracingField, _: &dyn std::fmt::Debug) {}
type PgoCollector (line 89) | struct PgoCollector {
method new (line 94) | fn new() -> Self {
method increment (line 100) | fn increment(&self, pc: u64) {
method take_pc_list (line 104) | fn take_pc_list(&self) -> Vec<u64> {
method on_event (line 113) | fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>) {
FILE: autoprecompiles/src/export.rs
type ExportOptions (line 25) | pub struct ExportOptions {
method new (line 49) | pub fn new(path: Option<PathBuf>, start_pcs: &[u64], level: ExportLeve...
method from_env_vars (line 58) | pub fn from_env_vars(
method export_requested (line 73) | pub fn export_requested(&self) -> bool {
method export_apc (line 77) | pub fn export_apc<A: Adapter>(
method export_apc_from_machine (line 95) | pub fn export_apc_from_machine<A: Adapter>(
method export_optimizer_outer (line 113) | pub fn export_optimizer_outer(&mut self, data: &impl serde::Serialize,...
method export_optimizer_outer_constraint_system (line 122) | pub fn export_optimizer_outer_constraint_system<T: FieldElement>(
method export_optimizer_inner (line 136) | pub fn export_optimizer_inner(&mut self, data: &impl serde::Serialize,...
method export_optimizer_inner_constraint_system (line 142) | pub fn export_optimizer_inner_constraint_system<T, V>(
method register_substituted_variables (line 157) | pub fn register_substituted_variables<Var, Expr>(
method export_substituted_variables (line 173) | pub fn export_substituted_variables(&mut self) {
method next_path (line 186) | fn next_path(&mut self, info: Option<&str>) -> PathBuf {
method write_to_next_file (line 197) | fn write_to_next_file(&mut self, data: &impl serde::Serialize, info: O...
method write_to_file (line 203) | fn write_to_file(&mut self, data: &impl serde::Serialize, path: PathBu...
type ExportLevel (line 33) | pub enum ExportLevel {
function create_full_path (line 210) | fn create_full_path(path: &PathBuf) -> BufWriter<std::fs::File> {
function instructions_to_powdr_field (line 220) | fn instructions_to_powdr_field<A: Adapter>(
type SimpleInstruction (line 251) | pub struct SimpleInstruction<T>(Vec<T>);
method fmt (line 254) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function pc_lookup_row (line 260) | fn pc_lookup_row(&self, _pc: u64) -> Vec<T> {
method pc_step (line 266) | fn pc_step() -> u32 {
type ApcWithBusMap (line 272) | pub struct ApcWithBusMap<Apc, BusMap> {
FILE: autoprecompiles/src/expression.rs
type AlgebraicExpression (line 10) | pub type AlgebraicExpression<T> = powdr_expression::AlgebraicExpression<...
type AlgebraicReference (line 13) | pub struct AlgebraicReference {
method fmt (line 22) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
method deserialize (line 61) | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
method partial_cmp (line 28) | fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
method cmp (line 34) | fn cmp(&self, other: &Self) -> std::cmp::Ordering {
method eq (line 40) | fn eq(&self, other: &Self) -> bool {
method hash (line 46) | fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
method serialize (line 52) | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
function try_convert (line 84) | pub fn try_convert<T, R: TryInto<AlgebraicReference>>(
type AlgebraicEvaluator (line 115) | pub trait AlgebraicEvaluator<F, E>
method eval_const (line 120) | fn eval_const(&self, c: F) -> E;
method eval_var (line 121) | fn eval_var(&self, algebraic_var: &AlgebraicReference) -> E;
method eval_expr (line 123) | fn eval_expr(&self, algebraic_expr: &AlgebraicExpression<F>) -> E {
method eval_bus_interaction (line 126) | fn eval_bus_interaction<'a, 'b>(
method eval_constraint (line 142) | fn eval_constraint(&self, constraint: &SymbolicConstraint<F>) -> Concr...
type RowEvaluator (line 150) | pub struct RowEvaluator<'a, F>
function new (line 161) | pub fn new(row: &'a [F]) -> Self {
function eval_const (line 170) | fn eval_const(&self, c: F) -> F {
function eval_var (line 174) | fn eval_var(&self, algebraic_var: &AlgebraicReference) -> F {
type MappingRowEvaluator (line 180) | pub struct MappingRowEvaluator<'a, F>
function new (line 192) | pub fn new(row: &'a [F], witness_id_to_index: &'a BTreeMap<u64, usize>) ...
function eval_const (line 204) | fn eval_const(&self, c: F) -> F {
function eval_var (line 208) | fn eval_var(&self, algebraic_var: &AlgebraicReference) -> F {
type ConcreteBusInteraction (line 214) | pub struct ConcreteBusInteraction<E, I> {
type ConcreteConstraint (line 220) | pub struct ConcreteConstraint<E> {
type WitnessEvaluator (line 225) | pub struct WitnessEvaluator<'a, V, F, E> {
function new (line 231) | pub fn new(witness: &'a BTreeMap<u64, V>) -> Self {
function eval_const (line 245) | fn eval_const(&self, c: F) -> E {
function eval_var (line 249) | fn eval_var(&self, algebraic_var: &AlgebraicReference) -> E {
FILE: autoprecompiles/src/expression_conversion.rs
function algebraic_to_grouped_expression (line 10) | pub fn algebraic_to_grouped_expression<T, V>(
function grouped_expression_to_algebraic (line 25) | pub fn grouped_expression_to_algebraic<T, V>(
function field_element_to_algebraic_expression (line 81) | fn field_element_to_algebraic_expression<T: FieldElement, V>(v: T) -> Al...
function extract_negation_if_possible (line 91) | fn extract_negation_if_possible<T, V>(
FILE: autoprecompiles/src/lib.rs
type PowdrConfig (line 62) | pub struct PowdrConfig {
method new (line 84) | pub fn new(autoprecompiles: u64, skip_autoprecompiles: u64, degree_bou...
method with_superblocks (line 98) | pub fn with_superblocks(
method with_apc_candidates_dir (line 118) | pub fn with_apc_candidates_dir<P: AsRef<Path>>(mut self, path: P) -> S...
method with_optimistic_precompiles (line 123) | pub fn with_optimistic_precompiles(mut self, should_use_optimistic_pre...
type InstructionKind (line 130) | pub enum InstructionKind {
type VmConfig (line 137) | pub struct VmConfig<'a, M, B, C> {
method clone (line 148) | fn clone(&self) -> Self {
type InstructionHandler (line 157) | pub trait InstructionHandler {
method degree_bound (line 163) | fn degree_bound(&self) -> DegreeBound;
method get_instruction_air_and_id (line 166) | fn get_instruction_air_and_id(
method get_instruction_air_stats (line 172) | fn get_instruction_air_stats(&self, instruction: &Self::Instruction) -...
type Substitution (line 176) | pub struct Substitution {
type Apc (line 184) | pub struct Apc<T, I, A, V> {
function subs (line 196) | pub fn subs(&self) -> &[Vec<Substitution>] {
function machine (line 200) | pub fn machine(&self) -> &SymbolicMachine<T> {
function instructions (line 205) | pub fn instructions(&self) -> impl Iterator<Item = &I> {
function start_pcs (line 210) | pub fn start_pcs(&self) -> Vec<u64> {
function new (line 216) | fn new(
type ColumnAllocator (line 255) | pub struct ColumnAllocator {
method from_max_poly_id_of_machine (line 263) | pub fn from_max_poly_id_of_machine(machine: &SymbolicMachine<impl Fiel...
method issue_next_poly_id (line 270) | pub fn issue_next_poly_id(&mut self) -> u64 {
method is_known_id (line 277) | pub fn is_known_id(&self, poly_id: u64) -> bool {
function build (line 282) | pub fn build<A: Adapter>(
function superblock_pc_constraints (line 393) | fn superblock_pc_constraints<A: Adapter>(
function satisfies_zero_witness (line 415) | fn satisfies_zero_witness<T: FieldElement>(expr: &AlgebraicExpression<T>...
function add_guards_constraint (line 427) | fn add_guards_constraint<T: FieldElement>(
function add_guards (line 456) | fn add_guards<T: FieldElement>(
FILE: autoprecompiles/src/low_degree_bus_interaction_optimizer.rs
type LowDegreeBusInteractionOptimizer (line 21) | pub struct LowDegreeBusInteractionOptimizer<'a, T, V, S, B> {
type LowDegreeReplacement (line 28) | struct LowDegreeReplacement<T: FieldElement, V> {
function new (line 41) | pub fn new(solver: &'a mut S, bus_interaction_handler: B, degree_bound: ...
function optimize (line 50) | pub fn optimize(self, mut system: ConstraintSystem<T, V>) -> ConstraintS...
function try_replace_bus_interaction (line 98) | fn try_replace_bus_interaction(
function symbolic_function_candidates_with_small_domain (line 147) | fn symbolic_function_candidates_with_small_domain(
function has_few_possible_values (line 196) | fn has_few_possible_values(
function find_low_degree_function (line 220) | fn find_low_degree_function(
function concrete_input_output_pairs (line 264) | fn concrete_input_output_pairs<'b>(
type LowDegreeFunction (line 311) | type LowDegreeFunction<T, V> = Box<dyn Fn(Vec<GroupedExpression<T, V>>) ...
constant MAX_DOMAIN_SIZE (line 314) | const MAX_DOMAIN_SIZE: u64 = 256;
type SymbolicField (line 318) | struct SymbolicField<T: FieldElement, V> {
type SymbolicFunction (line 328) | struct SymbolicFunction<T: FieldElement, V> {
function hypotheses (line 334) | fn hypotheses<T: FieldElement, V: Ord + Clone + Hash + Eq>(
type Var (line 387) | pub type Var = &'static str;
function var (line 388) | pub fn var(name: Var) -> GroupedExpression<BabyBearField, Var> {
function constant (line 392) | pub fn constant(value: u64) -> GroupedExpression<BabyBearField, Var> {
type XorBusHandler (line 397) | struct XorBusHandler;
method handle_bus_interaction (line 399) | fn handle_bus_interaction(
method is_stateful (line 427) | fn is_stateful(&self, _bus_id: BabyBearField) -> bool {
method pure_range_constraints (line 432) | fn pure_range_constraints<V: Ord + Clone + Eq + Display + Hash>(
method batch_make_range_constraints (line 439) | fn batch_make_range_constraints<V: Ord + Clone + Eq + Display + Hash>(
function compute_replacement (line 450) | fn compute_replacement(
function test_try_replace_bus_interaction_generic_xor (line 469) | fn test_try_replace_bus_interaction_generic_xor() {
function test_try_replace_bus_interaction_logical_not (line 484) | fn test_try_replace_bus_interaction_logical_not() {
function test_try_replace_bus_interaction_binary_inputs (line 500) | fn test_try_replace_bus_interaction_binary_inputs() {
function test_try_replace_bus_interaction_disjoint_masks (line 517) | fn test_try_replace_bus_interaction_disjoint_masks() {
FILE: autoprecompiles/src/memory_optimizer.rs
function optimize_memory (line 16) | pub fn optimize_memory<
type MemoryOp (line 52) | pub enum MemoryOp {
type MemoryBusInteractionConversionError (line 61) | pub struct MemoryBusInteractionConversionError;
type MemoryBusInteraction (line 67) | pub trait MemoryBusInteraction<T, V>: Sized {
method try_from_bus_interaction (line 81) | fn try_from_bus_interaction(
method addr (line 87) | fn addr(&self) -> Self::Address;
method data (line 90) | fn data(&self) -> &[GroupedExpression<T, V>];
method timestamp_limbs (line 93) | fn timestamp_limbs(&self) -> &[GroupedExpression<T, V>];
method op (line 96) | fn op(&self) -> MemoryOp;
type Address (line 104) | struct Address<T, V>(Vec<GroupedExpression<T, V>>);
function from (line 110) | fn from(exprs: I) -> Self {
type MemoryContent (line 115) | struct MemoryContent<T, V> {
function from_bus_interaction (line 122) | fn from_bus_interaction<M: MemoryBusInteraction<T, V>>(bus_index: usize,...
function redundant_memory_interactions_indices (line 133) | fn redundant_memory_interactions_indices<
FILE: autoprecompiles/src/optimistic/algebraic_references.rs
type BlockCellAlgebraicReferenceMapper (line 6) | pub struct BlockCellAlgebraicReferenceMapper {
method new (line 16) | pub fn new(subs: &[Vec<u64>], columns: impl Iterator<Item = AlgebraicR...
method get_algebraic_reference (line 34) | pub fn get_algebraic_reference(&self, block_cell: &BlockCell) -> Optio...
method has_block_cell (line 38) | pub fn has_block_cell(&self, block_cell: &BlockCell) -> bool {
FILE: autoprecompiles/src/optimistic/config.rs
constant DEFAULT_EXECUTION_COUNT_THRESHOLD (line 1) | const DEFAULT_EXECUTION_COUNT_THRESHOLD: u64 = 100;
constant DEFAULT_MAX_SEGMENTS (line 2) | const DEFAULT_MAX_SEGMENTS: usize = 20;
type OptimisticPrecompileConfig (line 4) | pub struct OptimisticPrecompileConfig {
function optimistic_precompile_config (line 15) | pub fn optimistic_precompile_config() -> OptimisticPrecompileConfig {
FILE: autoprecompiles/src/optimistic/execution_constraint_generator.rs
function generate_execution_constraints (line 14) | pub fn generate_execution_constraints<T: FieldElement>(
function get_optimistic_expression (line 27) | fn get_optimistic_expression<T: FieldElement>(
FILE: autoprecompiles/src/optimistic/execution_literals.rs
function optimistic_literals (line 23) | pub fn optimistic_literals<A: Adapter>(
type ConcreteMemoryAccess (line 53) | struct ConcreteMemoryAccess<T> {
function extract_concrete_memory_accesses (line 64) | fn extract_concrete_memory_accesses<A: Adapter>(
function try_extract_concrete_memory_access (line 105) | fn try_extract_concrete_memory_access<A: Adapter>(
function generate_limb_mapping (line 146) | fn generate_limb_mapping<'a, T: Clone + 'a>(
FILE: autoprecompiles/src/optimizer.rs
function optimize (line 34) | pub fn optimize<T, B, BusTypes, MemoryBus>(
function optimize_exec_bus (line 199) | pub fn optimize_exec_bus<T: FieldElement>(
type Variable (line 253) | pub enum Variable<V> {
method fmt (line 259) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
FILE: autoprecompiles/src/pgo/cell/mod.rs
type ApcCandidate (line 21) | pub trait ApcCandidate<A: Adapter>: Sized {
method create (line 22) | fn create(apc_with_stats: AdapterApcWithStats<A>) -> Self;
method inner (line 23) | fn inner(&self) -> &AdapterApcWithStats<A>;
method into_inner (line 24) | fn into_inner(self) -> AdapterApcWithStats<A>;
method cost_before_opt (line 26) | fn cost_before_opt(&self) -> usize;
method cost_after_opt (line 28) | fn cost_after_opt(&self) -> usize;
method value_per_use (line 30) | fn value_per_use(&self) -> usize;
type ApcCandidateJsonExport (line 36) | pub struct ApcCandidateJsonExport {
type CellPgo (line 53) | pub struct CellPgo<A, C> {
function with_pgo_data_and_max_columns (line 60) | pub fn with_pgo_data_and_max_columns(
constant JSON_EXPORT_VERSION (line 80) | const JSON_EXPORT_VERSION: usize = 4;
type JsonExport (line 83) | struct JsonExport {
method new (line 90) | fn new(apcs: Vec<ApcCandidateJsonExport>, labels: BTreeMap<u64, Vec<St...
type Adapter (line 100) | type Adapter = A;
method create_apcs_with_pgo (line 102) | fn create_apcs_with_pgo(
method execution_profile (line 178) | fn execution_profile(&self) -> Option<&ExecutionProfile> {
function try_generate_candidate (line 184) | fn try_generate_candidate<A: Adapter, C: ApcCandidate<A>>(
function apc_candidate_json_export (line 207) | fn apc_candidate_json_export<A: Adapter, C: ApcCandidate<A>>(
FILE: autoprecompiles/src/pgo/cell/selection.rs
type BlockCandidate (line 14) | pub struct BlockCandidate {
method new (line 28) | pub fn new<A: Adapter, C: ApcCandidate<A>>(
method value (line 41) | pub fn value(&self) -> usize {
method cost (line 47) | pub fn cost(&self) -> usize {
method density (line 51) | pub fn density(&self) -> Density {
type Density (line 61) | pub struct Density {
method eq (line 68) | fn eq(&self, other: &Self) -> bool {
method partial_cmp (line 76) | fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
method cmp (line 83) | fn cmp(&self, other: &Self) -> std::cmp::Ordering {
function count_and_update_run (line 93) | fn count_and_update_run<'a>(
function count_and_update_execution (line 113) | fn count_and_update_execution(
function select_blocks_greedy (line 132) | pub fn select_blocks_greedy<A: Adapter, C: ApcCandidate<A>>(
function sblock (line 193) | fn sblock(start_pcs: Vec<u64>) -> BlockCandidate {
function run (line 203) | fn run(pcs: Vec<u64>) -> ExecutionBasicBlockRun {
function test_count_and_update_run (line 208) | fn test_count_and_update_run() {
FILE: autoprecompiles/src/pgo/instruction.rs
type InstructionPgo (line 12) | pub struct InstructionPgo<A> {
function with_pgo_data (line 18) | pub fn with_pgo_data(data: ExecutionProfile) -> Self {
type Adapter (line 27) | type Adapter = A;
method create_apcs_with_pgo (line 29) | fn create_apcs_with_pgo(
method execution_profile (line 80) | fn execution_profile(&self) -> Option<&ExecutionProfile> {
FILE: autoprecompiles/src/pgo/mod.rs
type PgoConfig (line 25) | pub enum PgoConfig {
method pc_execution_count (line 39) | pub fn pc_execution_count(&self, pc: u64) -> Option<u32> {
type PgoType (line 52) | pub enum PgoType {
function pgo_config (line 62) | pub fn pgo_config(
function create_apcs_for_all_blocks (line 76) | fn create_apcs_for_all_blocks<A: Adapter>(
FILE: autoprecompiles/src/pgo/none.rs
type NonePgo (line 14) | pub struct NonePgo<A> {
type Adapter (line 19) | type Adapter = A;
method create_apcs_with_pgo (line 21) | fn create_apcs_with_pgo(
FILE: autoprecompiles/src/powdr.rs
function make_refs_zero (line 11) | pub fn make_refs_zero<T: FieldElement>(expr: &mut AlgebraicExpression<T>) {
function make_bool (line 20) | pub fn make_bool<T: FieldElement>(expr: AlgebraicExpression<T>) -> Algeb...
function substitute_subexpressions (line 25) | pub fn substitute_subexpressions<T: Clone + std::cmp::Ord>(
type UniqueReferences (line 36) | pub trait UniqueReferences<'a, T: 'a, R> {
method unique_references (line 38) | fn unique_references(&'a self) -> impl Iterator<Item = R>;
method unique_references (line 45) | fn unique_references(&'a self) -> impl Iterator<Item = AlgebraicReferenc...
function globalize_references (line 66) | pub fn globalize_references<T: FieldElement>(
function globalize_reference_names (line 88) | fn globalize_reference_names<T: FieldElement>(
function offset_reference_ids (line 109) | fn offset_reference_ids<T: FieldElement>(
FILE: autoprecompiles/src/range_constraint_optimizer.rs
type RangeConstraints (line 15) | pub type RangeConstraints<T, V> = Vec<(GroupedExpression<T, V>, RangeCon...
type MakeRangeConstraintsError (line 19) | pub struct MakeRangeConstraintsError(pub String);
type RangeConstraintHandler (line 21) | pub trait RangeConstraintHandler<T: FieldElement> {
method pure_range_constraints (line 33) | fn pure_range_constraints<V: Ord + Clone + Eq + Display + Hash>(
method batch_make_range_constraints (line 46) | fn batch_make_range_constraints<V: Ord + Clone + Eq + Display + Hash>(
function optimize_range_constraints (line 58) | pub fn optimize_range_constraints<T: FieldElement, V: Ord + Clone + Hash...
function range_constraint_to_num_bits (line 153) | pub fn range_constraint_to_num_bits<T: FieldElement>(
function filter_byte_constraints (line 163) | pub fn filter_byte_constraints<T: FieldElement, V: Ord + Clone + Eq + Di...
FILE: autoprecompiles/src/stats_logger.rs
type StatsLogger (line 11) | pub struct StatsLogger {
method start (line 17) | pub fn start(system: impl Into<Stats>) -> Self {
method log (line 27) | pub fn log(&mut self, step: &str, system: impl Into<Stats>) {
method finalize (line 35) | pub fn finalize(self, system: impl Into<Stats>) {
type Stats (line 45) | pub struct Stats {
method from (line 62) | fn from(machine: &SymbolicMachine<P>) -> Self {
method from (line 72) | fn from(constraint_system: &ConstraintSystem<P, V>) -> Self {
method from (line 85) | fn from(constraint_system: &IndexedConstraintSystem<P, V>) -> Self {
method fmt (line 52) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
FILE: autoprecompiles/src/symbolic_machine.rs
type SymbolicInstructionStatement (line 21) | pub struct SymbolicInstructionStatement<T> {
type IntoIter (line 27) | type IntoIter = std::iter::Chain<std::iter::Once<T>, std::vec::IntoIter<...
type Item (line 28) | type Item = T;
method into_iter (line 30) | fn into_iter(self) -> Self::IntoIter {
type SymbolicConstraint (line 37) | pub struct SymbolicConstraint<T> {
method fmt (line 42) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function from (line 48) | fn from(expr: AlgebraicExpression<T>) -> Self {
function children (line 61) | fn children(&self) -> Box<dyn Iterator<Item = &AlgebraicExpression<T>> +...
function children_mut (line 65) | fn children_mut(&mut self) -> Box<dyn Iterator<Item = &mut AlgebraicExpr...
type SymbolicBusInteraction (line 71) | pub struct SymbolicBusInteraction<T> {
method fmt (line 78) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function try_multiplicity_to_number (line 90) | pub fn try_multiplicity_to_number(&self) -> Option<T> {
function children (line 99) | fn children(&self) -> Box<dyn Iterator<Item = &AlgebraicExpression<T>> +...
function children_mut (line 103) | fn children_mut(&mut self) -> Box<dyn Iterator<Item = &mut AlgebraicExpr...
type BusInteractionKind (line 109) | pub enum BusInteractionKind {
type SymbolicMachine (line 116) | pub struct SymbolicMachine<T> {
type ComputationMethod (line 126) | type ComputationMethod<T> =
function main_columns (line 130) | pub fn main_columns(&self) -> impl Iterator<Item = AlgebraicReference> +...
function concatenate (line 134) | pub fn concatenate(mut self, other: SymbolicMachine<T>) -> Self {
method fmt (line 143) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function render (line 155) | pub fn render<C: Display + Clone + PartialEq + Eq>(&self, bus_map: &BusM...
function degree (line 196) | pub fn degree(&self) -> usize {
function children (line 202) | fn children(&self) -> Box<dyn Iterator<Item = &AlgebraicExpression<T>> +...
function children_mut (line 211) | fn children_mut(&mut self) -> Box<dyn Iterator<Item = &mut AlgebraicExpr...
function symbolic_machine_to_constraint_system (line 225) | pub fn symbolic_machine_to_constraint_system<P: FieldElement>(
function constraint_system_to_symbolic_machine (line 262) | pub fn constraint_system_to_symbolic_machine<P: FieldElement>(
function symbolic_bus_interaction_to_bus_interaction (line 297) | pub fn symbolic_bus_interaction_to_bus_interaction<P: FieldElement>(
function bus_interaction_to_symbolic_bus_interaction (line 311) | fn bus_interaction_to_symbolic_bus_interaction<P: FieldElement>(
FILE: autoprecompiles/src/symbolic_machine_generator.rs
function convert_apc_field_type (line 16) | pub fn convert_apc_field_type<T, I, A, V, U>(
function convert_machine_field_type (line 29) | pub fn convert_machine_field_type<T, U>(
function convert_symbolic_constraint (line 63) | fn convert_symbolic_constraint<T, U>(
function convert_bus_interaction (line 72) | fn convert_bus_interaction<T, U>(
function convert_expression (line 87) | fn convert_expression<T, U>(
function statements_to_symbolic_machine (line 118) | pub(crate) fn statements_to_symbolic_machine<A: Adapter>(
function statements_to_symbolic_machines (line 134) | pub(crate) fn statements_to_symbolic_machines<A: Adapter>(
function exec_receive (line 207) | fn exec_receive<T: FieldElement>(
FILE: autoprecompiles/src/trace_handler.rs
type OriginalRowReference (line 12) | pub struct OriginalRowReference<'a, D> {
type TraceData (line 18) | pub struct TraceData<'a, F, D> {
type TraceTrait (line 31) | pub trait TraceTrait<F>: Send + Sync {
method width (line 34) | fn width(&self) -> usize;
method values (line 36) | fn values(&self) -> &Self::Values;
function generate_trace (line 40) | pub fn generate_trace<'a, IH, M: TraceTrait<IH::Field>, A, V>(
FILE: autoprecompiles/tests/optimizer.rs
constant DEFAULT_DEGREE_BOUND (line 16) | const DEFAULT_DEGREE_BOUND: DegreeBound = DegreeBound {
type TestApc (line 21) | type TestApc = Apc<BabyBearField, SimpleInstruction<BabyBearField>, (), ...
function import_apc_from_gzipped_json (line 23) | fn import_apc_from_gzipped_json(file: &str) -> ApcWithBusMap<TestApc, Bu...
function load_machine_json (line 30) | fn load_machine_json() {
function test_optimize (line 50) | fn test_optimize() {
function test_ecrecover (line 85) | fn test_ecrecover() {
function test_sha256 (line 120) | fn test_sha256() {
function test_single_div_nondet (line 155) | fn test_single_div_nondet() {
function test_optimize_reth_op (line 212) | fn test_optimize_reth_op() {
FILE: cli-openvm-riscv/src/main.rs
type Cli (line 26) | struct Cli {
type SharedArgs (line 32) | struct SharedArgs {
type Commands (line 73) | enum Commands {
function main (line 110) | fn main() -> Result<(), io::Error> {
function build_powdr_config (line 123) | fn build_powdr_config(shared: &SharedArgs) -> PowdrConfig {
function run_command (line 138) | fn run_command(command: Commands) {
function write_program_to_file (line 264) | fn write_program_to_file(
function validate_shared_args (line 275) | fn validate_shared_args(args: &SharedArgs) {
function stdin_from (line 286) | fn stdin_from(input: Option<u32>) -> StdIn {
function setup_tracing_with_log_level (line 294) | fn setup_tracing_with_log_level(level: Level) {
function run_with_metric_collection_to_file (line 307) | pub fn run_with_metric_collection_to_file<R>(file: std::fs::File, f: imp...
function maybe_compute_empirical_constraints (line 321) | fn maybe_compute_empirical_constraints(
FILE: constraint-solver/src/algebraic_constraint/mod.rs
type AlgebraicConstraint (line 16) | pub struct AlgebraicConstraint<V> {
function from (line 23) | fn from(expression: V) -> Self {
function assert_zero (line 30) | pub fn assert_zero(expression: V) -> Self {
function as_ref (line 35) | pub fn as_ref(&self) -> AlgebraicConstraint<&V> {
function cloned (line 43) | pub(crate) fn cloned(&self) -> AlgebraicConstraint<V> {
function assert_eq (line 52) | pub fn assert_eq(expression: GroupedExpression<T, V>, other: GroupedExpr...
function assert_bool (line 57) | pub fn assert_bool(expression: GroupedExpression<T, V>) -> Self {
function is_redundant (line 63) | pub fn is_redundant(&self) -> bool {
function substitute_by_known (line 73) | pub fn substitute_by_known(&mut self, variable: &V, substitution: &T) {
function degree (line 77) | pub fn degree(&self) -> usize {
method fmt (line 83) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function referenced_unknown_variables (line 90) | pub fn referenced_unknown_variables(&self) -> Box<dyn Iterator<Item = &V...
function referenced_unknown_variables (line 97) | pub fn referenced_unknown_variables(&self) -> Box<dyn Iterator<Item = &V...
FILE: constraint-solver/src/algebraic_constraint/solve.rs
type ProcessResult (line 16) | pub struct ProcessResult<T: FieldElement, V> {
function empty (line 22) | pub fn empty() -> Self {
function complete (line 28) | pub fn complete(effects: Vec<Effect<T, V>>) -> Self {
type Error (line 37) | pub enum Error {
function solve (line 55) | pub fn solve(
function try_solve_for (line 91) | pub fn try_solve_for(&self, variable: &V) -> Option<GroupedExpression<T,...
function try_solve_for_expr (line 112) | pub fn try_solve_for_expr(
function solve_affine (line 161) | fn solve_affine(
function transfer_constraints (line 210) | fn transfer_constraints(
function solve_quadratic (line 228) | fn solve_quadratic(
function combine_to_conditional_assignment (line 266) | fn combine_to_conditional_assignment<T: FieldElement, V: Ord + Clone + E...
function effect_to_range_constraint (line 316) | fn effect_to_range_constraint<T: FieldElement, V: Ord + Clone + Eq>(
function combine_range_constraints (line 329) | fn combine_range_constraints<T: FieldElement, V: Ord + Clone + Eq + Hash...
function assignment_if_satisfies_range_constraints (line 377) | fn assignment_if_satisfies_range_constraints<T: FieldElement, V: Ord + C...
type Qse (line 400) | type Qse = GroupedExpression<GoldilocksField, &'static str>;
function var (line 402) | fn var(name: &'static str) -> Qse {
function constant (line 406) | fn constant(value: u64) -> Qse {
function unsolvable (line 411) | fn unsolvable() {
function solvable_without_vars (line 418) | fn solvable_without_vars() {
function solve_simple_eq (line 427) | fn solve_simple_eq() {
function solve_constraint_transfer (line 454) | fn solve_constraint_transfer() {
function unpack_range_constraint (line 488) | fn unpack_range_constraint(
function detect_bit_constraint (line 501) | fn detect_bit_constraint() {
function detect_complete_range_constraint (line 526) | fn detect_complete_range_constraint() {
function detect_incomplete_range_constraint (line 549) | fn detect_incomplete_range_constraint() {
function bool_plus_one_cant_be_zero (line 574) | fn bool_plus_one_cant_be_zero() {
function solve_for (line 584) | fn solve_for() {
function solve_for_expr (line 600) | fn solve_for_expr() {
function solve_for_expr_normalization (line 645) | fn solve_for_expr_normalization() {
FILE: constraint-solver/src/bus_interaction_handler.rs
type ViolatesBusRules (line 8) | pub struct ViolatesBusRules {}
type BusInteractionHandler (line 11) | pub trait BusInteractionHandler<T: FieldElement> {
method handle_bus_interaction (line 22) | fn handle_bus_interaction(
method handle_bus_interaction_checked (line 29) | fn handle_bus_interaction_checked(
type DefaultBusInteractionHandler (line 53) | pub struct DefaultBusInteractionHandler<T: FieldElement> {
function handle_bus_interaction (line 58) | fn handle_bus_interaction(
FILE: constraint-solver/src/constraint_system.rs
type ConstraintSystem (line 21) | pub struct ConstraintSystem<T, V> {
method fmt (line 34) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function referenced_unknown_variables (line 61) | pub fn referenced_unknown_variables(&self) -> impl Iterator<Item = &V> {
function extend (line 74) | pub fn extend(&mut self, system: ConstraintSystem<T, V>) {
type DerivedVariable (line 83) | pub struct DerivedVariable<T, V, E> {
function new (line 89) | pub fn new(variable: V, computation_method: ComputationMethod<T, E>) -> ...
method serialize (line 102) | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
function deserialize (line 115) | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
type ComputationMethod (line 131) | pub enum ComputationMethod<T, E> {
method fmt (line 140) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function referenced_unknown_variables (line 150) | pub fn referenced_unknown_variables(&self) -> Box<dyn Iterator<Item = &F...
function substitute_by_known (line 166) | pub fn substitute_by_known(&mut self, variable: &V, substitution: &T) {
function substitute_by_unknown (line 180) | pub fn substitute_by_unknown(&mut self, variable: &V, substitution: &Gro...
type BusInteraction (line 193) | pub struct BusInteraction<V> {
function fields (line 207) | pub fn fields(&self) -> impl Iterator<Item = &V> {
function fields_mut (line 215) | pub fn fields_mut(&mut self) -> impl Iterator<Item = &mut V> {
method fmt (line 225) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function from_iter (line 237) | fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
function to_range_constraints (line 253) | pub fn to_range_constraints(
function solve (line 271) | pub fn solve(
function referenced_unknown_variables (line 305) | pub fn referenced_unknown_variables(&self) -> Box<dyn Iterator<Item = &V...
type ConstraintRef (line 314) | pub enum ConstraintRef<'a, T, V> {
function referenced_unknown_variables (line 320) | pub fn referenced_unknown_variables(&self) -> Box<dyn Iterator<Item = &V...
FILE: constraint-solver/src/effect.rs
type Effect (line 5) | pub enum Effect<T: RuntimeConstant, V> {
type Assertion (line 23) | pub struct Assertion<T: RuntimeConstant> {
function assert_is_zero (line 32) | pub fn assert_is_zero<V>(condition: T) -> Effect<T, V> {
function assert_is_nonzero (line 35) | pub fn assert_is_nonzero<V>(condition: T) -> Effect<T, V> {
function assert_eq (line 38) | pub fn assert_eq<V>(lhs: T, rhs: T) -> Effect<T, V> {
function assert_neq (line 45) | pub fn assert_neq<V>(lhs: T, rhs: T) -> Effect<T, V> {
type Condition (line 55) | pub struct Condition<T: RuntimeConstant> {
FILE: constraint-solver/src/grouped_expression.rs
constant MAX_SUM_SIZE_FOR_QUADRATIC_ANALYSIS (line 21) | const MAX_SUM_SIZE_FOR_QUADRATIC_ANALYSIS: usize = 20;
type GroupedExpression (line 37) | pub struct GroupedExpression<T, V> {
type GroupedExpressionComponent (line 50) | pub enum GroupedExpressionComponent<T, V> {
function from (line 65) | fn from(s: GroupedExpressionComponent<T, V>) -> Self {
function from_number (line 87) | pub fn from_number(k: F) -> Self {
method zero (line 97) | fn zero() -> Self {
method is_zero (line 105) | fn is_zero(&self) -> bool {
method one (line 111) | fn one() -> Self {
method is_one (line 119) | fn is_one(&self) -> bool {
function from_known_symbol (line 125) | pub fn from_known_symbol(symbol: V, rc: RangeConstraint<F>) -> Self {
function from_runtime_constant (line 131) | pub fn from_runtime_constant(constant: T) -> Self {
function from_unknown_variable (line 139) | pub fn from_unknown_variable(var: V) -> Self {
function try_to_known (line 148) | pub fn try_to_known(&self) -> Option<&T> {
function is_affine (line 157) | pub fn is_affine(&self) -> bool {
function try_to_number (line 162) | pub fn try_to_number(&self) -> Option<T::FieldType> {
function try_to_simple_unknown (line 167) | pub fn try_to_simple_unknown(&self) -> Option<V> {
function is_quadratic (line 181) | pub fn is_quadratic(&self) -> bool {
function try_as_single_product (line 186) | pub fn try_as_single_product(&self) -> Option<(&Self, &Self)> {
function to_factors (line 201) | pub fn to_factors(&self) -> Vec<Self> {
function try_split_head_tail (line 237) | pub fn try_split_head_tail(mut self) -> Option<(Self, Self)> {
function linear_components (line 257) | pub fn linear_components(
function constant_offset (line 265) | pub fn constant_offset(&self) -> &T {
function quadratic_components (line 270) | pub fn quadratic_components(&self) -> &[(Self, Self)] {
function into_summands (line 275) | pub fn into_summands(self) -> impl Iterator<Item = GroupedExpressionComp...
function degree (line 294) | pub fn degree(&self) -> usize {
function degree_of_variable (line 305) | pub fn degree_of_variable(&self, var: &V) -> usize {
function coefficient_of_variable_in_affine_part (line 321) | pub fn coefficient_of_variable_in_affine_part<'a>(&'a self, var: &V) -> ...
function try_extract_affine_var (line 330) | pub fn try_extract_affine_var(&self, var: V) -> Option<(T, Self)> {
function range_constraint (line 346) | pub fn range_constraint(
function substitute_simple (line 372) | pub fn substitute_simple(&mut self, variable: &V, substitution: T) {
function substitute_by_known (line 412) | pub fn substitute_by_known(&mut self, variable: &V, substitution: &T) {
function substitute_by_unknown (line 463) | pub fn substitute_by_unknown(&mut self, variable: &V, substitution: &Gro...
function referenced_unknown_variables (line 507) | pub fn referenced_unknown_variables(&self) -> Box<dyn Iterator<Item = &V...
type Transformed (line 519) | type Transformed = GroupedExpression<T::Transformed, V2>;
function try_transform_var_type (line 521) | fn try_transform_var_type(
type RangeConstraintProvider (line 549) | pub trait RangeConstraintProvider<T: FieldElement, V> {
method get (line 550) | fn get(&self, var: &V) -> RangeConstraint<T>;
function get (line 554) | fn get(&self, var: &V) -> RangeConstraint<T> {
function get (line 562) | fn get(&self, var: &V) -> RangeConstraint<T> {
type NoRangeConstraints (line 568) | pub struct NoRangeConstraints;
method get (line 570) | fn get(&self, _var: &V) -> RangeConstraint<T> {
type Output (line 576) | type Output = GroupedExpression<T, V>;
method add (line 578) | fn add(mut self, rhs: Self) -> Self {
type Output (line 585) | type Output = GroupedExpression<T, V>;
method add (line 587) | fn add(self, rhs: Self) -> Self::Output {
function add_assign (line 595) | fn add_assign(&mut self, rhs: Self) {
function combine_removing_zeros (line 610) | fn combine_removing_zeros<E: PartialEq>(first: Vec<(E, E)>, mut second: ...
function remove_quadratic_terms_adding_to_zero (line 640) | fn remove_quadratic_terms_adding_to_zero<E: PartialEq>(terms: &mut Vec<(...
function quadratic_terms_add_to_zero (line 673) | fn quadratic_terms_add_to_zero<E: PartialEq>(first: &(E, E), second: &(E...
type Output (line 686) | type Output = GroupedExpression<T, V>;
method sub (line 688) | fn sub(self, rhs: Self) -> Self::Output {
type Output (line 694) | type Output = GroupedExpression<T, V>;
method sub (line 696) | fn sub(self, rhs: Self) -> Self::Output {
function negate (line 702) | fn negate(&mut self) {
type Output (line 714) | type Output = GroupedExpression<T, V>;
method neg (line 716) | fn neg(mut self) -> Self {
type Output (line 723) | type Output = GroupedExpression<T, V>;
method neg (line 725) | fn neg(self) -> Self::Output {
type Output (line 732) | type Output = GroupedExpression<T, V>;
function mul (line 734) | fn mul(mut self, rhs: &T) -> Self {
type Output (line 741) | type Output = GroupedExpression<T, V>;
function mul (line 743) | fn mul(self, rhs: T) -> Self {
function mul_assign (line 749) | fn mul_assign(&mut self, rhs: &T) {
method sum (line 765) | fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
type Output (line 774) | type Output = GroupedExpression<T, V>;
method mul (line 776) | fn mul(self, rhs: GroupedExpression<T, V>) -> Self {
method fmt (line 792) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function to_signed_string (line 803) | fn to_signed_string(&self) -> (bool, String) {
function symbolic_expression_to_signed_string (line 840) | fn symbolic_expression_to_signed_string(value: &T) -> (bool, String) {
method serialize (line 857) | fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Er...
type SumSerializer (line 868) | struct SumSerializer<'a, I> {
function new (line 873) | pub fn new(items: &'a [I]) -> Self {
method serialize (line 880) | fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Er...
method serialize (line 893) | fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Er...
type Qse (line 924) | type Qse = GroupedExpression<SymbolicExpression<GoldilocksField, &'stati...
function test_mul (line 927) | fn test_mul() {
function test_add (line 936) | fn test_add() {
function test_mul_by_known (line 950) | fn test_mul_by_known() {
function test_mul_by_zero (line 960) | fn test_mul_by_zero() {
function test_apply_update (line 971) | fn test_apply_update() {
function test_apply_update_inner_zero (line 999) | fn test_apply_update_inner_zero() {
function substitute_known (line 1019) | fn substitute_known() {
function test_substitute_by_unknown_basic_replacement (line 1041) | fn test_substitute_by_unknown_basic_replacement() {
function test_substitute_by_unknown_linear_to_quadratic (line 1050) | fn test_substitute_by_unknown_linear_to_quadratic() {
function test_substitute_by_unknown_inside_quadratic (line 1060) | fn test_substitute_by_unknown_inside_quadratic() {
function test_substitute_by_unknown_linear (line 1070) | fn test_substitute_by_unknown_linear() {
function test_complex_expression_multiple_substitution (line 1081) | fn test_complex_expression_multiple_substitution() {
function test_substitute_by_unknown_coeff_distribution (line 1126) | fn test_substitute_by_unknown_coeff_distribution() {
function combine_removing_zeros (line 1148) | fn combine_removing_zeros() {
function remove_quadratic_zeros_after_substitution (line 1159) | fn remove_quadratic_zeros_after_substitution() {
function to_factors (line 1174) | fn to_factors() {
function rc_of_square (line 1190) | fn rc_of_square() {
function serialize_sum (line 1207) | fn serialize_sum() {
function serialize_grouped_expression (line 1218) | fn serialize_grouped_expression() {
function serialize_zero (line 1228) | fn serialize_zero() {
FILE: constraint-solver/src/indexed_constraint_system.rs
function apply_substitutions (line 21) | pub fn apply_substitutions<T: RuntimeConstant + Substitutable<V>, V: Has...
function apply_substitutions_to_expressions (line 31) | pub fn apply_substitutions_to_expressions<
type IndexedConstraintSystem (line 59) | pub struct IndexedConstraintSystem<T, V> {
type IndexedConstraintSystemWithQueue (line 76) | pub struct IndexedConstraintSystemWithQueue<T, V> {
type ConstraintSystemItem (line 83) | enum ConstraintSystemItem {
method flat_constraint_id (line 96) | fn flat_constraint_id(&self) -> usize {
method index (line 106) | fn index(&self) -> usize {
method is_derived_variable (line 115) | fn is_derived_variable(&self) -> bool {
method try_to_constraint_ref (line 121) | fn try_to_constraint_ref<'a, T, V>(
function from (line 142) | fn from(constraint_system: ConstraintSystem<T, V>) -> Self {
function from (line 154) | fn from(indexed_constraint_system: IndexedConstraintSystem<T, V>) -> Self {
function system (line 160) | pub fn system(&self) -> &ConstraintSystem<T, V> {
function algebraic_constraints (line 164) | pub fn algebraic_constraints(&self) -> &[AlgebraicConstraint<GroupedExpr...
function bus_interactions (line 168) | pub fn bus_interactions(&self) -> &[BusInteraction<GroupedExpression<T, ...
function variables (line 176) | pub fn variables(&self) -> impl Iterator<Item = &V> {
function referenced_unknown_variables (line 182) | pub fn referenced_unknown_variables(&self) -> impl Iterator<Item = &V> {
function retain_algebraic_constraints (line 187) | pub fn retain_algebraic_constraints(
function retain_bus_interactions (line 200) | pub fn retain_bus_interactions(
function retain_derived_variables (line 213) | pub fn retain_derived_variables(
function retain (line 230) | fn retain<V, Item>(
function add_algebraic_constraints (line 273) | pub fn add_algebraic_constraints(
function add_bus_interactions (line 285) | pub fn add_bus_interactions(
function extend (line 297) | pub fn extend(&mut self, system: ConstraintSystem<T, V>) {
function constraints_referencing_variables (line 328) | pub fn constraints_referencing_variables<'a>(
function substitute_by_known (line 345) | pub fn substitute_by_known(&mut self, variable: &V, substitution: &T) {
function substitute_by_unknown (line 363) | pub fn substitute_by_unknown(&mut self, variable: &V, substitution: &Gro...
function apply_substitutions (line 389) | pub fn apply_substitutions(
function variable_occurrences (line 402) | fn variable_occurrences<T: RuntimeConstant, V: Hash + Eq + Clone>(
function substitute_by_known_in_item (line 453) | fn substitute_by_known_in_item<T: RuntimeConstant + Substitutable<V>, V:...
function substitute_by_unknown_in_item (line 476) | fn substitute_by_unknown_in_item<T: RuntimeConstant + Substitutable<V>, ...
method fmt (line 502) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function from (line 510) | fn from(constraint_system: C) -> Self {
function system (line 526) | pub fn system(&self) -> &IndexedConstraintSystem<T, V> {
function pop_front (line 531) | pub fn pop_front<'a>(&'a mut self) -> Option<ConstraintRef<'a, T, V>> {
function variable_updated (line 543) | pub fn variable_updated(&mut self, variable: &V) {
function substitute_by_unknown (line 558) | pub fn substitute_by_unknown(&mut self, variable: &V, substitution: &Gro...
function add_algebraic_constraints (line 564) | pub fn add_algebraic_constraints(
function add_bus_interactions (line 581) | pub fn add_bus_interactions(
function retain_algebraic_constraints (line 598) | pub fn retain_algebraic_constraints(
function retain_bus_interactions (line 610) | pub fn retain_bus_interactions(
method fmt (line 626) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type ConstraintSystemQueue (line 636) | struct ConstraintSystemQueue {
method new (line 642) | fn new<T, V>(constraint_system: &ConstraintSystem<T, V>) -> Self {
method push (line 659) | fn push(&mut self, item: ConstraintSystemItem) {
method pop_front (line 670) | fn pop_front(&mut self) -> Option<ConstraintSystemItem> {
function format_system (line 687) | fn format_system(s: &IndexedConstraintSystem<GoldilocksField, &'static s...
function substitute_by_unknown (line 708) | fn substitute_by_unknown() {
function retain_update_index (line 745) | fn retain_update_index() {
function substitute_in_derived_columns (line 813) | fn substitute_in_derived_columns() {
FILE: constraint-solver/src/inliner.rs
type DegreeBound (line 14) | pub struct DegreeBound {
function replace_constrained_witness_columns (line 22) | pub fn replace_constrained_witness_columns<
function inline_everything_below_degree_bound (line 77) | pub fn inline_everything_below_degree_bound<T: FieldElement, V: Ord + Cl...
function substitution_would_not_violate_degree_bound (line 87) | pub fn substitution_would_not_violate_degree_bound<T: FieldElement, V: O...
function find_inlinable_variables (line 115) | fn find_inlinable_variables<T: FieldElement, V: Ord + Clone + Hash + Eq ...
function expression_degree_with_virtual_substitution (line 132) | fn expression_degree_with_virtual_substitution<T: FieldElement, V: Ord +...
function var (line 159) | pub fn var(name: &'static str) -> GroupedExpression<GoldilocksField, &'s...
function constant (line 163) | pub fn constant(value: u64) -> GroupedExpression<GoldilocksField, &'stat...
function bounds (line 167) | fn bounds<T: FieldElement, V: Ord + Clone + Hash + Eq>(
function test_no_substitution (line 178) | fn test_no_substitution() {
function test_replace_witness_columns (line 192) | fn test_replace_witness_columns() {
function test_replace_witness_columns_with_multiplication (line 233) | fn test_replace_witness_columns_with_multiplication() {
function test_replace_witness_columns_no_keep (line 269) | fn test_replace_witness_columns_no_keep() {
function test_replace_constrained_witness_suboptimal (line 302) | fn test_replace_constrained_witness_suboptimal() {
function test_replace_constrained_witness_columns_max_degree_limit (line 336) | fn test_replace_constrained_witness_columns_max_degree_limit() {
function test_inline_max_degree_suboptimal_greedy (line 396) | fn test_inline_max_degree_suboptimal_greedy() {
FILE: constraint-solver/src/range_constraint.rs
type RangeConstraint (line 39) | pub struct RangeConstraint<T: FieldElement> {
function from_max_bit (line 52) | pub fn from_max_bit(max_bit: usize) -> Self {
function from_mask (line 58) | pub fn from_mask<M: Into<T::Integer>>(mask: M) -> Self {
function from_value (line 69) | pub fn from_value(value: T) -> Self {
function from_range (line 83) | pub fn from_range(min: T, max: T) -> Self {
function unconstrained (line 93) | pub fn unconstrained() -> Self {
function is_unconstrained (line 99) | pub fn is_unconstrained(&self) -> bool {
function mask (line 107) | pub fn mask(&self) -> &T::Integer {
function range (line 116) | pub fn range(&self) -> (T, T) {
function range_width (line 122) | pub fn range_width(&self) -> T::Integer {
function size_estimate (line 127) | pub fn size_estimate(&self) -> T::Integer {
function allows_value (line 131) | pub fn allows_value(&self, v: T) -> bool {
function combine_sum (line 144) | pub fn combine_sum(&self, other: &Self) -> Self {
function combine_product (line 174) | pub fn combine_product(&self, other: &Self) -> Self {
function square (line 192) | pub fn square(&self) -> Self {
function conjunction (line 213) | pub fn conjunction(&self, other: &Self) -> Self {
function disjunction (line 252) | pub fn disjunction(&self, other: &Self) -> Self {
function multiple (line 280) | pub fn multiple(&self, factor: T) -> Self {
function try_to_single_value (line 298) | pub fn try_to_single_value(&self) -> Option<T> {
function is_disjoint (line 308) | pub fn is_disjoint(&self, other: &RangeConstraint<T>) -> bool {
function allowed_values (line 322) | pub fn allowed_values(&self) -> impl Iterator<Item = T> + '_ {
method default (line 330) | fn default() -> Self {
function range_width (line 337) | fn range_width<T: FieldElement>(min: T, max: T) -> T::Integer {
function mask_from_bits (line 346) | fn mask_from_bits<T: FieldElement>(bits: usize) -> T::Integer {
function range_multiple (line 361) | fn range_multiple<T: FieldElement>(min: T, max: T, factor: T) -> (T, T) {
function interval_intersection (line 379) | fn interval_intersection<T: FieldElement>(a: (T, T), b: (T, T)) -> Optio...
function shifted_interval (line 410) | fn shifted_interval<T: FieldElement>((min, max): (T, T), shift: T) -> (T...
type Output (line 415) | type Output = Self;
function neg (line 417) | fn neg(self) -> Self::Output {
method fmt (line 424) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function format_negated (line 435) | fn format_negated<T: FieldElement>(value: T) -> String {
type RCg (line 451) | type RCg = RangeConstraint<GoldilocksField>;
function from_max_bit (line 454) | fn from_max_bit() {
function from_value (line 461) | fn from_value() {
function from_range (line 473) | fn from_range() {
function range_width (line 493) | fn range_width() {
function combine_sum (line 512) | fn combine_sum() {
function combine_sum_around_modulus (line 546) | fn combine_sum_around_modulus() {
function mul_add (line 590) | fn mul_add() {
function multiple_negative (line 603) | fn multiple_negative() {
function multiple_overflow (line 612) | fn multiple_overflow() {
function combinations (line 646) | fn combinations() {
function weird_combinations (line 655) | fn weird_combinations() {
function interval_intersections (line 663) | fn interval_intersections() {
function allows_value (line 752) | fn allows_value() {
function conjunction (line 769) | fn conjunction() {
function disjunction (line 797) | fn disjunction() {
function disjunction_combinations (line 811) | fn disjunction_combinations() {
function is_disjoint (line 837) | fn is_disjoint() {
function is_unconstrained (line 861) | fn is_unconstrained() {
FILE: constraint-solver/src/reachability.rs
function reachable_variables (line 13) | pub fn reachable_variables<T, V>(
function reachable_variables_except_blocked (line 30) | pub fn reachable_variables_except_blocked<T, V>(
FILE: constraint-solver/src/rule_based_optimizer/driver.rs
type VariableAssignment (line 28) | pub type VariableAssignment<T, V> = (V, GroupedExpression<T, V>);
function rule_based_optimization (line 40) | pub fn rule_based_optimization<T: FieldElement, V: Hash + Eq + Ord + Clo...
function undo_variable_transform_and_recreate_new_variables (line 255) | fn undo_variable_transform_and_recreate_new_variables<
type ReplacementAction (line 294) | pub(crate) struct ReplacementAction<T, V> {
function new (line 303) | fn new(
function is_replacement_within_degree_bound (line 322) | fn is_replacement_within_degree_bound<T: FieldElement, V: Hash + Eq + Or...
function batch_replace_algebraic_constraints (line 355) | pub(crate) fn batch_replace_algebraic_constraints<
function transform_constraint_system (line 454) | fn transform_constraint_system<T: FieldElement, V: Hash + Eq + Ord + Clo...
function transform_variables (line 482) | fn transform_variables<T: FieldElement, V: Hash + Eq + Ord + Clone + Dis...
function undo_variable_transform (line 490) | fn undo_variable_transform<T: FieldElement, V: Hash + Eq + Ord + Clone +...
function undo_variable_transform_in_computation_method (line 498) | fn undo_variable_transform_in_computation_method<
FILE: constraint-solver/src/rule_based_optimizer/environment.rs
type Environment (line 26) | pub struct Environment<T: FieldElement> {
method eq (line 37) | fn eq(&self, _other: &Self) -> bool {
method partial_cmp (line 46) | fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
method cmp (line 53) | fn cmp(&self, _other: &Self) -> std::cmp::Ordering {
method hash (line 60) | fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
function new (line 67) | pub fn new(
function terminate (line 82) | pub fn terminate(self) -> (ItemDB<GroupedExpression<T, Var>, Expr>, NewV...
function insert (line 92) | pub fn insert(&self, expr: &GroupedExpression<T, Var>) -> Expr {
function insert_owned (line 100) | pub fn insert_owned(&self, expr: GroupedExpression<T, Var>) -> Expr {
function extract (line 106) | pub fn extract(&self, expr: Expr) -> GroupedExpression<T, Var> {
function new_var (line 110) | pub fn new_var(
function single_occurrence_variables (line 118) | pub fn single_occurrence_variables(&self) -> impl Iterator<Item = &Var> {
function try_split_into_head_tail (line 123) | pub fn try_split_into_head_tail(&self, expr: Expr) -> Option<(Expr, Expr...
function affine_var_count (line 134) | pub fn affine_var_count(&self, expr: Expr) -> Option<usize> {
function try_to_affine (line 142) | pub fn try_to_affine(&self, expr: Expr) -> Option<(T, Var, T)> {
function try_to_number (line 152) | pub fn try_to_number(&self, expr: Expr) -> Option<T> {
function on_expr (line 162) | pub fn on_expr<Args, Ret>(
function try_as_single_product (line 174) | pub fn try_as_single_product(&self, expr: Expr) -> Option<(Expr, Expr)> {
function differ_in_exactly_one_variable (line 188) | pub fn differ_in_exactly_one_variable(&self, a_id: Expr, b_id: Expr) -> ...
function substitute_by_known (line 234) | pub fn substitute_by_known(&self, e: Expr, var: Var, value: T) -> Expr {
function substitute_by_var (line 248) | pub fn substitute_by_var(&self, e: Expr, var: Var, replacement: Var) -> ...
function format_expr (line 262) | pub fn format_expr(&self, expr: Expr) -> String {
function format_var (line 270) | pub fn format_var(&self, var: Var) -> String {
FILE: constraint-solver/src/rule_based_optimizer/item_db.rs
type ItemDB (line 13) | pub struct ItemDB<Item, Ident> {
function from_iter (line 23) | fn from_iter<T: IntoIterator<Item = Item>>(iter: T) -> Self {
type Output (line 42) | type Output = Item;
function index (line 43) | fn index(&self, index: Ident) -> &Self::Output {
function insert_owned_new (line 53) | fn insert_owned_new(&mut self, item: Item) -> Ident {
function insert (line 63) | pub fn insert(&mut self, item: &Item) -> Ident {
function insert_owned (line 73) | pub fn insert_owned(&mut self, item: Item) -> Ident {
function id (line 81) | pub fn id(&self, item: &Item) -> Ident {
function iter (line 85) | pub fn iter(&self) -> impl Iterator<Item = (Ident, &Item)> {
function next_free_id (line 93) | pub fn next_free_id(&self) -> usize {
FILE: constraint-solver/src/rule_based_optimizer/new_var_generator.rs
type NewVarRequest (line 10) | pub struct NewVarRequest<T> {
type NewVarGenerator (line 19) | pub struct NewVarGenerator<T> {
function new (line 25) | pub fn new(initial_counter: usize) -> Self {
function generate (line 32) | pub fn generate(
function requests (line 50) | pub fn requests(self) -> HashMap<Var, NewVarRequest<T>> {
FILE: constraint-solver/src/rule_based_optimizer/rules.rs
function extend_by_none (line 710) | fn extend_by_none<const N1: usize, const N2: usize>(items: [Expr; N1]) -...
FILE: constraint-solver/src/rule_based_optimizer/tests.rs
function assert_zero (line 21) | fn assert_zero<T: FieldElement, V: Hash + Eq + Ord + Clone + Display>(
function v (line 27) | fn v(name: &str) -> GroupedExpression<BabyBearField, String> {
function c (line 31) | fn c(value: i64) -> GroupedExpression<BabyBearField, String> {
function new_var (line 35) | fn new_var() -> impl FnMut(&str) -> String {
function handle_variable_range_checker (line 44) | fn handle_variable_range_checker<T: FieldElement>(
function try_handle_bus_interaction (line 68) | fn try_handle_bus_interaction<T: FieldElement>(
type TestBusInteractionHandler (line 92) | struct TestBusInteractionHandler;
method handle_bus_interaction (line 95) | fn handle_bus_interaction(
function bit_constraint (line 104) | fn bit_constraint(
function test_rule_based_optimization_empty (line 116) | fn test_rule_based_optimization_empty() {
function test_rule_based_optimization_simple_assignment (line 129) | fn test_rule_based_optimization_simple_assignment() {
function add_with_carry (line 147) | fn add_with_carry() {
function test_rule_based_optimization_quadratic_equality (line 179) | fn test_rule_based_optimization_quadratic_equality() {
function test_batch_replace_with_duplicate_constraints (line 231) | fn test_batch_replace_with_duplicate_constraints() {
function test_batch_replace_with_duplicate_constraints2 (line 269) | fn test_batch_replace_with_duplicate_constraints2() {
function test_batch_replace_with_duplicate_constraints3 (line 298) | fn test_batch_replace_with_duplicate_constraints3() {
function test_batch_replace_with_conflict (line 331) | fn test_batch_replace_with_conflict() {
function test_rule_split_constraints_based_on_minimal_range (line 394) | fn test_rule_split_constraints_based_on_minimal_range() {
function one_hot_flags (line 431) | fn one_hot_flags() {
FILE: constraint-solver/src/rule_based_optimizer/types.rs
type Var (line 9) | pub struct Var(usize);
method fmt (line 12) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type Expr (line 18) | pub struct Expr(usize);
type Action (line 21) | pub enum Action<T: FieldElement> {
type ReplaceConstraintsAction (line 35) | pub struct ReplaceConstraintsAction {
FILE: constraint-solver/src/runtime_constant.rs
type RuntimeConstant (line 13) | pub trait RuntimeConstant:
method try_to_number (line 31) | fn try_to_number(&self) -> Option<Self::FieldType>;
method range_constraint (line 35) | fn range_constraint(&self) -> RangeConstraint<Self::FieldType>;
method field_div (line 38) | fn field_div(&self, other: &Self) -> Self {
method field_inverse (line 43) | fn field_inverse(&self) -> Self;
method from_u64 (line 46) | fn from_u64(k: u64) -> Self {
method is_known_zero (line 51) | fn is_known_zero(&self) -> bool {
method is_known_one (line 56) | fn is_known_one(&self) -> bool {
method is_known_minus_one (line 61) | fn is_known_minus_one(&self) -> bool {
method is_known_nonzero (line 69) | fn is_known_nonzero(&self) -> bool {
type FieldType (line 100) | type FieldType = T;
method try_to_number (line 102) | fn try_to_number(&self) -> Option<Self> {
method range_constraint (line 106) | fn range_constraint(&self) -> RangeConstraint<Self::FieldType> {
method field_div (line 110) | fn field_div(&self, other: &Self) -> Self {
method field_inverse (line 114) | fn field_inverse(&self) -> Self {
type Substitutable (line 76) | pub trait Substitutable<V> {
method substitute (line 78) | fn substitute(&mut self, variable: &V, substitution: &Self);
type VarTransformable (line 84) | pub trait VarTransformable<V1, V2> {
method transform_var_type (line 88) | fn transform_var_type(&self, var_transform: &mut impl FnMut(&V1) -> V2...
method try_transform_var_type (line 93) | fn try_transform_var_type(
method substitute (line 120) | fn substitute(&mut self, _variable: &V, _substitution: &Self) {
type Transformed (line 126) | type Transformed = T;
method transform_var_type (line 128) | fn transform_var_type(&self, _var_transform: &mut impl FnMut(&V1) -> V2)...
method try_transform_var_type (line 133) | fn try_transform_var_type(
FILE: constraint-solver/src/solver.rs
function solve_system (line 26) | pub fn solve_system<T, V>(
function new_solver (line 38) | pub fn new_solver<T, V>(
type Solver (line 54) | pub trait Solver<T: FieldElement, V>: RangeConstraintProvider<T, V> + Si...
method solve (line 57) | fn solve(&mut self) -> Result<Vec<VariableAssignment<T, V>>, Error>;
method add_algebraic_constraints (line 60) | fn add_algebraic_constraints(
method add_bus_interactions (line 66) | fn add_bus_interactions(
method add_range_constraint (line 72) | fn add_range_constraint(&mut self, var: &V, constraint: RangeConstrain...
method retain_variables (line 76) | fn retain_variables(&mut self, variables_to_keep: &HashSet<V>);
method range_constraint_for_expression (line 79) | fn range_constraint_for_expression(&self, expr: &GroupedExpression<T, V>)
method try_to_equivalent_constant (line 88) | fn try_to_equivalent_constant(&self, expr: &GroupedExpression<T, V>) -...
method are_expressions_known_to_be_different (line 94) | fn are_expressions_known_to_be_different(
type Error (line 104) | pub enum Error {
type VariableAssignment (line 115) | pub type VariableAssignment<T, V> = (V, GroupedExpression<T, V>);
FILE: constraint-solver/src/solver/base.rs
type BaseSolver (line 35) | pub struct BaseSolver<T: FieldElement, V, BusInterHandler, VarDisp> {
type VarDispenser (line 57) | pub trait VarDispenser<V> {
method next_boolean (line 59) | fn next_boolean(&mut self) -> V;
method next_linear (line 62) | fn next_linear(&mut self) -> V;
method all_linearized_vars (line 65) | fn all_linearized_vars(&self) -> impl Iterator<Item = V>;
type VarDispenserImpl (line 69) | pub struct VarDispenserImpl {
method next_boolean (line 75) | fn next_boolean(&mut self) -> Variable<V> {
method next_linear (line 81) | fn next_linear(&mut self) -> Variable<V> {
method all_linearized_vars (line 88) | fn all_linearized_vars(&self) -> impl Iterator<Item = Variable<V>> {
function new (line 94) | pub fn new(bus_interaction_handler: B) -> Self {
function get (line 113) | fn get(&self, var: &V) -> RangeConstraint<T> {
method fmt (line 121) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function solve (line 132) | fn solve(&mut self) -> Result<Vec<VariableAssignment<T, V>>, Error> {
function add_algebraic_constraints (line 147) | fn add_algebraic_constraints(
function add_bus_interactions (line 171) | fn add_bus_interactions(
function add_range_constraint (line 189) | fn add_range_constraint(&mut self, variable: &V, constraint: RangeConstr...
function retain_variables (line 194) | fn retain_variables(&mut self, variables_to_keep: &HashSet<V>) {
function range_constraint_for_expression (line 224) | fn range_constraint_for_expression(
function try_to_equivalent_constant (line 235) | fn try_to_equivalent_constant(&self, expr: &GroupedExpression<T, V>) -> ...
function are_expressions_known_to_be_different (line 242) | fn are_expressions_known_to_be_different(
function try_extract_boolean (line 269) | fn try_extract_boolean(
function linearize_constraint (line 287) | fn linearize_constraint(
function linearize_bus_interaction (line 308) | fn linearize_bus_interaction(
function loop_until_no_progress (line 332) | fn loop_until_no_progress(&mut self) -> Result<(), Error> {
function solve_in_isolation (line 352) | fn solve_in_isolation(&mut self) -> Result<bool, Error> {
function exhaustive_search (line 385) | fn exhaustive_search(&mut self) -> Result<bool, Error> {
function equivalent_expressions (line 442) | fn equivalent_expressions(
function apply_effect (line 475) | fn apply_effect(&mut self, effect: Effect<T, V>) -> bool {
function apply_range_constraint_update (line 490) | fn apply_range_constraint_update(
function apply_assignment (line 510) | fn apply_assignment(&mut self, variable: &V, expr: &GroupedExpression<T,...
function add_algebraic_constraints_if_new (line 544) | fn add_algebraic_constraints_if_new(
function contains_algebraic_constraint (line 561) | fn contains_algebraic_constraint(
function try_to_simple_equivalence (line 579) | fn try_to_simple_equivalence<T: FieldElement, V: Clone + Ord + Eq>(
type RangeConstraints (line 605) | pub struct RangeConstraints<T: FieldElement, V> {
function get (line 612) | fn get(&self, var: &V) -> RangeConstraint<T> {
function update (line 620) | fn update(&mut self, variable: &V, range_constraint: &RangeConstraint<T>...
type VarName (line 641) | type VarName = &'static str;
type Var (line 642) | type Var = Variable<VarName>;
type Qse (line 643) | type Qse = GroupedExpression<GoldilocksField, Var>;
function var (line 645) | fn var(name: VarName) -> Qse {
function constant (line 649) | fn constant(value: u64) -> Qse {
function expression_simplification (line 654) | fn expression_simplification() {
function is_known_to_by_nonzero (line 695) | fn is_known_to_by_nonzero() {
FILE: constraint-solver/src/solver/boolean_extractor.rs
type BooleanExtractor (line 14) | pub struct BooleanExtractor<T, V> {
type BooleanExtractionValue (line 27) | pub struct BooleanExtractionValue<T, V> {
function try_extract_boolean (line 48) | pub fn try_extract_boolean(
function try_to_abs_u64 (line 151) | fn try_to_abs_u64<T: FieldElement>(x: T) -> Option<u64> {
function apply_assignments (line 159) | pub fn apply_assignments(&mut self, assignments: &[VariableAssignment<T,...
type Var (line 175) | type Var = &'static str;
type Qse (line 176) | type Qse = GroupedExpression<GoldilocksField, Var>;
function var (line 178) | fn var(name: Var) -> Qse {
function constant (line 182) | fn constant(value: u64) -> Qse {
function test_extract_boolean (line 187) | fn test_extract_boolean() {
function test_extract_boolean_square (line 199) | fn test_extract_boolean_square() {
function test_extract_boolean_useless (line 211) | fn test_extract_boolean_useless() {
function do_not_extract_twice (line 226) | fn do_not_extract_twice() {
function do_not_extract_squares_twice (line 273) | fn do_not_extract_squares_twice() {
function apply_assignments (line 290) | fn apply_assignments() {
FILE: constraint-solver/src/solver/constraint_splitter.rs
function try_split_constraint (line 33) | pub fn try_split_constraint<T: FieldElement, V: Clone + Ord + Display>(
function group_components_by_coefficients (line 139) | fn group_components_by_coefficients<T: FieldElement, V: Clone + Ord + Di...
function find_solution (line 158) | fn find_solution<T: FieldElement, V: Clone + Ord + Display>(
function recombine_components (line 248) | fn recombine_components<T: FieldElement, V: Clone + Ord + Display>(
type Component (line 273) | struct Component<T, V> {
method fmt (line 279) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type Error (line 285) | type Error = ();
function try_from (line 286) | fn try_from((var, coeff): (&'a V, &'a T)) -> Result<Self, ()> {
function normalize (line 295) | fn normalize(self) -> Self {
type Output (line 308) | type Output = Self;
method add (line 310) | fn add(self, other: Self) -> Self {
type Output (line 320) | type Output = Self;
function div (line 322) | fn div(self, rhs: T) -> Self {
function from (line 332) | fn from(comp: Component<T, V>) -> Self {
method zero (line 338) | fn zero() -> Self {
method is_zero (line 345) | fn is_zero(&self) -> bool {
type Var (line 361) | type Var = &'static str;
type Qse (line 362) | type Qse = GroupedExpression<GoldilocksField, Var>;
function var (line 364) | fn var(name: Var) -> Qse {
function constant (line 368) | fn constant(value: u64) -> Qse {
function try_split (line 372) | fn try_split<T: FieldElement, V: Clone + Ord + Display>(
function split_simple (line 380) | fn split_simple() {
function split_multiple (line 397) | fn split_multiple() {
function split_seqz (line 425) | fn split_seqz() {
function split_multiple_with_const (line 455) | fn split_multiple_with_const() {
function split_limb_decomposition (line 487) | fn split_limb_decomposition() {
function negated_and_unnegated (line 514) | fn negated_and_unnegated() {
function wrapping_1 (line 540) | fn wrapping_1() {
function wrapping_2 (line 568) | fn wrapping_2() {
function split_at_boundary (line 584) | fn split_at_boundary() {
function bit_decomposition_bug (line 609) | fn bit_decomposition_bug() {
function split_fail_overlapping (line 626) | fn split_fail_overlapping() {
function split_fail_not_unique (line 637) | fn split_fail_not_unique() {
FILE: constraint-solver/src/solver/exhaustive_search.rs
constant MAX_SEARCH_WIDTH (line 21) | const MAX_SEARCH_WIDTH: u64 = 1 << 10;
constant MAX_VAR_RANGE_WIDTH (line 23) | const MAX_VAR_RANGE_WIDTH: u64 = 5;
function exhaustive_search_on_variable_set (line 31) | pub fn exhaustive_search_on_variable_set<T: FieldElement, V: Clone + Has...
function get_brute_force_candidates (line 77) | pub fn get_brute_force_candidates<'a, T: FieldElement, V: Clone + Hash +...
function is_candidate_for_exhaustive_search (line 120) | fn is_candidate_for_exhaustive_search<T: FieldElement, V: Clone + Ord>(
function has_small_max_range_constraint_size (line 128) | fn has_small_max_range_constraint_size<T: FieldElement, V: Clone + Ord>(
type ContradictingConstraintError (line 143) | struct ContradictingConstraintError;
function derive_new_range_constraints (line 151) | fn derive_new_range_constraints<T: FieldElement, V: Clone + Hash + Ord +...
FILE: constraint-solver/src/solver/linearizer.rs
type Linearizer (line 19) | pub struct Linearizer<T, V> {
function linearize_expression (line 28) | pub fn linearize_expression(
function try_linearize_existing (line 63) | pub fn try_linearize_existing(
function linearize_and_substitute_by_var (line 96) | fn linearize_and_substitute_by_var(
function substitute_by_var (line 111) | pub fn substitute_by_var(
function try_substitute_by_existing_var (line 132) | pub fn try_substitute_by_existing_var(
function internalized_versions_of_expression (line 147) | pub fn internalized_versions_of_expression(
function apply_assignments (line 164) | pub fn apply_assignments(&mut self, assignments: &[VariableAssignment<T,...
type Qse (line 191) | type Qse = GroupedExpression<GoldilocksField, Variable<&'static str>>;
function var (line 193) | fn var(name: &'static str) -> Qse {
function constant (line 197) | fn constant(value: u64) -> Qse {
function linearization (line 202) | fn linearization() {
function solver_transforms (line 224) | fn solver_transforms() {
FILE: constraint-solver/src/solver/var_transformation.rs
type Variable (line 16) | pub enum Variable<V> {
function from (line 27) | fn from(v: V) -> Self {
function from (line 34) | fn from(v: &V) -> Self {
function try_to_original (line 40) | pub fn try_to_original(&self) -> Option<V> {
method fmt (line 49) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type VarTransformation (line 59) | pub struct VarTransformation<T, V, S> {
function new (line 70) | pub fn new(solver: S) -> Self {
function get (line 84) | fn get(&self, var: &V) -> RangeConstraint<T> {
method fmt (line 90) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function solve (line 103) | fn solve(&mut self) -> Result<Vec<VariableAssignment<T, V>>, Error> {
function add_algebraic_constraints (line 116) | fn add_algebraic_constraints(
function add_bus_interactions (line 124) | fn add_bus_interactions(
function add_range_constraint (line 135) | fn add_range_constraint(&mut self, variable: &V, constraint: RangeConstr...
function retain_variables (line 140) | fn retain_variables(&mut self, variables_to_keep: &HashSet<V>) {
function range_constraint_for_expression (line 150) | fn range_constraint_for_expression(
function try_to_equivalent_constant (line 158) | fn try_to_equivalent_constant(&self, expr: &GroupedExpression<T, V>) -> ...
function are_expressions_known_to_be_different (line 163) | fn are_expressions_known_to_be_different(
function transform_expr (line 174) | fn transform_expr<T: FieldElement, V: Ord + Clone>(
function transform_constraint (line 180) | fn transform_constraint<T: FieldElement, V: Ord + Clone>(
FILE: constraint-solver/src/symbolic_expression.rs
type SymbolicExpression (line 23) | pub enum SymbolicExpression<T: FieldElement, S> {
type BinaryOperator (line 34) | pub enum BinaryOperator {
type UnaryOperator (line 43) | pub enum UnaryOperator {
function children (line 52) | fn children(&self) -> impl Iterator<Item = &SymbolicExpression<T, S>> {
function all_children (line 64) | pub fn all_children(&self) -> Box<dyn Iterator<Item = &SymbolicExpressio...
function from_symbol (line 70) | pub fn from_symbol(symbol: S, rc: RangeConstraint<T>) -> Self {
function compute_substitution (line 81) | pub fn compute_substitution(&self, variable: &S, substitution: &Self) ->...
function substitute (line 112) | pub fn substitute(&mut self, variable: &S, substitution: &Self) {
function try_to_expression (line 124) | fn try_to_expression<
type Transformed (line 167) | type Transformed = SymbolicExpression<T, S2>;
function try_transform_var_type (line 169) | fn try_transform_var_type(
method fmt (line 199) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
method fmt (line 218) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
method fmt (line 229) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
function from (line 237) | fn from(n: T) -> Self {
type Output (line 243) | type Output = SymbolicExpression<T, V>;
method add (line 245) | fn add(self, rhs: Self) -> Self::Output {
type Output (line 273) | type Output = SymbolicExpression<T, V>;
method add (line 274) | fn add(self, rhs: Self) -> Self::Output {
method add_assign (line 280) | fn add_assign(&mut self, rhs: Self) {
type Output (line 286) | type Output = SymbolicExpression<T, V>;
method sub (line 288) | fn sub(self, rhs: Self) -> Self::Output {
type Output (line 312) | type Output = SymbolicExpression<T, V>;
method sub (line 313) | fn sub(self, rhs: Self) -> Self::Output {
type Output (line 319) | type Output = SymbolicExpression<T, V>;
method neg (line 321) | fn neg(self) -> Self::Output {
type Output (line 368) | type Output = SymbolicExpression<T, V>;
method neg (line 369) | fn neg(self) -> Self::Output {
type Output (line 375) | type Output = SymbolicExpression<T, V>;
method mul (line 377) | fn mul(self, rhs: Self) -> Self::Output {
type Output (line 403) | type Output = SymbolicExpression<T, V>;
method mul (line 404) | fn mul(self, rhs: Self) -> Self {
method mul_assign (line 410) | fn mul_assign(&mut self, rhs: Self) {
method zero (line 416) | fn zero() -> Self {
method is_zero (line 420) | fn is_zero(&self) -> bool {
method one (line 426) | fn one() -> Self {
method is_one (line 430) | fn is_one(&self) -> bool {
type FieldType (line 436) | type FieldType = T;
method try_to_number (line 438) | fn try_to_number(&self) -> Option<Self::FieldType> {
method range_constraint (line 447) | fn range_constraint(&self) -> RangeConstraint<Self::FieldType> {
method field_div (line 458) | fn field_div(&self, rhs: &Self) -> Self {
method field_inverse (line 480) | fn field_inverse(&self) -> Self {
method from_u64 (line 501) | fn from_u64(k: u64) -> Self {
function substitute (line 507) | fn substitute(&mut self, variable: &V, substitution: &Self) {
FILE: constraint-solver/src/system_splitter.rs
function split_system (line 16) | pub fn split_system<T: RuntimeConstant, V: Clone + Ord + Hash + Display>(
FILE: constraint-solver/src/test_utils.rs
type Var (line 10) | pub type Var = &'static str;
type Qse (line 11) | pub type Qse = GroupedExpression<SymbolicExpression<GoldilocksField, Var...
function var (line 13) | pub fn var(name: Var) -> Qse {
function constant (line 17) | pub fn constant(value: u64) -> Qse {
function with_constraints (line 22) | pub fn with_constraints(
function with_bus_interactions (line 31) | pub fn with_bus_interactions(
FILE: constraint-solver/src/utils.rs
function has_few_possible_assignments (line 12) | pub fn has_few_possible_assignments<T: FieldElement, V: Clone + Ord>(
function get_all_possible_assignments (line 30) | pub fn get_all_possible_assignments<T: FieldElement, V: Clone + Ord>(
function possible_concrete_values (line 49) | pub fn possible_concrete_values<
FILE: constraint-solver/src/variable_update.rs
type VariableUpdate (line 7) | pub struct VariableUpdate<T: FieldElement, V, R> {
type UpdateKind (line 13) | pub enum UpdateKind<T: FieldElement, R> {
FILE: constraint-solver/tests/solver.rs
type Var (line 16) | type Var = &'static str;
function var (line 18) | fn var(name: Var) -> GroupedExpression<GoldilocksField, Var> {
function constant (line 22) | fn constant(value: u64) -> GroupedExpression<GoldilocksField, Var> {
function assert_solve_result (line 26) | pub fn assert_solve_result<B: BusInteractionHandler<GoldilocksField>>(
function assert_expected_state (line 36) | fn assert_expected_state(
function single_variable (line 61) | fn single_variable() {
function concretely_solvable (line 70) | fn concretely_solvable() {
function bit_decomposition (line 92) | fn bit_decomposition() {
constant BYTE_BUS_ID (line 116) | const BYTE_BUS_ID: u64 = 42;
constant XOR_BUS_ID (line 117) | const XOR_BUS_ID: u64 = 43;
type TestBusInteractionHandler (line 119) | struct TestBusInteractionHandler;
method handle_bus_interaction (line 121) | fn handle_bus_interaction(
function send (line 174) | fn send(
function byte_decomposition (line 186) | fn byte_decomposition() {
function xor (line 216) | fn xor() {
function xor_invalid (line 236) | fn xor_invalid() {
function one_hot_flags (line 252) | fn one_hot_flags() {
function binary_flags (line 284) | fn binary_flags() {
function ternary_flags (line 322) | fn ternary_flags() {
function bit_decomposition_bug (line 389) | fn bit_decomposition_bug() {
FILE: expression/src/display.rs
type ExpressionPrecedence (line 8) | type ExpressionPrecedence = u64;
type Precedence (line 9) | trait Precedence {
method precedence (line 10) | fn precedence(&self) -> Option<ExpressionPrecedence>;
method precedence (line 14) | fn precedence(&self) -> Option<ExpressionPrecedence> {
method precedence (line 22) | fn precedence(&self) -> Option<ExpressionPrecedence> {
method precedence (line 31) | fn precedence(&self) -> Option<ExpressionPrecedence> {
method fmt (line 41) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
method fmt (line 69) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
method fmt (line 84) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
method fmt (line 92) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
function test_display (line 109) | fn test_display(expr: AlgebraicExpression<GoldilocksField, &str>, expect...
function binary_op (line 114) | fn binary_op() {
FILE: expression/src/lib.rs
type AlgebraicExpression (line 26) | pub enum AlgebraicExpression<T, R> {
type AlgebraicBinaryOperation (line 40) | pub struct AlgebraicBinaryOperation<T, R> {
type AlgebraicBinaryOperator (line 49) | pub enum AlgebraicBinaryOperator {
type AlgebraicUnaryOperation (line 61) | pub struct AlgebraicUnaryOperation<T, R> {
type AlgebraicUnaryOperator (line 69) | pub enum AlgebraicUnaryOperator {
function children (line 79) | fn children(&self) -> Box<dyn Iterator<Item = &AlgebraicExpression<T, R>...
function children_mut (line 96) | fn children_mut(&mut self) -> Box<dyn Iterator<Item = &mut AlgebraicExpr...
function degree (line 111) | pub fn degree(&self) -> usize {
function new_binary (line 125) | pub fn new_binary(left: Self, op: AlgebraicBinaryOperator, right: Self) ...
function new_unary (line 133) | pub fn new_unary(op: AlgebraicUnaryOperator, expr: Self) -> Self {
type Output (line 142) | type Output = Self;
function add (line 144) | fn add(self, rhs: Self) -> Self::Output {
type Output (line 150) | type Output = Self;
function sub (line 152) | fn sub(self, rhs: Self) -> Self::Output {
type Output (line 158) | type Output = Self;
function neg (line 160) | fn neg(self) -> Self::Output {
type Output (line 166) | type Output = Self;
function mul (line 168) | fn mul(self, rhs: Self) -> Self::Output {
function from (line 174) | fn from(value: T) -> Self {
function to_expression (line 180) | fn to_expression<
function serialize_unary_operation (line 209) | fn serialize_unary_operation<S, T, R>(
function serialize_binary_operation (line 221) | fn serialize_binary_operation<S, T, R>(
function test_serde (line 238) | fn test_serde() {
FILE: expression/src/visitors.rs
type Children (line 11) | pub trait Children<O> {
method children (line 13) | fn children(&self) -> Box<dyn Iterator<Item = &O> + '_>;
method children_mut (line 15) | fn children_mut(&mut self) -> Box<dyn Iterator<Item = &mut O> + '_>;
type AllChildren (line 18) | pub trait AllChildren<O> {
method all_children (line 22) | fn all_children(&self) -> Box<dyn Iterator<Item = &O> + '_>;
type VisitOrder (line 26) | pub enum VisitOrder {
type ExpressionVisitable (line 38) | pub trait ExpressionVisitable<Expr> {
method pre_visit_expressions_mut (line 40) | fn pre_visit_expressions_mut<F>(&mut self, f: &mut F)
method post_visit_expressions_mut (line 54) | fn post_visit_expressions_mut<F>(&mut self, f: &mut F)
method visit_expressions (line 67) | fn visit_expressions<F, B>(&self, f: &mut F, order: VisitOrder) -> Con...
method visit_expressions_mut (line 71) | fn visit_expressions_mut<F, B>(&mut self, f: &mut F, order: VisitOrder...
method visit_expressions_mut (line 77) | fn visit_expressions_mut<F, B>(&mut self, f: &mut F, o: VisitOrder) -> C...
method visit_expressions (line 85) | fn visit_expressions<F, B>(&self, f: &mut F, o: VisitOrder) -> ControlFl...
method all_children (line 95) | fn all_children(&self) -> Box<dyn Iterator<Item = &Expr> + '_> {
function visit_expressions_mut (line 101) | fn visit_expressions_mut<F, B>(&mut self, f: &mut F, o: VisitOrder) -> C...
function visit_expressions (line 116) | fn visit_expressions<F, B>(&self, f: &mut F, o: VisitOrder) -> ControlFl...
function all_children (line 133) | fn all_children(&self) -> Box<dyn Iterator<Item = &AlgebraicExpression<T...
FILE: isa-utils/src/lib.rs
type SingleDataValue (line 2) | pub enum SingleDataValue {
function quote (line 13) | pub fn quote(s: &str) -> String {
function escape_label (line 18) | pub fn escape_label(l: &str) -> String {
FILE: number/src/baby_bear.rs
function bitwise (line 15) | fn bitwise() {
function zero_one (line 35) | fn zero_one() {
function lower_half (line 47) | fn lower_half() {
function integer_div_by_zero (line 59) | fn integer_div_by_zero() {
function div_by_zero (line 66) | fn div_by_zero() {
function to_signed_integer (line 71) | fn to_signed_integer() {
FILE: number/src/bn254.rs
function bitwise (line 16) | fn bitwise() {
function minus_one (line 52) | fn minus_one() {
function format (line 65) | fn format() {
function integer_div_by_zero (line 77) | fn integer_div_by_zero() {
function div_by_zero (line 84) | fn div_by_zero() {
function to_signed_integer (line 89) | fn to_signed_integer() {
FILE: number/src/expression_convertible.rs
type ExpressionConvertible (line 5) | pub trait ExpressionConvertible<T, V> {
method try_to_expression (line 13) | fn try_to_expression<
method to_expression (line 27) | fn to_expression<
method to_expression (line 40) | fn to_expression<
FILE: number/src/goldilocks.rs
constant EPSILON (line 22) | const EPSILON: u64 = (1 << 32) - 1;
type GoldilocksField (line 40) | pub struct GoldilocksField(u64);
constant ORDER (line 43) | const ORDER: u64 = 0xFFFFFFFF00000001;
method try_inverse (line 55) | fn try_inverse(&self) -> Option<Self> {
method square (line 96) | fn square(&self) -> Self {
method exp_power_of_2 (line 100) | fn exp_power_of_2(&self, power_log: usize) -> Self {
method from_canonical_u64 (line 109) | fn from_canonical_u64(n: u64) -> Self {
method from_noncanonical_i64 (line 115) | fn from_noncanonical_i64(n: i64) -> Self {
method to_canonical_u64 (line 127) | fn to_canonical_u64(self) -> u64 {
method from (line 405) | fn from(b: bool) -> Self {
method from (line 411) | fn from(n: i64) -> Self {
method from (line 417) | fn from(n: i32) -> Self {
method from (line 423) | fn from(n: u32) -> Self {
method from (line 430) | fn from(n: u64) -> Self {
method from (line 436) | fn from(n: crate::BigUint) -> Self {
method from (line 443) | fn from(n: GLLargeInt) -> Self {
function wrap (line 133) | fn wrap(x: u64) -> u64 {
type Output (line 142) | type Output = Self;
method neg (line 145) | fn neg(self) -> Self {
type Output (line 155) | type Output = Self;
method add (line 159) | fn add(self, rhs: Self) -> Self {
method add_assign (line 169) | fn add_assign(&mut self, rhs: Self) {
type Output (line 175) | type Output = Self;
method sub (line 179) | fn sub(self, rhs: Self) -> Self {
method sub_assign (line 189) | fn sub_assign(&mut self, rhs: Self) {
type Output (line 195) | type Output = Self;
method mul (line 197) | fn mul(self, rhs: Self) -> Self {
method mul_assign (line 203) | fn mul_assign(&mut self, rhs: Self) {
type Output (line 209) | type Output = Self;
method div (line 212) | fn div(self, rhs: Self) -> Self::Output {
function add_no_canonicalize_trashing_input (line 224) | unsafe fn add_no_canonicalize_trashing_input(x: u64, y: u64) -> u64 {
function add_no_canonicalize_trashing_input (line 251) | const unsafe fn add_no_canonicalize_trashing_input(x: u64, y: u64) -> u64 {
function reduce128 (line 259) | fn reduce128(x: u128) -> GoldilocksField {
function exp_acc (line 277) | fn exp_acc<const N: usize>(base: GoldilocksField, tail: GoldilocksField)...
function split (line 282) | const fn split(x: u128) -> (u64, u64) {
function assume (line 288) | pub fn assume(p: bool) {
function branch_hint (line 306) | pub fn branch_hint() {
type Integer (line 324) | type Integer = GLLargeInt;
constant BITS (line 326) | const BITS: u32 = 64;
method to_degree (line 328) | fn to_degree(&self) -> crate::DegreeType {
method to_integer (line 332) | fn to_integer(&self) -> Self::Integer {
method modulus (line 337) | fn modulus() -> Self::Integer {
method pow (line 341) | fn pow(self, exp: Self::Integer) -> Self {
method to_bytes_le (line 360) | fn to_bytes_le(&self) -> Vec<u8> {
method from_bytes_le (line 364) | fn from_bytes_le(bytes: &[u8]) -> Self {
method from_str_radix (line 368) | fn from_str_radix(s: &str, radix: u32) -> Result<Self, String> {
method checked_from (line 377) | fn checked_from(value: ibig::UBig) -> Option<Self> {
method is_in_lower_half (line 385) | fn is_in_lower_half(&self) -> bool {
method known_field (line 389) | fn known_field() -> Option<crate::KnownField> {
method has_direct_repr (line 393) | fn has_direct_repr() -> bool {
method fmt (line 399) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
constant ZERO (line 449) | const ZERO: Self = Self(0);
method zero (line 453) | fn zero() -> Self {
method is_zero (line 457) | fn is_zero(&self) -> bool {
constant ONE (line 463) | const ONE: Self = Self(1);
method one (line 467) | fn one() -> Self {
method is_one (line 471) | fn is_one(&self) -> bool {
type Err (line 477) | type Err = String;
method from_str (line 478) | fn from_str(s: &str) -> Result<Self, Self::Err> {
type GLLargeInt (line 518) | pub struct GLLargeInt(u64);
method from (line 554) | fn from(value: u32) -> Self {
method from (line 560) | fn from(value: u64) -> Self {
constant MAX (line 521) | const MAX: Self = Self(u64::MAX);
constant NUM_BITS (line 522) | const NUM_BITS: usize = 64;
method to_arbitrary_integer (line 524) | fn to_arbitrary_integer(self) -> ibig::UBig {
method num_bits (line 528) | fn num_bits(&self) -> usize {
method one (line 532) | fn one() -> Self {
method is_one (line 536) | fn is_one(&self) -> bool {
method try_into_u64 (line 540) | fn try_into_u64(&self) -> Option<u64> {
method try_into_u32 (line 544) | fn try_into_u32(&self) -> Option<u32> {
method from_hex (line 548) | fn from_hex(s: &str) -> Self {
method zero (line 566) | fn zero() -> Self {
method is_zero (line 570) | fn is_zero(&self) -> bool {
constant ZERO (line 576) | const ZERO: Self = Self(0);
method fmt (line 580) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
type Output (line 586) | type Output = Self;
method not (line 588) | fn not(self) -> Self::Output {
function bitwise (line 601) | fn bitwise() {
function lower_half (line 621) | fn lower_half() {
function from_str_radix_rejects_modulus (line 632) | fn from_str_radix_rejects_modulus() {
function from_str_radix_accepts_order_minus_one (line 638) | fn from_str_radix_accepts_order_minus_one() {
function integer_div_by_zero (line 646) | fn integer_div_by_zero() {
function div_by_zero (line 653) | fn div_by_zero() {
FILE: number/src/koala_bear.rs
function bitwise (line 15) | fn bitwise() {
function zero_one (line 35) | fn zero_one() {
function lower_half (line 47) | fn lower_half() {
function integer_div_by_zero (line 59) | fn integer_div_by_zero() {
function div_by_zero (line 66) | fn div_by_zero() {
FILE: number/src/lib.rs
type DegreeType (line 32) | pub type DegreeType = u64;
function log2_exact (line 35) | pub fn log2_exact(n: BigUint) -> Option<usize> {
function log2_exact_function (line 46) | fn log2_exact_function() {
FILE: number/src/mersenne31.rs
function bitwise (line 15) | fn bitwise() {
function zero_one (line 35) | fn zero_one() {
function lower_half (line 47) | fn lower_half() {
function integer_div_by_zero (line 59) | fn integer_div_by_zero() {
function div_by_zero (line 66) | fn div_by_zero() {
FILE: number/src/serialize.rs
type CsvRenderMode (line 15) | pub enum CsvRenderMode {
constant ROW_NAME (line 22) | const ROW_NAME: &str = "Row";
function write_polys_csv_file (line 24) | pub fn write_polys_csv_file<T: FieldElement>(
function read_polys_csv_file (line 60) | pub fn read_polys_csv_file<T: FieldElement>(file: impl Read) -> Vec<(Str...
function buffered_write_file (line 94) | pub fn buffered_write_file<R>(
type ReadWrite (line 105) | pub trait ReadWrite {
method read (line 106) | fn read(file: &mut impl Read) -> Self;
method write (line 107) | fn write(&self, path: &Path) -> Result<(), serde_cbor::Error>;
method read (line 111) | fn read(file: &mut impl Read) -> Self {
method write (line 114) | fn write(&self, path: &Path) -> Result<(), serde_cbor::Error> {
function ark_se (line 122) | pub fn ark_se<S, A: CanonicalSerialize>(a: &A, s: S) -> Result<S::Ok, S:...
function ark_de (line 132) | pub fn ark_de<'de, D, A: CanonicalDeserialize>(data: D) -> Result<A, D::...
function test_polys (line 149) | fn test_polys() -> Vec<(String, Vec<Bn254Field>)> {
function write_read (line 157) | fn write_read() {
function write_read_csv (line 169) | fn write_read_csv() {
FILE: number/src/traits.rs
type LargeInt (line 16) | pub trait LargeInt:
constant MAX (line 46) | const MAX: Self;
constant NUM_BITS (line 49) | const NUM_BITS: usize;
method to_arbitrary_integer (line 50) | fn to_arbitrary_integer(self) -> BigUint;
method num_bits (line 52) | fn num_bits(&self) -> usize;
method one (line 56) | fn one() -> Self;
method is_one (line 59) | fn is_one(&self) -> bool;
method try_into_u64 (line 64) | fn try_into_u64(&self) -> Option<u64>;
method try_into_u32 (line 69) | fn try_into_u32(&self) -> Option<u32>;
method from_hex (line 73) | fn from_hex(s: &str) -> Self;
type FieldSize (line 76) | pub enum FieldSize {
type KnownField (line 85) | pub enum KnownField {
method field_size (line 94) | pub fn field_size(&self) -> FieldSize {
method fmt (line 105) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type FieldElement (line 117) | pub trait FieldElement:
constant BITS (line 160) | const BITS: u32;
method to_degree (line 162) | fn to_degree(&self) -> DegreeType;
method to_integer (line 164) | fn to_integer(&self) -> Self::Integer;
method to_arbitrary_integer (line 166) | fn to_arbitrary_integer(&self) -> BigUint {
method modulus (line 170) | fn modulus() -> Self::Integer;
method pow (line 172) | fn pow(self, exponent: Self::Integer) -> Self;
method to_bytes_le (line 174) | fn to_bytes_le(&self) -> Vec<u8>;
method from_bytes_le (line 176) | fn from_bytes_le(bytes: &[u8]) -> Self;
method from_str_radix (line 178) | fn from_str_radix(s: &str, radix: u32) -> Result<Self, String>;
method checked_from (line 181) | fn checked_from(value: BigUint) -> Option<Self>;
method is_in_lower_half (line 185) | fn is_in_lower_half(&self) -> bool;
method known_field (line 188) | fn known_field() -> Option<KnownField>;
method to_signed_integer (line 194) | fn to_signed_integer(&self) -> IBig {
method has_direct_repr (line 212) | fn has_direct_repr() -> bool;
function int_from_hex_str (line 216) | pub fn int_from_hex_str<T: FieldElement>(s: &str) -> T::Integer {
FILE: openvm-bus-interaction-handler/src/bitwise_lookup.rs
function handle_bitwise_lookup (line 9) | pub fn handle_bitwise_lookup<T: FieldElement>(
function bitwise_lookup_pure_range_constraints (line 68) | pub fn bitwise_lookup_pure_range_constraints<T: FieldElement, V: Ord + C...
function run (line 115) | fn run(
function test_byte_constraint (line 133) | fn test_byte_constraint() {
function test_xor_known (line 149) | fn test_xor_known() {
function test_xor_unknown (line 165) | fn test_xor_unknown() {
function test_xor_one_unknown (line 181) | fn test_xor_one_unknown() {
function test_unknown_operation (line 198) | fn test_unknown_operation() {
FILE: openvm-bus-interaction-handler/src/bus_map.rs
constant DEFAULT_EXECUTION_BRIDGE (line 9) | pub const DEFAULT_EXECUTION_BRIDGE: u64 = 0;
constant DEFAULT_MEMORY (line 10) | pub const DEFAULT_MEMORY: u64 = 1;
constant DEFAULT_PC_LOOKUP (line 11) | pub const DEFAULT_PC_LOOKUP: u64 = 2;
constant DEFAULT_VARIABLE_RANGE_CHECKER (line 12) | pub const DEFAULT_VARIABLE_RANGE_CHECKER: u64 = 3;
constant DEFAULT_BITWISE_LOOKUP (line 13) | pub const DEFAULT_BITWISE_LOOKUP: u64 = 6;
constant DEFAULT_TUPLE_RANGE_CHECKER (line 14) | pub const DEFAULT_TUPLE_RANGE_CHECKER: u64 = 7;
type OpenVmBusType (line 17) | pub enum OpenVmBusType {
type BusMap (line 23) | pub type BusMap = powdr_autoprecompiles::bus_map::BusMap<OpenVmBusType>;
method fmt (line 26) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function default_openvm_bus_map (line 37) | pub fn default_openvm_bus_map() -> BusMap {
FILE: openvm-bus-interaction-handler/src/lib.rs
type OpenVmBusInteractionHandler (line 38) | pub struct OpenVmBusInteractionHandler<T: FieldElement> {
constant DEFAULT_RANGE_TUPLE_CHECKER_SIZES (line 44) | const DEFAULT_RANGE_TUPLE_CHECKER_SIZES: [u32; 2] = [1 << 8, 8 * (1 << 8)];
method default (line 47) | fn default() -> Self {
function new (line 53) | pub fn new(bus_map: BusMap) -> Self {
function tuple_range_checker_sizes (line 60) | pub fn tuple_range_checker_sizes(&self) -> [u32; 2] {
function handle_bus_interaction (line 76) | fn handle_bus_interaction(
function byte_constraint (line 120) | fn byte_constraint<T: FieldElement>() -> RangeConstraint<T> {
function is_stateful (line 125) | fn is_stateful(&self, bus_id: T) -> bool {
function pure_range_constraints (line 139) | fn pure_range_constraints<V: Ord + Clone + Eq>(
function batch_make_range_constraints (line 165) | fn batch_make_range_constraints<V: Ord + Clone + Eq + Display + Hash>(
function value (line 282) | pub fn value(value: u64) -> RangeConstraint<BabyBearField> {
function mask (line 286) | pub fn mask(mask: u64) -> RangeConstraint<BabyBearField> {
function range (line 290) | pub fn range(start: u64, end: u64) -> RangeConstraint<BabyBearField> {
FILE: openvm-bus-interaction-handler/src/memory.rs
constant RV32_REGISTER_AS (line 7) | pub const RV32_REGISTER_AS: u32 = 1;
constant RV32_MEMORY_AS (line 9) | pub const RV32_MEMORY_AS: u32 = 2;
function handle_memory (line 11) | pub fn handle_memory<T: FieldElement>(
function run (line 65) | fn run(
function test_receive (line 88) | fn test_receive() {
function test_send (line 113) | fn test_send() {
FILE: openvm-bus-interaction-handler/src/memory_bus_interaction.rs
constant REGISTER_ADDRESS_SPACE (line 13) | pub const REGISTER_ADDRESS_SPACE: u32 = 1;
type OpenVmMemoryBusInteraction (line 16) | pub struct OpenVmMemoryBusInteraction<T: FieldElement, V> {
type OpenVmAddress (line 24) | pub struct OpenVmAddress<T, V> {
type Item (line 32) | type Item = GroupedExpression<T, V>;
type IntoIter (line 33) | type IntoIter = IntoIter<GroupedExpression<T, V>, 2>;
method into_iter (line 35) | fn into_iter(self) -> Self::IntoIter {
type Address (line 47) | type Address = OpenVmAddress<T, V>;
function try_from_bus_interaction (line 49) | fn try_from_bus_interaction(
function addr (line 83) | fn addr(&self) -> Self::Address {
function data (line 87) | fn data(&self) -> &[GroupedExpression<T, V>] {
function timestamp_limbs (line 91) | fn timestamp_limbs(&self) -> &[GroupedExpression<T, V>] {
function op (line 95) | fn op(&self) -> MemoryOp {
FILE: openvm-bus-interaction-handler/src/tuple_range_checker.rs
type TupleRangeCheckerHandler (line 8) | pub struct TupleRangeCheckerHandler {
method new (line 13) | pub fn new(range_tuple_checker_sizes: [u32; 2]) -> Self {
method tuple_range_checker_ranges (line 19) | pub fn tuple_range_checker_ranges<T: FieldElement>(
method handle_bus_interaction (line 28) | pub fn handle_bus_interaction<T: FieldElement>(
method pure_range_constraints (line 42) | pub fn pure_range_constraints<T: FieldElement, V: Ord + Clone + Eq>(
function run (line 66) | fn run(
function test_unknown (line 82) | fn test_unknown() {
FILE: openvm-bus-interaction-handler/src/variable_range_checker.rs
constant MAX_BITS (line 9) | const MAX_BITS: u64 = 25;
function handle_variable_range_checker (line 13) | pub fn handle_variable_range_checker<T: FieldElement>(
function variable_range_checker_pure_range_constraints (line 36) | pub fn variable_range_checker_pure_range_constraints<T: FieldElement, V:...
function run (line 65) | fn run(
function test_unknown_bits (line 81) | fn test_unknown_bits() {
function test_known_bits (line 94) | fn test_known_bits() {
FILE: openvm-riscv/extensions/hints-circuit/src/executors.rs
type ReverseBytesSubEx (line 13) | pub struct ReverseBytesSubEx;
method phantom_execute (line 16) | fn phantom_execute(
type K256InverseFieldSubEx (line 45) | pub struct K256InverseFieldSubEx;
method phantom_execute (line 60) | fn phantom_execute(
constant FIELD10X26_BYTES (line 97) | const FIELD10X26_BYTES: usize = 40;
type K256InverseField10x26SubEx (line 102) | pub struct K256InverseField10x26SubEx;
method phantom_execute (line 105) | fn phantom_execute(
constant K256_NON_QUADRATIC_RESIDUE (line 146) | const K256_NON_QUADRATIC_RESIDUE: field10x26_k256::FieldElement10x26 =
type K256SqrtField10x26SubEx (line 152) | pub struct K256SqrtField10x26SubEx;
method phantom_execute (line 155) | fn phantom_execute(
FILE: openvm-riscv/extensions/hints-circuit/src/field10x26_k256.rs
type FieldBytes (line 14) | pub type FieldBytes = elliptic_curve::FieldBytes<Secp256k1>;
constant ORDER_HEX (line 17) | const ORDER_HEX: &str = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03...
constant ORDER (line 20) | const ORDER: U256 = U256::from_be_hex(ORDER_HEX);
type Secp256k1 (line 23) | pub struct Secp256k1;
type FieldBytesSize (line 27) | type FieldBytesSize = U32;
type Uint (line 30) | type Uint = U256;
constant ORDER (line 33) | const ORDER: U256 = ORDER;
method decode_field_bytes (line 37) | fn decode_field_bytes(field_bytes: &FieldBytes) -> Self {
method encode_field_bytes (line 41) | fn encode_field_bytes(&self) -> FieldBytes {
type FieldElement10x26 (line 56) | pub struct FieldElement10x26(pub(crate) [u32; 10]);
constant ZERO (line 62) | pub const ZERO: Self = Self([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
constant ONE (line 65) | pub const ONE: Self = Self([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
method from_bytes_unchecked (line 69) | pub(crate) const fn from_bytes_unchecked(bytes: &[u8; 32]) -> Self {
method from_bytes (line 117) | pub fn from_bytes(bytes: &FieldBytes) -> CtOption<Self> {
method from_u64 (line 124) | pub const fn from_u64(val: u64) -> Self {
method to_bytes (line 133) | pub fn to_bytes(self) -> FieldBytes {
method add_modulus_correction (line 171) | fn add_modulus_correction(&self, x: u32) -> Self {
method subtract_modulus_approximation (line 209) | fn subtract_modulus_approximation(&self) -> (Self, u32) {
method get_overflow (line 222) | fn get_overflow(&self) -> Choice {
method normalize_weak (line 232) | pub fn normalize_weak(&self) -> Self {
method normalize (line 248) | pub fn normalize(&self) -> Self {
method normalizes_to_zero (line 268) | pub fn normalizes_to_zero(&self) -> Choice {
method is_zero (line 303) | pub fn is_zero(&self) -> Choice {
method is_odd (line 324) | pub fn is_odd(&self) -> Choice {
method max_magnitude (line 329) | pub const fn max_magnitude() -> u32 {
method negate (line 335) | pub const fn negate(&self, magnitude: u32) -> Self {
method add (line 352) | pub const fn add(&self, rhs: &Self) -> Self {
method mul_single (line 369) | pub const fn mul_single(&self, rhs: u32) -> Self {
method mul_inner (line 385) | fn mul_inner(&self, rhs: &Self) -> Self {
method mul (line 699) | pub fn mul(&self, rhs: &Self) -> Self {
method square (line 706) | pub fn square(&self) -> Self {
method pow2k (line 710) | pub fn pow2k(&self, k: u32) -> Self {
method invert (line 720) | pub fn invert(&self) -> Self {
method sqrt (line 746) | pub fn sqrt(&self) -> CtOption<Self> {
method default (line 770) | fn default() -> Self {
method conditional_select (line 777) | fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
method ct_eq (line 794) | fn ct_eq(&self, other: &Self) -> Choice {
method zeroize (line 809) | fn zeroize(&mut self) {
FILE: openvm-riscv/extensions/hints-circuit/src/lib.rs
type HintsExtension (line 27) | pub struct HintsExtension;
type Executor (line 37) | type Executor = HintsExtensionExecutor<F>;
method extend_execution (line 39) | fn extend_execution(
method extend_circuit (line 64) | fn extend_circuit(&self, _: &mut AirInventory<SC>) -> Result<(), AirIn...
type HintsExtensionExecutor (line 32) | pub enum HintsExtensionExecutor<F: Field> {
type HintsProverExt (line 69) | pub struct HintsProverExt;
method extend_prover (line 76) | fn extend_prover(
FILE: openvm-riscv/extensions/hints-guest/src/lib.rs
constant OPCODE (line 7) | pub const OPCODE: u8 = 0x5b;
constant HINTS_FUNCT3 (line 8) | pub const HINTS_FUNCT3: u8 = 0b000;
type HintsFunct7 (line 12) | pub enum HintsFunct7 {
function insn_reverse_bytes (line 21) | fn insn_reverse_bytes(bytes: *const u8) {
function insn_k256_inverse_field (line 34) | fn insn_k256_inverse_field(bytes: *const u8) {
function insn_k256_inverse_field_10x26 (line 47) | fn insn_k256_inverse_field_10x26(bytes: *const u8) {
function insn_k256_sqrt_field_10x26 (line 60) | fn insn_k256_sqrt_field_10x26(bytes: *const u8) {
function hint_reverse_bytes (line 72) | pub fn hint_reverse_bytes(val: u32) -> u32 {
function hint_k256_inverse_field (line 94) | pub fn hint_k256_inverse_field(sec1_bytes: &[u8]) -> [u8; 32] {
function ensure_weakly_normalized_10x26 (line 106) | fn ensure_weakly_normalized_10x26(limbs: [u32; 10]) -> [u32; 10] {
function hint_k256_inverse_field_10x26 (line 127) | pub fn hint_k256_inverse_field_10x26(elem: [u32; 10]) -> [u32; 10] {
constant K256_NON_QUADRATIC_RESIDUE (line 139) | pub const K256_NON_QUADRATIC_RESIDUE: [u32; 10] = [3, 0, 0, 0, 0, 0, 0, ...
function hint_k256_sqrt_field_10x26 (line 146) | pub fn hint_k256_sqrt_field_10x26(elem: [u32; 10]) -> (bool, [u32; 10]) {
FILE: openvm-riscv/extensions/hints-transpiler/src/lib.rs
type HintsOpcode (line 16) | pub enum HintsOpcode {
type HintsPhantom (line 22) | pub enum HintsPhantom {
type HintsTranspilerExtension (line 33) | pub struct HintsTranspilerExtension;
method process_custom (line 36) | fn process_custom(&self, instruction_stream: &[u32]) -> Option<Transpi...
FILE: openvm-riscv/guest-ecc-manual/src/main.rs
function main (line 11) | pub fn main() {
FILE: openvm-riscv/guest-ecc-powdr-affine-hint/src/main.rs
function main (line 10) | pub fn main() {
FILE: openvm-riscv/guest-ecc-projective/src/main.rs
function main (line 10) | pub fn main() {
FILE: openvm-riscv/guest-ecrecover-manual/src/main.rs
type RecoveryTestVector (line 16) | struct RecoveryTestVector {
constant RECOVERY_TEST_VECTORS (line 22) | const RECOVERY_TEST_VECTORS: &[RecoveryTestVector] = &[
function main (line 44) | fn main() {
FILE: openvm-riscv/guest-ecrecover/src/main.rs
type RecoveryTestVector (line 9) | struct RecoveryTestVector {
constant RECOVERY_TEST_VECTORS (line 15) | const RECOVERY_TEST_VECTORS: &[RecoveryTestVector] = &[
function main (line 37) | pub fn main() {
FILE: openvm-riscv/guest-hints-test/src/main.rs
function main (line 7) | pub fn main() {
FILE: openvm-riscv/guest-keccak-manual-precompile/src/main.rs
function main (line 13) | pub fn main() {
FILE: openvm-riscv/guest-keccak/src/main.rs
function main (line 11) | pub fn main() {
FILE: openvm-riscv/guest-matmul/src/main.rs
function main (line 8) | pub fn main() {
constant SIZE (line 12) | const SIZE: usize = 6;
type Mat (line 14) | type Mat = [[i32; SIZE]; SIZE];
function matrix_multiply_unrolled (line 17) | fn matrix_multiply_unrolled(a: &Mat, b: &Mat, c: &mut Mat) {
function test_matrix (line 242) | fn test_matrix() {
function loop_test_matrix (line 271) | fn loop_test_matrix() {
FILE: openvm-riscv/guest-pairing-manual-precompile/src/main.rs
constant PAIR_ELEMENT_LEN (line 10) | const PAIR_ELEMENT_LEN: usize = 32 * (2 + 4);
function main (line 13) | pub fn main() {
FILE: openvm-riscv/guest-pairing/src/main.rs
constant PAIR_ELEMENT_LEN (line 8) | const PAIR_ELEMENT_LEN: usize = 32 * (2 + 4);
function main (line 10) | fn main() {
FILE: openvm-riscv/guest-sha256-manual-precompile/src/main.rs
function main (line 13) | pub fn main() {
FILE: openvm-riscv/guest-sha256/src/main.rs
function main (line 11) | pub fn main() {
FILE: openvm-riscv/guest-u256-manual-precompile/src/main.rs
constant N (line 8) | const N: usize = 70;
type Matrix (line 9) | type Matrix = [[U256; N]; N];
function get_matrix (line 11) | pub fn get_matrix(val: u32) -> Matrix {
function mult (line 15) | pub fn mult(a: &Matrix, b: &Matrix) -> Matrix {
function get_identity_matrix (line 27) | pub fn get_identity_matrix() -> Matrix {
function main (line 35) | pub fn main() {
FILE: openvm-riscv/guest-u256/src/main.rs
constant N (line 8) | const N: usize = 70;
type Matrix (line 9) | type Matrix = [[U256; N]; N];
function get_matrix (line 11) | pub fn get_matrix(val: u32) -> Matrix {
function mult (line 15) | pub fn mult(a: &Matrix, b: &Matrix) -> Matrix {
function get_identity_matrix (line 27) | pub fn get_identity_matrix() -> Matrix {
function main (line 35) | pub fn main() {
FILE: openvm-riscv/guest/src/main.rs
function main (line 8) | pub fn main() {
FILE: openvm-riscv/scripts/basic_metrics.py
function get_label (line 13) | def get_label(filepath):
function extract_metrics (line 24) | def extract_metrics(filename):
function summary_table (line 88) | def summary_table(metrics_files, csv):
function plot (line 97) | def plot(metrics_files, output):
function combine (line 201) | def combine(metrics_files):
FILE: openvm-riscv/scripts/generate_bench_results_readme.py
function github_blob_url (line 13) | def github_blob_url(relative_path: Path, run_id: str) -> str:
function github_tree_url (line 18) | def github_tree_url(run_id: str, subdir: str | None = None) -> str:
function viewer_url (line 25) | def viewer_url(viewer_base: str, data_url: str) -> str:
function find_apc_candidates (line 29) | def find_apc_candidates(experiment_dir: Path) -> Path | None:
function generate_readme (line 43) | def generate_readme(results_dir: Path, run_id: str) -> str:
function main (line 86) | def main() -> None:
FILE: openvm-riscv/scripts/metrics_utils.py
function load_metrics_dataframes (line 8) | def load_metrics_dataframes(filename):
function is_normal_instruction_air (line 37) | def is_normal_instruction_air(air_name):
function test_is_normal_instruction_air (line 62) | def test_is_normal_instruction_air():
FILE: openvm-riscv/scripts/plot_trace_cells.py
function autopct_with_billions (line 8) | def autopct_with_billions(pct, total):
function compute_cells_by_air (line 12) | def compute_cells_by_air(metrics_path):
function main (line 37) | def main(metrics_path, output_path=None, subtitle=None):
FILE: openvm-riscv/src/isa/instruction_formatter.rs
function openvm_instruction_formatter (line 6) | pub fn openvm_instruction_formatter<F: PrimeField32>(instruction: &Instr...
function openvm_opcode_formatter (line 51) | pub fn openvm_opcode_formatter(opcode: &VmOpcode) -> String {
FILE: openvm-riscv/src/isa/mod.rs
type RiscvISA (line 38) | pub struct RiscvISA;
type OpenVmRegisterAddress (line 42) | pub struct OpenVmRegisterAddress(u8);
function from (line 46) | fn from(value: ExtendedVmConfigExecutor<F>) -> Self {
type Executor (line 52) | type Executor<F: PrimeField32> = ExtendedVmConfigExecutor<F>;
type Config (line 53) | type Config = ExtendedVmConfig;
type CpuBuilder (line 54) | type CpuBuilder = ExtendedVmConfigCpuBuilder;
type GpuBuilder (line 56) | type GpuBuilder = ExtendedVmConfigGpuBuilder;
method branching_opcodes (line 58) | fn branching_opcodes() -> HashSet<VmOpcode> {
method format (line 62) | fn format<F: PrimeField32>(instruction: &Instruction<F>) -> String {
method allowed_opcodes (line 66) | fn allowed_opcodes() -> HashSet<VmOpcode> {
method create_original_chip_complex (line 70) | fn create_original_chip_complex(
type LinkedProgram (line 81) | type LinkedProgram<'a> = ElfProgram;
method get_symbol_table (line 83) | fn get_symbol_table<'a>(program: &Self::LinkedProgram<'a>) -> SymbolTable {
method get_jump_destinations (line 105) | fn get_jump_destinations(program: &OriginalCompiledProgram<Self>) -> BTr...
method create_dummy_airs (line 113) | fn create_dummy_airs<E: openvm_circuit::arch::VmCircuitExtension<powdr_o...
method create_dummy_chip_complex_cpu (line 121) | fn create_dummy_chip_complex_cpu(
method create_dummy_chip_complex_gpu (line 130) | fn create_dummy_chip_complex_gpu(
function add_extra_targets (line 147) | fn add_extra_targets(
FILE: openvm-riscv/src/isa/opcode.rs
constant BRANCH_OPCODES_BIGINT (line 101) | pub const BRANCH_OPCODES_BIGINT: &[usize] = &[
constant BRANCH_OPCODES (line 110) | pub const BRANCH_OPCODES: &[usize] = &[
function instruction_allowlist (line 122) | pub fn instruction_allowlist() -> HashSet<VmOpcode> {
function branch_opcodes_bigint_set (line 132) | pub fn branch_opcodes_bigint_set() -> HashSet<VmOpcode> {
function branch_opcodes_set (line 143) | pub fn branch_opcodes_set() -> HashSet<VmOpcode> {
function test_all_opcodes (line 154) | fn test_all_opcodes() {
function test_all_opcodes_except_bigint (line 165) | fn test_all_opcodes_except_bigint() {
function test_instruction_allowlist (line 176) | fn test_instruction_allowlist() {
FILE: openvm-riscv/src/isa/trace_generator/common.rs
function create_dummy_airs (line 6) | pub fn create_dummy_airs<E: VmCircuitExtension<BabyBearSC>>(
FILE: openvm-riscv/src/isa/trace_generator/cpu.rs
function create_dummy_chip_complex_cpu (line 19) | pub fn create_dummy_chip_complex_cpu(
FILE: openvm-riscv/src/isa/trace_generator/cuda.rs
function create_dummy_chip_complex_gpu (line 15) | pub fn create_dummy_chip_complex_gpu(
FILE: openvm-riscv/src/lib.rs
function build_elf_path (line 69) | pub fn build_elf_path<P: AsRef<Path>>(
function compile_openvm (line 91) | pub fn compile_openvm(
function compile_exe (line 150) | pub fn compile_exe(
type ExtendedVmConfig (line 200) | pub struct ExtendedVmConfig {
method transpiler (line 208) | fn transpiler(&self) -> Transpiler<BabyBear> {
type ExtendedVmConfigCpuBuilder (line 214) | pub struct ExtendedVmConfigCpuBuilder;
type VmConfig (line 220) | type VmConfig = ExtendedVmConfig;
type SystemChipInventory (line 221) | type SystemChipInventory = SystemChipInventory<BabyBearSC>;
type RecordArena (line 222) | type RecordArena = MatrixRecordArena<Val<BabyBearSC>>;
method create_chip_complex (line 224) | fn create_chip_complex(
type ExtendedVmConfigGpuBuilder (line 242) | pub struct ExtendedVmConfigGpuBuilder;
type VmConfig (line 246) | type VmConfig = ExtendedVmConfig;
type SystemChipInventory (line 247) | type SystemChipInventory = SystemChipInventoryGPU;
type RecordArena (line 248) | type RecordArena = DenseRecordArena;
method create_chip_complex (line 250) | fn create_chip_complex(
method generate_init_file_contents (line 274) | fn generate_init_file_contents(&self) -> Option<String> {
method write_to_init_file (line 278) | fn write_to_init_file(
function prove (line 287) | pub fn prove(
function compile_and_prove (line 371) | fn compile_and_prove(
function prove_simple (line 386) | fn prove_simple(
function prove_mock (line 405) | fn prove_mock(
function prove_recursion (line 424) | fn prove_recursion(
constant GUEST (line 443) | const GUEST: &str = "guest";
constant GUEST_ITER (line 444) | const GUEST_ITER: u32 = 1 << 10;
constant GUEST_APC (line 445) | const GUEST_APC: u64 = 1;
constant GUEST_SKIP_NO_APC_EXECUTED (line 446) | const GUEST_SKIP_NO_APC_EXECUTED: u64 = 56;
constant GUEST_SKIP_PGO (line 447) | const GUEST_SKIP_PGO: u64 = 0;
constant GUEST_KECCAK (line 449) | const GUEST_KECCAK: &str = "guest-keccak";
constant GUEST_KECCAK_ITER (line 450) | const GUEST_KECCAK_ITER: u32 = 1_000;
constant GUEST_KECCAK_ITER_SMALL (line 451) | const GUEST_KECCAK_ITER_SMALL: u32 = 10;
constant GUEST_KECCAK_ITER_LARGE (line 452) | const GUEST_KECCAK_ITER_LARGE: u32 = 25_000;
constant GUEST_KECCAK_APC (line 453) | const GUEST_KECCAK_APC: u64 = 1;
constant GUEST_KECCAK_APC_PGO (line 454) | const GUEST_KECCAK_APC_PGO: u64 = 10;
constant GUEST_KECCAK_APC_PGO_LARGE (line 455) | const GUEST_KECCAK_APC_PGO_LARGE: u64 = 100;
constant GUEST_KECCAK_SKIP (line 456) | const GUEST_KECCAK_SKIP: u64 = 0;
constant GUEST_SHA256_ITER (line 458) | const GUEST_SHA256_ITER: u32 = 1_000;
constant GUEST_SHA256_ITER_SMALL (line 459) | const GUEST_SHA256_ITER_SMALL: u32 = 10;
constant GUEST_SHA256_ITER_LARGE (line 460) | const GUEST_SHA256_ITER_LARGE: u32 = 25_000;
constant GUEST_SHA256 (line 461) | const GUEST_SHA256: &str = "guest-sha256";
constant GUEST_SHA256_APC_PGO (line 462) | const GUEST_SHA256_APC_PGO: u64 = 10;
constant GUEST_SHA256_APC_PGO_LARGE (line 463) | const GUEST_SHA256_APC_PGO_LARGE: u64 = 50;
constant GUEST_SHA256_SKIP (line 464) | const GUEST_SHA256_SKIP: u64 = 0;
constant GUEST_U256 (line 466) | const GUEST_U256: &str = "guest-u256";
constant GUEST_U256_APC_PGO (line 467) | const GUEST_U256_APC_PGO: u64 = 10;
constant GUEST_U256_SKIP (line 468) | const GUEST_U256_SKIP: u64 = 0;
constant GUEST_PAIRING (line 470) | const GUEST_PAIRING: &str = "guest-pairing";
constant GUEST_PAIRING_APC_PGO (line 471) | const GUEST_PAIRING_APC_PGO: u64 = 10;
constant GUEST_PAIRING_SKIP (line 472) | const GUEST_PAIRING_SKIP: u64 = 0;
constant GUEST_HINTS_TEST (line 474) | const GUEST_HINTS_TEST: &str = "guest-hints-test";
constant GUEST_ECC_HINTS (line 476) | const GUEST_ECC_HINTS: &str = "guest-ecc-powdr-affine-hint";
constant GUEST_ECC_APC_PGO (line 477) | const GUEST_ECC_APC_PGO: u64 = 50;
constant GUEST_ECC_SKIP (line 478) | const GUEST_ECC_SKIP: u64 = 0;
constant GUEST_ECC_ITER (line 481) | const GUEST_ECC_ITER: u32 = 0;
constant GUEST_ECC_PROJECTIVE (line 483) | const GUEST_ECC_PROJECTIVE: &str = "guest-ecc-projective";
constant GUEST_ECC_PROJECTIVE_APC_PGO (line 484) | const GUEST_ECC_PROJECTIVE_APC_PGO: u64 = 50;
constant GUEST_ECC_PROJECTIVE_SKIP (line 485) | const GUEST_ECC_PROJECTIVE_SKIP: u64 = 0;
constant GUEST_ECRECOVER_HINTS (line 487) | const GUEST_ECRECOVER_HINTS: &str = "guest-ecrecover";
constant GUEST_ECRECOVER_APC_PGO (line 488) | const GUEST_ECRECOVER_APC_PGO: u64 = 50;
constant GUEST_ECRECOVER_SKIP (line 489) | const GUEST_ECRECOVER_SKIP: u64 = 0;
constant GUEST_ECRECOVER_ITER (line 490) | const GUEST_ECRECOVER_ITER: u32 = 1;
function guest_prove_simple_no_apc_executed (line 493) | fn guest_prove_simple_no_apc_executed() {
function guest_prove_simple (line 528) | fn guest_prove_simple() {
function guest_prove_mock (line 538) | fn guest_prove_mock() {
function guest_prove_recursion (line 549) | fn guest_prove_recursion() {
function matmul_compile (line 560) | fn matmul_compile() {
function keccak_small_prove_simple (line 573) | fn keccak_small_prove_simple() {
function keccak_small_prove_simple_multi_segment (line 581) | fn keccak_small_prove_simple_multi_segment() {
function keccak_prove_simple (line 592) | fn keccak_prove_simple() {
function keccak_prove_many_apcs (line 601) | fn keccak_prove_many_apcs() {
function keccak_prove_large (line 627) | fn keccak_prove_large() {
function keccak_small_prove_mock (line 644) | fn keccak_small_prove_mock() {
function keccak_prove_mock (line 654) | fn keccak_prove_mock() {
function keccak_prove_multiple_pgo_modes (line 663) | fn keccak_prove_multiple_pgo_modes() {
function sha256_prove_simple (line 704) | fn sha256_prove_simple() {
function sha256_prove_mock (line 723) | fn sha256_prove_mock() {
function sha256_prove_many_apcs (line 742) | fn sha256_prove_many_apcs() {
function sha256_prove_large (line 768) | fn sha256_prove_large() {
function sha256_small_prove_simple (line 785) | fn sha256_small_prove_simple() {
function sha256_small_prove_mock (line 803) | fn sha256_small_prove_mock() {
function sha256_prove_multiple_pgo_modes (line 821) | fn sha256_prove_multiple_pgo_modes() {
function u256_prove_large (line 859) | fn u256_prove_large() {
function pairing_prove (line 882) | fn pairing_prove() {
function hints_test_prove (line 908) | fn hints_test_prove() {
function ecc_hint_prove (line 917) | fn ecc_hint_prove() {
function ecrecover_prove (line 933) | fn ecrecover_prove() {
function ecc_hint_prove_recursion_large (line 950) | fn ecc_hint_prove_recursion_large() {
function ecrecover_prove_recursion_large (line 967) | fn ecrecover_prove_recursion_large() {
function ecc_projective_prove (line 983) | fn ecc_projective_prove() {
function keccak_prove_recursion (line 1003) | fn keccak_prove_recursion() {
type GuestTestConfig (line 1012) | struct GuestTestConfig {
type MachineTestMetrics (line 1019) | struct MachineTestMetrics {
function test_machine_compilation (line 1026) | fn test_machine_compilation(
constant NON_POWDR_EXPECTED_MACHINE_COUNT (line 1111) | const NON_POWDR_EXPECTED_MACHINE_COUNT: usize = 19;
constant NON_POWDR_EXPECTED_SUM (line 1112) | const NON_POWDR_EXPECTED_SUM: AirMetrics = AirMetrics {
function guest_machine_pgo_modes (line 1123) | fn guest_machine_pgo_modes() {
function sha256_machine_pgo (line 1200) | fn sha256_machine_pgo() {
function ecc_hint_machine_pgo_cell (line 1277) | fn ecc_hint_machine_pgo_cell() {
function ecrecover_machine_pgo_cell (line 1326) | fn ecrecover_machine_pgo_cell() {
function keccak_machine_pgo_modes (line 1375) | fn keccak_machine_pgo_modes() {
function keccak_machine_cell_pgo_max_columns (line 1480) | fn keccak_machine_cell_pgo_max_columns() {
function test_get_bus_map (line 1554) | fn test_get_bus_map() {
FILE: openvm-riscv/tests/apc_builder_complex.rs
function assert_machine_output (line 8) | fn assert_machine_output(program: Vec<Instruction<BabyBear>>, test_name:...
function guest_top_block (line 17) | fn guest_top_block() {
function memcpy_block (line 35) | fn memcpy_block() {
function stack_accesses (line 54) | fn stack_accesses() {
function aligned_memcpy (line 73) | fn aligned_memcpy() {
function unaligned_memcpy (line 98) | fn unaligned_memcpy() {
function load_two_bytes_compare (line 126) | fn load_two_bytes_compare() {
function load_two_bytes_compare_unsigned (line 138) | fn load_two_bytes_compare_unsigned() {
function store_to_same_address (line 151) | fn store_to_same_address() {
function many_stores_relative_to_same_register (line 160) | fn many_stores_relative_to_same_register() {
function copy_byte (line 177) | fn copy_byte() {
function rotate (line 193) | fn rotate() {
FILE: openvm-riscv/tests/apc_builder_pseudo_instructions.rs
function assert_machine_output (line 8) | fn assert_machine_output(program: Vec<Instruction<BabyBear>>, test_name:...
function mv (line 18) | fn mv() {
function not (line 28) | fn not() {
function neg (line 40) | fn neg() {
function seqz (line 51) | fn seqz() {
function snez (line 63) | fn snez() {
function sltz (line 73) | fn sltz() {
function sgtz (line 83) | fn sgtz() {
function beqz (line 94) | fn beqz() {
function bnez (line 104) | fn bnez() {
function blez (line 114) | fn blez() {
function bgez (line 124) | fn bgez() {
function bltz (line 134) | fn bltz() {
function bgtz (line 144) | fn bgtz() {
function j (line 155) | fn j() {
function jr (line 165) | fn jr() {
function ret (line 175) | fn ret() {
function load_immediate (line 185) | fn load_immediate() {
FILE: openvm-riscv/tests/apc_builder_single_instructions.rs
function assert_machine_output (line 8) | fn assert_machine_output(program: Vec<Instruction<BabyBear>>, test_name:...
function single_add_1 (line 18) | fn single_add_1() {
function single_sub (line 27) | fn single_sub() {
function single_and_0 (line 36) | fn single_and_0() {
function single_xor (line 45) | fn single_xor() {
function single_mul (line 54) | fn single_mul() {
function single_loadw (line 65) | fn single_loadw() {
function single_loadbu (line 74) | fn single_loadbu() {
function single_loadhu (line 83) | fn single_loadhu() {
function single_storew (line 92) | fn single_storew() {
function single_storeh (line 101) | fn single_storeh() {
function single_storeb (line 110) | fn single_storeb() {
function single_loadh (line 120) | fn single_loadh() {
function single_loadb (line 129) | fn single_loadb() {
function single_loadb_imm0 (line 138) | fn single_loadb_imm0() {
function single_loadb_x0 (line 148) | fn single_loadb_x0() {
function single_beq (line 159) | fn single_beq() {
function single_bne (line 168) | fn single_bne() {
function single_blt (line 178) | fn single_blt() {
function single_bltu (line 187) | fn single_bltu() {
function single_bge (line 196) | fn single_bge() {
function single_bgeu (line 205) | fn single_bgeu() {
function single_srl (line 215) | fn single_srl() {
function single_sll (line 222) | fn single_sll() {
function single_sll_by_8 (line 229) | fn single_sll_by_8() {
function single_sra (line 236) | fn single_sra() {
function single_div (line 244) | fn single_div() {
function single_divu (line 251) | fn single_divu() {
function single_rem (line 258) | fn single_rem() {
function single_remu (line 265) | fn single_remu() {
FILE: openvm-riscv/tests/apc_builder_superblocks.rs
function assert_machine_output (line 8) | fn assert_machine_output(program: Vec<BasicBlock<Instruction<BabyBear>>>...
function bb (line 12) | fn bb(
function beq0_fallthrough (line 23) | fn beq0_fallthrough() {
function beq0_jump (line 36) | fn beq0_jump() {
function beq_fallthrough (line 49) | fn beq_fallthrough() {
function beq_jump (line 62) | fn beq_jump() {
function many_blocks (line 75) | fn many_blocks() {
FILE: openvm-riscv/tests/common/mod.rs
function original_vm_config (line 11) | pub fn original_vm_config() -> OriginalVmConfig<RiscvISA> {
function compile (line 31) | pub fn compile(superblock: SuperBlock<Instruction<BabyBear>>) -> String {
function assert_machine_output (line 38) | pub fn assert_machine_output(
FILE: openvm-riscv/tests/machine_extraction.rs
function extract_machine (line 11) | fn extract_machine() {
FILE: openvm/build.rs
function main (line 4) | fn main() {
FILE: openvm/metrics-viewer/spec.py
function load_metrics_dataframes (line 39) | def load_metrics_dataframes(
function is_normal_instruction_air (line 60) | def is_normal_instruction_air(name: str) -> bool:
function sum_metric (line 72) | def sum_metric(entries: list[Entry], metric_name: str) -> float:
function unique_metric (line 77) | def unique_metric(entries: list[Entry], metric_name: str) -> float:
function detect_version (line 84) | def detect_version(metrics_json: MetricsJson) -> Literal[1, 2]:
function extract_metrics (line 90) | def extract_metrics(run_name: str, metrics_json: MetricsJson) -> Metrics:
function fmt_ms (line 213) | def fmt_ms(ms: float) -> str:
function fmt_cells (line 216) | def fmt_cells(v: float) -> str:
function fmt_int (line 222) | def fmt_int(v: float) -> str:
function fmt_pct (line 225) | def fmt_pct(v: float) -> str:
function print_section (line 287) | def print_section(
function load_data (line 324) | def load_data(source: str) -> tuple[dict[str, Any], str]:
function resolve_experiments (line 335) | def resolve_experiments(
function main (line 362) | def main() -> None:
FILE: openvm/src/air_builder.rs
type PrepKeygenData (line 16) | pub struct PrepKeygenData<SC: StarkGenericConfig> {
type AirKeygenBuilder (line 21) | pub struct AirKeygenBuilder<SC: StarkGenericConfig> {
function compute_prep_data_for_air (line 26) | fn compute_prep_data_for_air<SC: StarkGenericConfig>(
function new (line 55) | pub fn new(pcs: &SC::Pcs, air: Arc<dyn AnyRap<SC>>) -> Self {
function get_symbolic_builder (line 63) | pub fn get_symbolic_builder(
function width (line 85) | pub fn width(&self) -> Option<usize> {
FILE: openvm/src/cuda_abi.rs
function _apc_tracegen (line 12) | pub fn _apc_tracegen(
function _apc_apply_derived_expr (line 24) | pub fn _apc_apply_derived_expr(
function _apc_apply_bus (line 36) | pub fn _apc_apply_bus(
type OriginalAir (line 68) | pub struct OriginalAir {
type Subst (line 77) | pub struct Subst {
type DerivedExprSpec (line 90) | pub struct DerivedExprSpec {
function apc_tracegen (line 97) | pub fn apc_tracegen(
function apc_apply_derived_expr (line 119) | pub fn apc_apply_derived_expr(
type OpCode (line 139) | pub enum OpCode {
type DevInteraction (line 152) | pub struct DevInteraction {
type ExprSpan (line 164) | pub struct ExprSpan {
function apc_apply_bus (line 174) | pub fn apc_apply_bus(
FILE: openvm/src/customize_exe.rs
constant POWDR_OPCODE (line 40) | pub const POWDR_OPCODE: usize = 0x10ff;
type BabyBearOpenVmApcAdapter (line 45) | pub struct BabyBearOpenVmApcAdapter<'a, ISA> {
type OpenVmExecutionState (line 50) | pub struct OpenVmExecutionState<'a, F, ISA> {
function from (line 58) | fn from(inner: &'a VmState<F, GuestMemory>) -> Self {
type RegisterAddress (line 67) | type RegisterAddress = ();
type Value (line 68) | type Value = u32;
method pc (line 70) | fn pc(&self) -> Self::Value {
method reg (line 74) | fn reg(&self, _addr: &Self::RegisterAddress) -> Self::Value {
method value_limb (line 78) | fn value_limb(_value: Self::Value, _limb_index: usize) -> Self::Value {
method global_clk (line 82) | fn global_clk(&self) -> usize {
type PowdrField (line 88) | type PowdrField = BabyBearField;
type Field (line 89) | type Field = BabyBear;
type InstructionHandler (line 90) | type InstructionHandler = OriginalAirs<Self::Field, ISA>;
type BusInteractionHandler (line 91) | type BusInteractionHandler = OpenVmBusInteractionHandler<Self::PowdrField>;
type Program (line 92) | type Program = Prog<'a, Self::Field>;
type Instruction (line 93) | type Instruction = Instr<Self::Field, ISA>;
type MemoryBusInteraction (line 94) | type MemoryBusInteraction<V: Ord + Clone + Eq + Display + Hash> =
type CustomBusTypes (line 96) | type CustomBusTypes = OpenVmBusType;
type ApcStats (line 97) | type ApcStats = OvmApcStats;
type AirId (line 98) | type AirId = String;
type ExecutionState (line 99) | type ExecutionState = OpenVmExecutionState<'a, BabyBear, ISA>;
method into_field (line 101) | fn into_field(e: Self::PowdrField) -> Self::Field {
method from_field (line 107) | fn from_field(e: Self::Field) -> Self::PowdrField {
method apc_stats (line 111) | fn apc_stats(
method is_allowed (line 136) | fn is_allowed(instruction: &Self::Instruction) -> bool {
method is_branching (line 140) | fn is_branching(instruction: &Self::Instruction) -> bool {
type Instr (line 146) | pub struct Instr<F, ISA> {
function from (line 152) | fn from(value: OpenVmInstruction<F>) -> Self {
method clone (line 165) | fn clone(&self) -> Self {
method fmt (line 174) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
method pc_step (line 180) | fn pc_step() -> u32 {
function pc_lookup_row (line 186) | fn pc_lookup_row(&self, pc: u64) -> Vec<F> {
function customize (line 204) | pub fn customize<'a, ISA: OpenVmISA, P: PgoAdapter<Adapter = BabyBearOpe...
type OvmApcStats (line 305) | pub struct OvmApcStats {
method new (line 310) | pub fn new(widths: AirWidthsDiff) -> Self {
type OpenVmApcCandidate (line 316) | pub struct OpenVmApcCandidate<ISA: OpenVmISA>(
function create (line 323) | fn create(apc_with_stats: AdapterApcWithStats<BabyBearOpenVmApcAdapter<'...
function inner (line 327) | fn inner(&self) -> &AdapterApcWithStats<BabyBearOpenVmApcAdapter<'a, ISA...
function into_inner (line 331) | fn into_inner(self) -> AdapterApcWithStats<BabyBearOpenVmApcAdapter<'a, ...
function cost_before_opt (line 335) | fn cost_before_opt(&self) -> usize {
function cost_after_opt (line 339) | fn cost_after_opt(&self) -> usize {
function value_per_use (line 343) | fn value_per_use(&self) -> usize {
FILE: openvm/src/empirical_constraints.rs
type Timestamp (line 31) | struct Timestamp {
type Row (line 39) | struct Row {
type Trace (line 50) | struct Trace {
method rows_by_pc (line 57) | fn rows_by_pc(&self) -> BTreeMap<u32, Vec<&Row>> {
method rows_sorted_by_time (line 65) | fn rows_sorted_by_time(&self) -> impl Iterator<Item = &Row> {
method take (line 69) | fn take(&mut self) -> Self {
function detect_empirical_constraints (line 76) | pub fn detect_empirical_constraints<ISA: OpenVmISA>(
function detect_empirical_constraints_from_input (line 109) | fn detect_empirical_constraints_from_input<ISA: OpenVmISA>(
function take_complete_blocks (line 234) | fn take_complete_blocks(constraint_detector: &ConstraintDetector, trace:...
type ConstraintDetector (line 260) | struct ConstraintDetector {
method new (line 293) | pub fn new(block_instruction_counts: HashMap<u64, usize>) -> Self {
method is_basic_block_start (line 300) | pub fn is_basic_block_start(&self, pc: u64) -> bool {
method finalize (line 304) | pub fn finalize(self) -> EmpiricalConstraints {
method process_trace (line 308) | pub fn process_trace(&mut self, trace: Trace, debug_info: DebugInfo) {
method detect_column_ranges_by_pc (line 331) | fn detect_column_ranges_by_pc(&self, trace: Trace) -> BTreeMap<u32, Ve...
method detect_column_ranges (line 340) | fn detect_column_ranges(&self, rows: &[&Row]) -> Vec<(u32, u32)> {
method generate_equivalence_classes_by_block (line 361) | fn generate_equivalence_classes_by_block(
method get_blocks (line 401) | fn get_blocks<'a>(&self, trace: &'a Trace) -> BTreeMap<u64, Vec<Concre...
type ConcreteBlock (line 268) | struct ConcreteBlock<'a> {
function equivalence_classes (line 273) | fn equivalence_classes(&self) -> Partition<BlockCell> {
function make_trace (line 438) | fn make_trace(rows_by_time_with_pc: Vec<(u32, Vec<u32>)>) -> Trace {
function test_constraint_detector (line 456) | fn test_constraint_detector() {
FILE: openvm/src/extraction_utils.rs
constant EXT_DEGREE (line 46) | const EXT_DEGREE: usize = 4;
type OriginalAirs (line 49) | pub struct OriginalAirs<F, ISA> {
type Field (line 61) | type Field = F;
type Instruction (line 62) | type Instruction = Instr<F, ISA>;
type AirId (line 63) | type AirId = String;
method get_instruction_air_and_id (line 65) | fn get_instruction_air_and_id(
method get_instruction_air_stats (line 78) | fn get_instruction_air_stats(&self, instruction: &Self::Instruction) -> ...
method degree_bound (line 84) | fn degree_bound(&self) -> DegreeBound {
function insert_opcode (line 90) | pub fn insert_opcode(
function get_instruction_metrics (line 112) | pub fn get_instruction_metrics(&self, opcode: VmOpcode) -> Option<&AirMe...
function allow_list (line 120) | pub fn allow_list(&self) -> Vec<VmOpcode> {
function airs_by_name (line 124) | pub fn airs_by_name(&self) -> impl Iterator<Item = (&String, &SymbolicMa...
function with_degree_bound (line 130) | fn with_degree_bound(degree_bound: DegreeBound) -> Self {
function get_air_machine (line 139) | pub fn get_air_machine(&self, air_name: &str) -> Option<&SymbolicMachine...
function record_arena_dimension_by_air_name_per_apc_call (line 146) | pub fn record_arena_dimension_by_air_name_per_apc_call<F, ISA: OpenVmISA>(
type ChipComplex (line 178) | type ChipComplex = OriginalCpuChipComplex;
type LazyChipComplex (line 180) | type LazyChipComplex = Option<ChipComplex>;
type CachedChipComplex (line 181) | type CachedChipComplex = Arc<Mutex<LazyChipComplex>>;
type ChipComplexGuard (line 183) | pub struct ChipComplexGuard<'a> {
type Target (line 188) | type Target = ChipComplex;
method deref (line 190) | fn deref(&self) -> &Self::Target {
type OriginalVmConfig (line 198) | pub struct OriginalVmConfig<ISA: OpenVmISA> {
function create_airs (line 205) | fn create_airs(&self) -> Result<AirInventory<BabyBearSC>, AirInventoryEr...
type Executor (line 211) | type Executor = <ISA::Config as VmExecutionConfig<BabyBear>>::Executor;
function create_executors (line 213) | fn create_executors(
function as_ref (line 221) | fn as_ref(&self) -> &SystemConfig {
function as_mut (line 227) | fn as_mut(&mut self) -> &mut SystemConfig {
function new (line 233) | pub fn new(config: ISA::Config) -> Self {
function config (line 240) | pub fn config(&self) -> &ISA::Config {
function config_mut (line 244) | pub fn config_mut(&mut self) -> &mut ISA::Config {
function chip_complex (line 250) | pub fn chip_complex(&self) -> ChipComplexGuard<'_> {
function airs (line 266) | pub fn airs(
function bus_map (line 324) | pub fn bus_map(&self) -> BusMap {
function chip_inventory_air_metrics (line 382) | pub fn chip_inventory_air_metrics(&self, max_degree: usize) -> HashMap<S...
function get_columns (line 398) | pub fn get_columns(air: Arc<dyn AnyRap<BabyBearSC>>) -> Vec<Arc<String>> {
function get_name (line 410) | pub fn get_name<SC: StarkGenericConfig>(air: Arc<dyn AnyRap<SC>>) -> Str...
function get_constraints (line 414) | pub fn get_constraints(
function get_air_metrics (line 421) | pub fn get_air_metrics(air: Arc<dyn AnyRap<BabyBearSC>>, max_degree: usi...
function symbolic_builder_with_degree (line 449) | pub fn symbolic_builder_with_degree(
type AirWidths (line 461) | pub struct AirWidths {
method sum (line 490) | fn sum<I: Iterator<Item = AirWidths>>(iter: I) -> AirWidths {
method total (line 496) | pub fn total(&self) -> usize {
method fmt (line 502) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type Output (line 468) | type Output = AirWidths;
method add (line 469) | fn add(self, rhs: AirWidths) -> AirWidths {
type Output (line 479) | type Output = AirWidths;
method sub (line 480) | fn sub(self, rhs: AirWidths) -> AirWidths {
type AirWidthsDiff (line 515) | pub struct AirWidthsDiff {
method new (line 521) | pub fn new(before: AirWidths, after: AirWidths) -> Self {
method columns_saved (line 525) | pub fn columns_saved(&self) -> AirWidths {
method sum (line 542) | fn sum<I: Iterator<Item = AirWidthsDiff>>(iter: I) -> AirWidthsDiff {
type Output (line 531) | type Output = AirWidthsDiff;
method add (line 533) | fn add(self, rhs: AirWidthsDiff) -> AirWidthsDiff {
FILE: openvm/src/isa.rs
type OriginalCpuChipComplex (line 29) | pub type OriginalCpuChipComplex = VmChipComplex<
type OriginalCpuChipInventory (line 35) | pub type OriginalCpuChipInventory =
type OriginalGpuChipComplex (line 39) | pub type OriginalGpuChipComplex =
type OriginalGpuChipInventory (line 42) | pub type OriginalGpuChipInventory = ChipInventory<BabyBearSC, DenseRecor...
type IsaApc (line 44) | pub type IsaApc<F, ISA> = Arc<powdr_autoprecompiles::Apc<F, Instr<F, ISA...
type OpenVmISA (line 46) | pub trait OpenVmISA: Send + Sync + Clone + 'static + Default {
method create_dummy_airs (line 83) | fn create_dummy_airs<E: VmCircuitExtension<BabyBearSC>>(
method create_original_chip_complex (line 88) | fn create_original_chip_complex(
method create_dummy_chip_complex_cpu (line 93) | fn create_dummy_chip_complex_cpu(
method create_dummy_chip_complex_gpu (line 100) | fn create_dummy_chip_complex_gpu(
method branching_opcodes (line 107) | fn branching_opcodes() -> HashSet<VmOpcode>;
method allowed_opcodes (line 110) | fn allowed_opcodes() -> HashSet<VmOpcode>;
method format (line 113) | fn format<F: PrimeField32>(instruction: &Instruction<F>) -> String;
method get_symbol_table (line 115) | fn get_symbol_table<'a>(program: &Self::LinkedProgram<'a>) -> SymbolTa...
method get_jump_destinations (line 118) | fn get_jump_destinations(original_program: &OriginalCompiledProgram<Se...
FILE: openvm/src/lib.rs
type BabyBearSC (line 69) | pub type BabyBearSC = BabyBearPoseidon2Config;
type PowdrSdkCpu (line 97) | pub type PowdrSdkCpu<ISA> =
type PowdrExecutionProfileSdkCpu (line 99) | pub type PowdrExecutionProfileSdkCpu<ISA> =
constant DEFAULT_OPENVM_DEGREE_BOUND (line 102) | pub const DEFAULT_OPENVM_DEGREE_BOUND: usize = 2 * DEFAULT_APP_LOG_BLOWU...
constant DEFAULT_DEGREE_BOUND (line 103) | pub const DEFAULT_DEGREE_BOUND: DegreeBound = DegreeBound {
function default_powdr_openvm_config (line 108) | pub fn default_powdr_openvm_config(apc: u64, skip: u64) -> PowdrConfig {
function format_fe (line 112) | pub fn format_fe<F: PrimeField32>(v: F) -> String {
type SpecializedConfig (line 133) | pub struct SpecializedConfig<ISA: OpenVmISA> {
type SpecializedConfigGpuBuilder (line 140) | pub struct SpecializedConfigGpuBuilder<ISA> {
type VmConfig (line 146) | type VmConfig = SpecializedConfig<ISA>;
type SystemChipInventory (line 147) | type SystemChipInventory = SystemChipInventoryGPU;
type RecordArena (line 148) | type RecordArena = DenseRecordArena;
function create_chip_complex (line 150) | fn create_chip_complex(
type SpecializedConfigCpuBuilder (line 174) | pub struct SpecializedConfigCpuBuilder<ISA> {
type VmConfig (line 188) | type VmConfig = SpecializedConfig<ISA>;
type SystemChipInventory (line 189) | type SystemChipInventory = SystemChipInventory<BabyBearSC>;
type RecordArena (line 190) | type RecordArena = MatrixRecordArena<Val<BabyBearSC>>;
function create_chip_complex (line 192) | fn create_chip_complex(
type PowdrGpuProverExt (line 217) | struct PowdrGpuProverExt<ISA> {
function extend_prover (line 226) | fn extend_prover(
type PeripheryBusIds (line 274) | pub struct PeripheryBusIds {
type PowdrCpuProverExt (line 281) | pub struct PowdrCpuProverExt<ISA> {
function extend_prover (line 291) | fn extend_prover(
function get_periphery_bus_ids (line 339) | fn get_periphery_bus_ids<SC, RA, PB>(inventory: &ChipInventory<SC, RA, P...
function transpiler (line 369) | fn transpiler(&self) -> Transpiler<BabyBear> {
method generate_init_file_contents (line 376) | fn generate_init_file_contents(&self) -> Option<String> {
method write_to_init_file (line 380) | fn write_to_init_file(
function as_ref (line 392) | fn as_ref(&self) -> &SystemConfig {
function as_mut (line 398) | fn as_mut(&mut self) -> &mut SystemConfig {
type SpecializedExecutor (line 407) | pub enum SpecializedExecutor<F: PrimeField32, ISA: OpenVmISA> {
function from (line 418) | fn from(value: PowdrExtensionExecutor<ISA>) -> Self {
function create_airs (line 426) | fn create_airs(&self) -> Result<AirInventory<BabyBearSC>, AirInventoryEr...
type Executor (line 435) | type Executor = SpecializedExecutor<BabyBear, ISA>;
function create_executors (line 437) | fn create_executors(
function new (line 447) | pub fn new(
type AirMetrics (line 463) | pub struct AirMetrics {
method sum (line 492) | fn sum<I: Iterator<Item = AirMetrics>>(iter: I) -> AirMetrics {
method total_width (line 498) | pub fn total_width(&self) -> usize {
method from (line 470) | fn from(metrics: AirMetrics) -> Self {
type Output (line 480) | type Output = AirMetrics;
method add (line 482) | fn add(self, rhs: AirMetrics) -> AirMetrics {
function air_metrics (line 505) | pub fn air_metrics(
function execute (line 552) | pub fn execute<ISA: OpenVmISA>(
function execution_profile_from_guest (line 577) | pub fn execution_profile_from_guest<ISA: OpenVmISA>(
FILE: openvm/src/powdr_extension/chip.rs
type PowdrChipCpu (line 34) | pub struct PowdrChipCpu<ISA: OpenVmISA> {
function new (line 41) | pub(crate) fn new(
type PowdrAir (line 64) | pub struct PowdrAir<F> {
function columns (line 71) | fn columns(&self) -> Option<Vec<String>> {
function new (line 77) | pub fn new(machine: SymbolicMachine<F>) -> Self {
function width (line 86) | fn width(&self) -> usize {
function eval (line 100) | fn eval(&self, builder: &mut AB) {
type PowdrChipGpu (line 152) | pub struct PowdrChipGpu<ISA: OpenVmISA> {
function new (line 159) | pub(crate) fn new(
FILE: openvm/src/powdr_extension/executor/mod.rs
type PowdrExecutor (line 46) | pub struct PowdrExecutor<ISA: OpenVmISA> {
type OriginalArenas (line 64) | pub enum OriginalArenas<A> {
function ensure_initialized (line 73) | fn ensure_initialized<ISA: OpenVmISA>(
type InitializedOriginalArenas (line 100) | pub struct InitializedOriginalArenas<A> {
function new (line 108) | pub fn new<ISA: OpenVmISA>(
function arena_mut_by_index (line 148) | fn arena_mut_by_index(&mut self, index: usize) -> &mut ArenaPair<A> {
function real_arena_mut_by_index (line 156) | fn real_arena_mut_by_index(&mut self, index: usize) -> &mut A {
function dummy_arena_mut_by_index (line 161) | fn dummy_arena_mut_by_index(&mut self, index: usize) -> &mut A {
function take_real_arena (line 165) | pub fn take_real_arena(&mut self, air_name: &str) -> Option<A> {
type ArenaPair (line 171) | pub struct ArenaPair<A> {
type RecordArenaDimension (line 177) | pub struct RecordArenaDimension {
type CachedInstructionMeta (line 184) | struct CachedInstructionMeta {
type PowdrPreCompute (line 193) | struct PowdrPreCompute<F, Ctx> {
function pre_compute_size (line 200) | fn pre_compute_size(&self) -> usize {
function pre_compute (line 207) | fn pre_compute<Ctx>(
function handler (line 224) | fn handler<Ctx>(
function metered_pre_compute_size (line 240) | fn metered_pre_compute_size(&self) -> usize {
function metered_pre_compute (line 247) | fn metered_pre_compute<Ctx>(
function metered_handler (line 266) | fn metered_handler<Ctx>(
function is_aot_supported (line 287) | fn is_aot_supported(&self, _inst: &Instruction<BabyBear>) -> bool {
function generate_x86_asm (line 291) | fn generate_x86_asm(
function is_aot_metered_supported (line 302) | fn is_aot_metered_supported(&self, _inst: &Instruction<BabyBear>) -> bool {
function generate_x86_metered_asm (line 306) | fn generate_x86_metered_asm(
function pre_compute_impl (line 321) | fn pre_compute_impl<Ctx>(
function pre_compute_impl (line 392) | fn pre_compute_impl<Ctx>(
function execute_e12_impl (line 404) | unsafe fn execute_e12_impl<F: PrimeField32, CTX: ExecutionCtxTrait, ISA:...
function execute_e1_impl (line 429) | unsafe fn execute_e1_impl<F: PrimeField32, CTX: ExecutionCtxTrait, ISA: ...
function execute_e2_impl (line 439) | unsafe fn execute_e2_impl<F: PrimeField32, CTX: MeteredExecutionCtxTrait...
function execute (line 460) | fn execute(
function get_opcode_name (line 527) | fn get_opcode_name(&self, opcode: usize) -> String {
function execute (line 534) | fn execute(
function get_opcode_name (line 601) | fn get_opcode_name(&self, opcode: usize) -> String {
function new (line 607) | pub fn new(
FILE: openvm/src/powdr_extension/opcode.rs
type PowdrOpcode (line 5) | pub struct PowdrOpcode {
constant CLASS_OFFSET (line 12) | const CLASS_OFFSET: usize = unreachable!();
method from_usize (line 14) | fn from_usize(value: usize) -> Self {
method local_usize (line 21) | fn local_usize(&self) -> usize {
method global_opcode (line 26) | fn global_opcode(&self) -> openvm_instructions::VmOpcode {
FILE: openvm/src/powdr_extension/trace_generator/common.rs
type DummyExecutor (line 11) | pub enum DummyExecutor<F: PrimeField32, ISA: OpenVmISA> {
type SharedExecutor (line 19) | pub enum SharedExecutor<F: PrimeField32> {
FILE: openvm/src/powdr_extension/trace_generator/cpu/inventory.rs
type DummyChipComplex (line 9) | pub type DummyChipComplex<SC> =
FILE: openvm/src/powdr_extension/trace_generator/cpu/mod.rs
type SharedCpuTrace (line 33) | pub struct SharedCpuTrace<F> {
type Values (line 38) | type Values = Vec<F>;
function width (line 40) | fn width(&self) -> usize {
function values (line 44) | fn values(&self) -> &Self::Values {
function from (line 50) | fn from(matrix: Arc<RowMajorMatrix<F>>) -> Self {
function generate_proving_ctx (line 58) | fn generate_proving_ctx(&self, _: R) -> AirProvingContext<PB> {
type PowdrTraceGeneratorCpu (line 69) | pub struct PowdrTraceGeneratorCpu<ISA: OpenVmISA> {
function new (line 77) | pub fn new(
function generate_witness (line 91) | pub fn generate_witness(
FILE: openvm/src/powdr_extension/trace_generator/cpu/periphery.rs
type PowdrPeripheryInstancesCpu (line 27) | pub struct PowdrPeripheryInstancesCpu<ISA> {
type SharedPeripheryChipsCpu (line 37) | pub struct SharedPeripheryChipsCpu<ISA> {
function new (line 45) | pub fn new(
type Executor (line 81) | type Executor = DummyExecutor<F, ISA>;
function extend_execution (line 83) | fn extend_execution(
function extend_circuit (line 95) | fn extend_circuit(&self, inventory: &mut AirInventory<SC>) -> Result<(),...
type SharedPeripheryChipsCpuProverExt (line 127) | pub struct SharedPeripheryChipsCpuProverExt;
method extend_prover (line 140) | fn extend_prover(
function apply (line 175) | pub fn apply(
FILE: openvm/src/powdr_extension/trace_generator/cuda/inventory.rs
type GpuDummyChipComplex (line 7) | pub type GpuDummyChipComplex<SC> =
FILE: openvm/src/powdr_extension/trace_generator/cuda/mod.rs
function emit_expr (line 49) | fn emit_expr(
function emit_expr_span (line 84) | fn emit_expr_span(
function compile_derived_to_gpu (line 100) | fn compile_derived_to_gpu(
function compile_bus_to_gpu (line 143) | pub fn compile_bus_to_gpu(
type PowdrTraceGeneratorGpu (line 179) | pub struct PowdrTraceGeneratorGpu<ISA: OpenVmISA> {
function new (line 187) | pub fn new(
function try_generate_witness (line 201) | fn try_generate_witness(
function generate_proving_ctx (line 400) | fn generate_proving_ctx(&self, _: R) -> AirProvingContext<PB> {
FILE: openvm/src/powdr_extension/trace_generator/cuda/periphery.rs
type PowdrPeripheryInstancesGpu (line 25) | pub struct PowdrPeripheryInstancesGpu<ISA> {
type SharedPeripheryChipsGpu (line 35) | pub struct SharedPeripheryChipsGpu<ISA> {
function new (line 43) | pub fn new(
type Executor (line 88) | type Executor = DummyExecutor<F, ISA>;
function extend_execution (line 90) | fn extend_execution(
function extend_circuit (line 102) | fn extend_circuit(&self, inventory: &mut AirInventory<SC>) -> Result<(),...
type SharedPeripheryChipsGpuProverExt (line 148) | pub struct SharedPeripheryChipsGpuProverExt;
method extend_prover (line 154) | fn extend_prover(
FILE: openvm/src/powdr_extension/vm.rs
type PowdrExtension (line 33) | pub struct PowdrExtension<F, ISA: OpenVmISA> {
type PowdrPrecompile (line 42) | pub struct PowdrPrecompile<F, ISA: OpenVmISA> {
function new (line 54) | pub fn new(
function new (line 73) | pub fn new(
type PowdrExtensionExecutor (line 90) | pub enum PowdrExtensionExecutor<ISA: OpenVmISA> {
type Executor (line 95) | type Executor = PowdrExtensionExecutor<ISA>;
function extend_execution (line 97) | fn extend_execution(
function extend_circuit (line 125) | fn extend_circuit(&self, inventory: &mut AirInventory<SC>) -> Result<(),...
function as_any_kind (line 135) | fn as_any_kind(&self) -> &dyn std::any::Any {
function as_any_kind_mut (line 141) | fn as_any_kind_mut(&mut self) -> &mut dyn std::any::Any {
function pre_compute_size (line 151) | fn pre_compute_size(&self) -> usize {
function pre_compute (line 158) | fn pre_compute<Ctx>(
function handler (line 176) | fn handler<Ctx>(
function metered_pre_compute_size (line 197) | fn metered_pre_compute_size(&self) -> usize {
function metered_pre_compute (line 204) | fn metered_pre_compute<Ctx>(
function metered_handler (line 223) | fn metered_handler<Ctx>(
function is_aot_supported (line 247) | fn is_aot_supported(&self, inst: &Instruction<BabyBear>) -> bool {
function generate_x86_asm (line 253) | fn generate_x86_asm(
function is_aot_metered_supported (line 270) | fn is_aot_metered_supported(&self, inst: &Instruction<BabyBear>) -> bool {
function generate_x86_metered_asm (line 276) | fn generate_x86_metered_asm(
function execute (line 294) | fn execute(
function get_opcode_name (line 308) | fn get_opcode_name(&self, opcode: usize) -> String {
FILE: openvm/src/program.rs
type CompiledProgram (line 17) | pub struct CompiledProgram<ISA: OpenVmISA> {
type OriginalCompiledProgram (line 23) | pub struct OriginalCompiledProgram<'a, ISA: OpenVmISA> {
function new (line 30) | pub fn new(
function collect_basic_blocks (line 43) | pub fn collect_basic_blocks(&self) -> Vec<BasicBlock<Instr<BabyBear, ISA...
function compiled_program (line 52) | pub fn compiled_program(&self, degree_bound: DegreeBound) -> CompiledPro...
type Prog (line 62) | pub struct Prog<'a, F>(&'a OpenVmProgram<F>);
function from (line 65) | fn from(program: &'a OpenVmProgram<F>) -> Self {
function base_pc (line 71) | fn base_pc(&self) -> u64 {
function instructions (line 75) | fn instructions(&self) -> Box<dyn Iterator<Item = Instr<F, ISA>> + '_> {
function length (line 84) | fn length(&self) -> u32 {
FILE: openvm/src/test_utils.rs
function compile_apc (line 22) | pub fn compile_apc<ISA: OpenVmISA>(
function assert_apc_snapshot (line 76) | pub fn assert_apc_snapshot(
function assert_apc_machine_output (line 120) | pub fn assert_apc_machine_output<ISA: OpenVmISA>(
FILE: openvm/src/trace_generation.rs
function do_with_trace (line 43) | pub fn do_with_trace<ISA: OpenVmISA>(
function do_with_cpu_trace (line 60) | pub fn do_with_cpu_trace<ISA: OpenVmISA>(
function do_with_trace_with_sdk (line 76) | fn do_with_trace_with_sdk<ISA: OpenVmISA, E, VB, NB>(
function create_app_config (line 148) | fn create_app_config<ISA: OpenVmISA>(
FILE: openvm/src/utils.rs
type OpenVmReference (line 22) | pub enum OpenVmReference {
method fmt (line 31) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type UnsupportedOpenVmReferenceError (line 46) | pub struct UnsupportedOpenVmReferenceError;
type Error (line 49) | type Error = UnsupportedOpenVmReferenceError;
method try_from (line 51) | fn try_from(value: OpenVmReference) -> Result<Self, Self::Error> {
function symbolic_to_algebraic (line 59) | pub fn symbolic_to_algebraic<F: PrimeField32>(
function openvm_bus_interaction_to_powdr (line 106) | pub fn openvm_bus_interaction_to_powdr<F: PrimeField32>(
function get_pil (line 122) | pub fn get_pil<F: PrimeField32>(
function format_bus_interaction (line 203) | fn format_bus_interaction<F: PrimeField32>(
function format_expr (line 226) | fn format_expr<F: PrimeField32>(
FILE: riscv-elf/src/bin/elf-labels.rs
function main (line 14) | fn main() {
function print_elf_info_32 (line 92) | fn print_elf_info_32(program: &powdr_riscv_elf::ElfProgram) {
function print_elf_info_64 (line 157) | fn print_elf_info_64(labels: &rv64::Rv64Labels) {
FILE: riscv-elf/src/debug_info.rs
type Reader (line 19) | type Reader<'a> = EndianSlice<'a, LittleEndian>;
type Error (line 22) | pub enum Error {
type DebugInfo (line 33) | pub struct DebugInfo {
method new (line 54) | pub fn new(
type SourceLocationInfo (line 45) | pub struct SourceLocationInfo {
function read_source_locations (line 119) | fn read_source_locations(
function read_unit_symbols (line 182) | fn read_unit_symbols(
function load_dwarf_sections (line 286) | fn load_dwarf_sections<'a>(elf: &Elf, file_buffer: &'a [u8]) -> Result<D...
function find_attr (line 325) | fn find_attr<'a>(
function as_str (line 338) | fn as_str<'a>(
function get_static_var_address (line 345) | fn get_static_var_address(
function get_function_start (line 371) | fn get_function_start(
function filter_locations_in_text (line 401) | fn filter_locations_in_text(locations: &mut Vec<SourceLocationInfo>, add...
function find_first_idx (line 416) | fn find_first_idx(slice: &[SourceLocationInfo], addr: u32) -> usize {
type SymbolTable (line 430) | pub struct SymbolTable(BTreeMap<u32, Vec<String>>);
method new (line 433) | pub fn new(elf: &Elf) -> SymbolTable {
method default_label (line 448) | fn default_label(addr: u32) -> Cow<'static, str> {
method try_get_one (line 453) | pub fn try_get_one(&self, addr: u32) -> Option<&str> {
method get_one (line 460) | pub fn get_one(&self, addr: u32) -> Cow<'_, str> {
method get_all (line 468) | pub fn get_all(&self, addr: u32) -> impl Iterator<Item = Cow<'_, str>> {
method table (line 483) | pub fn table(&self) -> &BTreeMap<u32, Vec<String>> {
method try_get_one_or_preceding (line 489) | pub fn try_get_one_or_preceding(&self, addr: u64) -> Option<(&str, u32...
method into_table (line 498) | pub fn into_table(self) -> BTreeMap<u32, Vec<String>> {
method from_table (line 502) | pub fn from_table(table: BTreeMap<u32, Vec<String>>) -> Self {
function read_symbol_table (line 507) | fn read_symbol_table(elf: &Elf) -> Vec<(String, u32)> {
function dedup_names (line 524) | fn dedup_names(symbols: &mut Vec<(String, u32)>) {
function dedup_names_pass (line 532) | fn dedup_names_pass(symbols: &mut Vec<(String, u32)>) -> bool {
function dedup_names (line 571) | fn dedup_names() {
FILE: riscv-elf/src/lib.rs
constant PT_POWDR_PROVER_DATA (line 34) | pub const PT_POWDR_PROVER_DATA: u32 = 0x600000da;
type ElfProgram (line 36) | pub struct ElfProgram {
method debug_info (line 279) | pub fn debug_info(&self) -> &DebugInfo {
method text_labels (line 283) | pub fn text_labels(&self) -> &BTreeSet<u32> {
function load_elf (line 45) | pub fn load_elf(file_name: &Path) -> ElfProgram {
function load_elf_from_buffer (line 51) | pub fn load_elf_from_buffer(file_buffer: &[u8]) -> ElfProgram {
function pie_relocate_data_sections (line 211) | fn pie_relocate_data_sections(
function static_relocate_data_sections (line 243) | fn static_relocate_data_sections(
method take_source_files_info (line 289) | fn take_source_files_info(&mut self) -> impl Iterator<Item = SourceFileI...
method take_initial_mem (line 302) | fn take_initial_mem(&mut self) -> impl Iterator<Item = MemEntry> {
method take_executable_statements (line 327) | fn take_executable_statements(
method prover_data_bounds (line 393) | fn prover_data_bounds(&self) -> (u32, u32) {
method start_function (line 397) | fn start_function(&self) -> impl AsRef<str> {
type WrappedArgs (line 404) | struct WrappedArgs<'a> {
type Error (line 410) | type Error = String;
method l (line 412) | fn l(&self) -> Result<impl AsRef<str>, Self::Error> {
method r (line 424) | fn r(&self) -> Result<Register, Self::Error> {
method rri (line 436) | fn rri(&self) -> Result<(Register, Register, u32), Self::Error> {
method rrr (line 452) | fn rrr(&self) -> Result<(Register, Register, Register), Self::Error> {
method rrr2 (line 468) | fn rrr2(&self) -> Result<(Register, Register, Register), Self::Error> {
method ri (line 484) | fn ri(&self) -> Result<(Register, u32), Self::Error> {
method rr (line 496) | fn rr(&self) -> Result<(Register, Register), Self::Error> {
method rrl (line 508) | fn rrl(
method rl (line 526) | fn rl(&self) -> Result<(Register, impl AsRef<str>), Self::Error> {
method rro (line 550) | fn rro(&self) -> Result<(Register, Register, u32), Self::Error> {
method empty (line 579) | fn empty(&self) -> Result<(), Self::Error> {
type AddressMap (line 595) | pub struct AddressMap<'a>(BTreeMap<u32, &'a ProgramHeader>);
function is_in_data_section (line 598) | fn is_in_data_section(&self, addr: u32) -> bool {
function is_in_text_section (line 603) | fn is_in_text_section(&self, addr: u32) -> bool {
function get_section_of_addr (line 608) | fn get_section_of_addr(&self, addr: u32) -> Option<&ProgramHeader> {
type Data (line 626) | enum Data {
function load_data_section (line 631) | fn load_data_section(mut addr: u32, data: &[u8], data_map: &mut BTreeMap...
type UnimpOrInstruction (line 647) | enum UnimpOrInstruction {
method len (line 654) | fn len(&self) -> u32 {
type MaybeInstruction (line 666) | struct MaybeInstruction {
type HighLevelImmediate (line 672) | enum HighLevelImmediate {
type HighLevelArgs (line 679) | struct HighLevelArgs {
method default (line 688) | fn default() -> Self {
type Location (line 699) | struct Location {
type HighLevelInsn (line 705) | struct HighLevelInsn {
type ReadOrWrite (line 711) | enum ReadOrWrite<'a, T> {
type InstructionLifter (line 716) | struct InstructionLifter<'a> {
function composed_immediate (line 723) | fn composed_immediate(
function try_map_two (line 773) | fn try_map_two(
function map_one (line 970) | fn map_one(&mut self, insn: MaybeInstruction) -> HighLevelInsn {
function search_text_addrs (line 1054) | fn search_text_addrs(
function lift_instructions (line 1075) | fn lift_instructions(
type RiscVInstructionIterator (line 1092) | struct RiscVInstructionIterator<'a> {
function new (line 1098) | fn new(base_addr: u32, data: &[u8]) -> RiscVInstructionIterator<'_> {
type Item (line 1107) | type Item = MaybeInstruction;
method next (line 1109) | fn next(&mut self) -> Option<Self::Item> {
function to_32bit_equivalent (line 1191) | fn to_32bit_equivalent(mut insn: Ins) -> Ins {
type TwoOrOneMapper (line 1318) | trait TwoOrOneMapper<E, R> {
method try_map_two (line 1320) | fn try_map_two(&mut self, first: &E, second: &E) -> Option<R>;
method map_one (line 1322) | fn map_one(&mut self, element: E) -> R;
function try_map_two_by_two (line 1329) | fn try_map_two_by_two<E, R>(
FILE: riscv-elf/src/rv64.rs
type JumpDest (line 13) | pub struct JumpDest {
type Rv64Labels (line 21) | pub struct Rv64Labels {
function compute_jumpdests (line 34) | pub fn compute_jumpdests(file_name: &Path) -> Rv64Labels {
function compute_jumpdests_from_buffer (line 40) | pub fn compute_jumpdests_from_buffer(file_buffer: &[u8]) -> Rv64Labels {
function scan_for_jump_targets (line 119) | fn scan_for_jump_targets(
FILE: riscv-types/src/lib.rs
type Register (line 5) | pub struct Register {
method new (line 10) | pub fn new(value: u8) -> Self {
method is_zero (line 14) | pub fn is_zero(&self) -> bool {
method addr (line 18) | pub fn addr(&self) -> u8 {
method fmt (line 69) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 75) | fn from(s: &str) -> Self {
constant REGISTER_NAMES (line 25) | pub const REGISTER_NAMES: [&str; 3] = ["main::query_arg_1", "main::query...
constant REGISTER_MEMORY_NAMES (line 28) | pub const REGISTER_MEMORY_NAMES: [&str; 37] = [
type Statement (line 84) | pub enum Statement<'a, L: AsRef<str>, A: InstructionArgs> {
type MemEntry (line 90) | pub struct MemEntry {
type SourceFileInfo (line 96) | pub struct SourceFileInfo<'a> {
type RiscVProgram (line 103) | pub trait RiscVProgram {
method take_source_files_info (line 105) | fn take_source_files_info(&mut self) -> impl Iterator<Item = SourceFil...
method take_initial_mem (line 108) | fn take_initial_mem(&mut self) -> impl Iterator<Item = MemEntry>;
method take_executable_statements (line 111) | fn take_executable_statements(
method prover_data_bounds (line 116) | fn prover_data_bounds(&self) -> (u32, u32);
method start_function (line 119) | fn start_function(&self) -> impl AsRef<str>;
type InstructionArgs (line 122) | pub trait InstructionArgs {
method l (line 125) | fn l(&self) -> Result<impl AsRef<str>, Self::Error>;
method r (line 126) | fn r(&self) -> Result<Register, Self::Error>;
method rri (line 127) | fn rri(&self) -> Result<(Register, Register, u32), Self::Error>;
method rrr (line 129) | fn rrr(&self) -> Result<(Register, Register, Register), Self::Error>;
method rrr2 (line 131) | fn rrr2(&self) -> Result<(Register, Register, Register), Self::Error>;
method ri (line 132) | fn ri(&self) -> Result<(Register, u32), Self::Error>;
method rr (line 133) | fn rr(&self) -> Result<(Register, Register), Self::Error>;
method rrl (line 134) | fn rrl(&self) -> Result<(Register, Register, impl AsRef<str>), Self::E...
method rl (line 135) | fn rl(&self) -> Result<(Register, impl AsRef<str>), Self::Error>;
method rro (line 136) | fn rro(&self) -> Result<(Register, Register, u32), Self::Error>;
method empty (line 137) | fn empty(&self) -> Result<(), Self::Error>;
FILE: scripts/analyze_nightly.py
function is_apc_config (line 39) | def is_apc_config(config: str) -> bool:
class BenchmarkResult (line 48) | class BenchmarkResult:
class ComparisonResult (line 57) | class ComparisonResult:
function fetch_url (line 69) | def fetch_url(url: str, headers: Optional[dict] = None) -> str:
function get_results_directories (line 85) | def get_results_directories() -> list[str]:
function fetch_benchmark_results (line 110) | def fetch_benchmark_results(run_dir: str, benchmark: str) -> Optional[Be...
function compare_results (line 148) | def compare_results(
function print_error_report (line 178) | def print_error_report(error_msg: str) -> None:
function format_change_percent (line 187) | def format_change_percent(change: float) -> str:
function format_report (line 197) | def format_report(
function main (line 254) | def main():
Condensed preview — 308 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,210K chars).
[
{
"path": ".config/nextest.toml",
"chars": 349,
"preview": "# Profiles to fail after a timeout, but continue with the other tests \n[profile.quick-10]\nslow-timeout = { period = \"10s"
},
{
"path": ".gitattributes",
"chars": 64,
"preview": "**/*.asm linguist-language=Rust\n**/*.pil linguist-language=Rust\n"
},
{
"path": ".github/actions/init-testing-instance/action.yml",
"chars": 1425,
"preview": "name: \"Init testing instance\"\ndescription: \"Initialises a testing instance with all required tools and fetches the preco"
},
{
"path": ".github/actions/init-testing-instance-gpu/action.yml",
"chars": 1573,
"preview": "name: \"Init testing instance (GPU)\"\ndescription: \"Initialises a testing instance with all required tools and fetches the"
},
{
"path": ".github/actions/patch-openvm-reth-benchmark/action.yml",
"chars": 1151,
"preview": "name: \"Patch openvm-reth-benchmark\"\ndescription: \"Checks out powdr-labs/openvm-reth-benchmark at a fixed ref and patches"
},
{
"path": ".github/runner/Dockerfile",
"chars": 1785,
"preview": "#\n# Runner for powdr github actions.\n# We don't automate runner token generation yet. This image should be used as follo"
},
{
"path": ".github/workflows/build-cache.yml",
"chars": 2156,
"preview": "name: Generate rust cache for PR builds\non:\n workflow_dispatch:\n schedule:\n - cron: '0 2 * * *' # run at 2 AM UTC\n\n"
},
{
"path": ".github/workflows/dead-links.yml",
"chars": 303,
"preview": "name: Check markdown links\non: [pull_request, merge_group]\njobs:\n markdown-link-check:\n runs-on: ubuntu-24.04\n st"
},
{
"path": ".github/workflows/nightly-analyze.yml",
"chars": 2285,
"preview": "name: Nightly Regression Analysis\n\non:\n workflow_dispatch:\n workflow_run:\n workflows: [\"Nightly tests\"]\n types:\n"
},
{
"path": ".github/workflows/nightly-tests.yml",
"chars": 12834,
"preview": "name: Nightly tests\non:\n workflow_dispatch:\n schedule:\n - cron: \"0 23 * * *\" # run at 11pm UTC\n\nenv:\n CARGO_TERM_C"
},
{
"path": ".github/workflows/post-merge-tests.yml",
"chars": 2617,
"preview": "name: Post-merge APC tests\non:\n workflow_dispatch:\n push:\n branches:\n - main\n paths:\n - \"**.rs\"\n "
},
{
"path": ".github/workflows/pr-tests-with-secrets.yml",
"chars": 4699,
"preview": "name: PR tests (with secrets)\n\n# This workflow uses pull_request_target to allow external PRs to access secrets\n# after "
},
{
"path": ".github/workflows/pr-tests.yml",
"chars": 7617,
"preview": "name: PR tests\n\non:\n workflow_dispatch:\n pull_request:\n types: [opened, synchronize, reopened, ready_for_review]\n "
},
{
"path": ".gitignore",
"chars": 400,
"preview": "# Generated by Cargo\n# will have compiled files and executables\n/target/\n\n# Cargo configuration\n/.cargo/\n\n# Remove Cargo"
},
{
"path": "CLAUDE.md",
"chars": 5750,
"preview": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## "
},
{
"path": "Cargo.toml",
"chars": 9417,
"preview": "[workspace]\n\nresolver = \"2\"\n\nmembers = [\n \"number\",\n \"constraint-solver\",\n \"expression\",\n \"riscv-elf\",\n \"riscv-type"
},
{
"path": "LICENSE-APACHE",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "LICENSE-MIT",
"chars": 1036,
"preview": "MIT License\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associate"
},
{
"path": "README.md",
"chars": 2090,
"preview": "<p align=\"center\">\n <img src=\"assets/powdr_wires.png\" width=\"600\">\n</p>\n\n# powdr\n\n[ candidate effectiveness in "
},
{
"path": "autoprecompile-analyzer/index.html",
"chars": 88269,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-widt"
},
{
"path": "autoprecompiles/Cargo.toml",
"chars": 1150,
"preview": "[package]\nname = \"powdr-autoprecompiles\"\nversion.workspace = true\nedition.workspace = true\nlicense.workspace = true\nhome"
},
{
"path": "autoprecompiles/benches/optimizer_benchmark.rs",
"chars": 1899,
"preview": "use criterion::{black_box, criterion_group, criterion_main, Criterion};\nuse powdr_autoprecompiles::{\n bus_map::BusMap"
},
{
"path": "autoprecompiles/scripts/plot_effectiveness.py",
"chars": 6887,
"preview": "#!/usr/bin/env python3\n\nimport json\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport matplotlib.colors as mcol"
},
{
"path": "autoprecompiles/scripts/rank_apc_candidates.py",
"chars": 9611,
"preview": "#!/usr/bin/env python3\n\"\"\"\nSimple APC Candidates JSON Parser\n\nThis script parses the apc_candidates.json file and extrac"
},
{
"path": "autoprecompiles/scripts/readme.md",
"chars": 161,
"preview": "### Scripts\n\nSet up (from the project root):\n\n```bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r aut"
},
{
"path": "autoprecompiles/scripts/requirements.txt",
"chars": 17,
"preview": "pandas\nmatplotlib"
},
{
"path": "autoprecompiles/src/adapter.rs",
"chars": 6331,
"preview": "use powdr_constraint_solver::constraint_system::BusInteractionHandler;\nuse std::collections::BTreeMap;\nuse std::hash::Ha"
},
{
"path": "autoprecompiles/src/blocks/detection.rs",
"chars": 2696,
"preview": "use std::collections::BTreeSet;\n\nuse crate::{\n adapter::Adapter,\n blocks::{BasicBlock, Program},\n};\n\n/// Collects "
},
{
"path": "autoprecompiles/src/blocks/mod.rs",
"chars": 16969,
"preview": "use std::{\n collections::{BTreeMap, HashMap},\n fmt::Display,\n};\n\nuse itertools::Itertools;\nuse rayon::iter::{\n "
},
{
"path": "autoprecompiles/src/bus_map.rs",
"chars": 2454,
"preview": "use serde::{Deserialize, Serialize};\nuse std::{collections::BTreeMap, fmt::Display};\n\n#[derive(Copy, Clone, Deserialize,"
},
{
"path": "autoprecompiles/src/constraint_optimizer.rs",
"chars": 23862,
"preview": "use std::{\n collections::{HashMap, HashSet},\n fmt::Display,\n hash::Hash,\n iter::once,\n};\n\nuse itertools::Ite"
},
{
"path": "autoprecompiles/src/empirical_constraints.rs",
"chars": 14810,
"preview": "use std::collections::btree_map::Entry;\nuse std::collections::BTreeMap;\nuse std::fmt::Debug;\nuse std::hash::Hash;\n\nuse i"
},
{
"path": "autoprecompiles/src/equivalence_classes.rs",
"chars": 10431,
"preview": "use std::collections::{BTreeSet, HashMap};\nuse std::hash::Hash;\n\nuse derivative::Derivative;\nuse itertools::Itertools;\nu"
},
{
"path": "autoprecompiles/src/evaluation.rs",
"chars": 3473,
"preview": "use std::{fmt::Display, iter::Sum, ops::Add, sync::Arc};\n\nuse crate::{\n adapter::{Adapter, AdapterApc, AdapterApcWith"
},
{
"path": "autoprecompiles/src/execution/ast.rs",
"chars": 3673,
"preview": "use std::iter;\n\nuse itertools::Itertools;\nuse powdr_expression::visitors::{AllChildren, Children};\nuse serde::{Deseriali"
},
{
"path": "autoprecompiles/src/execution/candidates.rs",
"chars": 25851,
"preview": "use std::cmp::Ordering;\n\nuse itertools::Itertools;\n\nuse crate::execution::{\n evaluator::OptimisticConstraintFailed, E"
},
{
"path": "autoprecompiles/src/execution/evaluator.rs",
"chars": 17278,
"preview": "use std::collections::HashMap;\n\nuse itertools::Itertools;\nuse serde::{Deserialize, Serialize};\n\nuse crate::{\n executi"
},
{
"path": "autoprecompiles/src/execution/mod.rs",
"chars": 1068,
"preview": "use serde::{Deserialize, Serialize};\n\nmod ast;\nmod candidates;\nmod evaluator;\n\npub use ast::*;\npub use candidates::{Apc,"
},
{
"path": "autoprecompiles/src/execution_profile.rs",
"chars": 4033,
"preview": "use crate::adapter::Adapter;\nuse crate::blocks::Program;\nuse std::collections::HashMap;\nuse std::sync::Arc;\nuse std::syn"
},
{
"path": "autoprecompiles/src/export.rs",
"chars": 9290,
"preview": "use std::{\n fmt::Display,\n io::{BufWriter, Write},\n path::PathBuf,\n};\n\nuse itertools::Itertools;\nuse powdr_cons"
},
{
"path": "autoprecompiles/src/expression.rs",
"chars": 8036,
"preview": "//! In this module, we instantiate `powdr_expression::AlgebraicExpression` using a\n//! custom `AlgebraicReference` type."
},
{
"path": "autoprecompiles/src/expression_conversion.rs",
"chars": 3743,
"preview": "use powdr_constraint_solver::{\n grouped_expression::{GroupedExpression, GroupedExpressionComponent},\n runtime_cons"
},
{
"path": "autoprecompiles/src/lib.rs",
"chars": 18743,
"preview": "use crate::adapter::{Adapter, AdapterApc, AdapterVmConfig};\nuse crate::blocks::{PcStep, SuperBlock};\nuse crate::bus_map:"
},
{
"path": "autoprecompiles/src/low_degree_bus_interaction_optimizer.rs",
"chars": 21682,
"preview": "use itertools::Itertools;\nuse powdr_constraint_solver::constraint_system::{\n AlgebraicConstraint, BusInteraction, Bus"
},
{
"path": "autoprecompiles/src/memory_optimizer.rs",
"chars": 8852,
"preview": "use std::collections::{HashMap, HashSet};\nuse std::fmt::Display;\nuse std::hash::Hash;\n\nuse itertools::Itertools;\nuse pow"
},
{
"path": "autoprecompiles/src/optimistic/algebraic_references.rs",
"chars": 1690,
"preview": "use std::collections::BTreeMap;\n\nuse crate::{empirical_constraints::BlockCell, expression::AlgebraicReference};\n\n/// Map"
},
{
"path": "autoprecompiles/src/optimistic/config.rs",
"chars": 1442,
"preview": "const DEFAULT_EXECUTION_COUNT_THRESHOLD: u64 = 100;\nconst DEFAULT_MAX_SEGMENTS: usize = 20;\n\npub struct OptimisticPrecom"
},
{
"path": "autoprecompiles/src/optimistic/execution_constraint_generator.rs",
"chars": 1627,
"preview": "use std::collections::BTreeMap;\n\nuse powdr_number::{FieldElement, LargeInt};\n\nuse crate::{\n empirical_constraints::{E"
},
{
"path": "autoprecompiles/src/optimistic/execution_literals.rs",
"chars": 6672,
"preview": "use std::collections::BTreeMap;\n\nuse crate::export::ExportOptions;\nuse crate::memory_optimizer::MemoryBusInteraction;\nus"
},
{
"path": "autoprecompiles/src/optimistic/mod.rs",
"chars": 114,
"preview": "pub mod algebraic_references;\npub mod config;\npub mod execution_constraint_generator;\npub mod execution_literals;\n"
},
{
"path": "autoprecompiles/src/optimizer.rs",
"chars": 9789,
"preview": "use std::fmt::Debug;\nuse std::fmt::Display;\nuse std::hash::Hash;\n\nuse itertools::Itertools;\nuse powdr_constraint_solver:"
},
{
"path": "autoprecompiles/src/optimizer_documentation.md",
"chars": 26361,
"preview": "# The Autoprecompiles Optimizer\n\n## Terminology\n\n### Field Elements\n\nThroughout this document, we will be working in a f"
},
{
"path": "autoprecompiles/src/pgo/cell/mod.rs",
"chars": 8166,
"preview": "use std::{collections::BTreeMap, io::BufWriter};\n\nuse itertools::Itertools;\nuse rayon::iter::{IntoParallelIterator, Para"
},
{
"path": "autoprecompiles/src/pgo/cell/selection.rs",
"chars": 8077,
"preview": "use itertools::Itertools;\nuse priority_queue::PriorityQueue;\nuse serde::{Deserialize, Serialize};\n\nuse crate::{\n adap"
},
{
"path": "autoprecompiles/src/pgo/instruction.rs",
"chars": 2579,
"preview": "use std::{cmp::Reverse, collections::BTreeMap};\n\nuse itertools::Itertools;\n\nuse crate::{\n adapter::{Adapter, AdapterA"
},
{
"path": "autoprecompiles/src/pgo/mod.rs",
"chars": 3483,
"preview": "use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};\nuse strum::{Display, EnumString};\n\nu"
},
{
"path": "autoprecompiles/src/pgo/none.rs",
"chars": 1806,
"preview": "use std::{cmp::Reverse, collections::BTreeMap};\n\nuse derivative::Derivative;\nuse itertools::Itertools;\n\nuse crate::{\n "
},
{
"path": "autoprecompiles/src/powdr.rs",
"chars": 4004,
"preview": "use std::collections::BTreeMap;\nuse std::sync::Arc;\n\nuse itertools::Itertools;\nuse powdr_expression::visitors::{AllChild"
},
{
"path": "autoprecompiles/src/range_constraint_optimizer.rs",
"chars": 7556,
"preview": "use std::collections::BTreeMap;\nuse std::fmt::Display;\nuse std::hash::Hash;\n\nuse itertools::Itertools;\nuse powdr_constra"
},
{
"path": "autoprecompiles/src/stats_logger.rs",
"chars": 2793,
"preview": "use std::hash::Hash;\nuse std::{fmt::Display, time::Instant};\n\nuse itertools::Itertools;\nuse powdr_constraint_solver::con"
},
{
"path": "autoprecompiles/src/symbolic_machine.rs",
"chars": 11705,
"preview": "use crate::bus_map::BusMap;\nuse crate::expression::{AlgebraicExpression, AlgebraicReference};\nuse crate::expression_conv"
},
{
"path": "autoprecompiles/src/symbolic_machine_generator.rs",
"chars": 7658,
"preview": "use itertools::Itertools;\nuse powdr_constraint_solver::constraint_system::{ComputationMethod, DerivedVariable};\nuse powd"
},
{
"path": "autoprecompiles/src/trace_handler.rs",
"chars": 4576,
"preview": "use itertools::Itertools;\nuse powdr_constraint_solver::constraint_system::DerivedVariable;\nuse rayon::prelude::*;\nuse st"
},
{
"path": "autoprecompiles/tests/optimizer.rs",
"chars": 7820,
"preview": "use expect_test::expect;\nuse itertools::Itertools;\nuse powdr_autoprecompiles::bus_map::BusMap;\nuse powdr_autoprecompiles"
},
{
"path": "cli-openvm-riscv/Cargo.toml",
"chars": 1045,
"preview": "[package]\nname = \"cli-openvm-riscv\"\nversion.workspace = true\nedition.workspace = true\nlicense.workspace = true\nhomepage."
},
{
"path": "cli-openvm-riscv/README.md",
"chars": 1494,
"preview": "# cli-openvm\n\nUse command `execute` to run the program only, and `prove` to prove.\nThe `prove` command has a `mock` opti"
},
{
"path": "cli-openvm-riscv/src/main.rs",
"chars": 11433,
"preview": "use eyre::Result;\nuse metrics_tracing_context::{MetricsLayer, TracingContextLayer};\nuse metrics_util::{debugging::Debugg"
},
{
"path": "constraint-solver/Cargo.toml",
"chars": 925,
"preview": "[package]\nname = \"powdr-constraint-solver\"\ndescription = \"powdr tools to analyze and solve algebraic constraints\"\nversio"
},
{
"path": "constraint-solver/src/algebraic_constraint/mod.rs",
"chars": 3399,
"preview": "use std::fmt::Display;\n\nuse crate::{\n grouped_expression::GroupedExpression,\n runtime_constant::{RuntimeConstant, "
},
{
"path": "constraint-solver/src/algebraic_constraint/solve.rs",
"chars": 24251,
"preview": "use std::{collections::HashSet, fmt::Display, hash::Hash};\n\nuse itertools::Itertools;\nuse num_traits::Zero;\nuse powdr_nu"
},
{
"path": "constraint-solver/src/bus_interaction_handler.rs",
"chars": 2528,
"preview": "use itertools::Itertools;\nuse powdr_number::FieldElement;\n\nuse crate::{constraint_system::BusInteraction, range_constrai"
},
{
"path": "constraint-solver/src/constraint_system.rs",
"chars": 12093,
"preview": "use crate::{\n bus_interaction_handler::ViolatesBusRules,\n effect::Effect,\n grouped_expression::{GroupedExpressi"
},
{
"path": "constraint-solver/src/effect.rs",
"chars": 1849,
"preview": "use crate::{range_constraint::RangeConstraint, runtime_constant::RuntimeConstant};\n\n/// The effect of solving a symbolic"
},
{
"path": "constraint-solver/src/grouped_expression.rs",
"chars": 43307,
"preview": "use std::{\n collections::{BTreeMap, HashMap, HashSet},\n fmt::Display,\n hash::Hash,\n iter::{once, Sum},\n o"
},
{
"path": "constraint-solver/src/indexed_constraint_system.rs",
"chars": 31808,
"preview": "use std::{\n cmp,\n collections::{BTreeSet, HashMap, VecDeque},\n fmt::Display,\n hash::Hash,\n};\n\nuse bitvec::ve"
},
{
"path": "constraint-solver/src/inliner.rs",
"chars": 16607,
"preview": "use crate::constraint_system::{AlgebraicConstraint, ConstraintRef};\nuse crate::grouped_expression::GroupedExpression;\nus"
},
{
"path": "constraint-solver/src/lib.rs",
"chars": 479,
"preview": "//! Tooling used for analysis and solving of constraints.\n\npub mod algebraic_constraint;\npub mod bus_interaction_handler"
},
{
"path": "constraint-solver/src/range_constraint.rs",
"chars": 32684,
"preview": "use std::fmt::{Debug, Display, Formatter};\nuse std::{cmp, ops};\n\nuse num_traits::Zero;\n\nuse powdr_number::{log2_exact, F"
},
{
"path": "constraint-solver/src/reachability.rs",
"chars": 2518,
"preview": "use std::collections::HashSet;\nuse std::fmt::Display;\nuse std::hash::Hash;\n\nuse itertools::Itertools;\n\nuse crate::indexe"
},
{
"path": "constraint-solver/src/rule_based_optimizer/driver.rs",
"chars": 21141,
"preview": "use std::collections::{HashMap, HashSet};\nuse std::fmt::Display;\nuse std::hash::Hash;\n\nuse itertools::Itertools;\nuse pow"
},
{
"path": "constraint-solver/src/rule_based_optimizer/environment.rs",
"chars": 9533,
"preview": "use std::{\n cell::RefCell,\n collections::{HashMap, HashSet},\n hash::Hash,\n};\n\nuse itertools::{EitherOrBoth, Ite"
},
{
"path": "constraint-solver/src/rule_based_optimizer/item_db.rs",
"chars": 2617,
"preview": "use std::collections::HashMap;\nuse std::hash::Hash;\nuse std::ops::Index;\n\nuse derivative::Derivative;\n\n/// A database of"
},
{
"path": "constraint-solver/src/rule_based_optimizer/mod.rs",
"chars": 190,
"preview": "mod driver;\nmod environment;\nmod item_db;\nmod new_var_generator;\nmod rules;\nmod types;\n\n#[cfg(test)]\nmod tests;\n\npub use"
},
{
"path": "constraint-solver/src/rule_based_optimizer/new_var_generator.rs",
"chars": 1592,
"preview": "use std::collections::HashMap;\n\nuse crate::{\n constraint_system::ComputationMethod, grouped_expression::GroupedExpres"
},
{
"path": "constraint-solver/src/rule_based_optimizer/rules.rs",
"chars": 33828,
"preview": "#![allow(clippy::iter_over_hash_type)]\n// This is about a warning about interior mutability for the key\n// `Env`. We nee"
},
{
"path": "constraint-solver/src/rule_based_optimizer/tests.rs",
"chars": 15738,
"preview": "use std::fmt::Display;\nuse std::hash::Hash;\n\nuse crate::bus_interaction_handler::DefaultBusInteractionHandler;\nuse crate"
},
{
"path": "constraint-solver/src/rule_based_optimizer/types.rs",
"chars": 1471,
"preview": "use std::fmt::Display;\n\nuse derive_more::{From, Into};\nuse powdr_number::FieldElement;\n\nuse crate::range_constraint::Ran"
},
{
"path": "constraint-solver/src/runtime_constant.rs",
"chars": 4526,
"preview": "use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub};\n\nuse num_traits::{One, Zero};\nuse powdr_number::FieldElement;\n"
},
{
"path": "constraint-solver/src/solver/base.rs",
"chars": 28602,
"preview": "use derivative::Derivative;\nuse itertools::Itertools;\nuse powdr_number::FieldElement;\n\nuse crate::constraint_system::{\n "
},
{
"path": "constraint-solver/src/solver/boolean_extractor.rs",
"chars": 13079,
"preview": "use std::{cmp::min, collections::HashMap, hash::Hash};\n\nuse derivative::Derivative;\nuse itertools::Itertools;\nuse powdr_"
},
{
"path": "constraint-solver/src/solver/constraint_splitter.rs",
"chars": 24206,
"preview": "use std::{\n fmt::Display,\n ops::{Add, Div},\n};\n\nuse itertools::Itertools;\nuse num_traits::Zero;\nuse powdr_number::"
},
{
"path": "constraint-solver/src/solver/exhaustive_search.rs",
"chars": 9388,
"preview": "use itertools::Itertools;\nuse powdr_number::FieldElement;\nuse powdr_number::LargeInt;\n\nuse crate::constraint_system::Bus"
},
{
"path": "constraint-solver/src/solver/linearizer.rs",
"chars": 11196,
"preview": "use std::collections::HashMap;\nuse std::hash::Hash;\n\nuse derivative::Derivative;\nuse itertools::Itertools;\nuse powdr_num"
},
{
"path": "constraint-solver/src/solver/var_transformation.rs",
"chars": 5669,
"preview": "use powdr_number::FieldElement;\n\nuse crate::constraint_system::{AlgebraicConstraint, BusInteraction};\nuse crate::grouped"
},
{
"path": "constraint-solver/src/solver.rs",
"chars": 4625,
"preview": "use powdr_number::FieldElement;\n\nuse crate::constraint_system::{\n AlgebraicConstraint, BusInteraction, BusInteraction"
},
{
"path": "constraint-solver/src/symbolic_expression.rs",
"chars": 18232,
"preview": "use auto_enums::auto_enum;\nuse num_traits::{One, Zero};\nuse std::hash::Hash;\nuse std::ops::Sub;\nuse std::ops::{AddAssign"
},
{
"path": "constraint-solver/src/system_splitter.rs",
"chars": 2605,
"preview": "use std::hash::Hash;\nuse std::{collections::BTreeSet, fmt::Display};\n\nuse crate::constraint_system::{AlgebraicConstraint"
},
{
"path": "constraint-solver/src/test_utils.rs",
"chars": 1118,
"preview": "use powdr_number::GoldilocksField;\n\nuse crate::{\n constraint_system::{AlgebraicConstraint, BusInteraction, Constraint"
},
{
"path": "constraint-solver/src/utils.rs",
"chars": 2834,
"preview": "use std::collections::BTreeMap;\nuse std::hash::Hash;\n\nuse itertools::Itertools;\nuse powdr_number::{FieldElement, LargeIn"
},
{
"path": "constraint-solver/src/variable_update.rs",
"chars": 531,
"preview": "use powdr_number::FieldElement;\n\nuse super::range_constraint::RangeConstraint;\n\n/// An update representing new informati"
},
{
"path": "constraint-solver/tests/solver.rs",
"chars": 15171,
"preview": "use std::collections::BTreeMap;\n\nuse num_traits::identities::{One, Zero};\nuse powdr_constraint_solver::{\n bus_interac"
},
{
"path": "expression/Cargo.toml",
"chars": 707,
"preview": "[package]\nname = \"powdr-expression\"\ndescription = \"powdr expression type\"\nversion = { workspace = true }\nedition = { wor"
},
{
"path": "expression/src/display.rs",
"chars": 4434,
"preview": "use std::fmt::{self, Display, Formatter};\n\nuse crate::{\n AlgebraicBinaryOperation, AlgebraicBinaryOperator, Algebraic"
},
{
"path": "expression/src/lib.rs",
"chars": 7882,
"preview": "use std::{\n iter,\n ops::{self, Add, Mul, Neg, Sub},\n};\n\nuse powdr_number::ExpressionConvertible;\nuse schemars::Jso"
},
{
"path": "expression/src/visitors.rs",
"chars": 4559,
"preview": "use std::{iter, ops::ControlFlow};\n\nuse crate::AlgebraicExpression;\n\n/// Generic trait that allows to iterate over sub-s"
},
{
"path": "isa-utils/Cargo.toml",
"chars": 358,
"preview": "[package]\nname = \"powdr-isa-utils\"\ndescription = \"powdr utilities for translating from native ISA code (RISCV for now)\"\n"
},
{
"path": "isa-utils/src/lib.rs",
"chars": 1073,
"preview": "/// A single 32-bit data value.\npub enum SingleDataValue {\n /// A literal value.\n Value(u32),\n /// The value of"
},
{
"path": "number/Cargo.toml",
"chars": 1491,
"preview": "[package]\nname = \"powdr-number\"\ndescription = \"powdr finite field definitions\"\nversion = { workspace = true }\nedition = "
},
{
"path": "number/src/baby_bear.rs",
"chars": 2712,
"preview": "use p3_baby_bear::BabyBear;\n\nuse crate::powdr_field_plonky3;\n\npowdr_field_plonky3!(BabyBearField, BabyBear);\n\n#[cfg(test"
},
{
"path": "number/src/bn254.rs",
"chars": 3373,
"preview": "use ark_bn254::Fr;\nuse schemars::JsonSchema;\nuse serde::{Deserialize, Serialize};\n\npowdr_field!(Bn254Field, Fr);\n\n#[cfg("
},
{
"path": "number/src/expression_convertible.rs",
"chars": 1607,
"preview": "use std::ops::{Add, Mul, Neg, Sub};\n\nuse crate::FieldElement;\n\npub trait ExpressionConvertible<T, V> {\n /// Converts "
},
{
"path": "number/src/goldilocks.rs",
"chars": 17245,
"preview": "use std::fmt::LowerHex;\nuse std::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Not, Sub, SubAssign};\nuse std::str::Fro"
},
{
"path": "number/src/koala_bear.rs",
"chars": 2096,
"preview": "use p3_koala_bear::KoalaBear;\n\nuse crate::powdr_field_plonky3;\n\npowdr_field_plonky3!(KoalaBearField, KoalaBear);\n\n#[cfg("
},
{
"path": "number/src/lib.rs",
"chars": 1507,
"preview": "//! Numerical types used across powdr\n\n#[macro_use]\nmod macros;\nmod baby_bear;\nmod bn254;\nmod goldilocks;\nmod koala_bear"
},
{
"path": "number/src/macros.rs",
"chars": 15055,
"preview": "macro_rules! powdr_field {\n ($name:ident, $ark_type:ty) => {\n use crate::{\n traits::{FieldElement, "
},
{
"path": "number/src/mersenne31.rs",
"chars": 2118,
"preview": "use p3_mersenne_31::Mersenne31;\n\nuse crate::powdr_field_plonky3;\n\npowdr_field_plonky3!(Mersenne31Field, Mersenne31);\n\n#["
},
{
"path": "number/src/plonky3_macros.rs",
"chars": 11442,
"preview": "#[macro_export]\nmacro_rules! powdr_field_plonky3 {\n ($name:ident, $p3_type:ty) => {\n use schemars::{\n "
},
{
"path": "number/src/serialize.rs",
"chars": 5563,
"preview": "use std::{\n fs::File,\n io::{self, BufWriter, Read, Write},\n path::Path,\n};\n\nuse ark_serialize::{CanonicalDeseri"
},
{
"path": "number/src/traits.rs",
"chars": 5759,
"preview": "use std::{\n fmt::{self, Display},\n hash::Hash,\n ops::*,\n str::FromStr,\n};\n\nuse ibig::IBig;\nuse num_traits::{"
},
{
"path": "openvm/Cargo.toml",
"chars": 1583,
"preview": "[package]\nname = \"powdr-openvm\"\nversion.workspace = true\nedition.workspace = true\nlicense.workspace = true\nhomepage.work"
},
{
"path": "openvm/build.rs",
"chars": 1040,
"preview": "#[cfg(feature = \"cuda\")]\nuse openvm_cuda_builder::{cuda_available, CudaBuilder};\n\nfn main() {\n #[cfg(feature = \"cuda\""
},
{
"path": "openvm/cuda/src/apc_apply_bus.cu",
"chars": 7836,
"preview": "#include <stdint.h>\n#include <assert.h>\n#include <stdio.h>\n#include \"primitives/buffer_view.cuh\"\n#include \"primitives/co"
},
{
"path": "openvm/cuda/src/apc_tracegen.cu",
"chars": 6177,
"preview": "#include \"primitives/buffer_view.cuh\"\n#include \"primitives/constants.h\"\n#include \"primitives/trace_access.h\"\n#include \"e"
},
{
"path": "openvm/cuda/src/expr_eval.cuh",
"chars": 3361,
"preview": "#pragma once\n\n#include <stdint.h>\n#include <assert.h>\n\n// This header provides a tiny stack-machine evaluator for algebr"
},
{
"path": "openvm/metrics-viewer/CLAUDE.md",
"chars": 11387,
"preview": "# Metrics Viewer\n\nSingle-page web app for visualizing proof metrics from OpenVM benchmarks. This is a web port of the Py"
},
{
"path": "openvm/metrics-viewer/index.html",
"chars": 81843,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width"
},
{
"path": "openvm/metrics-viewer/spec.py",
"chars": 17505,
"preview": "#!/usr/bin/env python3\n\"\"\"\nAudit script for OpenVM metrics viewer.\n\nRecomputes the experiment details table from a metri"
},
{
"path": "openvm/src/air_builder.rs",
"chars": 2936,
"preview": "use std::sync::Arc;\n\nuse openvm_stark_backend::air_builders::symbolic::get_symbolic_builder;\nuse openvm_stark_backend::a"
},
{
"path": "openvm/src/cuda_abi.rs",
"chars": 8771,
"preview": "#![cfg(feature = \"cuda\")]\n\nuse openvm_cuda_backend::base::DeviceMatrix;\nuse openvm_cuda_common::{d_buffer::DeviceBuffer,"
},
{
"path": "openvm/src/customize_exe.rs",
"chars": 11574,
"preview": "use std::fmt::Display;\nuse std::hash::Hash;\nuse std::iter::once;\nuse std::marker::PhantomData;\nuse std::sync::Arc;\n\nuse "
},
{
"path": "openvm/src/empirical_constraints.rs",
"chars": 17938,
"preview": "use crate::isa::OpenVmISA;\nuse crate::program::CompiledProgram;\nuse crate::trace_generation::do_with_cpu_trace;\nuse indi"
},
{
"path": "openvm/src/extraction_utils.rs",
"chars": 18087,
"preview": "use std::collections::{BTreeMap, HashMap};\nuse std::marker::PhantomData;\nuse std::sync::{Arc, Mutex};\n\nuse itertools::It"
},
{
"path": "openvm/src/isa.rs",
"chars": 4603,
"preview": "use std::collections::{BTreeSet, HashSet};\nuse std::sync::Arc;\n\nuse openvm_circuit::arch::{\n AirInventory, AirInvento"
},
{
"path": "openvm/src/lib.rs",
"chars": 20613,
"preview": "#![cfg_attr(feature = \"tco\", allow(internal_features))]\n#![cfg_attr(feature = \"tco\", allow(incomplete_features))]\n#]\npub mod cuda;\n\nmod common;\n\npub use cpu::{DummyChipComplex, SharedPeripheryChipsCp"
},
{
"path": "openvm/src/powdr_extension/vm.rs",
"chars": 9457,
"preview": "// Mostly taken from [this openvm extension](https://github.com/openvm-org/openvm/blob/1b76fd5a900a7d69850ee9173969f70ef"
},
{
"path": "openvm/src/program.rs",
"chars": 2891,
"preview": "use std::sync::Arc;\n\nuse openvm_instructions::exe::VmExe;\nuse openvm_instructions::program::Program as OpenVmProgram;\nus"
},
{
"path": "openvm/src/test_utils.rs",
"chars": 5035,
"preview": "use itertools::Itertools;\nuse openvm_instructions::instruction::Instruction;\nuse openvm_stark_sdk::p3_baby_bear::BabyBea"
},
{
"path": "openvm/src/trace_generation.rs",
"chars": 5988,
"preview": "use crate::PowdrSdkCpu;\nuse crate::SpecializedConfigCpuBuilder;\nuse crate::{isa::OpenVmISA, program::CompiledProgram, Sp"
},
{
"path": "openvm/src/utils.rs",
"chars": 7445,
"preview": "use core::fmt;\nuse std::{collections::BTreeMap, sync::Arc};\n\nuse itertools::Itertools;\nuse openvm_stark_backend::{\n a"
},
{
"path": "openvm-bus-interaction-handler/Cargo.toml",
"chars": 502,
"preview": "[package]\nname = \"powdr-openvm-bus-interaction-handler\"\nversion.workspace = true\nedition.workspace = true\nlicense.worksp"
},
{
"path": "openvm-bus-interaction-handler/src/bitwise_lookup.rs",
"chars": 7285,
"preview": "use powdr_autoprecompiles::range_constraint_optimizer::RangeConstraints;\nuse powdr_constraint_solver::{\n grouped_expr"
},
{
"path": "openvm-bus-interaction-handler/src/bus_map.rs",
"chars": 1928,
"preview": "//! To support an abstracted autoprecompile layer, this module stores type implementations specific to OpenVM\nuse std::f"
},
{
"path": "openvm-bus-interaction-handler/src/lib.rs",
"chars": 11732,
"preview": "use std::fmt::Display;\n\nuse bitwise_lookup::handle_bitwise_lookup;\nuse itertools::Itertools;\nuse memory::handle_memory;\n"
},
{
"path": "openvm-bus-interaction-handler/src/memory.rs",
"chars": 4835,
"preview": "use powdr_constraint_solver::range_constraint::RangeConstraint;\nuse powdr_number::{FieldElement, LargeInt};\n\nuse super::"
},
{
"path": "openvm-bus-interaction-handler/src/memory_bus_interaction.rs",
"chars": 3015,
"preview": "use std::hash::Hash;\nuse std::{array::IntoIter, fmt::Display};\n\nuse powdr_autoprecompiles::memory_optimizer::{\n Memor"
},
{
"path": "openvm-bus-interaction-handler/src/tuple_range_checker.rs",
"chars": 3368,
"preview": "use powdr_autoprecompiles::range_constraint_optimizer::RangeConstraints;\nuse powdr_constraint_solver::{\n grouped_expr"
},
{
"path": "openvm-bus-interaction-handler/src/variable_range_checker.rs",
"chars": 3557,
"preview": "use powdr_autoprecompiles::range_constraint_optimizer::RangeConstraints;\nuse powdr_constraint_solver::{\n grouped_expr"
},
{
"path": "openvm-riscv/.gitignore",
"chars": 829,
"preview": "# Generated by Cargo\n# will have compiled files and executables\ndebug/\ntarget/\n\n# Remove Cargo.lock from gitignore if cr"
},
{
"path": "openvm-riscv/Cargo.toml",
"chars": 2914,
"preview": "[package]\nname = \"powdr-openvm-riscv\"\nversion.workspace = true\nedition.workspace = true\nlicense.workspace = true\nhomepag"
},
{
"path": "openvm-riscv/extensions/hints-circuit/Cargo.toml",
"chars": 757,
"preview": "[package]\nname = \"powdr-openvm-riscv-hints-circuit\"\nversion.workspace = true\nedition.workspace = true\nlicense.workspace "
},
{
"path": "openvm-riscv/extensions/hints-circuit/src/executors.rs",
"chars": 7581,
"preview": "use openvm_circuit::arch::{PhantomSubExecutor, Streams};\nuse openvm_circuit::system::memory::online::GuestMemory;\nuse op"
},
{
"path": "openvm-riscv/extensions/hints-circuit/src/field10x26_k256.rs",
"chars": 33158,
"preview": "//! The code here has been mostly copied from the `k256` crate.\n//! Its the 32-bit implementation of the field element.\n"
},
{
"path": "openvm-riscv/extensions/hints-circuit/src/lib.rs",
"chars": 2983,
"preview": "#![cfg_attr(feature = \"tco\", allow(internal_features))]\n#![cfg_attr(feature = \"tco\", allow(incomplete_features))]\n#![cfg"
},
{
"path": "openvm-riscv/extensions/hints-guest/Cargo.toml",
"chars": 407,
"preview": "[package]\nname = \"powdr-openvm-riscv-hints-guest\"\nversion.workspace = true\nedition.workspace = true\nlicense.workspace = "
},
{
"path": "openvm-riscv/extensions/hints-guest/src/lib.rs",
"chars": 5562,
"preview": "#![no_std]\n#[cfg(target_os = \"zkvm\")]\nuse openvm_custom_insn; // needed for the hint_store_u32 macro\nuse strum_macros::F"
},
{
"path": "openvm-riscv/extensions/hints-transpiler/Cargo.toml",
"chars": 503,
"preview": "[package]\nname = \"powdr-openvm-riscv-hints-transpiler\"\nversion.workspace = true\nedition.workspace = true\nlicense.workspa"
},
{
"path": "openvm-riscv/extensions/hints-transpiler/src/lib.rs",
"chars": 2357,
"preview": "use openvm_instructions::{\n instruction::Instruction, riscv::RV32_REGISTER_NUM_LIMBS, LocalOpcode, PhantomDiscriminan"
},
{
"path": "openvm-riscv/guest/Cargo.toml",
"chars": 265,
"preview": "[workspace]\n[package]\nname = \"powdr-openvm-guest-stdin-test\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[dependencies]\nopenvm ="
},
{
"path": "openvm-riscv/guest/src/main.rs",
"chars": 381,
"preview": "#![cfg_attr(target_os = \"zkvm\", no_main)]\n#![cfg_attr(target_os = \"zkvm\", no_std)]\n\nopenvm::entry!(main);\n\nuse openvm::i"
},
{
"path": "openvm-riscv/guest-ecc-manual/Cargo.toml",
"chars": 795,
"preview": "\n[workspace]\n[package]\nname = \"openvm-ecc-test-programs\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[dependencies]\nopenvm = { g"
},
{
"path": "openvm-riscv/guest-ecc-manual/openvm.toml",
"chars": 550,
"preview": "[app_vm_config.rv32i]\n[app_vm_config.rv32m]\n[app_vm_config.io]\n\n[app_vm_config.modular]\nsupported_moduli = [\n \"115792"
},
{
"path": "openvm-riscv/guest-ecc-manual/src/main.rs",
"chars": 2451,
"preview": "use hex_literal::hex;\nuse openvm::io::read;\nuse openvm_algebra_guest::IntMod;\nuse openvm_ecc_guest::{weierstrass::Intrin"
},
{
"path": "openvm-riscv/guest-ecc-powdr-affine-hint/Cargo.toml",
"chars": 410,
"preview": "[workspace]\n[package]\nname = \"openvm-ecc-powdr-affine-hint\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[dependencies]\nopenvm = "
},
{
"path": "openvm-riscv/guest-ecc-powdr-affine-hint/src/main.rs",
"chars": 2801,
"preview": "use hex_literal::hex;\nuse k256::elliptic_curve::sec1::FromEncodedPoint;\nuse k256::elliptic_curve::PrimeField;\nuse k256::"
},
{
"path": "openvm-riscv/guest-ecc-projective/Cargo.toml",
"chars": 325,
"preview": "[workspace]\n[package]\nname = \"openvm-ecc-test-programs\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[dependencies]\nopenvm = { gi"
},
{
"path": "openvm-riscv/guest-ecc-projective/src/main.rs",
"chars": 2787,
"preview": "use hex_literal::hex;\nuse k256::elliptic_curve::ops::LinearCombination;\nuse k256::elliptic_curve::sec1::FromEncodedPoint"
},
{
"path": "openvm-riscv/guest-ecrecover/Cargo.toml",
"chars": 463,
"preview": "[workspace]\n[package]\nname = \"openvm-k256-ecrecover-programs\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[dependencies]\nopenvm "
},
{
"path": "openvm-riscv/guest-ecrecover/src/main.rs",
"chars": 1868,
"preview": "openvm::entry!(main);\n\nuse hex_literal::hex;\nuse k256::ecdsa::{PowdrVerifyKey, RecoveryId, Signature, VerifyingKey};\nuse"
},
{
"path": "openvm-riscv/guest-ecrecover-manual/Cargo.toml",
"chars": 884,
"preview": "[workspace]\n[package]\nname = \"openvm-k256-test-programs\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[dependencies]\nopenvm = { g"
},
{
"path": "openvm-riscv/guest-ecrecover-manual/openvm.toml",
"chars": 573,
"preview": "[app_vm_config.rv32i]\n[app_vm_config.rv32m]\n[app_vm_config.io]\n[app_vm_config.sha256]\n\n[app_vm_config.modular]\nsupported"
},
{
"path": "openvm-riscv/guest-ecrecover-manual/src/main.rs",
"chars": 1886,
"preview": "extern crate alloc;\n\nuse ecdsa::RecoveryId;\nuse hex_literal::hex;\nuse openvm_k256::ecdsa::{Signature, VerifyingKey};\n// "
},
{
"path": "openvm-riscv/guest-hints-test/Cargo.toml",
"chars": 515,
"preview": "[workspace]\n[package]\nname = \"powdr-openvm-guest-hints-test\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[dependencies]\n# The `r"
},
{
"path": "openvm-riscv/guest-hints-test/src/main.rs",
"chars": 260,
"preview": "#![cfg_attr(target_os = \"zkvm\", no_main)]\n#![cfg_attr(target_os = \"zkvm\", no_std)]\n\nopenvm::entry!(main);\nuse powdr_open"
},
{
"path": "openvm-riscv/guest-keccak/Cargo.toml",
"chars": 313,
"preview": "[workspace]\n[package]\nname = \"guest-keccak-stdin\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[dependencies]\nopenvm = { git = \"h"
},
{
"path": "openvm-riscv/guest-keccak/src/main.rs",
"chars": 408,
"preview": "#![no_std]\n#![no_main]\n\nopenvm::entry!(main);\n\nuse core::hint::black_box;\n\nuse openvm::io::{read, reveal_u32};\nuse tiny_"
},
{
"path": "openvm-riscv/guest-keccak-manual-precompile/Cargo.toml",
"chars": 397,
"preview": "[package]\nname = \"keccak-example\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[workspace]\nmembers = []\n\n[dependencies]\nopenvm = "
},
{
"path": "openvm-riscv/guest-keccak-manual-precompile/openvm.toml",
"chars": 85,
"preview": "[app_vm_config.rv32i]\n[app_vm_config.rv32m]\n[app_vm_config.io]\n[app_vm_config.keccak]"
},
{
"path": "openvm-riscv/guest-keccak-manual-precompile/src/main.rs",
"chars": 353,
"preview": "#![no_std]\n#![no_main]\n\nextern crate alloc;\n\nuse core::hint::black_box;\n\nuse openvm::io::{read, reveal_u32};\nuse openvm_"
},
{
"path": "openvm-riscv/guest-matmul/Cargo.toml",
"chars": 260,
"preview": "[workspace]\n[package]\nname = \"powdr-openvm-matmul-test\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[dependencies]\nopenvm = { gi"
},
{
"path": "openvm-riscv/guest-matmul/src/main.rs",
"chars": 7266,
"preview": "#![no_std]\n#![no_main]\n\nopenvm::entry!(main);\n\nuse openvm::io::reveal_u32;\n\npub fn main() {\n loop_test_matrix();\n}\n\nc"
},
{
"path": "openvm-riscv/guest-pairing/Cargo.toml",
"chars": 285,
"preview": "[package]\nname = \"guest-pairing\"\nversion = \"0.1.0\"\nedition = \"2024\"\n\n[workspace]\nmembers = []\n\n[dependencies]\nopenvm = {"
},
{
"path": "openvm-riscv/guest-pairing/src/main.rs",
"chars": 2313,
"preview": "use ark_bn254::{Bn254, Fq, Fq2, G1Affine, G2Affine};\nuse ark_ec::pairing::Pairing;\nuse ark_ff::fields::PrimeField;\nuse a"
},
{
"path": "openvm-riscv/guest-pairing-manual-precompile/Cargo.toml",
"chars": 715,
"preview": "[package]\nname = \"openvm-pairing-example\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[workspace]\nmembers = []\n\n[dependencies]\no"
},
{
"path": "openvm-riscv/guest-pairing-manual-precompile/openvm.toml",
"chars": 776,
"preview": "[app_vm_config.rv32i]\n[app_vm_config.rv32m]\n[app_vm_config.io]\n[app_vm_config.modular]\nsupported_moduli = [\n \"2188824"
},
{
"path": "openvm-riscv/guest-pairing-manual-precompile/src/main.rs",
"chars": 2372,
"preview": "use openvm_algebra_guest::IntMod;\nuse openvm_ecc_guest::AffinePoint;\nuse {\n openvm_pairing::bn254::{Bn254, Fp, Fp2},\n"
},
{
"path": "openvm-riscv/guest-sha256/Cargo.toml",
"chars": 364,
"preview": "[workspace]\n[package]\nname = \"guest-sha256-stdin\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[dependencies]\nopenvm = { git = \"h"
},
{
"path": "openvm-riscv/guest-sha256/src/main.rs",
"chars": 338,
"preview": "#![no_std]\n#![no_main]\n\nopenvm::entry!(main);\n\nuse core::hint::black_box;\n\nuse openvm::io::{read, reveal_u32};\nuse sha2:"
}
]
// ... and 108 more files (download for full content)
About this extraction
This page contains the full source code of the powdr-labs/powdr GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 308 files (30.0 MB), approximately 547.5k tokens, and a symbol index with 2247 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.