@@ -6,7 +6,7 @@ use itertools::Itertools;
66use rayon:: iter:: {
77 IndexedParallelIterator , IntoParallelRefIterator , IntoParallelRefMutIterator , ParallelIterator ,
88} ;
9- use std:: { marker:: PhantomData , sync :: Arc } ;
9+ use std:: marker:: PhantomData ;
1010use witness:: {
1111 InstancePaddingStrategy , RowMajorMatrix , next_pow2_instance_padding, set_fixed_val, set_val,
1212} ;
@@ -366,54 +366,62 @@ impl<DVRAM: DynVolatileRamTable + Send + Sync + Clone> DynVolatileRamTableConfig
366366 num_structural_witin : usize ,
367367 final_mem : & [ MemFinalRecord ] ,
368368 ) -> Result < [ RowMajorMatrix < F > ; 2 ] , CircuitBuilderError > {
369- assert ! ( final_mem. len( ) <= DVRAM :: max_len( & config. params) ) ;
370- assert ! ( DVRAM :: max_len( & config. params) . is_power_of_two( ) ) ;
369+ if final_mem. is_empty ( ) {
370+ return Ok ( [ RowMajorMatrix :: empty ( ) , RowMajorMatrix :: empty ( ) ] ) ;
371+ }
371372
372- let params = config. params . clone ( ) ;
373- let addr_id = config. addr . id as u64 ;
374- let addr_padding_fn = move |row : u64 , col : u64 | {
375- assert_eq ! ( col, addr_id) ;
376- DVRAM :: addr ( & params, row as usize ) as u64
377- } ;
373+ let num_instances_padded = next_pow2_instance_padding ( final_mem. len ( ) ) ;
374+ assert ! ( num_instances_padded <= DVRAM :: max_len( & config. params) ) ;
375+ assert ! ( DVRAM :: max_len( & config. params) . is_power_of_two( ) ) ;
378376
379- let mut witness =
380- RowMajorMatrix :: < F > :: new ( final_mem. len ( ) , num_witin, InstancePaddingStrategy :: Default ) ;
377+ let mut witness = RowMajorMatrix :: < F > :: new (
378+ num_instances_padded,
379+ num_witin,
380+ InstancePaddingStrategy :: Default ,
381+ ) ;
381382 let mut structural_witness = RowMajorMatrix :: < F > :: new (
382- final_mem . len ( ) ,
383+ num_instances_padded ,
383384 num_structural_witin,
384- InstancePaddingStrategy :: Custom ( Arc :: new ( addr_padding_fn ) ) ,
385+ InstancePaddingStrategy :: Default ,
385386 ) ;
386387
387388 witness
388389 . par_rows_mut ( )
389- . zip ( structural_witness. par_rows_mut ( ) )
390- . zip ( final_mem)
390+ . zip_eq ( structural_witness. par_rows_mut ( ) )
391391 . enumerate ( )
392- . for_each ( |( i, ( ( row, structural_row) , rec) ) | {
393- assert_eq ! (
394- rec. addr,
395- DVRAM :: addr( & config. params, i) ,
396- "rec.addr {:x} != expected {:x}" ,
397- rec. addr,
398- DVRAM :: addr( & config. params, i) ,
399- ) ;
400-
401- if config. final_v . len ( ) == 1 {
402- // Assign value directly.
403- set_val ! ( row, config. final_v[ 0 ] , rec. value as u64 ) ;
404- } else {
405- // Assign value limbs.
406- config. final_v . iter ( ) . enumerate ( ) . for_each ( |( l, limb) | {
407- let val = ( rec. value >> ( l * LIMB_BITS ) ) & LIMB_MASK ;
408- set_val ! ( row, limb, val as u64 ) ;
409- } ) ;
392+ . for_each ( |( i, ( row, structural_row) ) | {
393+ if cfg ! ( debug_assertions)
394+ && let Some ( addr) = final_mem. get ( i) . map ( |rec| rec. addr )
395+ {
396+ debug_assert_eq ! (
397+ addr,
398+ DVRAM :: addr( & config. params, i) ,
399+ "rec.addr {:x} != expected {:x}" ,
400+ addr,
401+ DVRAM :: addr( & config. params, i) ,
402+ ) ;
410403 }
411- set_val ! ( row, config. final_cycle, rec. cycle) ;
412404
413- set_val ! ( structural_row, config. addr, rec. addr as u64 ) ;
405+ if let Some ( rec) = final_mem. get ( i) {
406+ if config. final_v . len ( ) == 1 {
407+ // Assign value directly.
408+ set_val ! ( row, config. final_v[ 0 ] , rec. value as u64 ) ;
409+ } else {
410+ // Assign value limbs.
411+ config. final_v . iter ( ) . enumerate ( ) . for_each ( |( l, limb) | {
412+ let val = ( rec. value >> ( l * LIMB_BITS ) ) & LIMB_MASK ;
413+ set_val ! ( row, limb, val as u64 ) ;
414+ } ) ;
415+ }
416+ set_val ! ( row, config. final_cycle, rec. cycle) ;
417+ }
418+ set_val ! (
419+ structural_row,
420+ config. addr,
421+ DVRAM :: addr( & config. params, i) as u64
422+ ) ;
414423 } ) ;
415424
416- structural_witness. padding_by_strategy ( ) ;
417425 Ok ( [ witness, structural_witness] )
418426 }
419427}
@@ -487,10 +495,10 @@ impl<DVRAM: DynVolatileRamTable + Send + Sync + Clone> DynVolatileRamTableConfig
487495 if final_mem. is_empty ( ) {
488496 return Ok ( [ RowMajorMatrix :: empty ( ) , RowMajorMatrix :: empty ( ) ] ) ;
489497 }
490- assert ! ( final_mem. len( ) <= DVRAM :: max_len( & config. params) ) ;
491- assert ! ( DVRAM :: max_len( & config. params) . is_power_of_two( ) ) ;
492498
493499 let num_instances_padded = next_pow2_instance_padding ( final_mem. len ( ) ) ;
500+ assert ! ( num_instances_padded <= DVRAM :: max_len( & config. params) ) ;
501+ assert ! ( DVRAM :: max_len( & config. params) . is_power_of_two( ) ) ;
494502
495503 let mut structural_witness = RowMajorMatrix :: < F > :: new (
496504 num_instances_padded,
0 commit comments