quantrs2_device/job_scheduling/
impls_util.rs1#[cfg(not(feature = "scirs2"))]
6use super::fallback_scirs2::*;
7use super::types::*;
8use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
9use std::sync::{Arc, Mutex, RwLock};
10use std::time::{Duration, SystemTime};
11
12impl Clone for QuantumJobScheduler {
13 fn clone(&self) -> Self {
14 Self {
15 params: Arc::clone(&self.params),
16 job_queues: Arc::clone(&self.job_queues),
17 jobs: Arc::clone(&self.jobs),
18 backend_performance: Arc::clone(&self.backend_performance),
19 backends: Arc::clone(&self.backends),
20 running_jobs: Arc::clone(&self.running_jobs),
21 execution_history: Arc::clone(&self.execution_history),
22 user_shares: Arc::clone(&self.user_shares),
23 scheduler_running: Arc::clone(&self.scheduler_running),
24 event_sender: self.event_sender.clone(),
25 performance_predictor: Arc::clone(&self.performance_predictor),
26 resource_manager: Arc::clone(&self.resource_manager),
27 job_status_map: Arc::clone(&self.job_status_map),
28 job_config_map: Arc::clone(&self.job_config_map),
29 job_metrics_map: Arc::clone(&self.job_metrics_map),
30 }
31 }
32}
33impl PerformancePredictor {
34 pub(crate) fn new() -> Self {
35 Self {
36 history: VecDeque::new(),
37 model_params: HashMap::new(),
38 accuracy_metrics: HashMap::new(),
39 }
40 }
41}
42impl ResourceManager {
43 pub(crate) fn new() -> Self {
44 Self {
45 available_resources: HashMap::new(),
46 reservations: HashMap::new(),
47 utilization_history: VecDeque::new(),
48 }
49 }
50}
51pub fn create_high_priority_config(max_execution_time: Duration) -> JobConfig {
53 JobConfig {
54 priority: JobPriority::High,
55 max_execution_time,
56 retry_attempts: 5,
57 ..Default::default()
58 }
59}
60pub fn create_batch_job_config() -> JobConfig {
62 JobConfig {
63 priority: JobPriority::BestEffort,
64 max_execution_time: Duration::from_secs(3600 * 24),
65 max_queue_time: None,
66 retry_attempts: 1,
67 ..Default::default()
68 }
69}
70pub fn create_realtime_config() -> JobConfig {
72 JobConfig {
73 priority: JobPriority::Critical,
74 max_execution_time: Duration::from_secs(60),
75 max_queue_time: Some(Duration::from_secs(30)),
76 retry_attempts: 0,
77 ..Default::default()
78 }
79}
80pub fn create_sla_aware_config(tier: SLATier) -> JobConfig {
82 let (priority, max_execution_time, max_queue_time, retry_attempts) = match tier {
83 SLATier::Gold => (
84 JobPriority::Critical,
85 Duration::from_secs(300),
86 Some(Duration::from_secs(60)),
87 5,
88 ),
89 SLATier::Silver => (
90 JobPriority::High,
91 Duration::from_secs(600),
92 Some(Duration::from_secs(300)),
93 3,
94 ),
95 SLATier::Bronze => (
96 JobPriority::Normal,
97 Duration::from_secs(1800),
98 Some(Duration::from_secs(900)),
99 2,
100 ),
101 SLATier::Basic => (
102 JobPriority::Low,
103 Duration::from_secs(3600),
104 Some(Duration::from_secs(1800)),
105 1,
106 ),
107 };
108 JobConfig {
109 priority,
110 max_execution_time,
111 max_queue_time,
112 retry_attempts,
113 ..Default::default()
114 }
115}
116pub fn create_cost_optimized_config(budget_limit: f64) -> JobConfig {
118 JobConfig {
119 priority: JobPriority::BestEffort,
120 max_execution_time: Duration::from_secs(7200),
121 max_queue_time: None,
122 retry_attempts: 1,
123 cost_limit: Some(budget_limit),
124 preferred_backends: vec![],
125 ..Default::default()
126 }
127}
128pub fn create_energy_efficient_config() -> JobConfig {
130 JobConfig {
131 priority: JobPriority::Low,
132 max_execution_time: Duration::from_secs(3600),
133 max_queue_time: None,
134 retry_attempts: 2,
135 tags: std::iter::once(("energy_profile".to_string(), "green".to_string())).collect(),
136 ..Default::default()
137 }
138}
139pub fn create_research_config() -> JobConfig {
141 JobConfig {
142 priority: JobPriority::Normal,
143 max_execution_time: Duration::from_secs(14400),
144 max_queue_time: Some(Duration::from_secs(7200)),
145 retry_attempts: 3,
146 tags: [
147 ("workload_type".to_string(), "research".to_string()),
148 ("fault_tolerance".to_string(), "high".to_string()),
149 ]
150 .into_iter()
151 .collect(),
152 ..Default::default()
153 }
154}
155pub fn create_deadline_config(deadline: SystemTime) -> JobConfig {
157 JobConfig {
158 priority: JobPriority::High,
159 max_execution_time: Duration::from_secs(1800),
160 max_queue_time: Some(Duration::from_secs(300)),
161 retry_attempts: 2,
162 deadline: Some(deadline),
163 tags: std::iter::once((
164 "scheduling_type".to_string(),
165 "deadline_sensitive".to_string(),
166 ))
167 .collect(),
168 ..Default::default()
169 }
170}
171pub fn create_ml_training_config() -> JobConfig {
173 JobConfig {
174 priority: JobPriority::Normal,
175 max_execution_time: Duration::from_secs(21600),
176 max_queue_time: Some(Duration::from_secs(3600)),
177 retry_attempts: 2,
178 resource_requirements: ResourceRequirements {
179 min_qubits: 20,
180 max_depth: Some(1000),
181 min_fidelity: Some(0.95),
182 memory_mb: Some(16384),
183 cpu_cores: Some(8),
184 required_features: vec![
185 "variational_circuits".to_string(),
186 "parametric_gates".to_string(),
187 ],
188 ..Default::default()
189 },
190 tags: [
191 ("workload_type".to_string(), "machine_learning".to_string()),
192 ("resource_intensive".to_string(), "true".to_string()),
193 ]
194 .into_iter()
195 .collect(),
196 ..Default::default()
197 }
198}
199pub fn create_optimization_config() -> JobConfig {
201 JobConfig {
202 priority: JobPriority::Normal,
203 max_execution_time: Duration::from_secs(10800),
204 max_queue_time: Some(Duration::from_secs(1800)),
205 retry_attempts: 3,
206 resource_requirements: ResourceRequirements {
207 min_qubits: 10,
208 max_depth: Some(500),
209 min_fidelity: Some(0.90),
210 required_features: vec!["qaoa".to_string(), "variational_algorithms".to_string()],
211 ..Default::default()
212 },
213 tags: [
214 ("workload_type".to_string(), "optimization".to_string()),
215 ("algorithm_type".to_string(), "variational".to_string()),
216 ]
217 .into_iter()
218 .collect(),
219 ..Default::default()
220 }
221}
222pub fn create_simulation_config(qubit_count: usize) -> JobConfig {
224 let (max_execution_time, memory_requirement) = match qubit_count {
225 1..=20 => (Duration::from_secs(3600), 4096),
226 21..=30 => (Duration::from_secs(7200), 8192),
227 31..=40 => (Duration::from_secs(14400), 16384),
228 _ => (Duration::from_secs(28800), 32768),
229 };
230 JobConfig {
231 priority: JobPriority::Low,
232 max_execution_time,
233 max_queue_time: None,
234 retry_attempts: 1,
235 resource_requirements: ResourceRequirements {
236 min_qubits: qubit_count,
237 memory_mb: Some(memory_requirement),
238 cpu_cores: Some(16),
239 required_features: vec!["high_precision".to_string(), "large_circuits".to_string()],
240 ..Default::default()
241 },
242 tags: [
243 ("workload_type".to_string(), "simulation".to_string()),
244 ("qubit_count".to_string(), qubit_count.to_string()),
245 ]
246 .into_iter()
247 .collect(),
248 ..Default::default()
249 }
250}
251#[cfg(test)]
252mod tests {
253 use super::*;
254 use quantrs2_circuit::prelude::CircuitBuilder;
255 #[tokio::test]
256 async fn test_job_scheduler_creation() {
257 let params = SchedulingParams::default();
258 let scheduler = QuantumJobScheduler::new(params);
259 assert!(!*scheduler
260 .scheduler_running
261 .lock()
262 .expect("Failed to acquire lock on scheduler_running in test"));
263 }
264 #[tokio::test]
265 async fn test_job_config_validation() {
266 let config = JobConfig::default();
267 assert_eq!(config.priority, JobPriority::Normal);
268 assert_eq!(config.retry_attempts, 3);
269 assert!(config.dependencies.is_empty());
270 }
271 #[tokio::test]
272 async fn test_priority_ordering() {
273 assert!(JobPriority::Critical < JobPriority::High);
274 assert!(JobPriority::High < JobPriority::Normal);
275 assert!(JobPriority::Normal < JobPriority::Low);
276 assert!(JobPriority::Low < JobPriority::BestEffort);
277 }
278 #[test]
279 fn test_job_id_creation() {
280 let id1 = JobId::new();
281 let id2 = JobId::new();
282 assert_ne!(id1, id2);
283 assert!(!id1.0.is_empty());
284 }
285 #[test]
286 fn test_convenience_configs() {
287 let high_priority = create_high_priority_config(Duration::from_secs(300));
288 assert_eq!(high_priority.priority, JobPriority::High);
289 assert_eq!(high_priority.retry_attempts, 5);
290 let batch = create_batch_job_config();
291 assert_eq!(batch.priority, JobPriority::BestEffort);
292 assert!(batch.max_queue_time.is_none());
293 let realtime = create_realtime_config();
294 assert_eq!(realtime.priority, JobPriority::Critical);
295 assert_eq!(realtime.retry_attempts, 0);
296 }
297}