quantrs2_anneal/
heterogeneous_hybrid_engine.rs

1//! Heterogeneous Quantum-Classical Hybrid Execution Engine
2//!
3//! This module implements a sophisticated hybrid execution engine that seamlessly
4//! coordinates between quantum annealing hardware, classical optimization algorithms,
5//! and hybrid approaches. It provides intelligent workload distribution, dynamic
6//! resource allocation, and adaptive execution strategies for optimal performance.
7//!
8//! Key Features:
9//! - Intelligent algorithm selection and routing
10//! - Dynamic workload distribution between quantum and classical resources
11//! - Adaptive execution strategies based on problem characteristics
12//! - Resource-aware scheduling and load balancing
13//! - Performance monitoring and optimization
14//! - Fault tolerance and fallback mechanisms
15//! - Cost optimization for cloud quantum services
16//! - Quality-aware result aggregation and consensus
17
18use scirs2_core::random::prelude::*;
19use std::collections::{HashMap, VecDeque};
20use std::sync::{Arc, Mutex, RwLock};
21use std::thread;
22use std::time::{Duration, Instant};
23
24use crate::applications::{ApplicationError, ApplicationResult};
25use crate::braket::{BraketClient, BraketDevice};
26use crate::dwave::DWaveClient;
27use crate::ising::{IsingModel, QuboModel};
28use crate::multi_chip_embedding::{MultiChipConfig, MultiChipCoordinator};
29use crate::simulator::{AnnealingParams, AnnealingResult, ClassicalAnnealingSimulator};
30use crate::HardwareTopology;
31
32/// Hybrid execution engine configuration
33#[derive(Debug, Clone)]
34pub struct HybridEngineConfig {
35    /// Maximum execution time
36    pub max_execution_time: Duration,
37    /// Quality threshold for solutions
38    pub quality_threshold: f64,
39    /// Cost budget for cloud services
40    pub cost_budget: Option<f64>,
41    /// Resource allocation strategy
42    pub allocation_strategy: ResourceAllocationStrategy,
43    /// Execution strategy
44    pub execution_strategy: ExecutionStrategy,
45    /// Performance optimization settings
46    pub optimization_settings: OptimizationSettings,
47    /// Fault tolerance configuration
48    pub fault_tolerance: HybridFaultToleranceConfig,
49    /// Monitoring configuration
50    pub monitoring: HybridMonitoringConfig,
51}
52
53impl Default for HybridEngineConfig {
54    fn default() -> Self {
55        Self {
56            max_execution_time: Duration::from_secs(300),
57            quality_threshold: 0.95,
58            cost_budget: Some(100.0),
59            allocation_strategy: ResourceAllocationStrategy::Adaptive,
60            execution_strategy: ExecutionStrategy::Parallel,
61            optimization_settings: OptimizationSettings::default(),
62            fault_tolerance: HybridFaultToleranceConfig::default(),
63            monitoring: HybridMonitoringConfig::default(),
64        }
65    }
66}
67
68/// Resource allocation strategies
69#[derive(Debug, Clone, PartialEq, Eq)]
70pub enum ResourceAllocationStrategy {
71    /// Pure quantum execution
72    QuantumOnly,
73    /// Pure classical execution
74    ClassicalOnly,
75    /// Static allocation based on problem size
76    Static,
77    /// Adaptive allocation based on performance
78    Adaptive,
79    /// Cost-optimized allocation
80    CostOptimized,
81    /// Quality-focused allocation
82    QualityFocused,
83}
84
85/// Execution strategies
86#[derive(Debug, Clone, PartialEq, Eq)]
87pub enum ExecutionStrategy {
88    /// Sequential execution (quantum then classical fallback)
89    Sequential,
90    /// Parallel execution on all available resources
91    Parallel,
92    /// Competitive execution (first good result wins)
93    Competitive,
94    /// Cooperative execution (combine results)
95    Cooperative,
96    /// Adaptive execution (strategy chosen based on problem characteristics)
97    Adaptive,
98    /// Hierarchical execution (coarse then fine-grained)
99    Hierarchical,
100}
101
102/// Performance optimization settings
103#[derive(Debug, Clone)]
104pub struct OptimizationSettings {
105    /// Enable intelligent algorithm selection
106    pub enable_algorithm_selection: bool,
107    /// Enable dynamic resource reallocation
108    pub enable_dynamic_reallocation: bool,
109    /// Enable result quality assessment
110    pub enable_quality_assessment: bool,
111    /// Enable cost optimization
112    pub enable_cost_optimization: bool,
113    /// Learning rate for adaptive strategies
114    pub learning_rate: f64,
115    /// History window for performance tracking
116    pub history_window: usize,
117}
118
119impl Default for OptimizationSettings {
120    fn default() -> Self {
121        Self {
122            enable_algorithm_selection: true,
123            enable_dynamic_reallocation: true,
124            enable_quality_assessment: true,
125            enable_cost_optimization: true,
126            learning_rate: 0.1,
127            history_window: 100,
128        }
129    }
130}
131
132/// Hybrid fault tolerance configuration
133#[derive(Debug, Clone)]
134pub struct HybridFaultToleranceConfig {
135    /// Enable automatic fallback to classical
136    pub enable_classical_fallback: bool,
137    /// Enable result validation
138    pub enable_result_validation: bool,
139    /// Maximum retries per resource type
140    pub max_retries_per_type: usize,
141    /// Timeout for individual executions
142    pub individual_timeout: Duration,
143    /// Minimum consensus threshold
144    pub consensus_threshold: f64,
145}
146
147impl Default for HybridFaultToleranceConfig {
148    fn default() -> Self {
149        Self {
150            enable_classical_fallback: true,
151            enable_result_validation: true,
152            max_retries_per_type: 3,
153            individual_timeout: Duration::from_secs(120),
154            consensus_threshold: 0.7,
155        }
156    }
157}
158
159/// Hybrid monitoring configuration
160#[derive(Debug, Clone)]
161pub struct HybridMonitoringConfig {
162    /// Enable performance tracking
163    pub enable_performance_tracking: bool,
164    /// Enable cost tracking
165    pub enable_cost_tracking: bool,
166    /// Enable quality tracking
167    pub enable_quality_tracking: bool,
168    /// Metrics collection interval
169    pub collection_interval: Duration,
170}
171
172impl Default for HybridMonitoringConfig {
173    fn default() -> Self {
174        Self {
175            enable_performance_tracking: true,
176            enable_cost_tracking: true,
177            enable_quality_tracking: true,
178            collection_interval: Duration::from_secs(5),
179        }
180    }
181}
182
183/// Compute resource types
184#[derive(Debug, Clone, PartialEq, Eq)]
185pub enum ResourceType {
186    /// D-Wave quantum annealer
187    DWaveQuantum,
188    /// AWS Braket quantum device
189    BraketQuantum,
190    /// Classical annealing simulator
191    ClassicalSimulator,
192    /// Multi-chip quantum system
193    MultiChipQuantum,
194    /// GPU-accelerated classical
195    GPUClassical,
196    /// Custom hybrid algorithm
197    CustomHybrid,
198}
199
200/// Compute resource representation
201#[derive(Debug, Clone)]
202pub struct ComputeResource {
203    /// Resource identifier
204    pub id: String,
205    /// Resource type
206    pub resource_type: ResourceType,
207    /// Current availability
208    pub availability: ResourceAvailability,
209    /// Performance characteristics
210    pub performance: ResourcePerformance,
211    /// Cost characteristics
212    pub cost: ResourceCost,
213    /// Current workload
214    pub workload: Option<ResourceWorkload>,
215    /// Connection to resource
216    pub connection: ResourceConnection,
217}
218
219/// Resource availability status
220#[derive(Debug, Clone, PartialEq, Eq)]
221pub enum ResourceAvailability {
222    /// Available for immediate use
223    Available,
224    /// Busy with current task
225    Busy,
226    /// Temporarily unavailable
227    Unavailable,
228    /// In maintenance mode
229    Maintenance,
230    /// Failed or error state
231    Failed,
232}
233
234/// Resource performance characteristics
235#[derive(Debug, Clone)]
236pub struct ResourcePerformance {
237    /// Processing speed (problems/second)
238    pub throughput: f64,
239    /// Average latency
240    pub latency: Duration,
241    /// Success rate (0.0-1.0)
242    pub success_rate: f64,
243    /// Solution quality score
244    pub quality_score: f64,
245    /// Problem size capability range
246    pub size_range: (usize, usize),
247    /// Performance history
248    pub history: VecDeque<PerformanceEntry>,
249}
250
251/// Performance history entry
252#[derive(Debug, Clone)]
253pub struct PerformanceEntry {
254    /// Timestamp
255    pub timestamp: Instant,
256    /// Problem size
257    pub problem_size: usize,
258    /// Execution time
259    pub execution_time: Duration,
260    /// Solution quality
261    pub solution_quality: f64,
262    /// Cost incurred
263    pub cost: f64,
264}
265
266/// Resource cost characteristics
267#[derive(Debug, Clone)]
268pub struct ResourceCost {
269    /// Fixed cost per use
270    pub fixed_cost: f64,
271    /// Variable cost per problem variable
272    pub variable_cost: f64,
273    /// Time-based cost per second
274    pub time_cost: f64,
275    /// Quality premium factor
276    pub quality_premium: f64,
277}
278
279/// Current resource workload
280#[derive(Debug, Clone)]
281pub struct ResourceWorkload {
282    /// Problem being processed
283    pub problem_id: String,
284    /// Problem size
285    pub problem_size: usize,
286    /// Start time
287    pub start_time: Instant,
288    /// Estimated completion
289    pub estimated_completion: Instant,
290    /// Current progress (0.0-1.0)
291    pub progress: f64,
292}
293
294/// Resource connection interface
295#[derive(Debug, Clone)]
296pub enum ResourceConnection {
297    /// D-Wave cloud connection
298    DWave(Arc<Mutex<DWaveClient>>),
299    /// AWS Braket connection
300    Braket(Arc<Mutex<BraketClient>>),
301    /// Classical simulator (local)
302    Classical(Arc<Mutex<ClassicalAnnealingSimulator>>),
303    /// Multi-chip coordinator
304    MultiChip(Arc<Mutex<MultiChipCoordinator>>),
305    /// Custom connection
306    Custom(String),
307}
308
309/// Execution task for the hybrid engine
310#[derive(Debug, Clone)]
311pub struct HybridExecutionTask {
312    /// Task identifier
313    pub id: String,
314    /// Problem to solve
315    pub problem: IsingModel,
316    /// Quality requirements
317    pub quality_requirements: QualityRequirements,
318    /// Resource constraints
319    pub resource_constraints: ResourceConstraints,
320    /// Execution priority
321    pub priority: TaskPriority,
322    /// Deadline (optional)
323    pub deadline: Option<Instant>,
324}
325
326/// Quality requirements for solutions
327#[derive(Debug, Clone)]
328pub struct QualityRequirements {
329    /// Minimum solution quality
330    pub min_quality: f64,
331    /// Target solution quality
332    pub target_quality: f64,
333    /// Quality assessment method
334    pub assessment_method: QualityAssessmentMethod,
335    /// Acceptable solution count
336    pub min_solutions: usize,
337}
338
339/// Quality assessment methods
340#[derive(Debug, Clone, PartialEq, Eq)]
341pub enum QualityAssessmentMethod {
342    /// Energy-based quality (lower energy = higher quality)
343    EnergyBased,
344    /// Statistical consensus
345    Consensus,
346    /// Ground truth comparison
347    GroundTruth,
348    /// Custom quality function
349    Custom(String),
350}
351
352/// Resource constraints for execution
353#[derive(Debug, Clone)]
354pub struct ResourceConstraints {
355    /// Maximum cost budget
356    pub max_cost: Option<f64>,
357    /// Maximum execution time
358    pub max_time: Duration,
359    /// Preferred resource types
360    pub preferred_resources: Vec<ResourceType>,
361    /// Excluded resource types
362    pub excluded_resources: Vec<ResourceType>,
363    /// Geographic constraints
364    pub geographic_constraints: Option<GeographicConstraints>,
365}
366
367/// Geographic constraints for resource selection
368#[derive(Debug, Clone)]
369pub struct GeographicConstraints {
370    /// Preferred regions
371    pub preferred_regions: Vec<String>,
372    /// Maximum latency tolerance
373    pub max_latency: Duration,
374    /// Data locality requirements
375    pub data_locality: bool,
376}
377
378/// Task execution priority
379#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
380pub enum TaskPriority {
381    Low = 1,
382    Medium = 2,
383    High = 3,
384    Critical = 4,
385}
386
387/// Hybrid execution result
388#[derive(Debug, Clone)]
389pub struct HybridExecutionResult {
390    /// Task identifier
391    pub task_id: String,
392    /// Best solution found
393    pub best_solution: Vec<i32>,
394    /// Best energy achieved
395    pub best_energy: f64,
396    /// Solution quality score
397    pub quality_score: f64,
398    /// Total execution time
399    pub total_time: Duration,
400    /// Total cost incurred
401    pub total_cost: f64,
402    /// Resource utilization
403    pub resource_utilization: HashMap<String, ResourceUtilization>,
404    /// Individual results from each resource
405    pub individual_results: Vec<IndividualResult>,
406    /// Execution metadata
407    pub metadata: ExecutionMetadata,
408}
409
410/// Resource utilization metrics
411#[derive(Debug, Clone)]
412pub struct ResourceUtilization {
413    /// Resource identifier
414    pub resource_id: String,
415    /// Time used
416    pub time_used: Duration,
417    /// Cost incurred
418    pub cost: f64,
419    /// Success indicator
420    pub success: bool,
421    /// Quality achieved
422    pub quality: f64,
423}
424
425/// Individual result from a resource
426#[derive(Debug, Clone)]
427pub struct IndividualResult {
428    /// Resource that produced this result
429    pub resource_id: String,
430    /// Solution vector
431    pub solution: Vec<i32>,
432    /// Energy achieved
433    pub energy: f64,
434    /// Quality score
435    pub quality: f64,
436    /// Execution time
437    pub execution_time: Duration,
438    /// Cost incurred
439    pub cost: f64,
440    /// Additional metadata
441    pub metadata: HashMap<String, String>,
442}
443
444/// Execution metadata
445#[derive(Debug, Clone)]
446pub struct ExecutionMetadata {
447    /// Execution strategy used
448    pub strategy: ExecutionStrategy,
449    /// Resources utilized
450    pub resources_used: Vec<String>,
451    /// Algorithm selection decisions
452    pub algorithm_decisions: Vec<String>,
453    /// Performance metrics
454    pub performance_metrics: HashMap<String, f64>,
455    /// Any warnings or issues
456    pub warnings: Vec<String>,
457}
458
459/// Main heterogeneous hybrid execution engine
460pub struct HeterogeneousHybridEngine {
461    /// Engine configuration
462    pub config: HybridEngineConfig,
463    /// Available compute resources
464    pub resources: Arc<RwLock<HashMap<String, ComputeResource>>>,
465    /// Task queue
466    pub task_queue: Arc<Mutex<VecDeque<HybridExecutionTask>>>,
467    /// Active executions
468    pub active_executions: Arc<RwLock<HashMap<String, ActiveExecution>>>,
469    /// Performance monitor
470    pub monitor: Arc<Mutex<HybridPerformanceMonitor>>,
471    /// Resource scheduler
472    pub scheduler: Arc<Mutex<ResourceScheduler>>,
473    /// Result aggregator
474    pub aggregator: Arc<Mutex<ResultAggregator>>,
475}
476
477/// Active execution tracking
478#[derive(Debug)]
479pub struct ActiveExecution {
480    /// Task being executed
481    pub task: HybridExecutionTask,
482    /// Start time
483    pub start_time: Instant,
484    /// Assigned resources
485    pub assigned_resources: Vec<String>,
486    /// Partial results
487    pub partial_results: Vec<IndividualResult>,
488    /// Current status
489    pub status: ExecutionStatus,
490}
491
492/// Execution status
493#[derive(Debug, Clone, PartialEq, Eq)]
494pub enum ExecutionStatus {
495    /// Queued for execution
496    Queued,
497    /// Currently executing
498    Running,
499    /// Completed successfully
500    Completed,
501    /// Failed with error
502    Failed,
503    /// Cancelled by user
504    Cancelled,
505    /// Timed out
506    TimedOut,
507}
508
509/// Performance monitoring for hybrid engine
510pub struct HybridPerformanceMonitor {
511    /// Overall system metrics
512    pub system_metrics: HybridSystemMetrics,
513    /// Per-resource metrics
514    pub resource_metrics: HashMap<String, ResourceMetrics>,
515    /// Historical performance data
516    pub performance_history: VecDeque<PerformanceSnapshot>,
517    /// Cost tracking
518    pub cost_tracking: CostTracker,
519}
520
521/// System-wide hybrid metrics
522#[derive(Debug, Clone)]
523pub struct HybridSystemMetrics {
524    /// Total tasks processed
525    pub total_tasks: usize,
526    /// Average task completion time
527    pub avg_completion_time: Duration,
528    /// Overall success rate
529    pub success_rate: f64,
530    /// Average solution quality
531    pub avg_quality: f64,
532    /// Total cost incurred
533    pub total_cost: f64,
534    /// Resource efficiency
535    pub resource_efficiency: f64,
536}
537
538/// Per-resource metrics
539#[derive(Debug, Clone)]
540pub struct ResourceMetrics {
541    /// Resource identifier
542    pub resource_id: String,
543    /// Tasks processed
544    pub tasks_processed: usize,
545    /// Success rate
546    pub success_rate: f64,
547    /// Average quality
548    pub avg_quality: f64,
549    /// Total cost
550    pub total_cost: f64,
551    /// Utilization rate
552    pub utilization_rate: f64,
553}
554
555/// Performance snapshot for historical tracking
556#[derive(Debug, Clone)]
557pub struct PerformanceSnapshot {
558    /// Timestamp
559    pub timestamp: Instant,
560    /// System metrics
561    pub system_metrics: HybridSystemMetrics,
562    /// Resource metrics
563    pub resource_metrics: HashMap<String, ResourceMetrics>,
564}
565
566/// Cost tracking system
567#[derive(Debug, Clone)]
568pub struct CostTracker {
569    /// Current budget
570    pub current_budget: f64,
571    /// Spent amount
572    pub spent_amount: f64,
573    /// Cost per resource type
574    pub cost_breakdown: HashMap<ResourceType, f64>,
575    /// Cost predictions
576    pub cost_predictions: HashMap<String, f64>,
577}
578
579/// Resource scheduling system
580pub struct ResourceScheduler {
581    /// Scheduling strategy
582    pub strategy: ResourceAllocationStrategy,
583    /// Resource availability cache
584    pub availability_cache: HashMap<String, Instant>,
585    /// Performance predictions
586    pub performance_predictions: HashMap<String, f64>,
587    /// Load balancing decisions
588    pub load_balancing: LoadBalancingDecisions,
589}
590
591/// Load balancing decisions
592#[derive(Debug, Clone)]
593pub struct LoadBalancingDecisions {
594    /// Recent decisions
595    pub recent_decisions: VecDeque<SchedulingDecision>,
596    /// Success rates per resource
597    pub resource_success_rates: HashMap<String, f64>,
598    /// Performance trends
599    pub performance_trends: HashMap<String, f64>,
600}
601
602/// Scheduling decision
603#[derive(Debug, Clone)]
604pub struct SchedulingDecision {
605    /// Decision timestamp
606    pub timestamp: Instant,
607    /// Task assigned
608    pub task_id: String,
609    /// Resource selected
610    pub resource_id: String,
611    /// Selection rationale
612    pub rationale: String,
613    /// Predicted outcome
614    pub predicted_performance: f64,
615}
616
617/// Result aggregation system
618pub struct ResultAggregator {
619    /// Aggregation strategy
620    pub strategy: ResultAggregationStrategy,
621    /// Quality assessment system
622    pub quality_assessor: QualityAssessor,
623    /// Consensus algorithm
624    pub consensus_algorithm: ConsensusAlgorithm,
625}
626
627/// Result aggregation strategies
628#[derive(Debug, Clone, PartialEq, Eq)]
629pub enum ResultAggregationStrategy {
630    /// Best result wins
631    BestResult,
632    /// Majority consensus
633    MajorityConsensus,
634    /// Weighted average
635    WeightedAverage,
636    /// Quality-based selection
637    QualityBased,
638    /// Ensemble combination
639    Ensemble,
640}
641
642/// Quality assessment system
643#[derive(Debug)]
644pub struct QualityAssessor {
645    /// Assessment methods
646    pub methods: Vec<QualityAssessmentMethod>,
647    /// Quality thresholds
648    pub thresholds: HashMap<QualityAssessmentMethod, f64>,
649    /// Historical quality data
650    pub quality_history: VecDeque<QualityMeasurement>,
651}
652
653/// Quality measurement
654#[derive(Debug, Clone)]
655pub struct QualityMeasurement {
656    /// Timestamp
657    pub timestamp: Instant,
658    /// Resource that produced result
659    pub resource_id: String,
660    /// Quality score
661    pub quality_score: f64,
662    /// Assessment method used
663    pub method: QualityAssessmentMethod,
664}
665
666/// Consensus algorithm for result aggregation
667#[derive(Debug)]
668pub struct ConsensusAlgorithm {
669    /// Consensus threshold
670    pub threshold: f64,
671    /// Voting weights per resource
672    pub voting_weights: HashMap<String, f64>,
673    /// Historical consensus data
674    pub consensus_history: VecDeque<ConsensusResult>,
675}
676
677/// Consensus result
678#[derive(Debug, Clone)]
679pub struct ConsensusResult {
680    /// Task identifier
681    pub task_id: String,
682    /// Consensus solution
683    pub consensus_solution: Vec<i32>,
684    /// Confidence level
685    pub confidence: f64,
686    /// Participating resources
687    pub participants: Vec<String>,
688    /// Agreement score
689    pub agreement_score: f64,
690}
691
692impl HeterogeneousHybridEngine {
693    /// Create new hybrid execution engine
694    #[must_use]
695    pub fn new(config: HybridEngineConfig) -> Self {
696        Self {
697            config,
698            resources: Arc::new(RwLock::new(HashMap::new())),
699            task_queue: Arc::new(Mutex::new(VecDeque::new())),
700            active_executions: Arc::new(RwLock::new(HashMap::new())),
701            monitor: Arc::new(Mutex::new(HybridPerformanceMonitor::new())),
702            scheduler: Arc::new(Mutex::new(ResourceScheduler::new())),
703            aggregator: Arc::new(Mutex::new(ResultAggregator::new())),
704        }
705    }
706
707    /// Register a compute resource
708    pub fn register_resource(&self, resource: ComputeResource) -> ApplicationResult<()> {
709        let resource_id = resource.id.clone();
710        let mut resources = self.resources.write().map_err(|_| {
711            ApplicationError::OptimizationError(
712                "Failed to acquire resource registry lock".to_string(),
713            )
714        })?;
715
716        resources.insert(resource_id.clone(), resource);
717
718        println!(
719            "Registered compute resource: {} ({:?})",
720            resource_id, resources[&resource_id].resource_type
721        );
722        Ok(())
723    }
724
725    /// Submit task for hybrid execution
726    pub fn submit_task(&self, task: HybridExecutionTask) -> ApplicationResult<String> {
727        let task_id = task.id.clone();
728        let mut queue = self.task_queue.lock().map_err(|_| {
729            ApplicationError::OptimizationError("Failed to acquire task queue lock".to_string())
730        })?;
731
732        queue.push_back(task);
733        println!("Task {task_id} submitted to hybrid execution queue");
734        Ok(task_id)
735    }
736
737    /// Execute task using hybrid approach
738    pub fn execute_task(&self, task_id: &str) -> ApplicationResult<HybridExecutionResult> {
739        println!("Starting hybrid execution for task: {task_id}");
740
741        // Step 1: Get task from queue
742        let task = self.get_task_from_queue(task_id)?;
743
744        // Step 2: Analyze problem and select strategy
745        let execution_plan = self.create_execution_plan(&task)?;
746
747        // Step 3: Schedule resources
748        let resource_assignments = self.schedule_resources(&task, &execution_plan)?;
749
750        // Step 4: Execute on assigned resources
751        let individual_results = self.execute_on_resources(&task, &resource_assignments)?;
752
753        // Step 5: Aggregate results
754        let final_result = self.aggregate_results(&task, individual_results)?;
755
756        // Step 6: Update performance metrics
757        self.update_performance_metrics(&task, &final_result)?;
758
759        println!("Hybrid execution completed for task: {task_id}");
760        Ok(final_result)
761    }
762
763    /// Get task from queue
764    fn get_task_from_queue(&self, task_id: &str) -> ApplicationResult<HybridExecutionTask> {
765        let mut queue = self.task_queue.lock().map_err(|_| {
766            ApplicationError::OptimizationError("Failed to acquire task queue lock".to_string())
767        })?;
768
769        // Find and remove task from queue
770        let task_index = queue
771            .iter()
772            .position(|task| task.id == task_id)
773            .ok_or_else(|| {
774                ApplicationError::InvalidConfiguration(format!("Task {task_id} not found in queue"))
775            })?;
776
777        // Safety: task_index was obtained from position() which found the task,
778        // so remove() will always succeed
779        Ok(queue
780            .remove(task_index)
781            .expect("Task index was just found via position()"))
782    }
783
784    /// Create execution plan for task
785    fn create_execution_plan(
786        &self,
787        task: &HybridExecutionTask,
788    ) -> ApplicationResult<ExecutionPlan> {
789        let problem_size = task.problem.num_qubits;
790        let quality_requirements = &task.quality_requirements;
791
792        // Analyze problem characteristics
793        let problem_complexity = self.analyze_problem_complexity(&task.problem)?;
794
795        // Select optimal execution strategy
796        let strategy = match (&self.config.execution_strategy, problem_complexity) {
797            (ExecutionStrategy::Adaptive, ProblemComplexity::Simple) => {
798                ExecutionStrategy::Sequential
799            }
800            (ExecutionStrategy::Adaptive, ProblemComplexity::Complex) => {
801                ExecutionStrategy::Parallel
802            }
803            (strategy, _) => strategy.clone(),
804        };
805
806        // Determine resource requirements
807        let resource_requirements = self.determine_resource_requirements(task)?;
808
809        Ok(ExecutionPlan {
810            strategy,
811            resource_requirements,
812            estimated_time: Duration::from_secs(60),
813            estimated_cost: 10.0,
814            quality_target: quality_requirements.target_quality,
815        })
816    }
817
818    /// Analyze problem complexity
819    fn analyze_problem_complexity(
820        &self,
821        problem: &IsingModel,
822    ) -> ApplicationResult<ProblemComplexity> {
823        let num_qubits = problem.num_qubits;
824        let density = self.calculate_coupling_density(problem);
825
826        if num_qubits < 100 && density < 0.1 {
827            Ok(ProblemComplexity::Simple)
828        } else if num_qubits < 1000 && density < 0.5 {
829            Ok(ProblemComplexity::Medium)
830        } else {
831            Ok(ProblemComplexity::Complex)
832        }
833    }
834
835    /// Calculate coupling density of problem
836    fn calculate_coupling_density(&self, problem: &IsingModel) -> f64 {
837        let total_possible = problem.num_qubits * (problem.num_qubits - 1) / 2;
838
839        let couplings = problem.couplings();
840        let actual_couplings = couplings
841            .iter()
842            .filter(|coupling| coupling.strength != 0.0)
843            .count();
844
845        if total_possible > 0 {
846            actual_couplings as f64 / total_possible as f64
847        } else {
848            0.0
849        }
850    }
851
852    /// Determine resource requirements
853    fn determine_resource_requirements(
854        &self,
855        task: &HybridExecutionTask,
856    ) -> ApplicationResult<ResourceRequirements> {
857        let problem_size = task.problem.num_qubits;
858
859        // Determine suitable resource types
860        let mut suitable_types = Vec::new();
861
862        if problem_size <= 5000 {
863            suitable_types.push(ResourceType::DWaveQuantum);
864        }
865        if problem_size <= 2000 {
866            suitable_types.push(ResourceType::BraketQuantum);
867        }
868        suitable_types.push(ResourceType::ClassicalSimulator);
869
870        if problem_size > 1000 {
871            suitable_types.push(ResourceType::MultiChipQuantum);
872        }
873
874        Ok(ResourceRequirements {
875            suitable_types,
876            min_resources: 1,
877            max_resources: 3,
878            performance_requirements: PerformanceRequirements {
879                min_throughput: 0.1,
880                max_latency: Duration::from_secs(120),
881                min_quality: task.quality_requirements.min_quality,
882            },
883        })
884    }
885
886    /// Schedule resources for execution
887    fn schedule_resources(
888        &self,
889        task: &HybridExecutionTask,
890        plan: &ExecutionPlan,
891    ) -> ApplicationResult<Vec<String>> {
892        let mut scheduler = self.scheduler.lock().map_err(|_| {
893            ApplicationError::OptimizationError("Failed to acquire scheduler lock".to_string())
894        })?;
895
896        let resources = self.resources.read().map_err(|_| {
897            ApplicationError::OptimizationError("Failed to read resource registry".to_string())
898        })?;
899
900        // Filter available resources
901        let available_resources: Vec<_> = resources
902            .values()
903            .filter(|resource| resource.availability == ResourceAvailability::Available)
904            .filter(|resource| {
905                plan.resource_requirements
906                    .suitable_types
907                    .contains(&resource.resource_type)
908            })
909            .collect();
910
911        if available_resources.is_empty() {
912            return Err(ApplicationError::ResourceLimitExceeded(
913                "No suitable resources available".to_string(),
914            ));
915        }
916
917        // Select resources based on strategy
918        let selected = match self.config.allocation_strategy {
919            ResourceAllocationStrategy::Adaptive => {
920                self.select_adaptive_resources(&available_resources, task)?
921            }
922            ResourceAllocationStrategy::CostOptimized => {
923                self.select_cost_optimized_resources(&available_resources, task)?
924            }
925            ResourceAllocationStrategy::QualityFocused => {
926                self.select_quality_focused_resources(&available_resources, task)?
927            }
928            _ => {
929                // Default: select best performing resource
930                available_resources
931                    .iter()
932                    .max_by(|a, b| {
933                        a.performance
934                            .throughput
935                            .partial_cmp(&b.performance.throughput)
936                            .unwrap_or(std::cmp::Ordering::Equal)
937                    })
938                    .map(|r| vec![r.id.clone()])
939                    .unwrap_or_default()
940            }
941        };
942
943        Ok(selected)
944    }
945
946    /// Select resources using adaptive strategy
947    fn select_adaptive_resources(
948        &self,
949        available: &[&ComputeResource],
950        task: &HybridExecutionTask,
951    ) -> ApplicationResult<Vec<String>> {
952        // Score resources based on multiple factors
953        let mut scored_resources: Vec<_> = available
954            .iter()
955            .map(|resource| {
956                let performance_score =
957                    resource.performance.throughput * resource.performance.success_rate;
958                let quality_score = resource.performance.quality_score;
959                let cost_score = 1.0
960                    / resource.cost.variable_cost.mul_add(
961                        task.problem.num_qubits as f64,
962                        1.0 + resource.cost.fixed_cost,
963                    );
964
965                let total_score =
966                    performance_score.mul_add(0.4, quality_score * 0.4) + cost_score * 0.2;
967                (resource.id.clone(), total_score)
968            })
969            .collect();
970
971        // Sort by score (highest first)
972        scored_resources.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
973
974        // Select top resources
975        let num_resources = (scored_resources.len().min(3)).max(1);
976        Ok(scored_resources
977            .into_iter()
978            .take(num_resources)
979            .map(|(id, _)| id)
980            .collect())
981    }
982
983    /// Select cost-optimized resources
984    fn select_cost_optimized_resources(
985        &self,
986        available: &[&ComputeResource],
987        task: &HybridExecutionTask,
988    ) -> ApplicationResult<Vec<String>> {
989        let mut cost_sorted: Vec<_> = available
990            .iter()
991            .map(|resource| {
992                let total_cost = resource
993                    .cost
994                    .variable_cost
995                    .mul_add(task.problem.num_qubits as f64, resource.cost.fixed_cost);
996                (resource.id.clone(), total_cost)
997            })
998            .collect();
999
1000        cost_sorted.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(std::cmp::Ordering::Equal));
1001
1002        // Select cheapest resource that meets quality requirements
1003        for (resource_id, _cost) in &cost_sorted {
1004            if let Some(resource) = available.iter().find(|r| &r.id == resource_id) {
1005                if resource.performance.quality_score >= task.quality_requirements.min_quality {
1006                    return Ok(vec![resource_id.clone()]);
1007                }
1008            }
1009        }
1010
1011        // Fallback: select cheapest available
1012        Ok(vec![cost_sorted[0].0.clone()])
1013    }
1014
1015    /// Select quality-focused resources
1016    fn select_quality_focused_resources(
1017        &self,
1018        available: &[&ComputeResource],
1019        task: &HybridExecutionTask,
1020    ) -> ApplicationResult<Vec<String>> {
1021        let mut quality_sorted: Vec<_> = available
1022            .iter()
1023            .map(|resource| (resource.id.clone(), resource.performance.quality_score))
1024            .collect();
1025
1026        quality_sorted.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
1027
1028        // Select highest quality resources
1029        let num_resources = quality_sorted.len().min(2);
1030        Ok(quality_sorted
1031            .into_iter()
1032            .take(num_resources)
1033            .map(|(id, _)| id)
1034            .collect())
1035    }
1036
1037    /// Execute on assigned resources
1038    fn execute_on_resources(
1039        &self,
1040        task: &HybridExecutionTask,
1041        resources: &[String],
1042    ) -> ApplicationResult<Vec<IndividualResult>> {
1043        let mut results = Vec::new();
1044
1045        // Execute based on strategy
1046        match self.config.execution_strategy {
1047            ExecutionStrategy::Sequential => {
1048                results.extend(self.execute_sequential(task, resources)?);
1049            }
1050            ExecutionStrategy::Parallel => {
1051                results.extend(self.execute_parallel(task, resources)?);
1052            }
1053            ExecutionStrategy::Competitive => {
1054                results.extend(self.execute_competitive(task, resources)?);
1055            }
1056            _ => {
1057                // Default to parallel
1058                results.extend(self.execute_parallel(task, resources)?);
1059            }
1060        }
1061
1062        Ok(results)
1063    }
1064
1065    /// Execute sequentially on resources
1066    fn execute_sequential(
1067        &self,
1068        task: &HybridExecutionTask,
1069        resources: &[String],
1070    ) -> ApplicationResult<Vec<IndividualResult>> {
1071        let mut results = Vec::new();
1072
1073        for resource_id in resources {
1074            let result = self.execute_on_single_resource(task, resource_id)?;
1075            results.push(result.clone());
1076
1077            // Check if we achieved target quality
1078            if result.quality >= task.quality_requirements.target_quality {
1079                break;
1080            }
1081        }
1082
1083        Ok(results)
1084    }
1085
1086    /// Execute in parallel on resources
1087    fn execute_parallel(
1088        &self,
1089        task: &HybridExecutionTask,
1090        resources: &[String],
1091    ) -> ApplicationResult<Vec<IndividualResult>> {
1092        let mut results = Vec::new();
1093
1094        // Simulate parallel execution
1095        for resource_id in resources {
1096            let result = self.execute_on_single_resource(task, resource_id)?;
1097            results.push(result);
1098        }
1099
1100        Ok(results)
1101    }
1102
1103    /// Execute competitively (first good result wins)
1104    fn execute_competitive(
1105        &self,
1106        task: &HybridExecutionTask,
1107        resources: &[String],
1108    ) -> ApplicationResult<Vec<IndividualResult>> {
1109        // For now, simulate by running all and taking the best
1110        let all_results = self.execute_parallel(task, resources)?;
1111
1112        // Return best result
1113        if let Some(best) = all_results.iter().max_by(|a, b| {
1114            a.quality
1115                .partial_cmp(&b.quality)
1116                .unwrap_or(std::cmp::Ordering::Equal)
1117        }) {
1118            Ok(vec![best.clone()])
1119        } else {
1120            Ok(all_results)
1121        }
1122    }
1123
1124    /// Execute on single resource
1125    fn execute_on_single_resource(
1126        &self,
1127        task: &HybridExecutionTask,
1128        resource_id: &str,
1129    ) -> ApplicationResult<IndividualResult> {
1130        let start_time = Instant::now();
1131
1132        // Simulate execution based on resource type
1133        let resources = self.resources.read().map_err(|_| {
1134            ApplicationError::OptimizationError("Failed to read resource registry".to_string())
1135        })?;
1136
1137        let resource = resources.get(resource_id).ok_or_else(|| {
1138            ApplicationError::InvalidConfiguration(format!("Resource {resource_id} not found"))
1139        })?;
1140
1141        // Simulate execution time based on resource performance
1142        let execution_time =
1143            Duration::from_millis((1000.0 / resource.performance.throughput) as u64);
1144        thread::sleep(Duration::from_millis(10)); // Brief simulation
1145
1146        // Generate solution (simplified)
1147        let solution = self.generate_simulated_solution(task, resource)?;
1148        let energy = self.calculate_energy(&task.problem, &solution)?;
1149        let quality =
1150            resource.performance.quality_score * thread_rng().gen::<f64>().mul_add(0.4, 0.8);
1151        let cost = resource
1152            .cost
1153            .variable_cost
1154            .mul_add(task.problem.num_qubits as f64, resource.cost.fixed_cost);
1155
1156        Ok(IndividualResult {
1157            resource_id: resource_id.to_string(),
1158            solution,
1159            energy,
1160            quality,
1161            execution_time,
1162            cost,
1163            metadata: HashMap::new(),
1164        })
1165    }
1166
1167    /// Generate simulated solution
1168    fn generate_simulated_solution(
1169        &self,
1170        task: &HybridExecutionTask,
1171        resource: &ComputeResource,
1172    ) -> ApplicationResult<Vec<i32>> {
1173        let num_vars = task.problem.num_qubits;
1174        let mut solution = vec![1; num_vars];
1175
1176        // Add some randomness based on resource type
1177        for i in 0..num_vars {
1178            if thread_rng().gen::<f64>() < 0.5 {
1179                solution[i] = -1;
1180            }
1181        }
1182
1183        Ok(solution)
1184    }
1185
1186    /// Calculate energy for solution
1187    fn calculate_energy(&self, problem: &IsingModel, solution: &[i32]) -> ApplicationResult<f64> {
1188        let mut energy = 0.0;
1189
1190        // Bias terms
1191        for (i, &spin) in solution.iter().enumerate() {
1192            let biases = problem.biases();
1193            for (qubit_index, bias_value) in biases {
1194                if qubit_index == i {
1195                    energy += bias_value * f64::from(spin);
1196                    break;
1197                }
1198            }
1199        }
1200
1201        // Coupling terms
1202        let couplings = problem.couplings();
1203        for coupling in couplings {
1204            if coupling.i < solution.len() && coupling.j < solution.len() {
1205                energy += coupling.strength
1206                    * f64::from(solution[coupling.i])
1207                    * f64::from(solution[coupling.j]);
1208            }
1209        }
1210
1211        Ok(energy)
1212    }
1213
1214    /// Aggregate results from multiple resources
1215    fn aggregate_results(
1216        &self,
1217        task: &HybridExecutionTask,
1218        results: Vec<IndividualResult>,
1219    ) -> ApplicationResult<HybridExecutionResult> {
1220        let mut aggregator = self.aggregator.lock().map_err(|_| {
1221            ApplicationError::OptimizationError("Failed to acquire aggregator lock".to_string())
1222        })?;
1223
1224        let best_result = results
1225            .iter()
1226            .min_by(|a, b| {
1227                a.energy
1228                    .partial_cmp(&b.energy)
1229                    .unwrap_or(std::cmp::Ordering::Equal)
1230            })
1231            .cloned()
1232            .unwrap_or_else(|| IndividualResult {
1233                resource_id: "none".to_string(),
1234                solution: vec![],
1235                energy: f64::INFINITY,
1236                quality: 0.0,
1237                execution_time: Duration::from_secs(0),
1238                cost: 0.0,
1239                metadata: HashMap::new(),
1240            });
1241
1242        let total_time = results
1243            .iter()
1244            .map(|r| r.execution_time)
1245            .max()
1246            .unwrap_or(Duration::from_secs(0));
1247
1248        let total_cost = results.iter().map(|r| r.cost).sum();
1249
1250        let mut resource_utilization = HashMap::new();
1251        for result in &results {
1252            resource_utilization.insert(
1253                result.resource_id.clone(),
1254                ResourceUtilization {
1255                    resource_id: result.resource_id.clone(),
1256                    time_used: result.execution_time,
1257                    cost: result.cost,
1258                    success: result.quality > task.quality_requirements.min_quality,
1259                    quality: result.quality,
1260                },
1261            );
1262        }
1263
1264        Ok(HybridExecutionResult {
1265            task_id: task.id.clone(),
1266            best_solution: best_result.solution,
1267            best_energy: best_result.energy,
1268            quality_score: best_result.quality,
1269            total_time,
1270            total_cost,
1271            resource_utilization: resource_utilization.clone(),
1272            individual_results: results,
1273            metadata: ExecutionMetadata {
1274                strategy: self.config.execution_strategy.clone(),
1275                resources_used: resource_utilization.keys().cloned().collect(),
1276                algorithm_decisions: vec!["adaptive_selection".to_string()],
1277                performance_metrics: HashMap::new(),
1278                warnings: vec![],
1279            },
1280        })
1281    }
1282
1283    /// Update performance metrics after execution
1284    fn update_performance_metrics(
1285        &self,
1286        task: &HybridExecutionTask,
1287        result: &HybridExecutionResult,
1288    ) -> ApplicationResult<()> {
1289        let mut monitor = self.monitor.lock().map_err(|_| {
1290            ApplicationError::OptimizationError("Failed to acquire monitor lock".to_string())
1291        })?;
1292
1293        monitor.update_metrics(task, result);
1294        Ok(())
1295    }
1296
1297    /// Get current system performance
1298    pub fn get_system_performance(&self) -> ApplicationResult<HybridSystemMetrics> {
1299        let monitor = self.monitor.lock().map_err(|_| {
1300            ApplicationError::OptimizationError("Failed to acquire monitor lock".to_string())
1301        })?;
1302
1303        Ok(monitor.system_metrics.clone())
1304    }
1305}
1306
1307// Helper types
1308#[derive(Debug, Clone)]
1309pub struct ExecutionPlan {
1310    pub strategy: ExecutionStrategy,
1311    pub resource_requirements: ResourceRequirements,
1312    pub estimated_time: Duration,
1313    pub estimated_cost: f64,
1314    pub quality_target: f64,
1315}
1316
1317#[derive(Debug, Clone)]
1318pub struct ResourceRequirements {
1319    pub suitable_types: Vec<ResourceType>,
1320    pub min_resources: usize,
1321    pub max_resources: usize,
1322    pub performance_requirements: PerformanceRequirements,
1323}
1324
1325#[derive(Debug, Clone)]
1326pub struct PerformanceRequirements {
1327    pub min_throughput: f64,
1328    pub max_latency: Duration,
1329    pub min_quality: f64,
1330}
1331
1332#[derive(Debug, Clone, PartialEq, Eq)]
1333pub enum ProblemComplexity {
1334    Simple,
1335    Medium,
1336    Complex,
1337}
1338
1339impl HybridPerformanceMonitor {
1340    fn new() -> Self {
1341        Self {
1342            system_metrics: HybridSystemMetrics {
1343                total_tasks: 0,
1344                avg_completion_time: Duration::from_secs(0),
1345                success_rate: 1.0,
1346                avg_quality: 0.0,
1347                total_cost: 0.0,
1348                resource_efficiency: 1.0,
1349            },
1350            resource_metrics: HashMap::new(),
1351            performance_history: VecDeque::new(),
1352            cost_tracking: CostTracker {
1353                current_budget: 1000.0,
1354                spent_amount: 0.0,
1355                cost_breakdown: HashMap::new(),
1356                cost_predictions: HashMap::new(),
1357            },
1358        }
1359    }
1360
1361    fn update_metrics(&mut self, task: &HybridExecutionTask, result: &HybridExecutionResult) {
1362        self.system_metrics.total_tasks += 1;
1363        self.system_metrics.total_cost += result.total_cost;
1364        self.system_metrics.avg_quality = self.system_metrics.avg_quality.mul_add(
1365            (self.system_metrics.total_tasks - 1) as f64,
1366            result.quality_score,
1367        ) / self.system_metrics.total_tasks as f64;
1368
1369        self.cost_tracking.spent_amount += result.total_cost;
1370
1371        println!("Updated performance metrics for task {}", task.id);
1372    }
1373}
1374
1375impl ResourceScheduler {
1376    fn new() -> Self {
1377        Self {
1378            strategy: ResourceAllocationStrategy::Adaptive,
1379            availability_cache: HashMap::new(),
1380            performance_predictions: HashMap::new(),
1381            load_balancing: LoadBalancingDecisions {
1382                recent_decisions: VecDeque::new(),
1383                resource_success_rates: HashMap::new(),
1384                performance_trends: HashMap::new(),
1385            },
1386        }
1387    }
1388}
1389
1390impl ResultAggregator {
1391    fn new() -> Self {
1392        Self {
1393            strategy: ResultAggregationStrategy::BestResult,
1394            quality_assessor: QualityAssessor {
1395                methods: vec![QualityAssessmentMethod::EnergyBased],
1396                thresholds: HashMap::new(),
1397                quality_history: VecDeque::new(),
1398            },
1399            consensus_algorithm: ConsensusAlgorithm {
1400                threshold: 0.7,
1401                voting_weights: HashMap::new(),
1402                consensus_history: VecDeque::new(),
1403            },
1404        }
1405    }
1406}
1407
1408/// Create example hybrid engine with multiple resource types
1409pub fn create_example_hybrid_engine() -> ApplicationResult<HeterogeneousHybridEngine> {
1410    let config = HybridEngineConfig::default();
1411    let engine = HeterogeneousHybridEngine::new(config);
1412
1413    // Register D-Wave quantum resource
1414    let dwave_resource = ComputeResource {
1415        id: "dwave_advantage".to_string(),
1416        resource_type: ResourceType::DWaveQuantum,
1417        availability: ResourceAvailability::Available,
1418        performance: ResourcePerformance {
1419            throughput: 0.1,
1420            latency: Duration::from_secs(20),
1421            success_rate: 0.95,
1422            quality_score: 0.9,
1423            size_range: (10, 5000),
1424            history: VecDeque::new(),
1425        },
1426        cost: ResourceCost {
1427            fixed_cost: 1.0,
1428            variable_cost: 0.001,
1429            time_cost: 0.1,
1430            quality_premium: 1.2,
1431        },
1432        workload: None,
1433        connection: ResourceConnection::Custom("dwave_cloud".to_string()),
1434    };
1435
1436    // Register classical simulator resource
1437    let classical_resource = ComputeResource {
1438        id: "classical_simulator".to_string(),
1439        resource_type: ResourceType::ClassicalSimulator,
1440        availability: ResourceAvailability::Available,
1441        performance: ResourcePerformance {
1442            throughput: 1.0,
1443            latency: Duration::from_secs(5),
1444            success_rate: 0.99,
1445            quality_score: 0.8,
1446            size_range: (1, 10_000),
1447            history: VecDeque::new(),
1448        },
1449        cost: ResourceCost {
1450            fixed_cost: 0.1,
1451            variable_cost: 0.0001,
1452            time_cost: 0.01,
1453            quality_premium: 1.0,
1454        },
1455        workload: None,
1456        connection: ResourceConnection::Custom("local".to_string()),
1457    };
1458
1459    engine.register_resource(dwave_resource)?;
1460    engine.register_resource(classical_resource)?;
1461
1462    Ok(engine)
1463}
1464
1465#[cfg(test)]
1466mod tests {
1467    use super::*;
1468
1469    #[test]
1470    fn test_hybrid_engine_creation() {
1471        let config = HybridEngineConfig::default();
1472        let engine = HeterogeneousHybridEngine::new(config);
1473
1474        let resources = engine.resources.read().unwrap_or_else(|e| e.into_inner());
1475        assert!(resources.is_empty());
1476    }
1477
1478    #[test]
1479    fn test_resource_registration() {
1480        let engine =
1481            create_example_hybrid_engine().expect("Example hybrid engine creation should succeed");
1482
1483        let resources = engine.resources.read().unwrap_or_else(|e| e.into_inner());
1484        assert_eq!(resources.len(), 2);
1485        assert!(resources.contains_key("dwave_advantage"));
1486        assert!(resources.contains_key("classical_simulator"));
1487    }
1488
1489    #[test]
1490    fn test_task_submission() {
1491        let engine =
1492            create_example_hybrid_engine().expect("Example hybrid engine creation should succeed");
1493
1494        let problem = IsingModel::new(100);
1495        let task = HybridExecutionTask {
1496            id: "test_task".to_string(),
1497            problem,
1498            quality_requirements: QualityRequirements {
1499                min_quality: 0.8,
1500                target_quality: 0.9,
1501                assessment_method: QualityAssessmentMethod::EnergyBased,
1502                min_solutions: 1,
1503            },
1504            resource_constraints: ResourceConstraints {
1505                max_cost: Some(10.0),
1506                max_time: Duration::from_secs(60),
1507                preferred_resources: vec![ResourceType::ClassicalSimulator],
1508                excluded_resources: vec![],
1509                geographic_constraints: None,
1510            },
1511            priority: TaskPriority::Medium,
1512            deadline: None,
1513        };
1514
1515        let result = engine.submit_task(task);
1516        assert!(result.is_ok());
1517        assert_eq!(result.expect("Task submission should succeed"), "test_task");
1518    }
1519
1520    #[test]
1521    fn test_execution_strategies() {
1522        let config = HybridEngineConfig {
1523            execution_strategy: ExecutionStrategy::Parallel,
1524            ..Default::default()
1525        };
1526
1527        assert_eq!(config.execution_strategy, ExecutionStrategy::Parallel);
1528    }
1529
1530    #[test]
1531    fn test_resource_allocation_strategies() {
1532        let strategies = vec![
1533            ResourceAllocationStrategy::Adaptive,
1534            ResourceAllocationStrategy::CostOptimized,
1535            ResourceAllocationStrategy::QualityFocused,
1536        ];
1537
1538        for strategy in strategies {
1539            let config = HybridEngineConfig {
1540                allocation_strategy: strategy.clone(),
1541                ..Default::default()
1542            };
1543            assert_eq!(config.allocation_strategy, strategy);
1544        }
1545    }
1546}