Skip to content

Commit e797ff1

Browse files
author
Andrus Salumets
authored
Merge branch 'feat/bench' into distributed-query-integration-modifications
2 parents c2f5eba + e8bc6ce commit e797ff1

File tree

9 files changed

+508
-140
lines changed

9 files changed

+508
-140
lines changed

Cargo.lock

Lines changed: 68 additions & 58 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ edition = "2021"
88
[dependencies]
99
anyhow = "1.0.75"
1010
itertools = "0.12.0"
11-
plonky2 = "0.1.4"
1211
ethers = { version ="2.0.11", default-features = false, features = ["rustls"]}
12+
plonky2 = {version = "0.1.4", features = ["std"]}
1313

1414
# supporting latest plonky2
1515
plonky2_crypto = { git = "https://github.com/nikkolasg/plonky2-crypto" , branch = "feat/serialization" }
@@ -32,6 +32,9 @@ rmp-serde = "1.1.2"
3232
serde_json = "1.0.108"
3333
sha3 = "0.10.8"
3434
tokio = { version = "1.34.0", features = ["macros", "rt-multi-thread"] }
35+
env_logger = { version = "0.9.0", default-features = false }
36+
log = { version = "0.4.14", default-features = false }
37+
rand = "0.8.5"
3538

3639
[features]
3740
ci = []

