Add circuit::RegionIndex and circuit::RegionStart newtypes

This commit is contained in:
therealyingtong 2021-02-20 21:19:06 +08:00
parent c9b606212e
commit 84f732acb4
2 changed files with 52 additions and 15 deletions

View file

@ -28,11 +28,47 @@ pub trait Chip: Sized {
fn load(layouter: &mut impl Layouter<Self>) -> Result<(), Error>; fn load(layouter: &mut impl Layouter<Self>) -> Result<(), Error>;
} }
/// Index of a region in a layouter
#[derive(Clone, Copy, Debug)]
pub struct RegionIndex(usize);
impl From<usize> for RegionIndex {
fn from(idx: usize) -> RegionIndex {
RegionIndex(idx)
}
}
impl std::ops::Deref for RegionIndex {
type Target = usize;
fn deref(&self) -> &Self::Target {
&self.0
}
}
/// Starting row of a region in a layouter
#[derive(Clone, Copy, Debug)]
pub struct RegionStart(usize);
impl From<usize> for RegionStart {
fn from(idx: usize) -> RegionStart {
RegionStart(idx)
}
}
impl std::ops::Deref for RegionStart {
type Target = usize;
fn deref(&self) -> &Self::Target {
&self.0
}
}
/// A pointer to a cell within a circuit. /// A pointer to a cell within a circuit.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Cell { pub struct Cell {
/// Identifies the region in which this cell resides. /// Identifies the region in which this cell resides.
region_index: usize, region_index: RegionIndex,
row_offset: usize, row_offset: usize,
column: Column<Any>, column: Column<Any>,
} }

View file

