mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-07 16:23:12 +00:00
Misc
This commit is contained in:
parent
5d6da4f94a
commit
58425eb548
@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet};
|
|||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::iter::{Product, Sum};
|
use std::iter::{Product, Sum};
|
||||||
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||||
use std::ptr;
|
use std::{ptr, fmt};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use num::{BigUint, FromPrimitive, One, Zero};
|
use num::{BigUint, FromPrimitive, One, Zero};
|
||||||
@ -11,6 +11,7 @@ use crate::field::field::Field;
|
|||||||
use crate::wire::Wire;
|
use crate::wire::Wire;
|
||||||
use crate::gates::output_graph::GateOutputLocation;
|
use crate::gates::output_graph::GateOutputLocation;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
|
use std::fmt::{Display, Formatter, Debug};
|
||||||
|
|
||||||
pub(crate) struct EvaluationVars<'a, F: Field> {
|
pub(crate) struct EvaluationVars<'a, F: Field> {
|
||||||
pub(crate) local_constants: &'a [F],
|
pub(crate) local_constants: &'a [F],
|
||||||
@ -279,6 +280,12 @@ impl<F: Field> ConstraintPolynomial<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F: Field> Display for ConstraintPolynomial<F> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<F: Field> PartialEq for ConstraintPolynomial<F> {
|
impl<F: Field> PartialEq for ConstraintPolynomial<F> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
ptr::eq(&*self.0, &*other.0)
|
ptr::eq(&*self.0, &*other.0)
|
||||||
@ -480,6 +487,29 @@ pub(crate) enum ConstraintPolynomialInner<F: Field> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F: Field> Display for ConstraintPolynomialInner<F> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
ConstraintPolynomialInner::Constant(c) =>
|
||||||
|
write!(f, "{}", c),
|
||||||
|
ConstraintPolynomialInner::LocalConstant(i) =>
|
||||||
|
write!(f, "local_const_{}", i),
|
||||||
|
ConstraintPolynomialInner::NextConstant(i) =>
|
||||||
|
write!(f, "next_const_{}", i),
|
||||||
|
ConstraintPolynomialInner::LocalWireValue(i) =>
|
||||||
|
write!(f, "local_wire_{}", i),
|
||||||
|
ConstraintPolynomialInner::NextWireValue(i) =>
|
||||||
|
write!(f, "next_wire_{}", i),
|
||||||
|
ConstraintPolynomialInner::Sum { lhs, rhs } =>
|
||||||
|
write!(f, "({} + {})", lhs, rhs),
|
||||||
|
ConstraintPolynomialInner::Product { lhs, rhs } =>
|
||||||
|
write!(f, "({} * {})", lhs, rhs),
|
||||||
|
ConstraintPolynomialInner::Exponentiation { base, exponent } =>
|
||||||
|
write!(f, "({} ^ {})", base, exponent),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<F: Field> ConstraintPolynomialInner<F> {
|
impl<F: Field> ConstraintPolynomialInner<F> {
|
||||||
fn add_dependencies(&self, gate: usize, deps: &mut HashSet<Wire>) {
|
fn add_dependencies(&self, gate: usize, deps: &mut HashSet<Wire>) {
|
||||||
match self {
|
match self {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter, Display};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||||
|
|
||||||
@ -29,9 +29,15 @@ impl PartialEq for CrandallField {
|
|||||||
|
|
||||||
impl Eq for CrandallField {}
|
impl Eq for CrandallField {}
|
||||||
|
|
||||||
|
impl Display for CrandallField {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Debug for CrandallField {
|
impl Debug for CrandallField {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
self.0.fmt(f)
|
Debug::fmt(&self.0, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use std::fmt::Debug;
|
use std::fmt::{Debug, Display};
|
||||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||||
|
|
||||||
/// A finite field with prime order less than 2^64.
|
/// A finite field with prime order less than 2^64.
|
||||||
@ -16,6 +16,7 @@ pub trait Field: 'static
|
|||||||
+ Div<Self, Output=Self>
|
+ Div<Self, Output=Self>
|
||||||
+ DivAssign<Self>
|
+ DivAssign<Self>
|
||||||
+ Debug
|
+ Debug
|
||||||
|
+ Display
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync {
|
+ Sync {
|
||||||
const ZERO: Self;
|
const ZERO: Self;
|
||||||
|
|||||||
@ -123,10 +123,11 @@ mod tests {
|
|||||||
use crate::gates::deterministic_gate::DeterministicGate;
|
use crate::gates::deterministic_gate::DeterministicGate;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn degree() {
|
fn degree() {
|
||||||
type F = CrandallField;
|
type F = CrandallField;
|
||||||
const W: usize = 12;
|
const W: usize = 12;
|
||||||
const R: usize = 101;
|
const R: usize = 20;
|
||||||
let gate = GMiMCGate::<F, W, R> { constants: Arc::new([F::TWO; R]) };
|
let gate = GMiMCGate::<F, W, R> { constants: Arc::new([F::TWO; R]) };
|
||||||
let config = CircuitConfig {
|
let config = CircuitConfig {
|
||||||
num_wires: 200,
|
num_wires: 200,
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::iter;
|
use std::{iter, fmt};
|
||||||
|
|
||||||
use num::{BigUint, FromPrimitive, One};
|
use num::{BigUint, FromPrimitive, One, ToPrimitive};
|
||||||
|
|
||||||
use crate::constraint_polynomial::ConstraintPolynomial;
|
use crate::constraint_polynomial::ConstraintPolynomial;
|
||||||
use crate::field::field::Field;
|
use crate::field::field::Field;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
/// Represents a set of deterministic gate outputs, expressed as polynomials over witness
|
/// Represents a set of deterministic gate outputs, expressed as polynomials over witness
|
||||||
/// values.
|
/// values.
|
||||||
@ -31,32 +32,39 @@ impl<F: Field> OutputGraph<F> {
|
|||||||
|
|
||||||
let mut current_graph = self.clone();
|
let mut current_graph = self.clone();
|
||||||
|
|
||||||
while current_graph.count_high_degree_polys(max_degree) > 0 {
|
'shrinker: while current_graph.count_high_degree_polys(max_degree) > 0 {
|
||||||
// Find polynomials with a degree between 2 and the max, inclusive.
|
// Find polynomials with a degree between 2 and the max, inclusive.
|
||||||
// These are candidates for becoming new wires.
|
// These are candidates for becoming new wires.
|
||||||
let mut candidates = current_graph.degree_map().into_iter()
|
let degrees = current_graph.degree_map();
|
||||||
.filter(|(_poly, deg)| deg > &BigUint::one() && deg <= &max_degree_biguint)
|
let current_high_deg_count = current_graph.count_high_degree_polys(max_degree);
|
||||||
.map(|(poly, _deg)| poly);
|
let mut candidate_degrees: Vec<(ConstraintPolynomial<F>, usize)> = degrees
|
||||||
|
.iter()
|
||||||
|
.filter(|(poly, deg)| *deg > &BigUint::one() && *deg <= &max_degree_biguint)
|
||||||
|
.map(|(poly, deg)| (poly.clone(), deg.to_usize().unwrap()))
|
||||||
|
.collect();
|
||||||
|
candidate_degrees.sort_unstable_by_key(|(poly, deg)| *deg);
|
||||||
|
candidate_degrees.reverse();
|
||||||
|
|
||||||
// Pick the candidate that minimizes the number of high-degree polynomials in our graph.
|
for (poly, _deg) in &candidate_degrees {
|
||||||
// This is just a simple heuristic; it won't always give an optimal wire count.
|
let candidate_graph = current_graph.allocate_wire(poly.clone());
|
||||||
let mut first = candidates.next().expect("No candidate; cannot reduce degree further");
|
|
||||||
let mut leader_graph = current_graph.allocate_wire(first);
|
|
||||||
let mut leader_high_deg_count = leader_graph.count_high_degree_polys(max_degree);
|
|
||||||
|
|
||||||
for candidate in candidates {
|
|
||||||
let candidate_graph = current_graph.allocate_wire(candidate);
|
|
||||||
let candidate_high_deg_count = candidate_graph.count_high_degree_polys(max_degree);
|
let candidate_high_deg_count = candidate_graph.count_high_degree_polys(max_degree);
|
||||||
if candidate_high_deg_count < leader_high_deg_count {
|
if candidate_high_deg_count < current_high_deg_count {
|
||||||
leader_graph = candidate_graph;
|
// println!("before {}", ¤t_graph);
|
||||||
leader_high_deg_count = candidate_high_deg_count;
|
// println!("after {}", &candidate_graph);
|
||||||
|
current_graph = candidate_graph;
|
||||||
|
println!("Reduced high degree polys to {}", candidate_high_deg_count);
|
||||||
|
continue 'shrinker;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// println!("before {:?}", current_graph);
|
println!("No good candidates; cannot reduce high degree polys");
|
||||||
// println!("after {:?}", leader_graph);
|
for (poly, _deg) in candidate_degrees {
|
||||||
current_graph = leader_graph;
|
let candidate_graph = current_graph.allocate_wire(poly);
|
||||||
println!("{}", leader_high_deg_count);
|
current_graph = candidate_graph;
|
||||||
|
continue 'shrinker;
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("No candidate; cannot make progress");
|
||||||
}
|
}
|
||||||
|
|
||||||
current_graph
|
current_graph
|
||||||
@ -101,6 +109,15 @@ impl<F: Field> OutputGraph<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F: Field> Display for OutputGraph<F> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
for (loc, out) in &self.outputs {
|
||||||
|
write!(f, "{} := {}, ", loc, out)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents an output location of a deterministic gate.
|
/// Represents an output location of a deterministic gate.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum GateOutputLocation {
|
pub enum GateOutputLocation {
|
||||||
@ -110,12 +127,51 @@ pub enum GateOutputLocation {
|
|||||||
NextWire(usize),
|
NextWire(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for GateOutputLocation {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
GateOutputLocation::LocalWire(i) => write!(f, "local_wire_{}", i),
|
||||||
|
GateOutputLocation::NextWire(i) => write!(f, "next_wire_{}", i),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::constraint_polynomial::ConstraintPolynomial;
|
use crate::constraint_polynomial::ConstraintPolynomial;
|
||||||
use crate::field::crandall_field::CrandallField;
|
use crate::field::crandall_field::CrandallField;
|
||||||
use crate::gates::output_graph::{GateOutputLocation, OutputGraph};
|
use crate::gates::output_graph::{GateOutputLocation, OutputGraph};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shrink_mimc() {
|
||||||
|
// This is like a simplified version of GMiMC, for easy debugging.
|
||||||
|
type F = CrandallField;
|
||||||
|
let switch = ConstraintPolynomial::<F>::local_wire_value(0);
|
||||||
|
let x = ConstraintPolynomial::<F>::local_wire_value(1);
|
||||||
|
let y = ConstraintPolynomial::<F>::local_wire_value(2);
|
||||||
|
|
||||||
|
// deg 2
|
||||||
|
let delta = &switch * (&y - &x);
|
||||||
|
let l0 = &x + δ
|
||||||
|
let r0 = &y - δ
|
||||||
|
let s0 = &l0 + &r0;
|
||||||
|
|
||||||
|
// 2*3
|
||||||
|
let l1 = s0.cube(); let r1 = r0.cube(); let s1 = &l1 + &r1;
|
||||||
|
// 2*3*3
|
||||||
|
let l2 = s1.cube(); let r2 = r1.cube(); let s2 = &l2 + &r2;
|
||||||
|
// 2*3*3*3
|
||||||
|
let l3 = s2.cube(); let r3 = r2.cube(); let s3 = &l3 + &r3;
|
||||||
|
|
||||||
|
let og = OutputGraph { outputs: vec![
|
||||||
|
(GateOutputLocation::NextWire(0), l3),
|
||||||
|
(GateOutputLocation::NextWire(1), r3),
|
||||||
|
] };
|
||||||
|
|
||||||
|
let shrunk = og.shrink_degree(9);
|
||||||
|
assert_eq!(shrunk.max_wire_input_index(), Some(4));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn shrink_squaring_graph() {
|
fn shrink_squaring_graph() {
|
||||||
type F = CrandallField;
|
type F = CrandallField;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user