mirror of https://github.com/zcash/halo2.git
Compare commits
5 Commits
599b4e12b5
...
32a5c90bae
Author | SHA1 | Date |
---|---|---|
str4d | 32a5c90bae | |
Daira-Emma Hopwood | 7df93fd855 | |
adria0 | daaa638966 | |
Jack Grigg | 2d4d95e739 | |
Jack Grigg | 42ea7116a7 |
|
@ -12,7 +12,7 @@ jobs:
|
|||
- uses: actions/checkout@v3
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly
|
||||
toolchain: '1.76.0'
|
||||
override: true
|
||||
|
||||
# - name: Setup mdBook
|
||||
|
@ -26,7 +26,7 @@ jobs:
|
|||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
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
|
||||
uses: actions-rs/cargo@v1
|
||||
|
@ -40,6 +40,11 @@ jobs:
|
|||
- name: Build halo2 book
|
||||
run: mdbook build book/
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly-2023-10-05
|
||||
override: true
|
||||
|
||||
- name: Build latest rustdocs
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
|
|
|
@ -14,8 +14,6 @@ title = "The halo2 Book"
|
|||
macros = "macros.txt"
|
||||
renderers = ["html"]
|
||||
|
||||
[output.katex]
|
||||
|
||||
[output.html]
|
||||
|
||||
[output.html.print]
|
||||
|
|
|
@ -55,6 +55,8 @@ maybe-rayon = {version = "0.1.0", default-features = false}
|
|||
|
||||
# Developer tooling dependencies
|
||||
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 }
|
||||
|
||||
# Legacy circuit compatibility
|
||||
|
@ -78,7 +80,7 @@ getrandom = { version = "0.2", features = ["js"] }
|
|||
[features]
|
||||
default = ["batch", "multicore"]
|
||||
multicore = ["maybe-rayon/threads"]
|
||||
dev-graph = ["plotters", "tabbycat"]
|
||||
dev-graph = ["plotters", "serde", "serde_json", "tabbycat"]
|
||||
test-dev-graph = [
|
||||
"dev-graph",
|
||||
"plotters/bitmap_backend",
|
||||
|
|
|
@ -122,6 +122,7 @@ pub struct RegionShape {
|
|||
/// The virtual column involved in a region. This includes concrete columns,
|
||||
/// as well as selectors that are not concrete columns at this stage.
|
||||
#[derive(Eq, PartialEq, Copy, Clone, Debug, Hash)]
|
||||
#[cfg_attr(feature = "dev-graph", derive(serde::Serialize))]
|
||||
pub enum RegionColumn {
|
||||
/// Concrete column
|
||||
Column(Column<Any>),
|
||||
|
|
|
@ -36,7 +36,10 @@ mod graph;
|
|||
|
||||
#[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)]
|
||||
struct Region {
|
||||
|
|
|
@ -11,6 +11,9 @@ use std::{
|
|||
use ff::{Field, PrimeField};
|
||||
use group::prime::PrimeGroup;
|
||||
|
||||
#[cfg(feature = "dev-graph")]
|
||||
use serde::ser::SerializeStruct;
|
||||
|
||||
use crate::{
|
||||
circuit::{layouter::RegionColumn, Value},
|
||||
plonk::{
|
||||
|
@ -54,9 +57,37 @@ pub struct CircuitCost<G: PrimeGroup, ConcreteCircuit: Circuit<G::Scalar>> {
|
|||
_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
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "dev-graph", derive(serde::Serialize))]
|
||||
pub(crate) struct LayoutRegion {
|
||||
/// The name of the region. Not required to be unique.
|
||||
pub(crate) name: String,
|
||||
|
@ -66,8 +97,9 @@ pub(crate) struct LayoutRegion {
|
|||
pub(crate) offset: Option<usize>,
|
||||
/// The number of rows that this region takes up.
|
||||
pub(crate) rows: usize,
|
||||
/// The cells assigned in this region.
|
||||
pub(crate) cells: Vec<(RegionColumn, usize)>,
|
||||
/// The cells assigned in this region. We store this as a `Vec` to track multiple
|
||||
/// assignments to a cell.
|
||||
pub(crate) cells: Vec<Cell>,
|
||||
}
|
||||
|
||||
/// Cost and graphing layouter
|
||||
|
@ -84,10 +116,11 @@ pub(crate) struct Layout {
|
|||
pub(crate) total_advice_rows: usize,
|
||||
/// Total fixed rows
|
||||
pub(crate) total_fixed_rows: usize,
|
||||
/// Any cells assigned outside of a region.
|
||||
pub(crate) loose_cells: Vec<(RegionColumn, usize)>,
|
||||
/// Any cells assigned outside of a region. We store this as a `Vec` to track multiple
|
||||
/// assignments to a cell.
|
||||
pub(crate) loose_cells: Vec<Cell>,
|
||||
/// 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
|
||||
pub(crate) selectors: Vec<Vec<bool>>,
|
||||
}
|
||||
|
@ -139,9 +172,9 @@ impl Layout {
|
|||
region.rows = cmp::max(region.rows, row - offset + 1);
|
||||
region.offset = Some(offset);
|
||||
|
||||
region.cells.push((column, row));
|
||||
region.cells.push(Cell { column, row });
|
||||
} 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_row: usize,
|
||||
) -> 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(())
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,13 @@ use plotters::{
|
|||
coord::Shift,
|
||||
prelude::{DrawingArea, DrawingAreaErrorKind, DrawingBackend},
|
||||
};
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::ops::Range;
|
||||
|
||||
use crate::{
|
||||
circuit::layouter::RegionColumn,
|
||||
dev::cost::Layout,
|
||||
dev::cost::{Cell, Layout, LayoutRegion},
|
||||
plonk::{Any, Circuit, Column, ConstraintSystem, FloorPlanner},
|
||||
};
|
||||
|
||||
|
@ -242,26 +243,26 @@ impl CircuitLayout {
|
|||
|
||||
// Darken the cells of the region that have been assigned to.
|
||||
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)?;
|
||||
}
|
||||
}
|
||||
|
||||
// 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)?;
|
||||
}
|
||||
|
||||
// Mark equality-constrained cells.
|
||||
if self.mark_equality_cells {
|
||||
let mut cells = HashSet::new();
|
||||
for (l_col, l_row, r_col, r_row) in &layout.equality {
|
||||
let l_col = column_index(&cs, (*l_col).into());
|
||||
let r_col = column_index(&cs, (*r_col).into());
|
||||
for (l, r) in &layout.equality {
|
||||
let l_col = column_index(&cs, l.column);
|
||||
let r_col = column_index(&cs, r.column);
|
||||
|
||||
// Deduplicate cells.
|
||||
cells.insert((l_col, *l_row));
|
||||
cells.insert((r_col, *r_row));
|
||||
cells.insert((l_col, l.row));
|
||||
cells.insert((r_col, r.row));
|
||||
}
|
||||
|
||||
for (col, row) in cells {
|
||||
|
@ -274,11 +275,11 @@ impl CircuitLayout {
|
|||
|
||||
// Draw lines between equality-constrained cells.
|
||||
if self.show_equality_constraints {
|
||||
for (l_col, l_row, r_col, r_row) in &layout.equality {
|
||||
let l_col = column_index(&cs, (*l_col).into());
|
||||
let r_col = column_index(&cs, (*r_col).into());
|
||||
for (l, r) in &layout.equality {
|
||||
let l_col = column_index(&cs, l.column);
|
||||
let r_col = column_index(&cs, r.column);
|
||||
root.draw(&PathElement::new(
|
||||
[(l_col, *l_row), (r_col, *r_row)],
|
||||
[(l_col, l.row), (r_col, r.row)],
|
||||
ShapeStyle::from(&RED),
|
||||
))?;
|
||||
}
|
||||
|
@ -318,3 +319,35 @@ impl CircuitLayout {
|
|||
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)]
|
||||
#[cfg_attr(feature = "dev-graph", derive(serde::Serialize))]
|
||||
pub struct Selector(pub(crate) usize, bool);
|
||||
|
||||
impl Selector {
|
||||
|
|
Loading…
Reference in New Issue