mirror of https://github.com/zcash/halo2.git
Merge layouter used by cost and graph into one
This commit is contained in:
parent
55d470ffd2
commit
fad6201b34
|
@ -13,6 +13,7 @@ use crate::{
|
|||
Advice, Any, Assigned, Assignment, Circuit, Column, ConstraintSystem, Error, Fixed,
|
||||
FloorPlanner, Instance, Selector,
|
||||
},
|
||||
dev::cost::{Layout}
|
||||
};
|
||||
|
||||
/// Graphical renderer for circuit layouts.
|
||||
|
@ -321,184 +322,3 @@ impl CircuitLayout {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Region {
|
||||
/// The name of the region. Not required to be unique.
|
||||
name: String,
|
||||
/// The columns used by this region.
|
||||
columns: HashSet<RegionColumn>,
|
||||
/// The row that this region starts on, if known.
|
||||
offset: Option<usize>,
|
||||
/// The number of rows that this region takes up.
|
||||
rows: usize,
|
||||
/// The cells assigned in this region. We store this as a `Vec` so that if any cells
|
||||
/// are double-assigned, they will be visibly darker.
|
||||
cells: Vec<(RegionColumn, usize)>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Layout {
|
||||
k: u32,
|
||||
regions: Vec<Region>,
|
||||
current_region: Option<usize>,
|
||||
total_rows: usize,
|
||||
/// Any cells assigned outside of a region. We store this as a `Vec` so that if any
|
||||
/// cells are double-assigned, they will be visibly darker.
|
||||
loose_cells: Vec<(RegionColumn, usize)>,
|
||||
/// Pairs of cells between which we have equality constraints.
|
||||
equality: Vec<(Column<Any>, usize, Column<Any>, usize)>,
|
||||
/// Selector assignments used for optimization pass
|
||||
selectors: Vec<Vec<bool>>,
|
||||
}
|
||||
|
||||
impl Layout {
|
||||
fn new(k: u32, n: usize, num_selectors: usize) -> Self {
|
||||
Layout {
|
||||
k,
|
||||
regions: vec![],
|
||||
current_region: None,
|
||||
total_rows: 0,
|
||||
/// Any cells assigned outside of a region. We store this as a `Vec` so that if any
|
||||
/// cells are double-assigned, they will be visibly darker.
|
||||
loose_cells: vec![],
|
||||
/// Pairs of cells between which we have equality constraints.
|
||||
equality: vec![],
|
||||
/// Selector assignments used for optimization pass
|
||||
selectors: vec![vec![false; n]; num_selectors],
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, column: RegionColumn, row: usize) {
|
||||
self.total_rows = cmp::max(self.total_rows, row + 1);
|
||||
|
||||
if let Some(region) = self.current_region {
|
||||
let region = &mut self.regions[region];
|
||||
region.columns.insert(column);
|
||||
|
||||
// The region offset is the earliest row assigned to.
|
||||
let mut offset = region.offset.unwrap_or(row);
|
||||
if row < offset {
|
||||
// The first row assigned was not at offset 0 within the region.
|
||||
region.rows += offset - row;
|
||||
offset = row;
|
||||
}
|
||||
// The number of rows in this region is the gap between the earliest and
|
||||
// latest rows assigned.
|
||||
region.rows = cmp::max(region.rows, row - offset + 1);
|
||||
region.offset = Some(offset);
|
||||
|
||||
region.cells.push((column, row));
|
||||
} else {
|
||||
self.loose_cells.push((column, row));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> Assignment<F> for Layout {
|
||||
fn enter_region<NR, N>(&mut self, name_fn: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR,
|
||||
{
|
||||
assert!(self.current_region.is_none());
|
||||
self.current_region = Some(self.regions.len());
|
||||
self.regions.push(Region {
|
||||
name: name_fn().into(),
|
||||
columns: HashSet::default(),
|
||||
offset: None,
|
||||
rows: 0,
|
||||
cells: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
fn exit_region(&mut self) {
|
||||
assert!(self.current_region.is_some());
|
||||
self.current_region = None;
|
||||
}
|
||||
|
||||
fn enable_selector<A, AR>(&mut self, _: A, selector: &Selector, row: usize) -> Result<(), Error>
|
||||
where
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
{
|
||||
if let Some(cell) = self.selectors[selector.0].get_mut(row) {
|
||||
*cell = true;
|
||||
} else {
|
||||
return Err(Error::not_enough_rows_available(self.k));
|
||||
}
|
||||
|
||||
self.update((*selector).into(), row);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn query_instance(&self, _: Column<Instance>, _: usize) -> Result<Value<F>, Error> {
|
||||
Ok(Value::unknown())
|
||||
}
|
||||
|
||||
fn assign_advice<V, VR, A, AR>(
|
||||
&mut self,
|
||||
_: A,
|
||||
column: Column<Advice>,
|
||||
row: usize,
|
||||
_: V,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
V: FnOnce() -> Value<VR>,
|
||||
VR: Into<Assigned<F>>,
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
{
|
||||
self.update(Column::<Any>::from(column).into(), row);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn assign_fixed<V, VR, A, AR>(
|
||||
&mut self,
|
||||
_: A,
|
||||
column: Column<Fixed>,
|
||||
row: usize,
|
||||
_: V,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
V: FnOnce() -> Value<VR>,
|
||||
VR: Into<Assigned<F>>,
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
{
|
||||
self.update(Column::<Any>::from(column).into(), row);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn copy(
|
||||
&mut self,
|
||||
l_col: Column<Any>,
|
||||
l_row: usize,
|
||||
r_col: Column<Any>,
|
||||
r_row: usize,
|
||||
) -> Result<(), crate::plonk::Error> {
|
||||
self.equality.push((l_col, l_row, r_col, r_row));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fill_from_row(
|
||||
&mut self,
|
||||
_: Column<Fixed>,
|
||||
_: usize,
|
||||
_: Value<Assigned<F>>,
|
||||
) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn push_namespace<NR, N>(&mut self, _: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR,
|
||||
{
|
||||
// Do nothing; we don't care about namespaces in this context.
|
||||
}
|
||||
|
||||
fn pop_namespace(&mut self, _: Option<String>) {
|
||||
// Do nothing; we don't care about namespaces in this context.
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue