1#[derive(Debug, Clone)]
8#[non_exhaustive]
9pub struct MemoryBudget {
10 pub device_bytes: u64,
12 pub allow_ooc: bool,
14 pub abort_on_exceed: bool,
16}
17
18impl Default for MemoryBudget {
19 fn default() -> Self {
20 Self {
21 device_bytes: 0, allow_ooc: false,
23 abort_on_exceed: true,
24 }
25 }
26}
27
28impl MemoryBudget {
29 pub fn from_device_memory(total_bytes: u64) -> Self {
31 Self {
32 device_bytes: (total_bytes as f64 * 0.8) as u64,
33 allow_ooc: false,
34 abort_on_exceed: true,
35 }
36 }
37
38 pub fn with_limit(device_bytes: u64) -> Self {
40 Self {
41 device_bytes,
42 allow_ooc: false,
43 abort_on_exceed: true,
44 }
45 }
46
47 pub fn with_ooc(mut self) -> Self {
49 self.allow_ooc = true;
50 self
51 }
52}
53
54#[derive(Debug, Clone)]
58pub struct RuntimeConfig {
59 pub memory: MemoryBudget,
61 pub deterministic: bool,
63 pub profile: bool,
65 pub max_iterations: u32,
67}
68
69impl Default for RuntimeConfig {
70 fn default() -> Self {
71 Self {
72 memory: MemoryBudget::default(),
73 deterministic: true,
74 profile: false,
75 max_iterations: 1_000_000,
76 }
77 }
78}
79
80impl RuntimeConfig {
81 pub fn with_profiling(mut self) -> Self {
83 self.profile = true;
84 self
85 }
86
87 pub fn with_memory(mut self, memory: MemoryBudget) -> Self {
89 self.memory = memory;
90 self
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn test_memory_budget_default() {
100 let budget = MemoryBudget::default();
101 assert!(!budget.allow_ooc);
102 assert!(budget.abort_on_exceed);
103 }
104
105 #[test]
106 fn test_runtime_config_default() {
107 let config = RuntimeConfig::default();
108 assert!(config.deterministic);
109 assert!(!config.profile);
110 }
111
112 #[test]
113 fn test_memory_budget_from_device() {
114 let budget = MemoryBudget::from_device_memory(10_000_000_000);
115 assert_eq!(budget.device_bytes, 8_000_000_000);
116 }
117}