Commit Graph

246 Commits

Author SHA1 Message Date
Steve Wang
a03c1960ea Generalize CLI structs (#3123)
Generalize so that we can use `PgoType` and adjacent CLI functions in
more use cases in a generic way.
2025-08-01 15:27:17 +00:00
Georg Wiese
806a858cac Improve evaluate_apc (#3120)
As @qwang98 pointed out, my implementation of `evaluate_apc` was too
inefficient, because it recalculated the statistics for the original
AIRs for each instruction of the basic block. This PR fixes it by
requiring a new function
`InstructionHandler::get_instruction_air_stats`.
2025-08-01 03:26:26 +00:00
Steve Wang
1ded39b9f6 Refactor JsonExport and effectiveness plot (#3116)
Now `JsonExport` and `plot_effectiveness.py` both live in APC crate.

Didn't move other scripts, which rely on `metrics.json` and I think it's
specific to OVM?

---------

Co-authored-by: Georg Wiese <georgwiese@gmail.com>
2025-07-31 14:38:41 +00:00
Leandro Pacheco
4be51aa95a Powdr openvm extension with new hints (#3100)
Extend our openvm guest/host with support for new hints.
Includes hints for `k256` affine coordinate inverse and sqrt.
2025-07-30 15:50:23 +00:00
Steve Wang
a3fc1ee854 Create APC with constraint on max number of basic block instructions (#3114)
Reth test will be fixed after we merge this.
2025-07-30 08:45:35 +00:00
Georg Wiese
83cd1ecc3e Add optimize() benchmark (#3104)
```
$ cd openvm
$ cargo bench --bench optimizer_benchmark
Benchmarking optimize-keccak/optimize: Warming up for 3.0000 s
Warning: Unable to complete 10 samples in 5.0s. You may wish to increase target time to 44.2s.
optimize-keccak/optimize
                        time:   [4.3703 s 4.3856 s 4.4020 s]
                        change: [-1.2781% -0.5240% +0.2094%] (p = 0.21 > 0.05)
                        No change in performance detected.
```
2025-07-29 09:34:06 +00:00
Georg Wiese
11cb3d6803 Fix typo on comment (#3099)
Added a wrong comment in #3097 :/
2025-07-28 19:06:44 +00:00
Georg Wiese
45398d41a9 Test stack accesses (#3097) 2025-07-28 17:33:25 +00:00
Thibaut Schaeffer
9f36102a16 Keep openvm program intact (#3075)
Since #3055, we don't need to change the program anymore.
This PR keeps the program intact in openvm, passing the apc opcodes to
openvm through a new API in openvm.
See https://github.com/powdr-labs/openvm/pull/36
Related: https://github.com/powdr-labs/openvm-reth-benchmark/pull/26
2025-07-28 14:48:10 +00:00
chriseth
0d43b411b3 Turn solver into trait. (#3087)
Turns `Solver` into a trait to abstract away the bus interaction handler
and also allow other implementations in the future.

It also makes the solver persistent across optimization loops so that we
do not have to derive the same range constraints all over again.

This is also a preparatory PR to make the solver more independent from
the constraint system: The constraint system inside the solver will have
way more redundancies in the future.

---------

Co-authored-by: Georg Wiese <georgwiese@gmail.com>
2025-07-28 14:18:02 +00:00
chriseth
362d3f9fdb Remove redundant constraints. (#3074)
Removes algebraic constraints that are implied by other algebraic
constraints.

In order to do that, grouped expressions are turned into products of
factors such that these factors are as much normalized as possible. Then
we try to find algebraic constraints that are divisors of other
algebraic constraints (i.e. the factors are subsets).
2025-07-26 10:54:15 +00:00
Georg Wiese
0a1a7556e7 Add tests for pseudo instructions (#3073)
Done by Claude, not reviewed yet

---------

Co-authored-by: chriseth <chriseth.github@gmail.com>
2025-07-25 14:59:25 +00:00
Georg Wiese
6329f0ea65 Remove opcode (#3091)
We used to need the Opcode of the APC in order to hard-code it in the PC
lookup. However, for a while, we have removed PC lookups entirely,
hard-coding the PC in the execution bridge receive instead.

This removes the necessity to store the opcode. It was only used as an
ID of the APC. But for this, we can use the PC instead. This has the
added benefit that we can more easily relate it to the original program.
2025-07-25 14:33:43 +00:00
Georg Wiese
694450fdfe Include instructions & evaluation in APC snapshots (#3088)
Includes an evaluation of APCs in the snapshots.
2025-07-25 13:39:20 +00:00
chriseth
c79e4c17f0 Substitute bus vars at start and end. (#3078) 2025-07-25 11:08:22 +00:00
Steve Wang
1f43bce579 Expose Prog as public (#3089)
Small patch so that we can update reth here:
https://github.com/powdr-labs/openvm-reth-benchmark/pull/27.
2025-07-25 10:49:44 +00:00
Steve Wang
786642c0bc Generalize execution profile (#3086)
Move execution data (pc execution map) collection from OVM to APC.
2025-07-25 09:21:56 +00:00
chriseth
46549ee718 Replace xor bus interaction by algebraic constraint (#3058)
Optimize xor lookups such that if the inputs are already
boolean-constrained, the xor operation is computed using an algebraic
constraint instead.
2025-07-25 08:16:59 +00:00
chriseth
efe3652837 Use update-expect also for columns saved. (#3085) 2025-07-25 08:14:17 +00:00
chriseth
d2d8160711 Use expect-test (#3081) 2025-07-24 14:59:00 +00:00
chriseth
1b30e81d78 Use UPDATE_EXPECT feature also for apc builder tests. (#3082) 2025-07-24 12:54:36 +00:00
Georg Wiese
eeb6776e85 Generalize bus type (#3070)
The `BusType` enum in the `autoprecompiles` crate still listed the
OpenVM bus types. Now, the bus types that we actually rely on are
hard-coded (e.g. execution bridge, memory, etc), but there is an `Other`
variant where the integration can add their own types:

92ae7469e8/autoprecompiles/src/bus_map.rs (L5-L19)

---------

Co-authored-by: Thibaut Schaeffer <schaeffer.thibaut@gmail.com>
2025-07-23 13:50:57 +00:00
chriseth
9a97fca7c6 Take other bus interactions into account when computing xor range constraints (#3012) 2025-07-22 09:32:46 +00:00
Georg Wiese
d74aaa1a83 Generalize memory (#3065)
This PR generalizes the memory optimizer to not make any specific
assumptions about the structure of memory bus interactions. This is done
by turning `MemoryBusInteraction` into a trait, which is an associated
type in the `Adapter`. Currently, there is one concrete implementation,
`OpenVmMemoryBusInteraction`.
2025-07-22 08:19:13 +00:00
chriseth
bcae937044 Add memcpy block test. (#3067)
Co-authored-by: Georg Wiese <georgwiese@gmail.com>
2025-07-21 15:38:51 +00:00
chriseth
1480efd132 Store column count. (#3066)
In order to get a feel for the optimizer, I think it is good to also
output the column count. It is rather difficult to get the column count
before optimization, but in the end we are only interested in the effect
of a new optimization step anyway, so I think this is fine.

---------

Co-authored-by: Georg Wiese <georgwiese@gmail.com>
2025-07-21 11:03:06 +00:00
Georg Wiese
caf069eb85 Generalize PC lookup & execution bus handling (#3055)
Generalizations that make fewer assumptions about the structure of bus
interactions like PC lookups and bus interactions. See comments below.

One change is that we know inline the initial PC (because we know it for
any given basic block), which leads to *all* PC lookups being removed,
slightly improving performance (at least reducing one witness column &
one bus interaction).

---------

Co-authored-by: schaeff <thibaut@powdrlabs.com>
2025-07-20 08:09:32 +00:00
Georg Wiese
c856986f75 BasicBlock: Store start_pc (#3059)
Suggested alternative to #3057: Instead of `start_idx`, we store the
`start_pc` to identify a basic block. Both should uniquely identify the
basic block, but the start PC is useful information on its own (whereas
the `start_idx` only makes sense to someone who knows the entire
program).

See also
https://github.com/powdr-labs/powdr/pull/3055#discussion_r2215738707.
2025-07-18 15:16:03 +00:00
Thibaut Schaeffer
c5d2b13e31 Partially remove opcode concept from apc crate, use VmOpcode in openvm crate (#3054)
This PR does two things:
- it partially removes the notion of opcode in the autoprecompile crate,
and instead relies on user provided functions to know if an instruction
is allowed/branching
- it uses VmOpcode as much as possible in the openvm crate instead of
usize

After this PR, the only remaining notion of opcode in the apc crate is
in the `SymbolicInstructionStatement` where it is still a single field
element. @georgwiese shared ideas to remove that too, or at least shift
it to the client, see #3055
2025-07-18 09:28:58 +00:00
Thibaut Schaeffer
3e239cb965 Simplify SymbolicInstructionStatement treatment (#3052)
`SymbolicInstructionStatement` is only used to constraint the pc lookup.
Reuse the same type for the pc bus lookup and the instruction.
2025-07-16 17:09:34 +00:00
Thibaut Schaeffer
56acc3d858 Use full instruction when getting the instruction air (#3048) 2025-07-16 10:19:03 +00:00
Thibaut Schaeffer
cb5c1df549 Make pc 64bit (#3050) 2025-07-16 09:39:08 +00:00
Thibaut Schaeffer
6048ba8239 Move field conversion to the autoprecompile crate (#3041)
Based on #3040, this PR makes the autoprecompile crate responsible for
converting from and to the user's field type. As a result, the openvm
crate only deals with the openvm Babybear, the powdr Babybear is only
used inside the APC crate. This leads to a lot of simplification, and
enables some derives.

TODO:
- [x] fix the cargo tree clash
2025-07-16 09:18:44 +00:00
Georg Wiese
bd45df06e4 Generalize InstructionMachineHandler (#3049)
This way, the selected AIR can depend on the entire instruction, not
just the opcode.
2025-07-15 13:28:06 +00:00
Thibaut Schaeffer
922aa523c7 Trait based apc (#3040)
Group all traits under a single `Adapter` trait.
2025-07-15 11:56:56 +00:00
Steve Wang
9a07095cf3 Apc stats and columns saved tests (#3039)
Key design choices revolve around passing `ApcCandidate` stats out from
`create_apcs_with_cell_pgo`, `create_apcs_with_pgo`, etc. I explored a
few ways:
1. [Current solution] Add an `ApcStats` struct that wraps stats we want
to pass to `PowdrPrecompile`. I believe this is the most versatile
solution and avoids defects from the two solutions below.
2. Return `ApcCandidate` for `create_apcs_with_[x]_pgo` and
`create_apcs_with_pgo`. This solution requires filling dummy zeros for
`execution_frequency`, `width_before`, and `width_after`, which I think
aren't very clean. Besides, passing these values still require computing
the stats we care about later, so I think it's cleaner to explicitly
declare what we care about in `ApcStats` instead.
3. Use `Either::Left(ApcCandidate)` for cell PGO while
`Either::Right(Apc)` for other PGO modes. This isn't very clean, and
also has the disadvantage of requiring match clauses when constructing
elements of `PowdrExtension`.

```
struct ApcCandidate<P> {
    apc: Apc<P>,
    execution_frequency: usize,
    width_before: AirWidths,
    width_after: AirWidths,
}
```
2025-07-15 10:39:19 +00:00
chriseth
314da34308 Print function name for basic blocks. (#3032) 2025-07-14 15:52:45 +00:00
Thibaut Schaeffer
54861dd793 Move pgo to apc crate (#3036)
Larger PR, but after this basically everything that can be made agnostic
is agnostic.
`PowdrConfig` is split in two, as the `autoprecompile` crate does not
care about the arithmetization method. This could be cleaned up a bit
though.

Need to merge
https://github.com/powdr-labs/openvm-reth-benchmark/pull/24/ first and
update the hashes.

TODO:
- [x] merge #3033 
- [x] fix reth
- [x] remove POWDR_OPCODE constant in apc and pass it instead
2025-07-14 12:53:01 +00:00
Georg Wiese
5806f36c3a Better effectiveness plot (#3038)
Changes the effectiveness plot to this (example: Reth benchmark):
<img width="3323" height="1768" alt="reth"
src="https://github.com/user-attachments/assets/78f4eb2c-bd9b-4d83-b1c3-e2ea20286270"
/>

I think it is more intuitive that the [previous
version](https://github.com/powdr-labs/bench-results/blob/gh-pages/results/2025-07-10-0155/reth/effectiveness.png_stacked_histogram.png).

Also prints this summary of the largest blocks:
```
Top 10 Basic Blocks by Trace Cells:
 Opcode Trace Cells  Effectiveness  Instructions  Width Before  Width After
   4372      784.9M       3.358650            12           796          237
   4361      358.3M       4.085859            13           809          198
   8079      248.9M       3.692737            10           661          179
   4391      158.6M       2.861345            21          1362          476
   4359      130.3M       3.560976             5           292           82
   4390      128.9M       2.847418            37          2426          852
   9105      105.6M       5.720029           116          7968         1393
   4368       99.4M       6.938776            24          1700          245
   9104       97.2M       4.342214           104          7334         1689
   4385       87.8M       2.671587            11           724          271
```
2025-07-11 11:11:28 +00:00
Thibaut Schaeffer
55048cfd32 Move block detection to APC crate (#3033)
Moving block detection to the APC crate. 
After this PR, a larger chunk of the `customize` function is
openvm-agnostic.
2025-07-11 08:59:40 +00:00
Steve Wang
616492258c Improve OVM compilation tests (#3026)
In general, it makes more sense to always test:
- The full `AirMetrics` (including log up and preprocessed columns),
instead of just the main columns.
- The sum of `AirMetrics` for all APCs used, instead of just the first
APC in a testing profile (because of wasted data, and we can always just
create one APC if we only want to test one).

These won't add any cost to the testing CI run, because all data are
already there but we just aren't testing them fully yet.
2025-07-11 08:45:37 +00:00
Leandro Pacheco
6c9903d0a6 Fix effectiveness plot (#3037)
fix the script for the new apc candidates json format
2025-07-10 19:33:50 +00:00
Georg Wiese
f0a0e3a804 Benchmarks: Generate effectiveness plots (#3024)
Builds on #3023 and
https://github.com/powdr-labs/openvm-reth-benchmark/pull/23

Worked on this manually triggered nightly run:

https://github.com/powdr-labs/powdr/actions/runs/16182186333/job/45680988436

See these results:

https://github.com/powdr-labs/bench-results/tree/gh-pages/results/2025-07-10-0155
2025-07-10 09:29:52 +00:00
Thibaut Schaeffer
59c1ff6e8a Introduce constant for log blowup (#3002)
1 is recommended, and having a constant is an improvement over the
current way the blowup factor can be set everywhere.

update: 1 does not work, so set to 2 for now, as it was before.
2025-07-10 09:15:23 +00:00
Thibaut Schaeffer
89378a3d01 Move APC export to APC crate (#3021)
We currently export the APCs to disk in the openvm crate.
Now that the APCs are generic, we can export them in the APC crate
already.
The json file is still generated in openvm, since it contains some
openvm-specific data, such as the number of logup columns (which depends
on the stark config, which the APC crate does not know about)
2025-07-10 08:48:42 +00:00
Thibaut Schaeffer
d6844422f6 Move concept of block to APC crate (#3020)
Simplify and make the concept of block less openvm specific.
The next step will be to move the saving the apcs to disk to the apc
crate.
2025-07-10 07:43:35 +00:00
Georg Wiese
1d9635f709 Add plot_effectiveness.py (#3023)
Creates this plot from an `apc_candidates.json`:
![effectiveness
png_stacked_histogram](https://github.com/user-attachments/assets/cf419b81-0609-453e-89c5-5d1207b51385)

To reproduce the above plot, see the example in #3022 and run:
`python openvm/scripts/plot_effectiveness.py
cli-openvm/apcs/apc_candidates.json`
2025-07-09 19:52:52 +00:00
Thibaut Schaeffer
c19bc488a3 Generate APC candidate json (#3015)
Follow up to #3008
2025-07-09 14:16:42 +00:00
ShuangWu121
d17f2a0da5 Add sha256 guest (#2956)
Co-authored-by: Leo Alt <leo@powdrlabs.com>
2025-07-09 12:28:06 +00:00
Thibaut Schaeffer
0598605c68 Write APC candidates to disk (#3008)
@georgwiese built some graphs from the APC candidates by exporting the
main stats to CSV. This PR start extending that by persisting the
candidates to disk for further inspection.

This first PR creates one file per APC, and #3015 creates a single JSON
which has the main stats and points to this APC file.
2025-07-09 10:41:53 +00:00