@@ -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