@@ -112,7 +112,7 @@ pub struct RAMRecord {
112112
113113pub struct ShardContext < ' a > {
114114 shard_id : usize ,
115- num_shards : usize ,
115+ max_num_shards : usize ,
116116 max_cycle : Cycle ,
117117 addr_future_accesses : Cow < ' a , HashMap < ( WordAddr , Cycle ) , Cycle > > ,
118118 read_thread_based_record_storage : Either <
@@ -131,7 +131,7 @@ impl<'a> Default for ShardContext<'a> {
131131 let max_threads = max_usable_threads ( ) ;
132132 Self {
133133 shard_id : 0 ,
134- num_shards : 1 ,
134+ max_num_shards : 1 ,
135135 max_cycle : Cycle :: default ( ) ,
136136 addr_future_accesses : Cow :: Owned ( HashMap :: new ( ) ) ,
137137 read_thread_based_record_storage : Either :: Left (
@@ -154,20 +154,27 @@ impl<'a> Default for ShardContext<'a> {
154154impl < ' a > ShardContext < ' a > {
155155 pub fn new (
156156 shard_id : usize ,
157- num_shards : usize ,
157+ max_num_shards : usize ,
158158 executed_instructions : usize ,
159159 addr_future_accesses : HashMap < ( WordAddr , Cycle ) , Cycle > ,
160160 ) -> Self {
161+ // current strategy: at least each shard deal with one instruction
162+ let max_num_shards = max_num_shards. min ( executed_instructions) ;
163+ assert ! (
164+ shard_id < max_num_shards,
165+ "implement mechanism to skip current shard proof"
166+ ) ;
167+
161168 let max_threads = max_usable_threads ( ) ;
162169 // let max_record_per_thread = max_insts.div_ceil(max_threads as u64);
163- let expected_inst_per_shard = executed_instructions. div_ceil ( num_shards ) as usize ;
170+ let expected_inst_per_shard = executed_instructions. div_ceil ( max_num_shards ) as usize ;
164171 let max_cycle = ( executed_instructions + 1 ) * 4 ; // cycle start from 4
165- let cur_shard_cycle_range = ( shard_id * expected_inst_per_shard * 4 ) . max ( 4 )
166- ..( ( shard_id + 1 ) * expected_inst_per_shard * 4 ) . min ( max_cycle) ;
172+ let cur_shard_cycle_range = ( shard_id * expected_inst_per_shard * 4 + 4 )
173+ ..( ( shard_id + 1 ) * expected_inst_per_shard * 4 + 4 ) . min ( max_cycle) ;
167174
168175 ShardContext {
169176 shard_id,
170- num_shards ,
177+ max_num_shards ,
171178 max_cycle : max_cycle as Cycle ,
172179 addr_future_accesses : Cow :: Owned ( addr_future_accesses) ,
173180 // TODO with_capacity optimisation
@@ -201,7 +208,7 @@ impl<'a> ShardContext<'a> {
201208 . zip ( write_thread_based_record_storage. iter_mut ( ) )
202209 . map ( |( read, write) | ShardContext {
203210 shard_id : self . shard_id ,
204- num_shards : self . num_shards ,
211+ max_num_shards : self . max_num_shards ,
205212 max_cycle : self . max_cycle ,
206213 addr_future_accesses : Cow :: Borrowed ( self . addr_future_accesses . as_ref ( ) ) ,
207214 read_thread_based_record_storage : Either :: Right ( read) ,
@@ -220,14 +227,28 @@ impl<'a> ShardContext<'a> {
220227
221228 #[ inline( always) ]
222229 pub fn is_last_shard ( & self ) -> bool {
223- self . shard_id == self . num_shards - 1
230+ self . shard_id == self . max_num_shards - 1
224231 }
225232
226233 #[ inline( always) ]
227234 pub fn is_current_shard_cycle ( & self , cycle : Cycle ) -> bool {
228235 self . cur_shard_cycle_range . contains ( & ( cycle as usize ) )
229236 }
230237
238+ #[ inline( always) ]
239+ pub fn aligned_prev_ts ( & self , prev_cycle : Cycle ) -> Cycle {
240+ let mut ts = prev_cycle. saturating_sub ( self . cur_shard_cycle_range . start as Cycle ) ;
241+ if ts < 4 {
242+ ts = 0
243+ }
244+ ts
245+ }
246+
247+ pub fn current_shard_offset_cycle ( & self ) -> Cycle {
248+ // `-4` as cycle of each local shard start from 4
249+ ( self . cur_shard_cycle_range . start as Cycle ) - 4
250+ }
251+
231252 #[ inline( always) ]
232253 pub fn send (
233254 & mut self ,
@@ -475,7 +496,7 @@ pub fn emulate_program<'a>(
475496
476497 let shard_ctx = ShardContext :: new (
477498 shards. shard_id ,
478- shards. num_shards ,
499+ shards. max_num_shards ,
479500 insts,
480501 vm. take_tracer ( ) . next_accesses ( ) ,
481502 ) ;
0 commit comments