Change gate method for extra constants (#528)

* Change gate method for extra constants

* Rename

* feedback
This commit is contained in:
Daniel Lubarov 2022-04-04 14:33:54 -07:00 committed by GitHub
parent cc95cb5ee1
commit 8faf644f87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 40 deletions

View File

@ -6,7 +6,7 @@ use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
use crate::iop::ext_target::ExtensionTarget;
use crate::iop::generator::{ConstantGenerator, WitnessGenerator};
use crate::iop::generator::WitnessGenerator;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::vars::{
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
@ -95,16 +95,9 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ConstantGate {
self.num_consts
}
fn extra_constants(&self, gate_index: usize) -> Vec<ConstantGenerator<F>> {
fn extra_constant_wires(&self) -> Vec<(usize, usize)> {
(0..self.num_consts)
.map(|i| {
ConstantGenerator::new(
gate_index,
self.const_input(i),
self.wire_output(i),
F::ZERO,
)
})
.map(|i| (self.const_input(i), self.wire_output(i)))
.collect()
}
}

View File

@ -12,7 +12,7 @@ use crate::gates::selectors::UNUSED_SELECTOR;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
use crate::iop::ext_target::ExtensionTarget;
use crate::iop::generator::{ConstantGenerator, WitnessGenerator};
use crate::iop::generator::WitnessGenerator;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::vars::{
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
@ -181,8 +181,12 @@ pub trait Gate<F: RichField + Extendable<D>, const D: usize>: 'static + Send + S
.len()
}
/// Extra constants (i.e. constants that are not used in the gate's core functionality) generated by the gate.
fn extra_constants(&self, _gate_index: usize) -> Vec<ConstantGenerator<F>> {
/// Enables gates to store some "routed constants", if they have both unused constants and
/// unused routed wires.
///
/// Each entry in the returned `Vec` has the form `(constant_index, wire_index)`. `wire_index`
/// must correspond to a *routed* wire.
fn extra_constant_wires(&self) -> Vec<(usize, usize)> {
vec![]
}
}

View File

@ -10,9 +10,7 @@ use crate::gates::packed_util::PackedEvaluableBase;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
use crate::iop::ext_target::ExtensionTarget;
use crate::iop::generator::{
ConstantGenerator, GeneratedValues, SimpleGenerator, WitnessGenerator,
};
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
use crate::iop::target::Target;
use crate::iop::wire::Wire;
use crate::iop::witness::{PartitionWitness, Witness};
@ -77,17 +75,17 @@ impl<F: RichField + Extendable<D>, const D: usize> RandomAccessGate<F, D> {
(2 + self.vec_size()) * copy + 2 + i
}
fn num_ram_wires(&self) -> usize {
fn start_extra_constants(&self) -> usize {
(2 + self.vec_size()) * self.num_copies
}
fn wire_extra_constant(&self, i: usize) -> usize {
debug_assert!(i < self.num_extra_constants);
self.num_ram_wires() + i
self.start_extra_constants() + i
}
pub fn num_routed_wires(&self) -> usize {
self.num_ram_wires() + self.num_extra_constants
self.start_extra_constants() + self.num_extra_constants
}
/// An intermediate wire where the prover gives the (purported) binary decomposition of the
@ -255,9 +253,9 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGa
self.num_copies * constraints_per_copy + self.num_extra_constants
}
fn extra_constants(&self, gate_index: usize) -> Vec<ConstantGenerator<F>> {
fn extra_constant_wires(&self) -> Vec<(usize, usize)> {
(0..self.num_extra_constants)
.map(|i| ConstantGenerator::new(gate_index, i, self.wire_extra_constant(i), F::ZERO))
.map(|i| (i, self.wire_extra_constant(i)))
.collect()
}
}

View File

@ -328,27 +328,19 @@ impl<F: Field> SimpleGenerator<F> for NonzeroTestGenerator {
/// Generator used to fill an extra constant.
#[derive(Debug, Clone)]
pub struct ConstantGenerator<F: Field> {
pub(crate) struct ConstantGenerator<F: Field> {
pub gate_index: usize,
pub constant_index: usize,
pub target_index: usize,
pub wire_index: usize,
pub constant: F,
}
impl<F: Field> ConstantGenerator<F> {
pub fn new(gate_index: usize, constant_index: usize, target_index: usize, constant: F) -> Self {
ConstantGenerator {
gate_index,
constant_index,
target_index,
constant,
}
}
pub fn set_constant(&mut self, c: F) {
self.constant = c;
}
}
impl<F: Field> SimpleGenerator<F> for ConstantGenerator<F> {
fn dependencies(&self) -> Vec<Target> {
vec![]
@ -356,7 +348,7 @@ impl<F: Field> SimpleGenerator<F> for ConstantGenerator<F> {
fn run_once(&self, _witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) {
out_buffer.set_target(
Target::wire(self.gate_index, self.target_index),
Target::wire(self.gate_index, self.wire_index),
self.constant,
);
}

View File

@ -219,10 +219,17 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
);
constants.resize(gate_type.num_constants(), F::ZERO);
let index = self.gate_instances.len();
let gate_index = self.gate_instances.len();
self.constant_generators
.extend(gate_type.extra_constants(index));
.extend(gate_type.extra_constant_wires().into_iter().map(
|(constant_index, wire_index)| ConstantGenerator {
gate_index,
constant_index,
wire_index,
constant: F::ZERO, // Placeholder; will be replaced later.
},
));
// Note that we can't immediately add this gate's generators, because the list of constants
// could be modified later, i.e. in the case of `ConstantGate`. We will add them later in
@ -237,7 +244,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
constants,
});
index
gate_index
}
fn check_gate_compatibility<G: Gate<F, D>>(&self, gate: &G) {
@ -678,10 +685,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
// Set the constant in the constant polynomial.
self.gate_instances[const_gen.gate_index].constants[const_gen.constant_index] = c;
// Generate a copy between the target and the routable wire.
self.connect(
Target::wire(const_gen.gate_index, const_gen.target_index),
t,
);
self.connect(Target::wire(const_gen.gate_index, const_gen.wire_index), t);
// Set the constant in the generator (it's initially set with a dummy value).
const_gen.set_constant(c);
self.add_simple_generator(const_gen);