Replies: 4 comments 1 reply
-
I guess one optimization for 2. I can think of is the boolean constraint:
which gives us:
|
Beta Was this translation helpful? Give feedback.
-
(3) would be a great solution! We should go for it. I also think the existing system (1) -- keeping the AST around without reusing intermediate sealed variables -- leads to less efficient user code than the simpler (2) / sealing variables eagerly. To support doing something about this, I can give an example of user code that I saw several times, which is very inefficient just because we keep the AST around. A common pattern is to "select" a single variable out of an array let x = Field.zero;
for (let i=0; i<n; i++) {
x = Circuit.if(b[i], x[i], x);
}
// if exactly one of the b[i] was 1, and the others 0, then x === x[i] now Now consider that Circuit.if(b, x, y) === b*(x - y) + y // x if b=1=true, y else Note here that if y is an addition AST of length i, then So in the example user code above, I believe such pathological inefficiencies are easy to create, and educating users about the low-level details and how they can use |
Beta Was this translation helpful? Give feedback.
-
@mimoo, thinking about your example with the boolean constraint, I wonder if we can do this optimization automatically. Just keeping a hashmap of constrained variables doesn't solve it: When multiplying x by (1-x), I'm afraid our algorithm would treat (1-x) as a separate variable y and create two generic gates, |
Beta Was this translation helpful? Give feedback.
-
We could track for each variable whether it can be written as a polynomial of degree 2 in one or two other variables. So every variable could keep track of a representation of the form In the boolean example, we would recognize that the product of Can this be improved further? |
Beta Was this translation helpful? Give feedback.
-
Currently in snarky we build a small AST when operating on field vars (called
Cvars
). The AST looks like this:I believe this was used when snarky was targeting R1CS, and it was useful because additions are for free. But in Plonk it seems less useful. Worse, it seems like this might lead us to constrain the same things several times.
For example, this pseudo-code would constrain the additions in
x
twice asz
would contain the entire AST contained inx
:There's three ways to solve this, that I can think of:
seal
function IIUCSolution 3 seems interesting. When reducing an AST, the algorithm could hash the entire AST and see if it was already constrained, and if so what the result variable is. If it wasn't, step in the AST and do the same, rinse and repeat. This might the best solution to implement?
cc @imeckler @mitschabaude
Beta Was this translation helpful? Give feedback.
All reactions