plonky2/src/iop/target.rs
Daniel Lubarov 3f22663296
Split up PartitionWitness data (#273)
* Split up `PartitionWitness` data

This addresses two minor inefficiencies:
- Some preprocessed forest data was being cloned during proving.
- Some of the `ForestNode` data (like node sizes) is only needed in preprocessing, not proving. It was taking up cache space during proving because it was interleaved with data that is used during proving (parents, values).

Now `Forest` contains the disjoint-set forest. `PartitionWitness` is now mainly a Vec of target values; it also holds a reference to the (preprocessed) representative map.

On my laptop, this speeds up witness generation ~12%, resulting in an overall ~0.5% speedup.

* Feedback

* No size data (#278)

* No size data

* feedback
2021-09-28 22:31:20 -07:00

58 lines
1.6 KiB
Rust

use std::ops::Range;
use crate::iop::wire::Wire;
use crate::plonk::circuit_data::CircuitConfig;
/// A location in the witness.
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum Target {
Wire(Wire),
/// A target that doesn't have any inherent location in the witness (but it can be copied to
/// another target that does). This is useful for representing intermediate values in witness
/// generation.
VirtualTarget {
index: usize,
},
}
impl Target {
pub fn wire(gate: usize, input: usize) -> Self {
Self::Wire(Wire { gate, input })
}
pub fn is_routable(&self, config: &CircuitConfig) -> bool {
match self {
Target::Wire(wire) => wire.is_routable(config),
Target::VirtualTarget { .. } => true,
}
}
pub fn wires_from_range(gate: usize, range: Range<usize>) -> Vec<Self> {
range.map(|i| Self::wire(gate, i)).collect()
}
pub fn index(&self, num_wires: usize, degree: usize) -> usize {
match self {
Target::Wire(Wire { gate, input }) => gate * num_wires + input,
Target::VirtualTarget { index } => degree * num_wires + index,
}
}
}
/// A `Target` which has already been constrained such that it can only be 0 or 1.
#[derive(Copy, Clone, Debug)]
pub struct BoolTarget {
pub target: Target,
/// This private field is here to force all instantiations to go through `new_unsafe`.
_private: (),
}
impl BoolTarget {
pub fn new_unsafe(target: Target) -> BoolTarget {
BoolTarget {
target,
_private: (),
}
}
}