Skip to content
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

chore: the great documentation push of 2022 #84

Merged
merged 13 commits into from
Dec 28, 2022
23 changes: 23 additions & 0 deletions src/circuit/eltwise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,50 @@ use halo2_proofs::{
use log::error;
use std::{cell::RefCell, marker::PhantomData, rc::Rc};

/// Defines a non-linear layer.
pub trait Nonlinearity<F: FieldExt> {
/// Function that defines the non-linearity.
/// Arguments
///
/// * `x` - input to function
/// * `scales` - additional parameters that may parametrize the function
fn nonlinearity(x: i32, scales: &[usize]) -> F;
/// a value which is always in the table
fn default_pair(scales: &[usize]) -> (F, F) {
(F::zero(), Self::nonlinearity(0, scales))
}
}

/// A 1D non-linearity.
#[derive(Clone, Debug)]
pub struct Nonlin1d<F: FieldExt + TensorType, NL: Nonlinearity<F>> {
/// Input to the layer as a [ValTensor].
pub input: ValTensor<F>,
/// Input to the layer as a [ValTensor].
pub output: ValTensor<F>,
#[allow(missing_docs)]
pub _marker: PhantomData<(F, NL)>,
}

/// Halo2 lookup table for element wise non-linearities.
// Table that should be reused across all lookups (so no Clone)
#[derive(Clone, Debug)]
pub struct EltwiseTable<F: FieldExt, NL: Nonlinearity<F>> {
/// Input to table.
pub table_input: TableColumn,
/// Output of table
pub table_output: TableColumn,
/// Flags if table has been previously assigned to.
pub is_assigned: bool,
/// Number of bits used in lookup table.
pub scaling_params: Vec<usize>,
/// Number of bits used in lookup table.
pub bits: usize,
_marker: PhantomData<(F, NL)>,
}

impl<F: FieldExt, NL: Nonlinearity<F>> EltwiseTable<F, NL> {
/// Configures the table.
pub fn configure(
cs: &mut ConstraintSystem<F>,
bits: usize,
Expand All @@ -52,6 +68,7 @@ impl<F: FieldExt, NL: Nonlinearity<F>> EltwiseTable<F, NL> {
_marker: PhantomData,
}
}
/// Assigns values to the constraints generated when calling `configure`.
pub fn layout(&mut self, layouter: &mut impl Layouter<F>) {
assert!(!self.is_assigned);
let base = 2i32;
Expand Down Expand Up @@ -100,8 +117,11 @@ impl<F: FieldExt, NL: Nonlinearity<F>> EltwiseTable<F, NL> {
/// Configuration for element-wise non-linearities.
#[derive(Clone, Debug)]
pub struct EltwiseConfig<F: FieldExt + TensorType, NL: Nonlinearity<F>> {
/// [VarTensor] input to non-linearity.
pub input: VarTensor,
/// [VarTensor] input to non-linearity.
pub output: VarTensor,
/// Lookup table used to represent the non-linearity
pub table: Rc<RefCell<EltwiseTable<F, NL>>>,
qlookup: Selector,
_marker: PhantomData<(NL, F)>,
Expand Down Expand Up @@ -260,6 +280,7 @@ impl<F: FieldExt + TensorType, NL: 'static + Nonlinearity<F>> EltwiseConfig<F, N
}
}

#[allow(missing_docs)]
// Now implement nonlinearity functions like this
#[derive(Clone, Debug)]
pub struct ReLu<F> {
Expand All @@ -277,6 +298,7 @@ impl<F: FieldExt> Nonlinearity<F> for ReLu<F> {
}
}

#[allow(missing_docs)]
#[derive(Clone, Debug)]
pub struct Sigmoid<F> {
_marker: PhantomData<F>,
Expand All @@ -292,6 +314,7 @@ impl<F: FieldExt> Nonlinearity<F> for Sigmoid<F> {
}
}

#[allow(missing_docs)]
#[derive(Clone, Debug)]
pub struct DivideBy<F> {
_marker: PhantomData<F>,
Expand Down
2 changes: 2 additions & 0 deletions src/circuit/fused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use log::error;
use std::fmt;
use std::marker::PhantomData;

#[allow(missing_docs)]
/// An enum representing the operations that can be merged into a single circuit gate.
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum FusedOp {
Expand Down Expand Up @@ -100,6 +101,7 @@ pub struct FusedConfig<F: FieldExt + TensorType> {
nodes: Vec<FusedNode>,
/// the (currently singular) output of the fused operations.
pub output: VarTensor,
/// [Selector] generated when configuring the layer.
pub selector: Selector,
_marker: PhantomData<F>,
}
Expand Down
1 change: 1 addition & 0 deletions src/circuit/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::marker::PhantomData;
#[derive(Debug, Clone)]
pub struct RangeCheckConfig<F: FieldExt + TensorType> {
input: VarTensor,
/// The value we are expecting the output of the circuit to match (within a range)
pub expected: VarTensor,
selector: Selector,
_marker: PhantomData<F>,
Expand Down
6 changes: 6 additions & 0 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ use log::info;
use std::io::{stdin, stdout, Write};
use std::path::PathBuf;

#[allow(missing_docs)]
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct Cli {
#[command(subcommand)]
#[allow(missing_docs)]
pub command: Commands,
/// The tolerance for error on model outputs
#[arg(short = 'T', long, default_value = "0")]
Expand Down Expand Up @@ -35,6 +37,7 @@ pub struct Cli {
pub max_rotations: usize,
}

#[allow(missing_docs)]
#[derive(ValueEnum, Copy, Clone, Debug, PartialEq, Eq)]
pub enum ProofSystem {
IPA,
Expand All @@ -49,6 +52,7 @@ impl std::fmt::Display for ProofSystem {
}
}

#[allow(missing_docs)]
#[derive(Debug, Subcommand)]
pub enum Commands {
/// Loads model and prints model table
Expand Down Expand Up @@ -121,6 +125,7 @@ pub enum Commands {
default_missing_value = "always",
value_enum
)]
/// The [ProofSystem] we'll be using.
pfsys: ProofSystem,
// todo, optionally allow supplying proving key
},
Expand Down Expand Up @@ -156,6 +161,7 @@ pub enum Commands {
},
}

/// Loads the path to a path `data` represented as a [String]. If empty queries the user for an input.
pub fn data_path(data: String) -> PathBuf {
let mut s = String::new();
match data.is_empty() {
Expand Down
3 changes: 3 additions & 0 deletions src/fieldutils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/// Utilities for converting from Halo2 Field types to integers (and vice-versa).
use halo2_proofs::arithmetic::FieldExt;

/// Converts an i32 to a Field element.
pub fn i32_to_felt<F: FieldExt>(x: i32) -> F {
if x >= 0 {
F::from(x as u64)
Expand All @@ -12,6 +14,7 @@ fn felt_to_u32<F: FieldExt>(x: F) -> u32 {
x.get_lower_32()
}

/// Converts a Field element to an i32.
pub fn felt_to_i32<F: FieldExt>(x: F) -> i32 {
if x > F::from(65536) {
-(felt_to_u32(-x) as i32)
Expand Down
20 changes: 14 additions & 6 deletions src/graph/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
/// Helper functions
pub mod utilities;
pub use utilities::*;
/// Crate for defining a computational graph and building a ZK-circuit from it.
pub mod model;
/// Inner elements of a computational graph that represent a single operation / constraints.
pub mod node;
/// Representations of a computational graph's variables.
pub mod vars;

use crate::tensor::TensorType;
use crate::tensor::{Tensor, ValTensor};
use anyhow::Result;
Expand All @@ -6,21 +16,19 @@ use halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner, Value},
plonk::{Circuit, ConstraintSystem, Error},
};
use std::marker::PhantomData;
pub mod utilities;
pub use utilities::*;
pub mod model;
pub mod node;
pub mod vars;
use log::{info, trace};
pub use model::*;
pub use node::*;
use std::cmp::max;
use std::marker::PhantomData;
pub use vars::*;

/// Defines the circuit for a computational graph / model loaded from a `.onnx` file.
#[derive(Clone, Debug)]
pub struct ModelCircuit<F: FieldExt> {
/// Vector of input tensors to the model / graph of computations.
pub inputs: Vec<Tensor<i32>>,
/// Represents the Field we are using.
pub _marker: PhantomData<F>,
}

Expand Down
Loading