mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-10 01:33:07 +00:00
Add wrapper types for Lookup and LookupTable
This commit is contained in:
parent
4351237160
commit
91c55d15f9
@ -1,8 +1,6 @@
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use crate::field::extension::Extendable;
|
||||
use crate::gates::lookup::LookupGate;
|
||||
use crate::gates::lookup_table::LookupTableGate;
|
||||
use crate::gates::lookup_table::{LookupTable, LookupTableGate};
|
||||
use crate::gates::noop::NoopGate;
|
||||
use crate::hash::hash_types::RichField;
|
||||
use crate::iop::target::Target;
|
||||
@ -47,7 +45,7 @@ pub const SMALLER_TABLE: [u16; 8] = [2, 24, 56, 100, 128, 16, 20, 49];
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Adds a lookup table to the list of stored lookup tables `self.luts` based on a table of (input, output) pairs. It returns the index of the LUT within `self.luts`.
|
||||
pub fn add_lookup_table_from_pairs(&mut self, table: Arc<Vec<(u16, u16)>>) -> usize {
|
||||
pub fn add_lookup_table_from_pairs(&mut self, table: LookupTable) -> usize {
|
||||
self.update_luts_from_pairs(table)
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use core::usize;
|
||||
|
||||
use super::lookup_table::LookupTable;
|
||||
use crate::field::extension::Extendable;
|
||||
use crate::field::packed::PackedField;
|
||||
use crate::gates::gate::Gate;
|
||||
@ -22,17 +23,19 @@ use crate::plonk::vars::{
|
||||
};
|
||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||
|
||||
pub type Lookup = Vec<(Target, Target)>;
|
||||
|
||||
/// A gate which stores (input, output) lookup pairs made elsewhere in the trace. It doesn't check any constraints itself.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LookupGate {
|
||||
/// Number of lookups per gate.
|
||||
pub num_slots: usize,
|
||||
/// LUT associated to the gate.
|
||||
lut: Arc<Vec<(u16, u16)>>,
|
||||
lut: LookupTable,
|
||||
}
|
||||
|
||||
impl LookupGate {
|
||||
pub fn new_from_table(config: &CircuitConfig, lut: Arc<Vec<(u16, u16)>>) -> Self {
|
||||
pub fn new_from_table(config: &CircuitConfig, lut: LookupTable) -> Self {
|
||||
Self {
|
||||
num_slots: Self::num_slots(config),
|
||||
lut,
|
||||
@ -142,7 +145,7 @@ impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D> for
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct LookupGenerator {
|
||||
row: usize,
|
||||
lut: Arc<Vec<(u16, u16)>>,
|
||||
lut: LookupTable,
|
||||
slot_nb: usize,
|
||||
}
|
||||
|
||||
|
||||
@ -24,23 +24,21 @@ use crate::plonk::vars::{
|
||||
};
|
||||
use crate::util::serialization::{Buffer, IoResult, Read, Write};
|
||||
|
||||
pub type LookupTable = Arc<Vec<(u16, u16)>>;
|
||||
|
||||
/// A gate which stores the set of (input, output) value pairs of a lookup table, and their multiplicities.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LookupTableGate {
|
||||
/// Number of lookup entries per gate.
|
||||
pub num_slots: usize,
|
||||
/// Lookup table associated to the gate.
|
||||
pub lut: Arc<Vec<(u16, u16)>>,
|
||||
pub lut: LookupTable,
|
||||
/// First row of the lookup table.
|
||||
last_lut_row: usize,
|
||||
}
|
||||
|
||||
impl LookupTableGate {
|
||||
pub fn new_from_table(
|
||||
config: &CircuitConfig,
|
||||
lut: Arc<Vec<(u16, u16)>>,
|
||||
last_lut_row: usize,
|
||||
) -> Self {
|
||||
pub fn new_from_table(config: &CircuitConfig, lut: LookupTable, last_lut_row: usize) -> Self {
|
||||
Self {
|
||||
num_slots: Self::num_slots(config),
|
||||
lut,
|
||||
@ -164,7 +162,7 @@ impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D> for
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct LookupTableGenerator {
|
||||
row: usize,
|
||||
lut: Arc<Vec<(u16, u16)>>,
|
||||
lut: LookupTable,
|
||||
slot_nb: usize,
|
||||
num_slots: usize,
|
||||
last_lut_row: usize,
|
||||
|
||||
@ -9,6 +9,7 @@ mod tests {
|
||||
use log::{Level, LevelFilter};
|
||||
|
||||
use crate::gadgets::lookup::{OTHER_TABLE, SMALLER_TABLE, TIP5_TABLE};
|
||||
use crate::gates::lookup_table::LookupTable;
|
||||
use crate::gates::noop::NoopGate;
|
||||
use crate::plonk::prover::prove;
|
||||
use crate::util::timing::TimingTree;
|
||||
@ -54,7 +55,7 @@ mod tests {
|
||||
|
||||
LOGGER_INITIALIZED.call_once(|| init_logger().unwrap());
|
||||
let tip5_table = TIP5_TABLE.to_vec();
|
||||
let table: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
let table: LookupTable = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
@ -129,7 +130,7 @@ mod tests {
|
||||
let first_out = tip5_table[look_val_a];
|
||||
let second_out = tip5_table[look_val_b];
|
||||
|
||||
let table: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
let table: LookupTable = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
|
||||
let other_table = OTHER_TABLE.to_vec();
|
||||
|
||||
@ -142,7 +143,7 @@ mod tests {
|
||||
let s = first_out + second_out;
|
||||
let final_out = other_table[s as usize];
|
||||
|
||||
let table2: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(other_table).collect());
|
||||
let table2: LookupTable = Arc::new((0..256).zip_eq(other_table).collect());
|
||||
let table2_index = builder.add_lookup_table_from_pairs(table2);
|
||||
|
||||
let output_final = builder.add_lookup_from_index(sum, table2_index);
|
||||
@ -208,11 +209,11 @@ mod tests {
|
||||
let init_b = 2;
|
||||
|
||||
let tab: Vec<u16> = SMALLER_TABLE.to_vec();
|
||||
let table: Arc<Vec<(u16, u16)>> = Arc::new((2..10).zip_eq(tab).collect());
|
||||
let table: LookupTable = Arc::new((2..10).zip_eq(tab).collect());
|
||||
|
||||
let other_table = OTHER_TABLE.to_vec();
|
||||
|
||||
let table2: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(other_table).collect());
|
||||
let table2: LookupTable = Arc::new((0..256).zip_eq(other_table).collect());
|
||||
let small_index = builder.add_lookup_table_from_pairs(table.clone());
|
||||
let output_a = builder.add_lookup_from_index(initial_a, small_index);
|
||||
|
||||
@ -293,7 +294,7 @@ mod tests {
|
||||
let look_val_b = 2;
|
||||
|
||||
let tip5_table = TIP5_TABLE.to_vec();
|
||||
let table: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
let table: LookupTable = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
|
||||
let out_a = table[look_val_a].1;
|
||||
let out_b = table[look_val_b].1;
|
||||
@ -310,7 +311,7 @@ mod tests {
|
||||
|
||||
let other_table = OTHER_TABLE.to_vec();
|
||||
|
||||
let table2: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(other_table).collect());
|
||||
let table2: LookupTable = Arc::new((0..256).zip_eq(other_table).collect());
|
||||
|
||||
let s = out_a + out_b;
|
||||
let out_final = table2[s as usize].1;
|
||||
@ -384,7 +385,7 @@ mod tests {
|
||||
let look_val_b = 2;
|
||||
|
||||
let tip5_table = TIP5_TABLE.to_vec();
|
||||
let table: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
let table: LookupTable = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
|
||||
let table_index = builder.add_lookup_table_from_pairs(table.clone());
|
||||
let output_a = builder.add_lookup_from_index(initial_a, table_index);
|
||||
|
||||
@ -25,7 +25,8 @@ use crate::gates::arithmetic_base::ArithmeticGate;
|
||||
use crate::gates::arithmetic_extension::ArithmeticExtensionGate;
|
||||
use crate::gates::constant::ConstantGate;
|
||||
use crate::gates::gate::{CurrentSlot, Gate, GateInstance, GateRef};
|
||||
use crate::gates::lookup::LookupGate;
|
||||
use crate::gates::lookup::{Lookup, LookupGate};
|
||||
use crate::gates::lookup_table::LookupTable;
|
||||
use crate::gates::noop::NoopGate;
|
||||
use crate::gates::public_input::PublicInputGate;
|
||||
use crate::gates::selectors::{selector_ends_lookups, selector_polynomials, selectors_lookup};
|
||||
@ -129,10 +130,10 @@ pub struct CircuitBuilder<F: RichField + Extendable<D>, const D: usize> {
|
||||
lookup_rows: Vec<LookupWire>,
|
||||
|
||||
/// For each LUT index, vector of `(looking_in, looking_out)` pairs.
|
||||
lut_to_lookups: Vec<Vec<(Target, Target)>>,
|
||||
lut_to_lookups: Vec<Lookup>,
|
||||
|
||||
// Lookup tables in the form of `Vec<(input_value, output_value)>`.
|
||||
luts: Vec<Arc<Vec<(u16, u16)>>>,
|
||||
luts: Vec<LookupTable>,
|
||||
|
||||
/// Optional common data. When it is `Some(goal_data)`, the `build` function panics if the resulting
|
||||
/// common data doesn't equal `goal_data`.
|
||||
@ -581,12 +582,12 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
|
||||
/// Checks whether a LUT is already stored in `self.luts`
|
||||
pub fn is_stored(&self, lut: Arc<Vec<(u16, u16)>>) -> Option<usize> {
|
||||
pub fn is_stored(&self, lut: LookupTable) -> Option<usize> {
|
||||
self.luts.iter().position(|elt| *elt == lut)
|
||||
}
|
||||
|
||||
/// Returns the LUT at index `idx`.
|
||||
pub fn get_lut(&self, idx: usize) -> Arc<Vec<(u16, u16)>> {
|
||||
pub fn get_lut(&self, idx: usize) -> LookupTable {
|
||||
assert!(
|
||||
idx < self.luts.len(),
|
||||
"index idx: {} greater than the total number of created LUTS: {}",
|
||||
@ -632,7 +633,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.copied()
|
||||
.zip_eq(table.iter().copied())
|
||||
.collect();
|
||||
let lut: Arc<Vec<(u16, u16)>> = Arc::new(pairs);
|
||||
let lut: LookupTable = Arc::new(pairs);
|
||||
|
||||
// If the LUT `lut` is already stored in `self.luts`, return its index. Otherwise, append `table` to `self.luts` and return its index.
|
||||
if let Some(idx) = self.is_stored(lut.clone()) {
|
||||
@ -646,7 +647,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
|
||||
/// Adds a table to the vector of LUTs in the circuit builder.
|
||||
pub fn update_luts_from_pairs(&mut self, table: Arc<Vec<(u16, u16)>>) -> usize {
|
||||
pub fn update_luts_from_pairs(&mut self, table: LookupTable) -> usize {
|
||||
// If the LUT `table` is already stored in `self.luts`, return its index. Otherwise, append `table` to `self.luts` and return its index.
|
||||
if let Some(idx) = self.is_stored(table.clone()) {
|
||||
idx
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use core::ops::{Range, RangeFrom};
|
||||
@ -19,6 +18,8 @@ use crate::fri::structure::{
|
||||
};
|
||||
use crate::fri::{FriConfig, FriParams};
|
||||
use crate::gates::gate::GateRef;
|
||||
use crate::gates::lookup::Lookup;
|
||||
use crate::gates::lookup_table::LookupTable;
|
||||
use crate::gates::selectors::SelectorsInfo;
|
||||
use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
@ -317,7 +318,7 @@ pub struct ProverOnlyCircuitData<
|
||||
///The concrete placement of the lookup gates for each lookup table index.
|
||||
pub lookup_rows: Vec<LookupWire>,
|
||||
/// A vector of (looking_in, looking_out) pairs for for each lookup table index.
|
||||
pub lut_to_lookups: Vec<Vec<(Target, Target)>>,
|
||||
pub lut_to_lookups: Vec<Lookup>,
|
||||
}
|
||||
|
||||
/// Circuit data required by the verifier, but not the prover.
|
||||
@ -380,7 +381,7 @@ pub struct CommonCircuitData<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub num_lookup_selectors: usize,
|
||||
|
||||
/// The stored lookup tables.
|
||||
pub luts: Vec<Arc<Vec<(u16, u16)>>>,
|
||||
pub luts: Vec<LookupTable>,
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CommonCircuitData<F, D> {
|
||||
|
||||
@ -456,6 +456,7 @@ mod tests {
|
||||
|
||||
use crate::field::types::Sample;
|
||||
use crate::fri::reduction_strategies::FriReductionStrategy;
|
||||
use crate::gates::lookup_table::LookupTable;
|
||||
use crate::gates::noop::NoopGate;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -529,7 +530,7 @@ mod tests {
|
||||
241, 25, 149, 105, 156, 51, 53, 168, 145, 247, 223, 79, 78, 226, 15, 222, 82, 115, 70,
|
||||
210, 27, 41, 1, 170, 40, 131, 192, 229, 248, 255,
|
||||
];
|
||||
let table: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
let table: LookupTable = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
let lut_index = builder.add_lookup_table_from_pairs(table);
|
||||
|
||||
@ -201,6 +201,7 @@ mod tests {
|
||||
use crate::fri::reduction_strategies::FriReductionStrategy;
|
||||
use crate::fri::FriConfig;
|
||||
use crate::gadgets::lookup::{OTHER_TABLE, TIP5_TABLE};
|
||||
use crate::gates::lookup_table::LookupTable;
|
||||
use crate::gates::noop::NoopGate;
|
||||
use crate::iop::witness::{PartialWitness, WitnessWrite};
|
||||
use crate::plonk::circuit_data::{CircuitConfig, VerifierOnlyCircuitData};
|
||||
@ -421,7 +422,7 @@ mod tests {
|
||||
let look_val_b = 2;
|
||||
|
||||
let tip5_table = TIP5_TABLE.to_vec();
|
||||
let table: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
let table: LookupTable = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
|
||||
let out_a = table[look_val_a].1;
|
||||
let out_b = table[look_val_b].1;
|
||||
@ -482,7 +483,7 @@ mod tests {
|
||||
let first_out = tip5_table[look_val_a];
|
||||
let second_out = tip5_table[look_val_b];
|
||||
|
||||
let table: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
let table: LookupTable = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
|
||||
let other_table = OTHER_TABLE.to_vec();
|
||||
|
||||
@ -495,7 +496,7 @@ mod tests {
|
||||
let s = first_out + second_out;
|
||||
let final_out = other_table[s as usize];
|
||||
|
||||
let table2: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(other_table).collect());
|
||||
let table2: LookupTable = Arc::new((0..256).zip_eq(other_table).collect());
|
||||
|
||||
let other_index = builder.add_lookup_table_from_pairs(table2);
|
||||
let output_final = builder.add_lookup_from_index(sum, other_index);
|
||||
@ -556,7 +557,7 @@ mod tests {
|
||||
let look_val_b = 2;
|
||||
|
||||
let tip5_table = TIP5_TABLE.to_vec();
|
||||
let table: Arc<Vec<(u16, u16)>> = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
let table: LookupTable = Arc::new((0..256).zip_eq(tip5_table).collect());
|
||||
|
||||
let out_a = table[look_val_a].1;
|
||||
let out_b = table[look_val_b].1;
|
||||
|
||||
@ -31,6 +31,7 @@ use crate::fri::reduction_strategies::FriReductionStrategy;
|
||||
use crate::fri::{FriConfig, FriParams};
|
||||
use crate::gadgets::polynomial::PolynomialCoeffsExtTarget;
|
||||
use crate::gates::gate::GateRef;
|
||||
use crate::gates::lookup::Lookup;
|
||||
use crate::gates::selectors::SelectorsInfo;
|
||||
use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField};
|
||||
use crate::hash::merkle_proofs::{MerkleProof, MerkleProofTarget};
|
||||
@ -1152,9 +1153,9 @@ pub trait Read {
|
||||
Ok(lut)
|
||||
}
|
||||
|
||||
/// Reads a target lookup table stored as `Vec<(Target, Target)>` from `self`.
|
||||
/// Reads a target lookup table stored as `Lookup` from `self`.
|
||||
#[inline]
|
||||
fn read_target_lut(&mut self) -> IoResult<Vec<(Target, Target)>> {
|
||||
fn read_target_lut(&mut self) -> IoResult<Lookup> {
|
||||
let length = self.read_usize()?;
|
||||
let mut lut = Vec::with_capacity(length);
|
||||
for _ in 0..length {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user