-
Notifications
You must be signed in to change notification settings - Fork 369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: introduce constraint blueprints. improve memory usage, enables custom gates and group of constraints #641
Conversation
note: trying to have R1C and Hint blueprint implement solve to recover from solver perf regression. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a big PR and I tried to find something, but imo the implementation is very straightforward. Everything makes sense.
I tried to find any typos or problems, but couldn't find any. But in any case I would still let it settle one develop for a bit just to edge off any potential bugs.
func (system *System) AddBlueprint(b Blueprint) BlueprintID { | ||
system.Blueprints = append(system.Blueprints, b) | ||
return BlueprintID(len(system.Blueprints) - 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should check no duplicate blueprints?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably... but do you compare the object type or the object itself? so far our blueprint are stateless, but I'm thinking a specialized hint blueprint that store in the struct list of powers of 2 coeff IDs would be interesting.
Or a blue print that stores the params for MiMC permutation. (ie no need to store these in the constraint related to that).
Warning: fat PR. See #602 for context.
Breaking changes
For circuit builders / developers: none.
constraint
package is impacted; in particular, sinceConstraintSystem
object is now the same for R1CS / Plonkish, methodsAddConstraint
andGetConstraints
are nowAddR1C
(respAddSparseR1C
) andGetR1Cs
. Signature is slightly modified (seeExample
in _test.go files inconstraint/
).TLDR
Essentially the goal of this PR is to minimize the memory footprint of compiled constraint systems (for both R1CS and Plonkish). The core idea is instead of storing a flat list of constraint, to store a list of
Instruction
which points to somecalldata
enabling aBlueprint
to "compress" (during compile time) a constraint intocalldata
and to "decompress" it during solving (or setup for zk backends).So for a (simple) example a plonk gate doing qL * xa + qR * xb + qO * xc == 0 will just store these coefficients / wire ids (and not the unused one like qM or qC).
Additionally did refactor the
SparseR1C
structure to followqLxa...
notation.The blueprint solving arithmetic is done using the same mechanism than in the frontend; we allocate (on the stack) a
[6]uint64
and do field ops on that. I had a shot at generic again but it's just too ugly / adds barrier / performance & memory issues.TODO
CheckUnconstrainedWires
Perf Status;
comparing the emulated bn254 pairing on develop vs on this branch:
regression on R1CS solver (+11% slower). all the rest (compile / solving time for both types) is faster / less greedy.
(this is without block of constraints / optimized blueprints for hints, etc)
impacts on perf of the compiler & solver: