mirror of https://github.com/zcash/halo2.git
Compare commits
5 Commits
599b4e12b5
...
32a5c90bae
Author | SHA1 | Date |
---|---|---|
|
32a5c90bae | |
|
7df93fd855 | |
|
daaa638966 | |
|
2d4d95e739 | |
|
42ea7116a7 |
|
@ -12,7 +12,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: nightly
|
toolchain: '1.76.0'
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
# - name: Setup mdBook
|
# - name: Setup mdBook
|
||||||
|
@ -26,7 +26,7 @@ jobs:
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: install
|
command: install
|
||||||
args: mdbook --git https://github.com/HollowMan6/mdBook.git --rev 62e01b34c23b957579c04ee1b24b57814ed8a4d5
|
args: mdbook --git https://github.com/HollowMan6/mdBook.git --rev 5830c9555a4dc051675d17f1fcb04dd0920543e8
|
||||||
|
|
||||||
- name: Install mdbook-katex and mdbook-pdf
|
- name: Install mdbook-katex and mdbook-pdf
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
|
@ -40,6 +40,11 @@ jobs:
|
||||||
- name: Build halo2 book
|
- name: Build halo2 book
|
||||||
run: mdbook build book/
|
run: mdbook build book/
|
||||||
|
|
||||||
|
- uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: nightly-2023-10-05
|
||||||
|
override: true
|
||||||
|
|
||||||
- name: Build latest rustdocs
|
- name: Build latest rustdocs
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -14,8 +14,6 @@ title = "The halo2 Book"
|
||||||
macros = "macros.txt"
|
macros = "macros.txt"
|
||||||
renderers = ["html"]
|
renderers = ["html"]
|
||||||
|
|
||||||
[output.katex]
|
|
||||||
|
|
||||||
[output.html]
|
[output.html]
|
||||||
|
|
||||||
[output.html.print]
|
[output.html.print]
|
||||||
|
|
|
@ -55,6 +55,8 @@ maybe-rayon = {version = "0.1.0", default-features = false}
|
||||||
|
|
||||||
# Developer tooling dependencies
|
# Developer tooling dependencies
|
||||||
plotters = { version = "0.3.0", default-features = false, optional = true }
|
plotters = { version = "0.3.0", default-features = false, optional = true }
|
||||||
|
serde = { version = "1", features = ["derive"], optional = true }
|
||||||
|
serde_json = { version = "1", optional = true }
|
||||||
tabbycat = { version = "0.1", features = ["attributes"], optional = true }
|
tabbycat = { version = "0.1", features = ["attributes"], optional = true }
|
||||||
|
|
||||||
# Legacy circuit compatibility
|
# Legacy circuit compatibility
|
||||||
|
@ -78,7 +80,7 @@ getrandom = { version = "0.2", features = ["js"] }
|
||||||
[features]
|
[features]
|
||||||
default = ["batch", "multicore"]
|
default = ["batch", "multicore"]
|
||||||
multicore = ["maybe-rayon/threads"]
|
multicore = ["maybe-rayon/threads"]
|
||||||
dev-graph = ["plotters", "tabbycat"]
|
dev-graph = ["plotters", "serde", "serde_json", "tabbycat"]
|
||||||
test-dev-graph = [
|
test-dev-graph = [
|
||||||
"dev-graph",
|
"dev-graph",
|
||||||
"plotters/bitmap_backend",
|
"plotters/bitmap_backend",
|
||||||
|
|
|
@ -122,6 +122,7 @@ pub struct RegionShape {
|
||||||
/// The virtual column involved in a region. This includes concrete columns,
|
/// The virtual column involved in a region. This includes concrete columns,
|
||||||
/// as well as selectors that are not concrete columns at this stage.
|
/// as well as selectors that are not concrete columns at this stage.
|
||||||
#[derive(Eq, PartialEq, Copy, Clone, Debug, Hash)]
|
#[derive(Eq, PartialEq, Copy, Clone, Debug, Hash)]
|
||||||
|
#[cfg_attr(feature = "dev-graph", derive(serde::Serialize))]
|
||||||
pub enum RegionColumn {
|
pub enum RegionColumn {
|
||||||
/// Concrete column
|
/// Concrete column
|
||||||
Column(Column<Any>),
|
Column(Column<Any>),
|
||||||
|
|
|
@ -36,7 +36,10 @@ mod graph;
|
||||||
|
|
||||||
#[cfg(feature = "dev-graph")]
|
#[cfg(feature = "dev-graph")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "dev-graph")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "dev-graph")))]
|
||||||
pub use graph::{circuit_dot_graph, layout::CircuitLayout};
|
pub use graph::{
|
||||||
|
circuit_dot_graph,
|
||||||
|
layout::{render_to_json, CircuitLayout},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Region {
|
struct Region {
|
||||||
|
|
|
@ -11,6 +11,9 @@ use std::{
|
||||||
use ff::{Field, PrimeField};
|
use ff::{Field, PrimeField};
|
||||||
use group::prime::PrimeGroup;
|
use group::prime::PrimeGroup;
|
||||||
|
|
||||||
|
#[cfg(feature = "dev-graph")]
|
||||||
|
use serde::ser::SerializeStruct;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
circuit::{layouter::RegionColumn, Value},
|
circuit::{layouter::RegionColumn, Value},
|
||||||
plonk::{
|
plonk::{
|
||||||
|
@ -54,9 +57,37 @@ pub struct CircuitCost<G: PrimeGroup, ConcreteCircuit: Circuit<G::Scalar>> {
|
||||||
_marker: PhantomData<(G, ConcreteCircuit)>,
|
_marker: PhantomData<(G, ConcreteCircuit)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "dev-graph")]
|
||||||
|
impl serde::Serialize for Column<Any> {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
let mut state = serializer.serialize_struct("Column", 2)?;
|
||||||
|
state.serialize_field(
|
||||||
|
"kind",
|
||||||
|
match self.column_type() {
|
||||||
|
Any::Advice => "advice",
|
||||||
|
Any::Fixed => "fixed",
|
||||||
|
Any::Instance => "instance",
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
state.serialize_field("index", &self.index())?;
|
||||||
|
state.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[cfg_attr(feature = "dev-graph", derive(serde::Serialize))]
|
||||||
|
pub(crate) struct Cell {
|
||||||
|
pub(crate) column: RegionColumn,
|
||||||
|
pub(crate) row: usize,
|
||||||
|
}
|
||||||
|
|
||||||
/// Region implementation used by Layout
|
/// Region implementation used by Layout
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[cfg_attr(feature = "dev-graph", derive(serde::Serialize))]
|
||||||
pub(crate) struct LayoutRegion {
|
pub(crate) struct LayoutRegion {
|
||||||
/// The name of the region. Not required to be unique.
|
/// The name of the region. Not required to be unique.
|
||||||
pub(crate) name: String,
|
pub(crate) name: String,
|
||||||
|
@ -66,8 +97,9 @@ pub(crate) struct LayoutRegion {
|
||||||
pub(crate) offset: Option<usize>,
|
pub(crate) offset: Option<usize>,
|
||||||
/// The number of rows that this region takes up.
|
/// The number of rows that this region takes up.
|
||||||
pub(crate) rows: usize,
|
pub(crate) rows: usize,
|
||||||
/// The cells assigned in this region.
|
/// The cells assigned in this region. We store this as a `Vec` to track multiple
|
||||||
pub(crate) cells: Vec<(RegionColumn, usize)>,
|
/// assignments to a cell.
|
||||||
|
pub(crate) cells: Vec<Cell>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cost and graphing layouter
|
/// Cost and graphing layouter
|
||||||
|
@ -84,10 +116,11 @@ pub(crate) struct Layout {
|
||||||
pub(crate) total_advice_rows: usize,
|
pub(crate) total_advice_rows: usize,
|
||||||
/// Total fixed rows
|
/// Total fixed rows
|
||||||
pub(crate) total_fixed_rows: usize,
|
pub(crate) total_fixed_rows: usize,
|
||||||
/// Any cells assigned outside of a region.
|
/// Any cells assigned outside of a region. We store this as a `Vec` to track multiple
|
||||||
pub(crate) loose_cells: Vec<(RegionColumn, usize)>,
|
/// assignments to a cell.
|
||||||
|
pub(crate) loose_cells: Vec<Cell>,
|
||||||
/// Pairs of cells between which we have equality constraints.
|
/// Pairs of cells between which we have equality constraints.
|
||||||
pub(crate) equality: Vec<(Column<Any>, usize, Column<Any>, usize)>,
|
pub(crate) equality: Vec<(Cell, Cell)>,
|
||||||
/// Selector assignments used for optimization pass
|
/// Selector assignments used for optimization pass
|
||||||
pub(crate) selectors: Vec<Vec<bool>>,
|
pub(crate) selectors: Vec<Vec<bool>>,
|
||||||
}
|
}
|
||||||
|
@ -139,9 +172,9 @@ impl Layout {
|
||||||
region.rows = cmp::max(region.rows, row - offset + 1);
|
region.rows = cmp::max(region.rows, row - offset + 1);
|
||||||
region.offset = Some(offset);
|
region.offset = Some(offset);
|
||||||
|
|
||||||
region.cells.push((column, row));
|
region.cells.push(Cell { column, row });
|
||||||
} else {
|
} else {
|
||||||
self.loose_cells.push((column, row));
|
self.loose_cells.push(Cell { column, row });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,7 +261,16 @@ impl<F: Field> Assignment<F> for Layout {
|
||||||
r_col: Column<Any>,
|
r_col: Column<Any>,
|
||||||
r_row: usize,
|
r_row: usize,
|
||||||
) -> Result<(), crate::plonk::Error> {
|
) -> Result<(), crate::plonk::Error> {
|
||||||
self.equality.push((l_col, l_row, r_col, r_row));
|
self.equality.push((
|
||||||
|
Cell {
|
||||||
|
column: l_col.into(),
|
||||||
|
row: l_row,
|
||||||
|
},
|
||||||
|
Cell {
|
||||||
|
column: r_col.into(),
|
||||||
|
row: r_row,
|
||||||
|
},
|
||||||
|
));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,13 @@ use plotters::{
|
||||||
coord::Shift,
|
coord::Shift,
|
||||||
prelude::{DrawingArea, DrawingAreaErrorKind, DrawingBackend},
|
prelude::{DrawingArea, DrawingAreaErrorKind, DrawingBackend},
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
circuit::layouter::RegionColumn,
|
circuit::layouter::RegionColumn,
|
||||||
dev::cost::Layout,
|
dev::cost::{Cell, Layout, LayoutRegion},
|
||||||
plonk::{Any, Circuit, Column, ConstraintSystem, FloorPlanner},
|
plonk::{Any, Circuit, Column, ConstraintSystem, FloorPlanner},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -242,26 +243,26 @@ impl CircuitLayout {
|
||||||
|
|
||||||
// Darken the cells of the region that have been assigned to.
|
// Darken the cells of the region that have been assigned to.
|
||||||
for region in layout.regions {
|
for region in layout.regions {
|
||||||
for (column, row) in region.cells {
|
for Cell { column, row } in region.cells {
|
||||||
draw_cell(&root, column_index(&cs, column), row)?;
|
draw_cell(&root, column_index(&cs, column), row)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Darken any loose cells that have been assigned to.
|
// Darken any loose cells that have been assigned to.
|
||||||
for (column, row) in layout.loose_cells {
|
for Cell { column, row } in layout.loose_cells {
|
||||||
draw_cell(&root, column_index(&cs, column), row)?;
|
draw_cell(&root, column_index(&cs, column), row)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark equality-constrained cells.
|
// Mark equality-constrained cells.
|
||||||
if self.mark_equality_cells {
|
if self.mark_equality_cells {
|
||||||
let mut cells = HashSet::new();
|
let mut cells = HashSet::new();
|
||||||
for (l_col, l_row, r_col, r_row) in &layout.equality {
|
for (l, r) in &layout.equality {
|
||||||
let l_col = column_index(&cs, (*l_col).into());
|
let l_col = column_index(&cs, l.column);
|
||||||
let r_col = column_index(&cs, (*r_col).into());
|
let r_col = column_index(&cs, r.column);
|
||||||
|
|
||||||
// Deduplicate cells.
|
// Deduplicate cells.
|
||||||
cells.insert((l_col, *l_row));
|
cells.insert((l_col, l.row));
|
||||||
cells.insert((r_col, *r_row));
|
cells.insert((r_col, r.row));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (col, row) in cells {
|
for (col, row) in cells {
|
||||||
|
@ -274,11 +275,11 @@ impl CircuitLayout {
|
||||||
|
|
||||||
// Draw lines between equality-constrained cells.
|
// Draw lines between equality-constrained cells.
|
||||||
if self.show_equality_constraints {
|
if self.show_equality_constraints {
|
||||||
for (l_col, l_row, r_col, r_row) in &layout.equality {
|
for (l, r) in &layout.equality {
|
||||||
let l_col = column_index(&cs, (*l_col).into());
|
let l_col = column_index(&cs, l.column);
|
||||||
let r_col = column_index(&cs, (*r_col).into());
|
let r_col = column_index(&cs, r.column);
|
||||||
root.draw(&PathElement::new(
|
root.draw(&PathElement::new(
|
||||||
[(l_col, *l_row), (r_col, *r_row)],
|
[(l_col, l.row), (r_col, r.row)],
|
||||||
ShapeStyle::from(&RED),
|
ShapeStyle::from(&RED),
|
||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
|
@ -318,3 +319,35 @@ impl CircuitLayout {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Renders the given circuit layout to a JSON string.
|
||||||
|
pub fn render_to_json<F: Field, ConcreteCircuit: Circuit<F>>(
|
||||||
|
circuit: &ConcreteCircuit,
|
||||||
|
) -> Result<String, serde_json::Error> {
|
||||||
|
// Collect the layout details.
|
||||||
|
let mut cs = ConstraintSystem::default();
|
||||||
|
let config = ConcreteCircuit::configure(&mut cs);
|
||||||
|
let mut layout = Layout::default();
|
||||||
|
ConcreteCircuit::FloorPlanner::synthesize(&mut layout, circuit, config, cs.constants).unwrap();
|
||||||
|
|
||||||
|
// Render.
|
||||||
|
#[derive(serde::Serialize)]
|
||||||
|
struct Circuit {
|
||||||
|
num_instance_columns: usize,
|
||||||
|
num_advice_columns: usize,
|
||||||
|
num_fixed_columns: usize,
|
||||||
|
total_rows: usize,
|
||||||
|
regions: Vec<LayoutRegion>,
|
||||||
|
loose_cells: Vec<Cell>,
|
||||||
|
selectors: Vec<Vec<bool>>,
|
||||||
|
}
|
||||||
|
serde_json::to_string(&Circuit {
|
||||||
|
num_instance_columns: cs.num_instance_columns,
|
||||||
|
num_advice_columns: cs.num_advice_columns,
|
||||||
|
num_fixed_columns: cs.num_fixed_columns,
|
||||||
|
total_rows: layout.total_rows,
|
||||||
|
regions: layout.regions,
|
||||||
|
loose_cells: layout.loose_cells,
|
||||||
|
selectors: layout.selectors,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -253,6 +253,7 @@ impl TryFrom<Column<Any>> for Column<Instance> {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
#[cfg_attr(feature = "dev-graph", derive(serde::Serialize))]
|
||||||
pub struct Selector(pub(crate) usize, bool);
|
pub struct Selector(pub(crate) usize, bool);
|
||||||
|
|
||||||
impl Selector {
|
impl Selector {
|
||||||
|
|
Loading…
Reference in New Issue