Commit Graph

3087 Commits

Author SHA1 Message Date
Steve Wang
bbffdfe4e6 fix commits and clippy 2025-09-05 11:06:13 +08:00
Steve Wang
2ea3b59d82 merge upstream and update map name 2025-09-04 18:17:46 +08:00
Steve Wang
b214cc8480 updated TraceHandler to allow function level life time to accommodate for owned and borrowed hashmap of dummy traces 2025-09-04 17:59:55 +08:00
Steve Wang
dab22715bc rename map 2025-09-04 15:45:52 +08:00
Steve Wang
7a8eb6c192 first commit including TraceHandler trait and OVM implementation, though I wanted to move more contents to the trait 2025-09-04 15:29:50 +08:00
Steve Wang
3bf91006af first commit with passing keccak test 2025-09-04 11:59:57 +08:00
chriseth
38b8406c78 Some refactoring of AlgebraicConstraint. (#3242)
Co-authored-by: Thibaut Schaeffer <schaeffer.thibaut@gmail.com>
2025-09-03 09:37:12 +00:00
Thibaut Schaeffer
6dbb2710e3 Remove option in instruction handler trait (#3240)
We unwrap the returned value in side the autoprecompiles crate, so might
as well not return an option.
2025-09-02 06:09:53 +00:00
chriseth
cfc7cf31e2 Derive clone for ConstraintRef (#3241)
Derives `Clone` (and some other traits) for `ConstraintRef`. Since it is
a reference, it should implement Clone.

Note that `Clone` for `AlgebraicConstraint` is only auto-derived if `V`
is `Clone`, which is the case if `V` is a reference.
2025-09-01 17:11:46 +00:00
Thibaut Schaeffer
396737e749 Remove one level of nested calls in the optimizer (#3218)
In order to make the optimizer clearer, this PR tries to put all
optimization passes one after another in `optimize_constraints`.

Also removes `JournalingConstraintSystem`.

TODO:
- [x] Figure out what to do about the `JournalingConstraintSystem`
2025-09-01 13:41:38 +00:00
Thibaut Schaeffer
f32fd0c81a Make the solver work over constraints not expressions (#3220)
- remove `Deref` for `AlgebraicConstraint` so we cannot call functions
that expect `&GroupedExpression`
- make constraint solver work over constraints instead of expressions
- move algebraic expression to its own module, along with said solver
- make more components like the boolean extractor work on
`AlgebraicConstraint<&E>`
2025-09-01 13:03:21 +00:00
Leandro Pacheco
3caa321441 run larger tests by themselves (#3237)
somehow they run out of memory if run as part of the full suite
2025-08-29 13:40:10 +00:00
Leo
85bcab38df update readme (#3239)
The image was gone with the cleanup, bringing it back + adjusting text.
2025-08-29 10:10:07 +00:00
Leandro Pacheco
fff802a933 post merge APC tests (#3238)
run some of the nightly tests in a non-blocking way after merging to
main
2025-08-29 07:46:33 +00:00
Georg Wiese
dec7394b3b Improve free variable detection (#3235)
As a real-life example, consider this constraint:
```
(opcode_loadb_flag0_1 + opcode_loadb_flag1_1) *
(
    from_state__timestamp_0
    - rs1_aux_cols__base__prev_timestamp_1
    - rs1_aux_cols__base__timestamp_lt_aux__lower_decomp__0_1
    - 131072 * rs1_aux_cols__base__timestamp_lt_aux__lower_decomp__1_1
    - + 2
) = 0
```

And assume that `rs1_aux_cols__base__prev_timestamp_1` does not appear
in other constraints, i.e., is a free variable.

Then this constraint is redundant: For any assignment of the other
variables, the prover can always solve for the value of
`rs1_aux_cols__base__prev_timestamp_1` that makes the second factor
evaluate to 0.

The previous implementation would not catch that: It would just call
`constraint.try_solve_for(free_variable).is_some()`, which would return
`false`, see the implementation of `try_solve_for`:


c5b35ea4b0/constraint-solver/src/grouped_expression.rs (L511-L533)
2025-08-28 16:51:21 +00:00
Leo
a210dde5d6 remove witgen opt (#3236)
The code removed here is an execution optimization to not have to
perform more computation than needed. However it relies on some
assumptions on the optimizer that don't always hold, therefore it's
safer to remove it.
This fixes some benchmarks that were broken on nightly.
2025-08-28 16:47:41 +00:00
Leo
c5b35ea4b0 remove podwr vm from main repo (#3231)
- Remove all crates that are not linked with `autoprecompiles`,
`openvm`, `constraint-solver`
- Remove tests and artifacts linked with removed crates
- Adjust CI
2025-08-28 10:03:36 +00:00
chriseth
1ea44337f1 Fix invalid conflict resolution. (#3232)
This optimizer function call is now called inside
`remove_redundant_constraints` because that depends on it to work
correctly.
2025-08-28 09:04:38 +00:00
ShuangWu121
71c3c3db71 k256 updated, ecc tests with larger input (#3217)
k256 is updated with the newer openvm-guest-hint and we can test ecc
with larger input 50

---------

Co-authored-by: Georg Wiese <georgwiese@gmail.com>
2025-08-26 14:23:58 +00:00
Thibaut Schaeffer
dcb82fafed Implement serde on ApcWithStats (#3228) 2025-08-26 14:17:11 +00:00
ShuangWu121
9805874e20 New ecc manual guest, using msm without pippenger (#3219)
manual ecc using msm with the version that does not use pippenger, which
is cheaper

INFO │ ┝━ i [info]: total_trace_cells = 12_704_468 (excluding
preprocessed)
2025-08-26 14:16:03 +00:00
chriseth
e65df60cfe Document is_simple_equivalence. (#3224) 2025-08-26 14:14:44 +00:00
chriseth
349c742fcc Display for Block. (#3226)
It is much more convenient for debugging to have a `Display` available,
especially when debugging the generic code.
2025-08-26 10:27:48 +00:00
chriseth
91bb74b192 Use RuntimeConstant instead of FieldElement. (#3225) 2025-08-26 09:52:04 +00:00
Thibaut Schaeffer
3cc2de7e0d Introduce AlgebraicConstraint type in solver (#3215)
I got confused before about what is an expression and what is a
constraint.
For example, in boolean extraction, we return an expression which I
thought was the boolean. But it turns out the expression is the new
constraint.

Similarly, there are some things that we can do for constraints which
wouldn't work for expression: for example, `2 * x == 0` can be replaced
by `x == 0`. But `2 * x` as an expression cannot be replaced by `x`.

This PR introduces a wrapper and uses it where possible.

Some caveats:
- This PR implements `Deref` and `DerefMut` for the constraint, which
means that we can call any function which takes a reference to an
expression by passing a constraint. This partially defeats the purpose
of the change, as we can by mistake call a function which would only be
meant for expressions. This is fixed in #3220
- This PR keeps the `solve` functions as before, where they run on
expressions, not constraints. This does not make sense in my opinion, as
solving should be for constraints only, however here's an example which
would break if we made this change: if we are solving the constraint `a
* b = 0` we want to solve the constraint `a = 0`. This would require
creating a constraint out of `a` on the fly, which is not implemented in
this PR. This is fixed in #3220
2025-08-25 19:08:44 +00:00
Georg Wiese
8700b12716 Candidate JSON: Pretty-print instructions (#3223)
We used to export instruction in their JSON format, e.g.
`{"opcode":512,"a":1879048082,"b":1879048082,"c":2013265793,"d":268435454,"e":268435454,"f":0,"g":0}`.

I changed this to be the pretty-printed string instead. I think this
makes more sense, because we don't reading them like this is hard and we
don't want to re-implement the pretty-printing in Python.

I checked that currently our Python scripts don't really read this
value, they only use the length of the list, so this PR doesn't break
them. In the future, I'm hoping to get Claude to generate an interactive
version of the effectiveness plot, so that we can also explore the
source code of each block.
2025-08-25 19:03:20 +00:00
chriseth
2748ac0579 Inline only at end (#3173)
Fixes https://github.com/powdr-labs/powdr/issues/3113

---------

Co-authored-by: Georg Wiese <georgwiese@gmail.com>
Co-authored-by: schaeff <thibaut@powdrlabs.com>
2025-08-25 15:41:02 +00:00
Georg Wiese
608a1f09ca Nightly hot fix: Move tests after benchmarks (#3222)
Nightly has been failing for a while. We should fix that, but by moving
ignored the tests after the benchmarks, we should at least get nightly
benchmark results again (and test our most important guest programs).

I think this is also a good idea in general, because we often manually
run nightly to get the latest benchmarks on a particular branch. This
way, we get results earlier.

I started a manual run on this branch:
https://github.com/powdr-labs/powdr/actions/runs/17212171321
2025-08-25 15:36:22 +00:00
ShuangWu121
6c0d481b50 Add ecrecover guest (#3160)
Manual precompile: total_trace_cells = 15_368_081

ecrecover with PowdrAffinePoint:
APC=50: total_trace_cells = 228_239_394

---------

Co-authored-by: Georg Wiese <georgwiese@gmail.com>
2025-08-22 23:16:30 +00:00
Thibaut Schaeffer
86c31acd9a Make powdr generic over the pgo method (#3188)
Introduce `PgoAdapter` which wraps `Adapter` and can call apc
generation. Removes the match statements over the pgo method. Breaking
change. Now the client can pick some pgo implementations like
`pgo::CellPgo` and use it like
`CellPgo::<MyAdapter>::new(pgo_data).generate_apcs(blocks)`. The client
can also implement `PgoAdapter<A: Adapter>` for its own pgo
implementation.
2025-08-22 13:59:23 +00:00
chriseth
4adeccd914 Remove duplicate factors. (#3205)
This new optimizer step removes duplicate factors in a single algebraic
constraint.

It was detected by the assertion that is now commented, which assumed
that if all factors of one constraint also appear in another constraint
then the number of factors is also less or equal the number of factors
in the other constraint.

By running the duplicate factor removal right before that other step
this assumption gets true.
2025-08-22 13:09:22 +00:00
Georg Wiese
95e773400f Remove BusType::OpenVmBitwiseLookup (#3211)
After #3209, it is no longer necessary to list OpenVM's "bitwise lookup"
bus in the `BusType` enum, which lives in the VM-agnostic
`autoprecompiles` crate.
2025-08-22 11:19:53 +00:00
Georg Wiese
6289eb6a90 Inline run_optimization_loop_until_no_change (#3212)
Having an extra function for this used to make sense when we were
calling it twice (once with and once without bus interaction variables),
but that got removed with #3171. I think now inlining this is easier to
read.
2025-08-22 08:58:31 +00:00
chriseth
1ecfbf5484 Booleanize changed constraints. (#3208)
The boolean extractor currently handles newly incoming algebraic
constraints. Substitutions that are performed during solving can lead to
constraints being boolean-extractable where we were not able to do
boolean extraction before. This PR tries to perform boolean extraction
on all constraints that potentially changed because of a substitution.

---------

Co-authored-by: schaeff <thibaut@powdrlabs.com>
2025-08-21 15:01:45 +00:00
Georg Wiese
3422658efd Add ECC nightly test (#3207)
Built on #3203

This PR:
- Modifies the ECC tests to continue doing MSMs for a number of times
(passed as an input)
- Adds this as a benchmark to the nightly test

I got these results:

| filename | num_segments | app_proof_cells | app_proof_cols |
total_proof_time_ms | app_proof_time_ms | leaf_proof_time_ms |
inner_recursion_proof_time_ms |

|---------------------------------|--------------|-----------------|----------------|---------------------|-------------------|--------------------|-------------------------------|
| affine-hint-apc000/metrics.json | 4 | 3852743848 | 6044 | 69327 |
35904 | 12783 | 20640 |
| affine-hint-apc003/metrics.json | 3 | 3140411518 | 6219 | 50886 |
30551 | 9791 | 10544 |
| affine-hint-apc010/metrics.json | 2 | 1618931796 | 33742 | 51152 |
16193 | 25074 | 9885 |
| affine-hint-apc030/metrics.json | 1 | 1091031082 | 40436 | 40165 |
11166 | 23824 | 5175 |
| affine-hint-apc100/metrics.json | 1 | 944216106 | 54662 | 55193 |
10174 | 39800 | 5219 |
| manual/metrics.json | 1 | 1041144324 | 5618 | 21215 | 10090 | 6236 |
4889 |
| projective-apc000/metrics.json | 9 | 9622555316 | 12991 | 156526 |
88927 | 28593 | 39006 |
| projective-apc003/metrics.json | 2 | 3195273488 | 31100 | 64314 |
31006 | 23439 | 9869 |
| projective-apc010/metrics.json | 2 | 3644260624 | 33710 | 70673 |
35933 | 24873 | 9867 |
| projective-apc030/metrics.json | 1 | 1931874516 | 56279 | 62528 |
18945 | 38336 | 5247 |
| projective-apc100/metrics.json | 1 | 1806846164 | 70086 | 65856 |
18181 | 42434 | 5241 |

It shows that:
- Using `k256` out of the box without APCs takes 156s
- Switching to affine representation + using hints for the base field
inverse takes 69s
- Accelerating the resulting code using APCs takes 40s
- Using OpenVMs manual precompile takes 21s

The Hint + APC version is similar to the manual precompile in terms of
app prove time, but due to the much larger number of columns, recursion
becomes expensive.
2025-08-21 14:45:18 +00:00
ShuangWu121
16b5ccff53 Normalize the hint before sending to prover from host (#3210)
Normalize the hint before sending to prover from host
2025-08-21 14:42:39 +00:00
Georg Wiese
d0c58e7b5b Remove Bitwise Lookup Optimizer (#3209)
Removes an optimizer is highly OpenVM specific and redundant after #3151
and #3130.
2025-08-21 14:34:36 +00:00
Georg Wiese
f4345b5304 Improve basic metrics summary (#3203)
Adds `app_proof_cols` and `total_proof_time_ms` columns to the result
CSV.
2025-08-21 14:09:12 +00:00
chriseth
b5aa6759b4 Avoid running boolean extraction twice. (#3200)
In a future PR (#3208) we will try to run boolean extraction on any
newly changed constraint. This can have the risk that we perform boolean
extraction on a constraint where we already have run boolean extraction.
This PR stores a map of substitutions we performed to avoid introducing
a new boolean variable that then just turns out to be equivalent to an
already existing one.

Closes 3202

---------

Co-authored-by: schaeff <thibaut@powdrlabs.com>
2025-08-21 13:56:15 +00:00
Georg Wiese
81ae444b4c Refactor run_guest_benches.sh (#3198)
I wanted to refactor the `run_guest_benches.sh` to make it a bit more
flexible. With this, it should be possible to test the ECC guest easily
(#3118), which actually has 3 guests (manual, out-of-the-box software,
hint-optimized software).

I also brought the matmul test back.

The file structure is not exactly the same as before, but similar (and
more organized):

https://github.com/powdr-labs/bench-results/tree/gh-pages/results/2025-08-20-1538

(which is from this run:
https://github.com/powdr-labs/powdr/actions/runs/17099625118/job/48492387082)

---------

Co-authored-by: chriseth <chris@ethereum.org>
2025-08-21 10:59:04 +00:00
chriseth
8701951b47 Collapse solvers (#3199)
The layered trait-based solver structure does provide a clean separation
but if we want to implement #3106 we have to call the boolean extractor
component from the innermost component which is quite difficult to
achieve. Also, most of the layers were just a simple pass-through for
most of the functions.

So this PR collapses the boolean extractor, linearizer and base solver
into one solver. It still keeps the VarTransform layer because it is
convenient to keep the type generic.
2025-08-20 16:27:57 +00:00
chriseth
4fa8d35674 Remove variables that are only constrained by a simple solvable algebraic constraints. (#3196)
Fixes https://github.com/powdr-labs/powdr/issues/3113

---------

Co-authored-by: Georg Wiese <georgwiese@gmail.com>
2025-08-20 15:20:43 +00:00
chriseth
5e83a8a93a Do not use bus field variables. (#3171)
Removes the special introduction and removal of bus variables because
the solver can now handle this on its own through the `LinearizedSolver`
component. It also has the benefit that we do not need to run the
optimizer twice any more (once with bus interaction variables and once
without).

Previously we would introduce a new variable type outside of the solver
and replace all bus interactions `bus_interaction(1, x + y * z)` by
`bus_interaction(1, bus_var_1)` and the algebraic constraint `bus_var_1
= x + y * z`.

Now the `LinearizedSolver` is a component inside the solver that
replaces all bus interaction fields (that are not already constants or
simple variables) and also replaces all non-linear components:

`bus_interaction(1, x + y * z)`

becomes

```
bus_interaction(1, v1)
v1 = x + v2
v2 = y * z
```

The reason behind also replacing non-linear parts is because range
constraints are only stored for variables, not for all sub-expressions.
Also if we find the same non-linear sub-expression multiple times, we
can now replace it directly by the same variable.

---------

Co-authored-by: Georg Wiese <georgwiese@gmail.com>
2025-08-20 14:20:15 +00:00
ShuangWu121
3166a8e99f ECC guests using hint (#3118)
guest programs perform multi scalar multiplication: two scalar, two
points, add their results together.
the points and scalars are random, chosen by a [test
](912d939948/k256/src/arithmetic/mul.rs (L467))
of unmodified k256 that tests random point scalar multiplication with
random scalar.
some performance results:
- manual: 
`total_trace_cells = 38_567_392`

- affine with hint:
apc=0: `total_trace_cells = 295_963_682`
apc=10: `total_trace_cells = 87_338_018`
apc=100: `total_trace_cells = 58_438_434`
apc=200: `total_trace_cells = 55_226_498`

- projective:
apc=0: `total_trace_cells = 576_778_288 `
apc=100: `total_trace_cells = 84_235_440`

- affine without hint:
apc=0: 
```
INFO     │        ┝━ i [info]: total_trace_cells = 815_132_720 (excluding preprocessed)
INFO     │        ┝━ i [info]: total_trace_cells = 742_574_128 (excluding preprocessed)
INFO     │        ┝━ i [info]: total_trace_cells = 814_925_872 (excluding preprocessed)
INFO     │        ┝━ i [info]: total_trace_cells = 814_925_872 (excluding preprocessed)
INFO     │        ┝━ i [info]: total_trace_cells = 814_925_872 (excluding preprocessed)
INFO     │        ┝━ i [info]: total_trace_cells = 742_574_128 (excluding preprocessed)
INFO     │        ┝━ i [info]: total_trace_cells = 54_618_160 (excluding preprocessed)
```

apc=100: `total_trace_cells = 1_105_868_464`

---------

Co-authored-by: Georg Wiese <georgwiese@gmail.com>
2025-08-19 14:53:10 +00:00
chriseth
bb49beb9b6 Remove outer negation when converting a grouped expression to an algebraic constraint. (#3194) 2025-08-19 11:26:33 +00:00
chriseth
2b2006d6db Emit rerun directives so that we only re-build the parser if the grammar changed. (#3195) 2025-08-19 11:03:25 +00:00
chriseth
36bd7abec7 Ignore range constraint on output. (#3190)
Summary: We do not need to add the range constraint on the output
because the output is uniquely determined by the formula and the range
constraints on the inputs.

Details:

This slightly improves the "low degree bus interaction optimizer". It
replaces a bus interaction by an algebraic constraint and simple range
constraints in the following way:

1. It performs exhaustive search about which of the non-constant fields
in the bus interaction are inputs and which (only one) is the output
2. Determines currently-known range constraints on inputs and outputs
3. Using exhaustive search, chooses a candidate function and checks that
for all input values in the range constraints, the candidate computes
the same output as the bus interaction would (i.e. the bus interaction
also allows exactly one output compatible with the concrete values for
the inputs).
4. If such a candidate is function, it replaces the bus interaction by
the candidate turned into an algebraic constraint and simple range
constraints (the ones determined in the beginning)

This PR changes the mechanism in that it does not re-add range
constraints for the output, only for the inputs. The reason is that the
algebraic constraint directly computes the value for the output for all
inputs within the range constraints of the input. So the algebraic
constraint already enforces the range constraint on the output from the
range constraints on the inputs.
2025-08-19 09:52:23 +00:00
chriseth
908a3f7fb3 Improve test reporting. (#3191)
Previously, for successful tests, it would still update the expectation
file and print that it did so, even though the contents were the same.
Now the "update" message is only printed if the contents are actually
different.
2025-08-19 09:08:43 +00:00
chriseth
1b7c2816ab Fix strum dependency. (#3193)
The feature is actually used in the crate. It did not produce a build
error because we never compile crates individually and it's enough for
the feature to be enabled in some crate.
2025-08-18 17:14:13 +00:00
chriseth
ffc3395056 Increase number of runners. (#3189) 2025-08-18 14:54:04 +00:00