Open str4d opened 3 years ago
Actually, in the above sketch there's no need to reuse StandardPlonk
for holding values; StandardPlonk::assign_addition
is a concrete method, so it can just take the necessary values as parameters.
After discussing this more last week, I'm pretty sure that this would require several more changes from the above:
Option<_>
to support side-effects (like pulling from iterators).T
and S
above.So I think the next step is to write a macro that produces the gate structs and associated boilerplate / mappings, and then try to use them for a few example circuits.
See also https://github.com/zcash/halo2/issues/509#issuecomment-1146025689 wrt value assignments.
During Office Hours today, while trying to figure out how to assign table rows inside regions, we noted that a nice way to do overlapping gate assignments would be to use the Value
type directly, and then after synthesis the backend does a pass to ensure that all queried gate cells were assigned. This would enable users doing tesselation to just assign values for the zero-rotation row of the gate (or whichever rotations are most convenient for the gate author), leaving the next gate to fill in the blanks (that are represented in the current gate by Value::unknown()
), and then the first and/or last gate assignments handle the ends.
Currently, to use a custom gate (being a group of constraints), the circuit developer needs to do the following:
Layouter::assign_region
to create a region in which the gate can be used.x
.x
.Note that the "definition" of the gate is not propagated from configuration to synthesis; the circuit developer just has to "remember" that definition and assign cells appropriately. On the one hand, this makes it easy to detect unintended double-assignments to cells, as the developer can assign once to a cell used in multiple overlapping gates. On the other hand, it's still on the developer to prevent those double-assignments, and it's more likely that the developer will get the assignments wrong due to needing to manually position the gate's "Tetris piece".
My idea for improving this (which I thought I'd already written down somewhere, but oh well) is that gates should be defined as structs with generic parameters:
At configure time, each gate struct is constructed to contain "cell templates", which are then used to configure the gate with the constraint relations:
The gate structs (
foo
in the above example) are then stored in the circuit config.Each gate struct has assignment functions that can be called at synthesis time within a region, by providing the offset to assign the gate at, and the values that should be assigned:
The use of the same struct (template) for both the gate and its values, reduces the chance that developers miss any cell assignments. Reviewers would only need to look at
StandardPlonk::assign_addition
to understand that assignment, instead of in potentially-repeated untethered functions.