miden_processor/
execution_options.rs1use miden_air::trace::MIN_TRACE_LEN;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct ExecutionOptions {
12 max_cycles: u32,
13 expected_cycles: u32,
14 core_trace_fragment_size: usize,
15 enable_tracing: bool,
16 enable_debugging: bool,
17}
18
19impl Default for ExecutionOptions {
20 fn default() -> Self {
21 ExecutionOptions {
22 max_cycles: Self::MAX_CYCLES,
23 expected_cycles: MIN_TRACE_LEN as u32,
24 core_trace_fragment_size: Self::DEFAULT_CORE_TRACE_FRAGMENT_SIZE,
25 enable_tracing: false,
26 enable_debugging: false,
27 }
28 }
29}
30
31impl ExecutionOptions {
32 pub const MAX_CYCLES: u32 = 1 << 29;
37
38 pub const DEFAULT_CORE_TRACE_FRAGMENT_SIZE: usize = 4096; pub fn new(
54 max_cycles: Option<u32>,
55 expected_cycles: u32,
56 core_trace_fragment_size: usize,
57 enable_tracing: bool,
58 enable_debugging: bool,
59 ) -> Result<Self, ExecutionOptionsError> {
60 let max_cycles = if let Some(max_cycles) = max_cycles {
62 if max_cycles > Self::MAX_CYCLES {
63 return Err(ExecutionOptionsError::MaxCycleNumTooBig {
64 max_cycles,
65 max_cycles_limit: Self::MAX_CYCLES,
66 });
67 }
68 if max_cycles < MIN_TRACE_LEN as u32 {
69 return Err(ExecutionOptionsError::MaxCycleNumTooSmall {
70 max_cycles,
71 min_cycles_limit: MIN_TRACE_LEN,
72 });
73 }
74 max_cycles
75 } else {
76 Self::MAX_CYCLES
77 };
78 if max_cycles < expected_cycles {
80 return Err(ExecutionOptionsError::ExpectedCyclesTooBig {
81 max_cycles,
82 expected_cycles,
83 });
84 }
85 let expected_cycles = expected_cycles.next_power_of_two().max(MIN_TRACE_LEN as u32);
88
89 if core_trace_fragment_size == 0 {
91 return Err(ExecutionOptionsError::CoreTraceFragmentSizeTooSmall);
92 }
93
94 Ok(ExecutionOptions {
95 max_cycles,
96 expected_cycles,
97 core_trace_fragment_size,
98 enable_tracing,
99 enable_debugging,
100 })
101 }
102
103 pub fn with_core_trace_fragment_size(
107 mut self,
108 size: usize,
109 ) -> Result<Self, ExecutionOptionsError> {
110 if size == 0 {
111 return Err(ExecutionOptionsError::CoreTraceFragmentSizeTooSmall);
112 }
113 self.core_trace_fragment_size = size;
114 Ok(self)
115 }
116
117 pub fn with_tracing(mut self, enable_tracing: bool) -> Self {
119 self.enable_tracing = enable_tracing;
120 self
121 }
122
123 pub fn with_debugging(mut self, enable_debugging: bool) -> Self {
131 self.enable_debugging = enable_debugging;
132 self
133 }
134
135 #[inline(always)]
140 pub fn max_cycles(&self) -> u32 {
141 self.max_cycles
142 }
143
144 pub fn expected_cycles(&self) -> u32 {
150 self.expected_cycles
151 }
152
153 pub fn core_trace_fragment_size(&self) -> usize {
155 self.core_trace_fragment_size
156 }
157
158 #[inline]
160 pub fn enable_tracing(&self) -> bool {
161 self.enable_tracing
162 }
163
164 #[inline]
166 pub fn enable_debugging(&self) -> bool {
167 self.enable_debugging
168 }
169}
170
171#[derive(Debug, thiserror::Error)]
175pub enum ExecutionOptionsError {
176 #[error(
177 "expected number of cycles {expected_cycles} must be smaller than the maximum number of cycles {max_cycles}"
178 )]
179 ExpectedCyclesTooBig { max_cycles: u32, expected_cycles: u32 },
180 #[error("maximum number of cycles {max_cycles} must be greater than {min_cycles_limit}")]
181 MaxCycleNumTooSmall { max_cycles: u32, min_cycles_limit: usize },
182 #[error("maximum number of cycles {max_cycles} must be less than {max_cycles_limit}")]
183 MaxCycleNumTooBig { max_cycles: u32, max_cycles_limit: u32 },
184 #[error("core trace fragment size must be greater than 0")]
185 CoreTraceFragmentSizeTooSmall,
186}
187
188#[cfg(test)]
192mod tests {
193 use super::*;
194
195 #[test]
196 fn valid_fragment_size() {
197 let opts = ExecutionOptions::new(None, 64, 1024, false, false);
199 assert!(opts.is_ok());
200 assert_eq!(opts.unwrap().core_trace_fragment_size(), 1024);
201
202 let opts = ExecutionOptions::new(None, 64, 4096, false, false);
203 assert!(opts.is_ok());
204
205 let opts = ExecutionOptions::new(None, 64, 1, false, false);
206 assert!(opts.is_ok());
207 }
208
209 #[test]
210 fn zero_fragment_size_fails() {
211 let opts = ExecutionOptions::new(None, 64, 0, false, false);
212 assert!(matches!(opts, Err(ExecutionOptionsError::CoreTraceFragmentSizeTooSmall)));
213 }
214
215 #[test]
216 fn with_core_trace_fragment_size_validates() {
217 let result = ExecutionOptions::default().with_core_trace_fragment_size(2048);
219 assert!(result.is_ok());
220 assert_eq!(result.unwrap().core_trace_fragment_size(), 2048);
221
222 let result = ExecutionOptions::default().with_core_trace_fragment_size(0);
224 assert!(matches!(result, Err(ExecutionOptionsError::CoreTraceFragmentSizeTooSmall)));
225 }
226}