Distinguish between selectors and all other columns in layouter using RegionColumn.

This commit is contained in:
Sean Bowe 2021-07-21 10:19:35 -06:00
parent 4283713ec7
commit dfbd5e3332
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
4 changed files with 67 additions and 22 deletions

View File

@ -7,11 +7,11 @@ use ff::Field;
use crate::{
circuit::{
layouter::{RegionLayouter, RegionShape},
layouter::{RegionColumn, RegionLayouter, RegionShape},
Cell, Layouter, Region, RegionIndex, RegionStart,
},
plonk::{
Advice, Any, Assigned, Assignment, Circuit, Column, Error, Fixed, FloorPlanner, Instance,
Advice, Assigned, Assignment, Circuit, Column, Error, Fixed, FloorPlanner, Instance,
Selector,
},
};
@ -43,7 +43,7 @@ pub struct SingleChipLayouter<'a, F: Field, CS: Assignment<F> + 'a> {
/// Stores the starting row for each region.
regions: Vec<RegionStart>,
/// Stores the first empty row for each column.
columns: HashMap<Column<Any>, usize>,
columns: HashMap<RegionColumn, usize>,
_marker: PhantomData<F>,
}

View File

@ -4,11 +4,11 @@ use ff::Field;
use crate::{
circuit::{
layouter::{RegionLayouter, RegionShape},
layouter::{RegionColumn, RegionLayouter, RegionShape},
Cell, Layouter, Region, RegionIndex, RegionStart,
},
plonk::{
Advice, Assigned, Assignment, Circuit, Column, Error, Fixed, FloorPlanner, Instance,
Advice, Any, Assigned, Assignment, Circuit, Column, Error, Fixed, FloorPlanner, Instance,
Selector,
},
};
@ -89,7 +89,7 @@ impl FloorPlanner for V1 {
(
c,
column_allocations
.get(&c.into())
.get(&Column::<Any>::from(c).into())
.cloned()
.unwrap_or_default(),
)

View File

@ -4,11 +4,8 @@ use std::{
ops::Range,
};
use super::RegionShape;
use crate::{
circuit::RegionStart,
plonk::{Any, Column},
};
use super::{RegionColumn, RegionShape};
use crate::{circuit::RegionStart, plonk::Any};
/// A region allocated within a column.
#[derive(Clone, Default, Debug, PartialEq, Eq)]
@ -102,14 +99,14 @@ impl Allocations {
}
/// Allocated rows within a circuit.
pub type CircuitAllocations = HashMap<Column<Any>, Allocations>;
pub type CircuitAllocations = HashMap<RegionColumn, Allocations>;
/// - `start` is the current start row of the region (not of this column).
/// - `slack` is the maximum number of rows the start could be moved down, taking into
/// account prior columns.
fn first_fit_region(
column_allocations: &mut CircuitAllocations,
region_columns: &[Column<Any>],
region_columns: &[RegionColumn],
region_length: usize,
start: usize,
slack: Option<usize>,
@ -207,7 +204,10 @@ pub fn slot_in_biggest_advice_first(
let advice_cols = shape
.columns()
.iter()
.filter(|c| matches!(c.column_type(), Any::Advice))
.filter(|c| match c {
RegionColumn::Column(c) => matches!(c.column_type(), Any::Advice),
_ => false,
})
.count();
// Sort by advice area (since this has the most contention).
advice_cols * shape.row_count()
@ -226,23 +226,30 @@ pub fn slot_in_biggest_advice_first(
#[test]
fn test_slot_in() {
use crate::plonk::Column;
let regions = vec![
RegionShape {
region_index: 0.into(),
columns: vec![Column::new(0, Any::Advice), Column::new(1, Any::Advice)]
.into_iter()
.map(|a| Column::<Any>::from(a).into())
.collect(),
row_count: 15,
},
RegionShape {
region_index: 1.into(),
columns: vec![Column::new(2, Any::Advice)].into_iter().collect(),
columns: vec![Column::new(2, Any::Advice)]
.into_iter()
.map(|a| Column::<Any>::from(a).into())
.collect(),
row_count: 10,
},
RegionShape {
region_index: 2.into(),
columns: vec![Column::new(2, Any::Advice), Column::new(0, Any::Advice)]
.into_iter()
.map(|a| Column::<Any>::from(a).into())
.collect(),
row_count: 10,
},

View File

@ -110,10 +110,49 @@ pub trait RegionLayouter<F: Field>: fmt::Debug {
#[derive(Clone, Debug)]
pub struct RegionShape {
pub(super) region_index: RegionIndex,
pub(super) columns: HashSet<Column<Any>>,
pub(super) columns: HashSet<RegionColumn>,
pub(super) row_count: usize,
}
/// The virtual column involved in a region. This includes normal "logical"
/// columns as well as selectors that are not definite columns at this stage.
#[derive(Eq, PartialEq, Copy, Clone, Debug, Hash)]
pub enum RegionColumn {
/// Logical column
Column(Column<Any>),
/// Virtual column representing a (boolean) selector
Selector(Selector),
}
impl From<Column<Any>> for RegionColumn {
fn from(column: Column<Any>) -> RegionColumn {
RegionColumn::Column(column)
}
}
impl From<Selector> for RegionColumn {
fn from(selector: Selector) -> RegionColumn {
RegionColumn::Selector(selector)
}
}
impl Ord for RegionColumn {
fn cmp(&self, other: &Self) -> cmp::Ordering {
match (self, other) {
(Self::Column(ref a), Self::Column(ref b)) => a.cmp(b),
(Self::Selector(ref a), Self::Selector(ref b)) => a.0.cmp(&b.0),
(Self::Column(_), Self::Selector(_)) => cmp::Ordering::Greater,
(Self::Selector(_), Self::Column(_)) => cmp::Ordering::Less,
}
}
}
impl PartialOrd for RegionColumn {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}
}
impl RegionShape {
/// Create a new `RegionShape` for a region at `region_index`.
pub fn new(region_index: RegionIndex) -> Self {
@ -130,7 +169,7 @@ impl RegionShape {
}
/// Get a reference to the set of `columns` used in a `RegionShape`.
pub fn columns(&self) -> &HashSet<Column<Any>> {
pub fn columns(&self) -> &HashSet<RegionColumn> {
&self.columns
}
@ -148,8 +187,7 @@ impl<F: Field> RegionLayouter<F> for RegionShape {
offset: usize,
) -> Result<(), Error> {
// Track the selector's fixed column as part of the region's shape.
// TODO: Avoid exposing selector internals?
self.columns.insert(selector.0.into());
self.columns.insert((*selector).into());
self.row_count = cmp::max(self.row_count, offset + 1);
Ok(())
}
@ -161,7 +199,7 @@ impl<F: Field> RegionLayouter<F> for RegionShape {
offset: usize,
_to: &'v mut (dyn FnMut() -> Result<Assigned<F>, Error> + 'v),
) -> Result<Cell, Error> {
self.columns.insert(column.into());
self.columns.insert(Column::<Any>::from(column).into());
self.row_count = cmp::max(self.row_count, offset + 1);
Ok(Cell {
@ -190,7 +228,7 @@ impl<F: Field> RegionLayouter<F> for RegionShape {
advice: Column<Advice>,
offset: usize,
) -> Result<(Cell, Option<F>), Error> {
self.columns.insert(advice.into());
self.columns.insert(Column::<Any>::from(advice).into());
self.row_count = cmp::max(self.row_count, offset + 1);
Ok((
@ -210,7 +248,7 @@ impl<F: Field> RegionLayouter<F> for RegionShape {
offset: usize,
_to: &'v mut (dyn FnMut() -> Result<Assigned<F>, Error> + 'v),
) -> Result<Cell, Error> {
self.columns.insert(column.into());
self.columns.insert(Column::<Any>::from(column).into());
self.row_count = cmp::max(self.row_count, offset + 1);
Ok(Cell {