@ -5,7 +5,7 @@ use std::collections::{HashMap, HashSet};
use std::fmt; use std::fmt;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::{Cell, Chip, Layouter, Permutation, Region}; use super::{Cell, Chip, Layouter, Permutation, Region, RegionIndex, RegionStart};
use crate::plonk::{Advice, Any, Assignment, Column, Error, Fixed}; use crate::plonk::{Advice, Any, Assignment, Column, Error, Fixed};
/// Helper trait for implementing a custom [`Layouter`]. /// Helper trait for implementing a custom [`Layouter`].
@ -70,7 +70,8 @@ pub trait RegionLayouter<C: Chip>: fmt::Debug {
pub struct SingleChip<'a, C: Chip, CS: Assignment<C::Field> + 'a> { pub struct SingleChip<'a, C: Chip, CS: Assignment<C::Field> + 'a> {
cs: &'a mut CS, cs: &'a mut CS,
config: C::Config, config: C::Config,
regions: Vec<usize>, /// Stores the starting row for each region.
regions: Vec<RegionStart>,
/// Stores the first empty row for each column. /// Stores the first empty row for each column.
columns: HashMap<Column<Any>, usize>, columns: HashMap<Column<Any>, usize>,
_marker: PhantomData<C>, _marker: PhantomData<C>,
@ -115,7 +116,7 @@ impl<'a, C: Chip, CS: Assignment<C::Field> + 'a> Layouter<C> for SingleChip<'a,
let region_index = self.regions.len(); let region_index = self.regions.len();
// Get shape of the region. // Get shape of the region.
let mut shape = RegionShape::new(region_index); let mut shape = RegionShape::new(region_index.into());
{ {
let region: &mut dyn RegionLayouter<C> = &mut shape; let region: &mut dyn RegionLayouter<C> = &mut shape;
assignment(region.into())?; assignment(region.into())?;
@ -127,7 +128,7 @@ impl<'a, C: Chip, CS: Assignment<C::Field> + 'a> Layouter<C> for SingleChip<'a,
for column in &shape.columns { for column in &shape.columns {
region_start = cmp::max(region_start, self.columns.get(column).cloned().unwrap_or(0)); region_start = cmp::max(region_start, self.columns.get(column).cloned().unwrap_or(0));
} }
self.regions.push(region_start); self.regions.push(region_start.into());
// Update column usage information. // Update column usage information.
for column in shape.columns { for column in shape.columns {
@ -135,7 +136,7 @@ impl<'a, C: Chip, CS: Assignment<C::Field> + 'a> Layouter<C> for SingleChip<'a,
} }
self.cs.enter_region(name); self.cs.enter_region(name);
let mut region = SingleChipRegion::new(self, region_index); let mut region = SingleChipRegion::new(self, region_index.into());
let result = { let result = {
let region: &mut dyn RegionLayouter<C> = &mut region; let region: &mut dyn RegionLayouter<C> = &mut region;
assignment(region.into()) assignment(region.into())
@ -166,14 +167,14 @@ impl<'a, C: Chip, CS: Assignment<C::Field> + 'a> Layouter<C> for SingleChip<'a,
/// the set of columns it uses as well as the number of rows it uses. /// the set of columns it uses as well as the number of rows it uses.
#[derive(Debug)] #[derive(Debug)]
pub struct RegionShape { pub struct RegionShape {
region_index: usize, region_index: RegionIndex,
columns: HashSet<Column<Any>>, columns: HashSet<Column<Any>>,
row_count: usize, row_count: usize,
} }
impl RegionShape { impl RegionShape {
/// Create a new `RegionShape` for a region at `region_index`. /// Create a new `RegionShape` for a region at `region_index`.
pub fn new(region_index: usize) -> Self { pub fn new(region_index: RegionIndex) -> Self {
RegionShape { RegionShape {
region_index, region_index,
columns: HashSet::default(), columns: HashSet::default(),
@ -182,7 +183,7 @@ impl RegionShape {
} }
/// Get the `region_index` of a `RegionShape`. /// Get the `region_index` of a `RegionShape`.
pub fn region_index(&self) -> usize { pub fn region_index(&self) -> RegionIndex {
self.region_index self.region_index
} }
@ -245,7 +246,7 @@ impl<C: Chip> RegionLayouter<C> for RegionShape {
struct SingleChipRegion<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> { struct SingleChipRegion<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> {
layouter: &'r mut SingleChip<'a, C, CS>, layouter: &'r mut SingleChip<'a, C, CS>,
region_index: usize, region_index: RegionIndex,
} }
impl<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> fmt::Debug impl<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> fmt::Debug
@ -260,7 +261,7 @@ impl<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> fmt::Debug
} }
impl<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> SingleChipRegion<'r, 'a, C, CS> { impl<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> SingleChipRegion<'r, 'a, C, CS> {
fn new(layouter: &'r mut SingleChip<'a, C, CS>, region_index: usize) -> Self { fn new(layouter: &'r mut SingleChip<'a, C, CS>, region_index: RegionIndex) -> Self {
SingleChipRegion { SingleChipRegion {
layouter, layouter,
region_index, region_index,
@ -281,7 +282,7 @@ impl<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> RegionLayouter<C>
self.layouter.cs.assign_advice( self.layouter.cs.assign_advice(
annotation, annotation,
column, column,
self.layouter.regions[self.region_index] + offset, *self.layouter.regions[*self.region_index] + offset,
to, to,
)?; )?;
@ -302,7 +303,7 @@ impl<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> RegionLayouter<C>
self.layouter.cs.assign_fixed( self.layouter.cs.assign_fixed(
annotation, annotation,
column, column,
self.layouter.regions[self.region_index] + offset, *self.layouter.regions[*self.region_index] + offset,
to, to,
)?; )?;
@ -333,9 +334,9 @@ impl<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> RegionLayouter<C>
self.layouter.cs.copy( self.layouter.cs.copy(
permutation.index, permutation.index,
left_column, left_column,
self.layouter.regions[left.region_index] + left.row_offset, *self.layouter.regions[*left.region_index] + left.row_offset,
right_column, right_column,
self.layouter.regions[right.region_index] + right.row_offset, *self.layouter.regions[*right.region_index] + right.row_offset,
)?; )?;
Ok(()) Ok(())