Skip to content

Commit aec3eb4

Browse files
draft: Add support for caching hint data
1 parent f17b0e3 commit aec3eb4

File tree

7 files changed

+95
-48
lines changed

7 files changed

+95
-48
lines changed

vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ impl HintProcessorLogic for BuiltinHintProcessor {
188188
&mut self,
189189
vm: &mut VirtualMachine,
190190
exec_scopes: &mut ExecutionScopes,
191-
hint_data: &Box<dyn Any>,
191+
hint_data: &dyn Any,
192192
) -> Result<(), HintError> {
193193
let hint_data = hint_data
194194
.downcast_ref::<HintProcessorData>()

vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,7 @@ impl HintProcessorLogic for Cairo1HintProcessor {
12841284
//access current scope variables
12851285
exec_scopes: &mut ExecutionScopes,
12861286
//Data structure that can be downcasted to the structure generated by compile_hint
1287-
hint_data: &Box<dyn Any>,
1287+
hint_data: &dyn Any,
12881288
) -> Result<(), HintError> {
12891289
let hints: &Vec<Hint> = hint_data.downcast_ref().ok_or(HintError::WrongHintData)?;
12901290
for hint in hints {

vm/src/hint_processor/hint_processor_definition.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub trait HintProcessorLogic {
2626
vm: &mut VirtualMachine,
2727
exec_scopes: &mut ExecutionScopes,
2828
//Data structure that can be downcasted to the structure generated by compile_hint
29-
hint_data: &Box<dyn Any>,
29+
hint_data: &dyn Any,
3030
) -> Result<(), HintError>;
3131

3232
//Transforms hint data outputed by the VM into whichever format will be later used by execute_hint
@@ -62,7 +62,7 @@ pub trait HintProcessorLogic {
6262
vm: &mut VirtualMachine,
6363
exec_scopes: &mut ExecutionScopes,
6464
//Data structure that can be downcasted to the structure generated by compile_hint
65-
hint_data: &Box<dyn Any>,
65+
hint_data: &dyn Any,
6666
) -> Result<HintExtension, HintError> {
6767
self.execute_hint(vm, exec_scopes, hint_data)?;
6868
Ok(HintExtension::default())
@@ -71,7 +71,7 @@ pub trait HintProcessorLogic {
7171

7272
// A map of hints that can be used to extend the current map of hints for the vm run
7373
// The map matches the pc at which the hints should be executed to a vec of compiled hints (Outputed by HintProcessor::CompileHint)
74-
pub type HintExtension = HashMap<Relocatable, Vec<Box<dyn Any>>>;
74+
pub type HintExtension = HashMap<Relocatable, Vec<Rc<dyn Any>>>;
7575

7676
pub trait HintProcessor: HintProcessorLogic + ResourceTracker {}
7777
impl<T> HintProcessor for T where T: HintProcessorLogic + ResourceTracker {}

vm/src/tests/run_deprecated_contract_class_simplified.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ impl HintProcessorLogic for SimplifiedOsHintProcessor {
7979
_vm: &mut crate::vm::vm_core::VirtualMachine,
8080
_exec_scopes: &mut crate::types::exec_scope::ExecutionScopes,
8181
//Data structure that can be downcasted to the structure generated by compile_hint
82-
_hint_data: &Box<dyn core::any::Any>,
82+
_hint_data: &dyn core::any::Any,
8383
) -> Result<(), crate::vm::errors::hint_errors::HintError> {
8484
// Empty impl as we are using `execute_hint_extensive` instead for this case
8585
Ok(())
@@ -90,7 +90,7 @@ impl HintProcessorLogic for SimplifiedOsHintProcessor {
9090
vm: &mut crate::vm::vm_core::VirtualMachine,
9191
exec_scopes: &mut crate::types::exec_scope::ExecutionScopes,
9292
//Data structure that can be downcasted to the structure generated by compile_hint
93-
hint_data: &Box<dyn core::any::Any>,
93+
hint_data: &dyn core::any::Any,
9494
) -> Result<
9595
crate::hint_processor::hint_processor_definition::HintExtension,
9696
crate::vm::errors::hint_errors::HintError,
@@ -291,13 +291,15 @@ pub fn vm_load_program(
291291
let reference_ids = HashMap::default();
292292
let references = vec![];
293293
// Compile the hint
294-
let compiled_hint = hint_processor.compile_hint(
295-
hint_code,
296-
&hint_ap_tracking_data,
297-
&reference_ids,
298-
&references,
299-
Default::default(),
300-
)?;
294+
let compiled_hint = hint_processor
295+
.compile_hint(
296+
hint_code,
297+
&hint_ap_tracking_data,
298+
&reference_ids,
299+
&references,
300+
Default::default(),
301+
)?
302+
.into();
301303
// Create the hint extension
302304
// As the hint from the compiled constract has offset 0, the hint pc will be equal to the loaded contract's program base:
303305
// This ptr can be found at ids.compiled_class.bytecode_ptr

vm/src/vm/hooks.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//! - pre_step_instruction, executed before each instruction_step in [step](VirtualMachine::step)
1010
//! - post_step_instruction, executed after each instruction_step in [step](VirtualMachine::step)
1111
12-
use crate::stdlib::{any::Any, collections::HashMap, prelude::*, sync::Arc};
12+
use crate::stdlib::{any::Any, collections::HashMap, prelude::*, rc::Rc, sync::Arc};
1313

1414
use crate::Felt252;
1515

@@ -20,15 +20,15 @@ use crate::{
2020
use super::{errors::vm_errors::VirtualMachineError, vm_core::VirtualMachine};
2121

2222
type BeforeFirstStepHookFunc = Arc<
23-
dyn Fn(&mut VirtualMachine, &[Box<dyn Any>]) -> Result<(), VirtualMachineError> + Sync + Send,
23+
dyn Fn(&mut VirtualMachine, &[Rc<dyn Any>]) -> Result<(), VirtualMachineError> + Sync + Send,
2424
>;
2525

2626
type StepHookFunc = Arc<
2727
dyn Fn(
2828
&mut VirtualMachine,
2929
&mut dyn HintProcessor,
3030
&mut ExecutionScopes,
31-
&[Box<dyn Any>],
31+
&[Rc<dyn Any>],
3232
&HashMap<String, Felt252>,
3333
) -> Result<(), VirtualMachineError>
3434
+ Sync
@@ -62,7 +62,7 @@ impl Hooks {
6262
impl VirtualMachine {
6363
pub fn execute_before_first_step(
6464
&mut self,
65-
hint_data: &[Box<dyn Any>],
65+
hint_data: &[Rc<dyn Any>],
6666
) -> Result<(), VirtualMachineError> {
6767
if let Some(hook_func) = self.hooks.clone().before_first_step {
6868
(hook_func)(self, hint_data)?;
@@ -75,7 +75,7 @@ impl VirtualMachine {
7575
&mut self,
7676
hint_executor: &mut dyn HintProcessor,
7777
exec_scope: &mut ExecutionScopes,
78-
hint_data: &[Box<dyn Any>],
78+
hint_data: &[Rc<dyn Any>],
7979
constants: &HashMap<String, Felt252>,
8080
) -> Result<(), VirtualMachineError> {
8181
if let Some(hook_func) = self.hooks.clone().pre_step_instruction {
@@ -89,7 +89,7 @@ impl VirtualMachine {
8989
&mut self,
9090
hint_executor: &mut dyn HintProcessor,
9191
exec_scope: &mut ExecutionScopes,
92-
hint_data: &[Box<dyn Any>],
92+
hint_data: &[Rc<dyn Any>],
9393
constants: &HashMap<String, Felt252>,
9494
) -> Result<(), VirtualMachineError> {
9595
if let Some(hook_func) = self.hooks.clone().post_step_instruction {
@@ -133,7 +133,7 @@ mod tests {
133133

134134
fn before_first_step_hook(
135135
_vm: &mut VirtualMachine,
136-
_hint_data: &[Box<dyn Any>],
136+
_hint_data: &[Rc<dyn Any>],
137137
) -> Result<(), VirtualMachineError> {
138138
Err(VirtualMachineError::Unexpected)
139139
}
@@ -142,7 +142,7 @@ mod tests {
142142
_vm: &mut VirtualMachine,
143143
_hint_processor: &mut dyn HintProcessor,
144144
_exec_scope: &mut ExecutionScopes,
145-
_hint_data: &[Box<dyn Any>],
145+
_hint_data: &[Rc<dyn Any>],
146146
_constants: &HashMap<String, Felt252>,
147147
) -> Result<(), VirtualMachineError> {
148148
Err(VirtualMachineError::Unexpected)
@@ -152,7 +152,7 @@ mod tests {
152152
_vm: &mut VirtualMachine,
153153
_hint_processor: &mut dyn HintProcessor,
154154
_exec_scope: &mut ExecutionScopes,
155-
_hint_data: &[Box<dyn Any>],
155+
_hint_data: &[Rc<dyn Any>],
156156
_constants: &HashMap<String, Felt252>,
157157
) -> Result<(), VirtualMachineError> {
158158
Err(VirtualMachineError::Unexpected)
@@ -193,7 +193,7 @@ mod tests {
193193

194194
fn before_first_step_hook(
195195
_vm: &mut VirtualMachine,
196-
_hint_data: &[Box<dyn Any>],
196+
_hint_data: &[Rc<dyn Any>],
197197
) -> Result<(), VirtualMachineError> {
198198
Ok(())
199199
}
@@ -202,7 +202,7 @@ mod tests {
202202
_vm: &mut VirtualMachine,
203203
_hint_processor: &mut dyn HintProcessor,
204204
_exec_scope: &mut ExecutionScopes,
205-
_hint_data: &[Box<dyn Any>],
205+
_hint_data: &[Rc<dyn Any>],
206206
_constants: &HashMap<String, Felt252>,
207207
) -> Result<(), VirtualMachineError> {
208208
Ok(())
@@ -212,7 +212,7 @@ mod tests {
212212
_vm: &mut VirtualMachine,
213213
_hint_processor: &mut dyn HintProcessor,
214214
_exec_scope: &mut ExecutionScopes,
215-
_hint_data: &[Box<dyn Any>],
215+
_hint_data: &[Rc<dyn Any>],
216216
_constants: &HashMap<String, Felt252>,
217217
) -> Result<(), VirtualMachineError> {
218218
Ok(())

vm/src/vm/runners/cairo_runner.rs

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ impl ResourceTracker for RunResources {
144144

145145
#[derive(Clone)]
146146
pub struct CairoRunnerBuilder {
147-
program: Program,
147+
pub program: Program,
148148
layout: CairoLayout,
149149
runner_mode: RunnerMode,
150150
// Flags.
@@ -162,7 +162,7 @@ pub struct CairoRunnerBuilder {
162162
// Set after loading instruction cache.
163163
// instructions: Vec<Option<Instruction>>,
164164
// Set after compiling hints.
165-
// hints: Vec<Rc<dyn Any>>,
165+
hints: Option<Vec<Rc<dyn Any>>>,
166166
}
167167

168168
impl CairoRunnerBuilder {
@@ -203,6 +203,7 @@ impl CairoRunnerBuilder {
203203
execution_base: None,
204204
memory: MemorySegmentManager::new(),
205205
loaded_program: false,
206+
hints: None,
206207
})
207208
}
208209

@@ -221,7 +222,7 @@ impl CairoRunnerBuilder {
221222
|| self.runner_mode == RunnerMode::ProofModeCairo1
222223
}
223224

224-
fn add_memory_segment(&mut self) -> Relocatable {
225+
pub fn add_memory_segment(&mut self) -> Relocatable {
225226
self.memory.add()
226227
}
227228

@@ -352,9 +353,12 @@ impl CairoRunnerBuilder {
352353
Ok(())
353354
}
354355

355-
pub fn initialize_segments(&mut self) {
356+
pub fn initialize_base_segments(&mut self) {
356357
self.program_base = Some(self.add_memory_segment());
357358
self.execution_base = Some(self.add_memory_segment());
359+
}
360+
361+
pub fn initialize_builtin_segments(&mut self) {
358362
for builtin_runner in self.builtin_runners.iter_mut() {
359363
builtin_runner.initialize_segments(&mut self.memory);
360364
}
@@ -372,6 +376,35 @@ impl CairoRunnerBuilder {
372376
Ok(())
373377
}
374378

379+
pub fn compile_hints(
380+
&mut self,
381+
hint_processor: &mut dyn HintProcessor,
382+
) -> Result<(), VirtualMachineError> {
383+
let constants = Rc::new(self.program.constants.clone());
384+
let references = &self.program.shared_program_data.reference_manager;
385+
let compiled_hints = self
386+
.program
387+
.shared_program_data
388+
.hints_collection
389+
.iter_hints()
390+
.map(|hint| {
391+
hint_processor
392+
.compile_hint(
393+
&hint.code,
394+
&hint.flow_tracking_data.ap_tracking,
395+
&hint.flow_tracking_data.reference_ids,
396+
references,
397+
constants.clone(),
398+
)
399+
.map_err(|_| VirtualMachineError::CompileHintFail(hint.code.clone().into()))
400+
.map(Into::into)
401+
})
402+
.collect::<Result<Vec<Rc<dyn Any>>, VirtualMachineError>>()?;
403+
404+
self.hints = Some(compiled_hints);
405+
Ok(())
406+
}
407+
375408
pub fn build(self) -> Result<CairoRunner, RunnerError> {
376409
let mut vm = VirtualMachine::new(self.enable_trace, self.disable_trace_padding);
377410

@@ -401,6 +434,7 @@ impl CairoRunnerBuilder {
401434
relocated_trace: None,
402435
program: self.program,
403436
loaded_program: self.loaded_program,
437+
hints: self.hints,
404438
})
405439
}
406440
}
@@ -424,6 +458,7 @@ pub struct CairoRunner {
424458
pub exec_scopes: ExecutionScopes,
425459
pub relocated_trace: Option<Vec<RelocatedTraceEntry>>,
426460
loaded_program: bool,
461+
hints: Option<Vec<Rc<dyn Any>>>,
427462
}
428463

429464
#[derive(Clone, Debug, PartialEq)]
@@ -486,6 +521,7 @@ impl CairoRunner {
486521
},
487522
relocated_trace: None,
488523
loaded_program: false,
524+
hints: None,
489525
})
490526
}
491527

@@ -912,7 +948,7 @@ impl CairoRunner {
912948
&self,
913949
references: &[HintReference],
914950
hint_executor: &mut dyn HintProcessor,
915-
) -> Result<Vec<Box<dyn Any>>, VirtualMachineError> {
951+
) -> Result<Vec<Rc<dyn Any>>, VirtualMachineError> {
916952
let constants = Rc::new(self.program.constants.clone());
917953

918954
self.program
@@ -929,6 +965,7 @@ impl CairoRunner {
929965
constants.clone(),
930966
)
931967
.map_err(|_| VirtualMachineError::CompileHintFail(hint.code.clone().into()))
968+
.map(Into::into)
932969
})
933970
.collect()
934971
}
@@ -947,10 +984,12 @@ impl CairoRunner {
947984
hint_processor: &mut dyn HintProcessor,
948985
) -> Result<(), VirtualMachineError> {
949986
let references = &self.program.shared_program_data.reference_manager;
950-
#[cfg(not(feature = "extensive_hints"))]
951-
let hint_data = self.get_hint_data(references, hint_processor)?;
952-
#[cfg(feature = "extensive_hints")]
953-
let mut hint_data = self.get_hint_data(references, hint_processor)?;
987+
#[cfg_attr(not(feature = "extensive_hints"), allow(unused_mut))]
988+
let mut hint_data = if let Some(hint_data) = &self.hints {
989+
hint_data.clone()
990+
} else {
991+
self.get_hint_data(references, hint_processor)?
992+
};
954993
#[cfg(feature = "extensive_hints")]
955994
let mut hint_ranges = self
956995
.program
@@ -998,10 +1037,12 @@ impl CairoRunner {
9981037
hint_processor: &mut dyn HintProcessor,
9991038
) -> Result<(), VirtualMachineError> {
10001039
let references = &self.program.shared_program_data.reference_manager;
1001-
#[cfg(not(feature = "extensive_hints"))]
1002-
let hint_data = self.get_hint_data(references, hint_processor)?;
1003-
#[cfg(feature = "extensive_hints")]
1004-
let mut hint_data = self.get_hint_data(references, hint_processor)?;
1040+
#[cfg_attr(not(feature = "extensive_hints"), allow(unused_mut))]
1041+
let mut hint_data = if let Some(hint_data) = &self.hints {
1042+
hint_data.clone()
1043+
} else {
1044+
self.get_hint_data(references, hint_processor)?
1045+
};
10051046
#[cfg(feature = "extensive_hints")]
10061047
let mut hint_ranges = self
10071048
.program

0 commit comments

Comments
 (0)