-
Notifications
You must be signed in to change notification settings - Fork 504
feat: introduce constraint blueprints. improve memory usage, enables custom gates and group of constraints #641
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
Conversation
|
note: trying to have R1C and Hint blueprint implement solve to recover from solver perf regression. |
ivokub
left a comment
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.
constraintpackage is impacted; in particular, sinceConstraintSystemobject is now the same for R1CS / Plonkish, methodsAddConstraintandGetConstraintsare nowAddR1C(respAddSparseR1C) andGetR1Cs. Signature is slightly modified (seeExamplein _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
Instructionwhich points to somecalldataenabling aBlueprintto "compress" (during compile time) a constraint intocalldataand 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
SparseR1Cstructure to followqLxa...notation.The blueprint solving arithmetic is done using the same mechanism than in the frontend; we allocate (on the stack) a
[6]uint64and do field ops on that. I had a shot at generic again but it's just too ugly / adds barrier / performance & memory issues.TODO
CheckUnconstrainedWiresPerf 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: