1
1
//! Circuit cost model.
2
- use std:: {
3
- time:: Instant , io, fs, collections:: BTreeMap , mem,
4
- } ;
2
+ use std:: { collections:: BTreeMap , fs, io, mem, time:: Instant } ;
5
3
6
4
use crate :: {
7
- arithmetic:: { Field , CurveAffine , Engine , eval_polynomial } ,
5
+ arithmetic:: { eval_polynomial , CurveAffine , Engine , Field } ,
8
6
circuit:: { Cell , Layouter , SimpleFloorPlanner } ,
7
+ multicore,
9
8
plonk:: * ,
10
9
poly:: { commitment:: Params , commitment:: ParamsVerifier , EvaluationDomain , Rotation } ,
11
- transcript:: { Blake2bRead , Blake2bWrite , Challenge255 } , multicore ,
10
+ transcript:: { Blake2bRead , Blake2bWrite , Challenge255 } ,
12
11
} ;
13
12
use group:: { prime:: PrimeCurveAffine , GroupEncoding } ;
14
13
use pairing:: bn256:: { Bn256 , Fr as Fp , G1Affine } ;
@@ -41,12 +40,10 @@ impl EstimateResult {
41
40
}
42
41
43
42
impl Calculation {
44
- fn fake_evaluate < F : Field > (
45
- & self ,
46
- ) -> usize {
43
+ fn fake_evaluate < F : Field > ( & self ) -> usize {
47
44
match self {
48
45
Calculation :: Add ( _, _) => 0 ,
49
- Calculation :: Sub ( _, _) => 0 ,
46
+ Calculation :: Sub ( _, _) => 0 ,
50
47
Calculation :: Mul ( _, _) => 1 ,
51
48
Calculation :: Negate ( _) => 0 ,
52
49
Calculation :: LcBeta ( _, _) => 1 ,
@@ -58,11 +55,7 @@ impl Calculation {
58
55
}
59
56
60
57
impl < C : CurveAffine > Evaluator < C > {
61
- fn fake_evaluate_h (
62
- & self ,
63
- pk : & ProvingKey < C > ,
64
- l : usize ,
65
- ) -> usize {
58
+ fn fake_evaluate_h ( & self , pk : & ProvingKey < C > , l : usize ) -> usize {
66
59
let cs = pk. get_vk ( ) . get_cs ( ) ;
67
60
let mut num_mul = 0 ;
68
61
// All calculations, with cached intermediate results
@@ -96,7 +89,7 @@ impl<C: CurveAffine> Evaluator<C> {
96
89
if num_perm_slices > 0 {
97
90
num_mul += 2 * ( num_perm_slices - 1 ) ;
98
91
}
99
-
92
+
100
93
// delta_start * beta_start
101
94
num_mul += 1 ;
102
95
// And for all the sets we enforce:
@@ -156,15 +149,12 @@ impl<C: CurveAffine> Evaluator<C> {
156
149
}
157
150
158
151
/// estimate is to estimate the prover time, peek memory usage and aggregate circuit size.
159
- pub fn estimate <
160
- E : Engine ,
161
- ConcreteCircuit : Circuit < E :: Scalar > ,
162
- > (
152
+ pub fn estimate < E : Engine , ConcreteCircuit : Circuit < E :: Scalar > > (
163
153
circuit : ConcreteCircuit ,
164
154
k : usize ,
165
155
) -> EstimateResult {
166
156
// Generate small vk & pk
167
- let params: Params < E :: G1Affine > = Params :: < E :: G1Affine > :: unsafe_setup :: < E > ( 15 as u32 ) ;
157
+ let params: Params < E :: G1Affine > = Params :: < E :: G1Affine > :: unsafe_setup :: < E > ( k as u32 ) ;
168
158
let vk = keygen_vk ( & params, & circuit) . expect ( "keygen_vk should not fail" ) ;
169
159
let pk = keygen_pk ( & params, vk, & circuit) . expect ( "keygen_pk should not fail" ) ;
170
160
@@ -183,20 +173,20 @@ pub fn estimate<
183
173
Params {
184
174
k : k as u32 ,
185
175
n : n as u64 ,
186
- g : ( 0 ..n) . map ( |_| rand_c1. clone ( ) ) . collect ( ) ,
187
- g_lagrange : ( 0 ..n) . map ( |_| rand_c1. clone ( ) ) . collect ( ) ,
176
+ g : ( 0 ..n) . map ( |_| rand_c1) . collect ( ) ,
177
+ g_lagrange : ( 0 ..n) . map ( |_| rand_c1) . collect ( ) ,
188
178
additional_data : Vec :: from ( rand_c2. to_bytes ( ) . as_ref ( ) ) ,
189
179
}
190
180
} ;
191
181
192
182
let params = generate_fake_params ( k) ;
193
-
183
+
194
184
// Initialize the domain
195
185
let domain = EvaluationDomain :: fake_new ( cs. degree ( ) as u32 , params. k , E :: Scalar :: random ( OsRng ) ) ;
196
-
186
+
197
187
let n = 1 << k as usize ;
198
188
let rand_ele = E :: Scalar :: random ( & mut OsRng ) ;
199
- let rand_vec: Vec :: < E :: Scalar > = ( 0 ..n) . map ( |_| rand_ele. clone ( ) ) . collect ( ) ;
189
+ let rand_vec: Vec < E :: Scalar > = ( 0 ..n) . map ( |_| rand_ele) . collect ( ) ;
200
190
let rand_vec2 = rand_vec. clone ( ) ;
201
191
let rand_values = domain. lagrange_from_vec ( rand_vec) ;
202
192
@@ -209,12 +199,14 @@ pub fn estimate<
209
199
let ( time_extended_fft, _) = measure_elapsed_time ( || domain. coeff_to_extended ( rand_poly) ) ;
210
200
// BTree time cost in lookup argument
211
201
let ( time_btree, _) = measure_elapsed_time ( || {
212
- let mut leftover_table_map: BTreeMap < E :: Scalar , u32 > = rand_vec2
213
- . iter ( ) . take ( n)
214
- . fold ( BTreeMap :: new ( ) , |mut acc, coeff| {
215
- * acc. entry ( * coeff) . or_insert ( 0 ) += 1 ;
216
- acc
217
- } ) ;
202
+ let mut leftover_table_map: BTreeMap < E :: Scalar , u32 > =
203
+ rand_vec2
204
+ . iter ( )
205
+ . take ( n)
206
+ . fold ( BTreeMap :: new ( ) , |mut acc, coeff| {
207
+ * acc. entry ( * coeff) . or_insert ( 0 ) += 1 ;
208
+ acc
209
+ } ) ;
218
210
for item in & rand_vec2 {
219
211
if let Some ( count) = leftover_table_map. get_mut ( item) {
220
212
* count -= 1 ;
@@ -225,17 +217,19 @@ pub fn estimate<
225
217
let num_threads = multicore:: current_num_threads ( ) ;
226
218
227
219
// NOTE(sphere): estimate op count
228
- let FuncCount { num_fft, num_extended_fft, num_msm, num_btree, num_mul, mem_usage} = dummy_proof (
229
- & params,
230
- & pk,
231
- & domain,
232
- l,
233
- ) ;
220
+ let FuncCount {
221
+ num_fft,
222
+ num_extended_fft,
223
+ num_msm,
224
+ num_btree,
225
+ num_mul,
226
+ mem_usage,
227
+ } = dummy_proof ( & params, & pk, & domain, l) ;
234
228
235
229
let estimate_add_mul_field_op_time = || {
236
230
let m = ( domain. extended_len ( ) + num_threads - 1 ) / num_threads;
237
- let a = rand_ele. clone ( ) ;
238
- let mut b = rand_ele. clone ( ) ;
231
+ let a = rand_ele;
232
+ let mut b = rand_ele;
239
233
// m mul field ops
240
234
let ( time_mul, _) = measure_elapsed_time ( || {
241
235
for _ in 0 ..m {
@@ -248,15 +242,17 @@ pub fn estimate<
248
242
} ;
249
243
250
244
println ! ( "num_fft = {}, time_fft = {}" , num_fft, time_fft) ;
251
- println ! ( "num_extended_fft = {}, time_extended_fft = {}" , num_extended_fft, time_extended_fft) ;
245
+ println ! (
246
+ "num_extended_fft = {}, time_extended_fft = {}" ,
247
+ num_extended_fft, time_extended_fft
248
+ ) ;
252
249
println ! ( "num_msm = {}, time_msm = {}" , num_msm, time_msm) ;
253
250
println ! ( "num_btree = {}, time_btree = {}" , num_btree, time_btree) ;
254
-
255
251
256
- let pt_non_linear = ( num_fft as f64 ) * time_fft +
257
- ( num_extended_fft as f64 ) * time_extended_fft +
258
- ( num_msm as f64 ) * time_msm +
259
- ( num_btree as f64 ) * time_btree;
252
+ let pt_non_linear = ( num_fft as f64 ) * time_fft
253
+ + ( num_extended_fft as f64 ) * time_extended_fft
254
+ + ( num_msm as f64 ) * time_msm
255
+ + ( num_btree as f64 ) * time_btree;
260
256
println ! ( "pt_non_linear = {}" , pt_non_linear) ;
261
257
262
258
let pt_linear = estimate_add_mul_field_op_time ( ) ;
@@ -270,7 +266,7 @@ pub fn estimate<
270
266
random_poly
271
267
} ) ;
272
268
println ! ( "pt_random = {}" , pt_random) ;
273
- println ! ( "" ) ;
269
+ println ! ( ) ;
274
270
275
271
let prover_time = pt_non_linear + pt_linear + pt_random;
276
272
@@ -286,18 +282,18 @@ pub fn estimate<
286
282
// println!("mem_usage by linear regression = {}", mem_usage2);
287
283
288
284
// NOTE(sphere): calculate aggregate_circuit_size
289
-
285
+
290
286
EstimateResult {
291
287
prover_time,
292
288
mem_usage : ( mem_usage as f64 ) / 1024.0 , // to KB
293
289
}
294
290
}
295
291
296
292
/// simulate_circuit is to run a circuit proving process.
297
- pub fn simulate_circuit <
298
- E : Engine ,
299
- ConcreteCircuit : Circuit < E :: Scalar > ,
300
- > ( circuit : ConcreteCircuit , k : usize ) {
293
+ pub fn simulate_circuit < E : Engine , ConcreteCircuit : Circuit < E :: Scalar > > (
294
+ circuit : ConcreteCircuit ,
295
+ k : usize ,
296
+ ) {
301
297
// let public_inputs_size = 0;
302
298
303
299
// Initialize the polynomial commitment parameters
@@ -310,17 +306,17 @@ pub fn simulate_circuit<
310
306
// Create a proof
311
307
let mut transcript = Blake2bWrite :: < _ , _ , Challenge255 < _ > > :: init ( vec ! [ ] ) ;
312
308
313
- let ( prover_time, _) = measure_elapsed_time ( ||
309
+ let ( prover_time, _) = measure_elapsed_time ( || {
314
310
create_proof ( & params, & pk, & [ circuit] , & [ & [ ] ] , OsRng , & mut transcript)
315
- . expect ( "proof generation should not fail" )
316
- ) ;
311
+ . expect ( "proof generation should not fail" )
312
+ } ) ;
317
313
318
314
// NOTE(liutainyi): output prover_time
319
315
println ! ( "k = {}, prover_time = {}" , k, prover_time) ;
320
316
}
321
317
322
318
struct FuncCount {
323
- num_fft : usize ,
319
+ num_fft : usize ,
324
320
num_extended_fft : usize ,
325
321
num_msm : usize ,
326
322
num_btree : usize ,
@@ -334,10 +330,10 @@ fn dummy_proof<C: CurveAffine>(
334
330
domain : & EvaluationDomain < C :: Scalar > ,
335
331
l : usize , // The number of input.
336
332
) -> FuncCount {
337
- let mut num_fft = 0 as usize ;
338
- let mut num_extended_fft = 0 as usize ;
339
- let mut num_msm = 0 as usize ;
340
- let mut num_btree = 0 as usize ;
333
+ let mut num_fft = 0_usize ;
334
+ let mut num_extended_fft = 0_usize ;
335
+ let mut num_msm = 0_usize ;
336
+ let mut num_btree = 0_usize ;
341
337
342
338
let cs = pk. get_vk ( ) . get_cs ( ) ;
343
339
@@ -364,13 +360,14 @@ fn dummy_proof<C: CurveAffine>(
364
360
// Commit to permutations.
365
361
// NOTE(sphere): l * perm_commit_t
366
362
// commit_lagrange: z
367
- let num_perm_slices = ( cs. permutation . get_columns ( ) . len ( ) + ( cs. degree ( ) - 3 ) ) / ( cs. degree ( ) - 2 ) ;
363
+ let num_perm_slices =
364
+ ( cs. permutation . get_columns ( ) . len ( ) + ( cs. degree ( ) - 3 ) ) / ( cs. degree ( ) - 2 ) ;
368
365
num_msm += num_perm_slices;
369
366
// lagrange_to_coeff: z
370
367
num_fft += num_perm_slices;
371
368
// coeff_to_extended: z
372
369
num_extended_fft += num_perm_slices;
373
-
370
+
374
371
// NOTE(sphere): pt += lookup_commit_product
375
372
// commit_lagrange: z, a', s'
376
373
num_msm += 3 * num_lookups;
@@ -389,21 +386,21 @@ fn dummy_proof<C: CurveAffine>(
389
386
// Construct the vanishing argument's h(X) commitments
390
387
// NOTE(sphere): pt += vanishing_construct
391
388
// extended_to_coeff: h_poly
392
- num_extended_fft += 1 ;
389
+ num_extended_fft += 1 ;
393
390
// commit: h_poly_i
394
391
let num_h_pieces = ( ( domain. extended_len ( ) as u64 + params. n - 1 ) / params. n ) as usize ;
395
392
num_msm += num_h_pieces;
396
393
397
394
// NOTE(sphere): evaluate h.
398
- let num_mul = pk. get_ev ( ) . fake_evaluate_h ( & pk, l) ;
395
+ let num_mul = pk. get_ev ( ) . fake_evaluate_h ( pk, l) ;
399
396
400
- // NOTE (sphere): multiopen(shplonk).
397
+ // TODO (sphere): multiopen(shplonk). There should be a more detailed evaluation .
401
398
// commit: h_x, h_x
402
399
// The evaluations in multiopen is too small.
403
400
num_msm += 2 ;
404
401
405
- // TODO (sphere): Memory
406
- let mut mem_usage = 0 as usize ;
402
+ // NOTE (sphere): Memory
403
+ let mut mem_usage = 0_usize ;
407
404
// instance / advice / fixed as value poly, and coset:
408
405
let n = 1 << params. k as usize ;
409
406
let ext_n = domain. extended_len ( ) ;
@@ -437,7 +434,7 @@ fn dummy_proof<C: CurveAffine>(
437
434
mem_usage *= mem:: size_of :: < C :: Scalar > ( ) ;
438
435
439
436
FuncCount {
440
- num_fft,
437
+ num_fft,
441
438
num_extended_fft,
442
439
num_msm,
443
440
num_btree,
@@ -446,20 +443,20 @@ fn dummy_proof<C: CurveAffine>(
446
443
}
447
444
}
448
445
449
-
450
446
/// cost_model_main is to generate a main function to run the cost model for a circuit.
451
447
#[ macro_export]
452
448
macro_rules! cost_model_main {
453
449
( $cir: expr) => {
454
- use halo2_proofs:: dev:: {
455
- simulate_circuit,
456
- estimate,
457
- } ;
450
+ use halo2_proofs:: dev:: { estimate, simulate_circuit} ;
458
451
459
452
fn main( ) {
460
453
// NOTE(sphere): get k from args
461
454
let mode = std:: env:: args( ) . nth( 1 ) . expect( "no running-mode given" ) ;
462
- let k = std:: env:: args( ) . nth( 2 ) . expect( "no circuit size given" ) . parse( ) . unwrap( ) ;
455
+ let k = std:: env:: args( )
456
+ . nth( 2 )
457
+ . expect( "no circuit size given" )
458
+ . parse( )
459
+ . unwrap( ) ;
463
460
// NOTE(sphere): estimate linear cost (cfg == simulate)
464
461
let circuit = $cir;
465
462
if mode. eq( & String :: from( "simulate" ) ) {
@@ -471,5 +468,5 @@ macro_rules! cost_model_main {
471
468
panic!( "unrecognized format" ) ;
472
469
}
473
470
}
474
- }
471
+ } ;
475
472
}
0 commit comments