src/benches/circuit.rs

Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
1+
#[cfg(test)]
2+
mod tests {
3+
use anyhow::Result;
4+
use log::{log_enabled, Level, LevelFilter};
5+
use plonky2::field::types::Field;
6+
use plonky2::iop::target::Target;
7+
use plonky2::iop::witness::PartialWitness;
8+
use plonky2::plonk::circuit_builder::CircuitBuilder;
9+
use plonky2::plonk::circuit_data::CircuitConfig;
10+
use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
11+
use std::env;
12+
use std::io::Write;
13+
use std::time::Instant;
14+
15+
#[test]
16+
fn compare_quin_random_access() -> Result<()> {
17+
use crate::rlp::quin_selector;
18+
use rand::Rng;
19+
20+
// if this is `k` then the array will have 2^k elements
21+
let array_bits_of_length_max: usize = 6;
22+
23+
let comparison = |k: usize| {
24+
// common to both circuits
25+
const D: usize = 2;
26+
type C = PoseidonGoldilocksConfig;
27+
type F = <C as GenericConfig<D>>::F;
28+
29+
// both versions of the circuit need to capture this information
30+
let bits_of_length: usize = k;
31+
let byte_arr: Vec<u8> = (0..1 << bits_of_length)
32+
.map(|_i| rand::thread_rng().gen())
33+
.collect();
34+
println!("\nArray length: {}", byte_arr.len());
35+
let rand_index: usize = rand::thread_rng().gen_range(0..1 << bits_of_length);
36+
37+
let config = CircuitConfig::standard_recursion_config();
38+
39+
let quin_version = |builder: &mut CircuitBuilder<F, D>| {
40+
let arr_target: Vec<Target> = byte_arr
41+
.iter()
42+
.map(|x| builder.constant(F::from_canonical_u8(*x)))
43+
.collect();
44+
let n: Target = builder.constant(F::from_canonical_usize(rand_index));
45+
let element = arr_target[rand_index];
46+
47+
let ret_element = quin_selector(builder, &arr_target, n);
48+
49+
builder.connect(element, ret_element);
50+
builder.register_public_input(ret_element);
51+
builder.register_public_inputs(&arr_target);
52+
};
53+
54+
let random_access_version = |builder: &mut CircuitBuilder<F, D>| {
55+
let arr_target: Vec<Target> = byte_arr
56+
.iter()
57+
.map(|x| builder.constant(F::from_canonical_u8(*x)))
58+
.collect();
59+
let n: Target = builder.constant(F::from_canonical_usize(rand_index));
60+
let element = arr_target[rand_index];
61+
62+
let ret_element = builder.random_access(n, arr_target.clone());
63+
64+
builder.connect(element, ret_element);
65+
builder.register_public_input(ret_element);
66+
builder.register_public_inputs(&arr_target);
67+
};
68+
69+
// in this case there is nothing to do to the circuit
70+
// after each version so we pass the identity function
71+
compare::<C, D>(
72+
config,
73+
(quin_version, "QUIN VERSION"),
74+
(random_access_version, "RANDOM ACCESS VERSION"),
75+
|_| {}, // identity function
76+
)
77+
};
78+
79+
(0..(array_bits_of_length_max + 1))
80+
.map(comparison)
81+
.fold(Ok(()), |r, state| state.and(r))
82+
}
83+
84+
/// Sets RUST_LOG=debug and initializes the logger
85+
/// if it hasn't been enabled already.
86+
fn init_logging() {
87+
if !log_enabled!(Level::Debug) {
88+
env::set_var("RUST_LOG", "debug");
89+
env_logger::builder()
90+
.format(|buf, record| writeln!(buf, " {}", record.args()))
91+
.init();
92+
log::set_max_level(LevelFilter::Debug);
93+
}
94+
}
95+
96+
/// Compares the gate counts, LDE size, build time, proving time, and verification time
97+
/// of two circuits. Accepts two closures `v1` and `v2` which are the only places where
98+
/// the two circuits are allowed to add different gates to the circuit. The `after` closure
99+
/// can be used to add identical gates after the differences.
100+
fn compare<C, const D: usize>(
101+
config: CircuitConfig,
102+
(v1, v1_name): (impl Fn(&mut CircuitBuilder<C::F, D>), &str),
103+
(v2, v2_name): (impl Fn(&mut CircuitBuilder<C::F, D>), &str),
104+
after: impl Fn(&mut CircuitBuilder<C::F, D>),
105+
) -> Result<()>
106+
where
107+
C: GenericConfig<D>,
108+
{
109+
// turn on logging and force DEBUG level logs
110+
// to be printed to the screen
111+
init_logging();
112+
113+
let end = |builder: CircuitBuilder<C::F, D>| {
114+
// print gate information from the DEBUG log level
115+
builder.print_gate_counts(0);
116+
117+
// time the build process
118+
print!(" Building....");
119+
let now = Instant::now();
120+
let data = builder.build::<C>();
121+
println!("{:.2?}", now.elapsed());
122+
123+
// time the proving process
124+
print!(" Proving.....");
125+
let pw = PartialWitness::new();
126+
let now = Instant::now();
127+
let proof = data.prove(pw)?;
128+
println!("{:.2?}", now.elapsed());
129+
130+
// time the verification process
131+
print!(" Verifying...");
132+
let now = Instant::now();
133+
let res = data.verify(proof);
134+
println!("{:.2?}", now.elapsed());
135+
136+
println!(" LDE size: {}", data.common.lde_size());
137+
138+
res
139+
};
140+
141+
let mut builder1 = CircuitBuilder::<C::F, D>::new(config.clone());
142+
println!("\n{}", v1_name);
143+
v1(&mut builder1);
144+
after(&mut builder1);
145+
let verified1 = end(builder1);
146+
147+
let mut builder2 = CircuitBuilder::<C::F, D>::new(config);
148+
println!("\n{}", v2_name);
149+
v2(&mut builder2);
150+
after(&mut builder2);
151+
let verified2 = end(builder2);
152+
153+
assert!(verified1.is_ok());
154+
assert!(verified2.is_ok());
155+
verified1.and(verified2)
156+
}
157+
}
158+
159+
/*
160+
161+
Bench results with array lengths from 2^0 to 2^6
162+
163+
`random_access` fails for arrays longer than 2^6
164+
because it packs a random access gate into a single row
165+
which has 64 wires in the standard configuration
166+
167+
running 1 test
168+
169+
Array length: 1
170+
171+
QUIN VERSION
172+
2 gates to root
173+
Total gate counts:
174+
- 2 instances of ArithmeticGate { num_ops: 20 }
175+
Degree before blinding & padding: 6
176+
Degree after blinding & padding: 8
177+
Building circuit took 0.043633606s
178+
Building....43.70ms
179+
Proving.....2.02s
180+
Verifying...93.23ms
181+
LDE size: 64
182+
183+
RANDOM ACCESS VERSION
184+
0 gates to root
185+
Total gate counts:
186+
Degree before blinding & padding: 3
187+
Degree after blinding & padding: 4
188+
Building circuit took 0.0190342s
189+
Building....19.13ms
190+
Proving.....786.01ms
191+
Verifying...93.12ms
192+
LDE size: 32
193+
194+
Array length: 2
195+
196+
QUIN VERSION
197+
3 gates to root
198+
Total gate counts:
199+
- 3 instances of ArithmeticGate { num_ops: 20 }
200+
Degree before blinding & padding: 7
201+
Degree after blinding & padding: 8
202+
Building circuit took 0.06195052s
203+
Building....62.48ms
204+
Proving.....607.86ms
205+
Verifying...110.70ms
206+
LDE size: 64
207+
208+
RANDOM ACCESS VERSION
209+
1 gates to root
210+
Total gate counts:
211+
- 1 instances of RandomAccessGate { bits: 1, num_copies: 20, num_extra_constants: 0, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
212+
Degree before blinding & padding: 5
213+
Degree after blinding & padding: 8
214+
Building circuit took 0.02839202s
215+
Building....28.44ms
216+
Proving.....1.91s
217+
Verifying...96.69ms
218+
LDE size: 64
219+
220+
Array length: 4
221+
222+
QUIN VERSION
223+
3 gates to root
224+
Total gate counts:
225+
- 3 instances of ArithmeticGate { num_ops: 20 }
226+
Degree before blinding & padding: 10
227+
Degree after blinding & padding: 16
228+
Building circuit took 0.06623432s
229+
Building....66.30ms
230+
Proving.....520.85ms
231+
Verifying...103.93ms
232+
LDE size: 128
233+
234+
RANDOM ACCESS VERSION
235+
1 gates to root
236+
Total gate counts:
237+
- 1 instances of RandomAccessGate { bits: 2, num_copies: 13, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
238+
Degree before blinding & padding: 5
239+
Degree after blinding & padding: 8
240+
Building circuit took 0.04746539s
241+
Building....47.53ms
242+
Proving.....848.61ms
243+
Verifying...92.31ms
244+
LDE size: 64
245+
246+
Array length: 8
247+
248+
QUIN VERSION
249+
3 gates to root
250+
Total gate counts:
251+
- 3 instances of ArithmeticGate { num_ops: 20 }
252+
Degree before blinding & padding: 16
253+
Degree after blinding & padding: 16
254+
Building circuit took 0.07234759s
255+
Building....72.44ms
256+
Proving.....572.17ms
257+
Verifying...94.25ms
258+
LDE size: 128
259+
260+
RANDOM ACCESS VERSION
261+
1 gates to root
262+
Total gate counts:
263+
- 1 instances of RandomAccessGate { bits: 3, num_copies: 8, num_extra_constants: 0, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
264+
Degree before blinding & padding: 9
265+
Degree after blinding & padding: 16
266+
Building circuit took 0.076199085s
267+
Building....76.26ms
268+
Proving.....664.78ms
269+
Verifying...95.64ms
270+
LDE size: 128
271+
272+
Array length: 16
273+
274+
QUIN VERSION
275+
6 gates to root
276+
Total gate counts:
277+
- 6 instances of ArithmeticGate { num_ops: 20 }
278+
Degree before blinding & padding: 26
279+
Degree after blinding & padding: 32
280+
Building circuit took 0.1314385s
281+
Building....131.55ms
282+
Proving.....1.55s
283+
Verifying...104.35ms
284+
LDE size: 256
285+
286+
RANDOM ACCESS VERSION
287+
1 gates to root
288+
Total gate counts:
289+
- 1 instances of RandomAccessGate { bits: 4, num_copies: 4, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
290+
Degree before blinding & padding: 13
291+
Degree after blinding & padding: 16
292+
Building circuit took 0.07145585s
293+
Building....71.51ms
294+
Proving.....516.23ms
295+
Verifying...104.20ms
296+
LDE size: 128
297+
298+
Array length: 32
299+
300+
QUIN VERSION
301+
11 gates to root
302+
Total gate counts:
303+
- 11 instances of ArithmeticGate { num_ops: 20 }
304+
Degree before blinding & padding: 57
305+
Degree after blinding & padding: 64
306+
Building circuit took 0.21333219s
307+
Building....213.50ms
308+
Proving.....4.38s
309+
Verifying...120.49ms
310+
LDE size: 512
311+
312+
RANDOM ACCESS VERSION
313+
1 gates to root
314+
Total gate counts:
315+
- 1 instances of RandomAccessGate { bits: 5, num_copies: 2, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
316+
Degree before blinding & padding: 23
317+
Degree after blinding & padding: 32
318+
Building circuit took 0.1523578s
319+
Building....152.82ms
320+
Proving.....604.20ms
321+
Verifying...125.65ms
322+
LDE size: 256
323+
324+
Array length: 64
325+
326+
QUIN VERSION
327+
21 gates to root
328+
Total gate counts:
329+
- 21 instances of ArithmeticGate { num_ops: 20 }
330+
Degree before blinding & padding: 107
331+
Degree after blinding & padding: 128
332+
Building circuit took 0.3929123s
333+
Building....393.29ms
334+
Proving.....1.54s
335+
Verifying...130.57ms
336+
LDE size: 1024
337+
338+
RANDOM ACCESS VERSION
339+
1 gates to root
340+
Total gate counts:
341+
- 1 instances of RandomAccessGate { bits: 6, num_copies: 1, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
342+
Degree before blinding & padding: 39
343+
Degree after blinding & padding: 64
344+
Building circuit took 0.21680678s
345+
Building....216.89ms
346+
Proving.....1.62s
347+
Verifying...138.10ms
348+
LDE size: 512
349+
test benches::circuit::tests::compare_quin_random_access ... ok
350+
351+
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 18 filtered out; finished in 21.25s
352+
353+
*/

src/benches/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mod circuit;

0 commit comments

Comments
 (0)