use std::collections::{HashMap, VecDeque};
use std::sync::{mpsc, Arc, Mutex, RwLock};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use super::analysis::{
compute_cost_analysis, compute_cost_metrics, compute_cross_platform_analysis,
compute_performance_metrics, compute_reliability_metrics, compute_resource_analysis,
default_algorithm_level_results, default_circuit_level_results, default_gate_level_results,
default_scirs2_analysis, default_system_level_results,
};
use super::config::{
AlgorithmBenchmarkConfig, CircuitBenchmarkConfig, GateBenchmarkConfig, SystemBenchmarkConfig,
UnifiedBenchmarkConfig,
};
use super::events::BenchmarkEvent;
use super::optimization::OptimizationEngine;
use super::reporting::ReportGenerator;
use super::results::{
AlgorithmLevelResults, CircuitLevelResults, CoherenceTimes, ConnectivityInfo,
CostAnalysisResult, CostMetrics, CrossPlatformAnalysis, DeviceInfo, DeviceSpecifications,
DeviceStatus, ExecutionMetadata, GateLevelResults, HistoricalComparisonResult,
OptimizationRecommendation, PlatformBenchmarkResult, PlatformPerformanceMetrics,
QuantumTechnology, ReliabilityMetrics, ResourceAnalysisResult, SciRS2AnalysisResult,
SystemLevelResults, TopologyType, UnifiedBenchmarkResult,
};
use super::types::{PerformanceBaseline, QuantumPlatform};
use crate::{
advanced_benchmarking_suite::{AdvancedBenchmarkConfig, AdvancedHardwareBenchmarkSuite},
calibration::CalibrationManager,
cross_platform_benchmarking::{CrossPlatformBenchmarkConfig, CrossPlatformBenchmarker},
topology::HardwareTopology,
DeviceError, DeviceResult, QuantumDevice,
};
use quantrs2_core::error::{QuantRS2Error, QuantRS2Result};
use scirs2_core::ndarray::Array2;
pub struct UnifiedQuantumBenchmarkSystem {
config: Arc<RwLock<UnifiedBenchmarkConfig>>,
platform_clients: Arc<RwLock<HashMap<QuantumPlatform, Box<dyn QuantumDevice + Send + Sync>>>>,
cross_platform_benchmarker: Arc<Mutex<CrossPlatformBenchmarker>>,
advanced_suite: Arc<Mutex<AdvancedHardwareBenchmarkSuite>>,
calibration_manager: Arc<Mutex<CalibrationManager>>,
historical_data: Arc<RwLock<VecDeque<UnifiedBenchmarkResult>>>,
baselines: Arc<RwLock<HashMap<String, PerformanceBaseline>>>,
monitoring_handle: Arc<Mutex<Option<std::thread::JoinHandle<()>>>>,
event_publisher: mpsc::Sender<BenchmarkEvent>,
optimization_engine: Arc<Mutex<OptimizationEngine>>,
report_generator: Arc<Mutex<ReportGenerator>>,
}
impl UnifiedQuantumBenchmarkSystem {
pub async fn new(
config: UnifiedBenchmarkConfig,
calibration_manager: CalibrationManager,
) -> DeviceResult<Self> {
let (event_publisher, _) = mpsc::channel();
let config = Arc::new(RwLock::new(config));
let platform_clients = Arc::new(RwLock::new(HashMap::new()));
let cross_platform_config = CrossPlatformBenchmarkConfig::default();
let cross_platform_benchmarker = Arc::new(Mutex::new(CrossPlatformBenchmarker::new(
cross_platform_config,
calibration_manager.clone(),
)));
let advanced_config = AdvancedBenchmarkConfig::default();
let topology = HardwareTopology::linear_topology(8); let advanced_suite = Arc::new(Mutex::new(
AdvancedHardwareBenchmarkSuite::new(
advanced_config,
calibration_manager.clone(),
topology,
)
.await?,
));
let historical_data = Arc::new(RwLock::new(VecDeque::with_capacity(10000)));
let baselines = Arc::new(RwLock::new(HashMap::new()));
let monitoring_handle = Arc::new(Mutex::new(None));
let optimization_engine = Arc::new(Mutex::new(OptimizationEngine::new()));
let report_generator = Arc::new(Mutex::new(ReportGenerator::new()));
Ok(Self {
config,
platform_clients,
cross_platform_benchmarker,
advanced_suite,
calibration_manager: Arc::new(Mutex::new(calibration_manager)),
historical_data,
baselines,
monitoring_handle,
event_publisher,
optimization_engine,
report_generator,
})
}
pub async fn register_platform(
&self,
platform: QuantumPlatform,
device: Box<dyn QuantumDevice + Send + Sync>,
) -> DeviceResult<()> {
let mut clients = self
.platform_clients
.write()
.unwrap_or_else(|e| e.into_inner());
clients.insert(platform, device);
Ok(())
}
pub async fn run_comprehensive_benchmark(&self) -> DeviceResult<UnifiedBenchmarkResult> {
let execution_id = self.generate_execution_id();
let start_time = SystemTime::now();
let config = self
.config
.read()
.unwrap_or_else(|e| e.into_inner())
.clone();
let _ = self.event_publisher.send(BenchmarkEvent::BenchmarkStarted {
execution_id: execution_id.clone(),
platforms: config.target_platforms.clone(),
timestamp: start_time,
});
let mut platform_results = HashMap::new();
for platform in &config.target_platforms {
match self.run_platform_benchmark(platform, &execution_id).await {
Ok(result) => {
let _ = self
.event_publisher
.send(BenchmarkEvent::PlatformBenchmarkCompleted {
execution_id: execution_id.clone(),
platform: platform.clone(),
result: result.clone(),
timestamp: SystemTime::now(),
});
platform_results.insert(platform.clone(), result);
}
Err(e) => {
eprintln!("Platform benchmark failed for {platform:?}: {e}");
}
}
}
let cross_platform_analysis = self
.perform_cross_platform_analysis(&platform_results)
.await?;
let scirs2_analysis = self.perform_scirs2_analysis(&platform_results).await?;
let resource_analysis = self.perform_resource_analysis(&platform_results).await?;
let cost_analysis = self.perform_cost_analysis(&platform_results).await?;
let optimization_recommendations = self
.generate_optimization_recommendations(
&platform_results,
&cross_platform_analysis,
&scirs2_analysis,
)
.await?;
let historical_comparison = self
.perform_historical_comparison(&platform_results)
.await?;
let execution_metadata = ExecutionMetadata {
execution_start_time: start_time,
execution_end_time: SystemTime::now(),
total_duration: SystemTime::now()
.duration_since(start_time)
.unwrap_or(Duration::ZERO),
platforms_tested: config.target_platforms.clone(),
benchmarks_executed: platform_results.len(),
system_info: self.get_system_info(),
};
let result = UnifiedBenchmarkResult {
execution_id: execution_id.clone(),
timestamp: start_time,
config,
platform_results,
cross_platform_analysis,
scirs2_analysis,
resource_analysis,
cost_analysis,
optimization_recommendations,
historical_comparison,
execution_metadata,
};
self.store_historical_result(&result).await;
self.update_baselines(&result).await;
if result
.config
.optimization_config
.enable_intelligent_allocation
{
self.trigger_optimization(&result).await?;
}
if result
.config
.reporting_config
.automated_reports
.enable_automated
{
self.generate_automated_reports(&result).await?;
}
let _ = self
.event_publisher
.send(BenchmarkEvent::BenchmarkCompleted {
execution_id: execution_id.clone(),
result: result.clone(),
timestamp: SystemTime::now(),
});
Ok(result)
}
async fn run_platform_benchmark(
&self,
platform: &QuantumPlatform,
execution_id: &str,
) -> DeviceResult<PlatformBenchmarkResult> {
let config = self
.config
.read()
.unwrap_or_else(|e| e.into_inner())
.clone();
let device_info = self.get_device_info(platform).await?;
let gate_level_results = self
.run_gate_level_benchmarks(platform, &config.benchmark_suite.gate_benchmarks)
.await?;
let circuit_level_results = self
.run_circuit_level_benchmarks(platform, &config.benchmark_suite.circuit_benchmarks)
.await?;
let algorithm_level_results = self
.run_algorithm_level_benchmarks(platform, &config.benchmark_suite.algorithm_benchmarks)
.await?;
let system_level_results = self
.run_system_level_benchmarks(platform, &config.benchmark_suite.system_benchmarks)
.await?;
let performance_metrics = self
.calculate_platform_performance_metrics(
&gate_level_results,
&circuit_level_results,
&algorithm_level_results,
&system_level_results,
)
.await?;
let reliability_metrics = self
.calculate_reliability_metrics(
&gate_level_results,
&circuit_level_results,
&algorithm_level_results,
)
.await?;
let cost_metrics = self
.calculate_cost_metrics(
&gate_level_results,
&circuit_level_results,
&algorithm_level_results,
)
.await?;
Ok(PlatformBenchmarkResult {
platform: platform.clone(),
device_info,
gate_level_results,
circuit_level_results,
algorithm_level_results,
system_level_results,
performance_metrics,
reliability_metrics,
cost_metrics,
})
}
fn generate_execution_id(&self) -> String {
format!(
"unified_benchmark_{}",
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or(Duration::ZERO)
.as_millis()
)
}
async fn get_device_info(&self, platform: &QuantumPlatform) -> DeviceResult<DeviceInfo> {
let (provider, technology) = match platform {
QuantumPlatform::IBMQuantum { .. } => {
("IBM".to_string(), QuantumTechnology::Superconducting)
}
QuantumPlatform::AWSBraket { .. } => {
("AWS".to_string(), QuantumTechnology::Superconducting)
}
QuantumPlatform::AzureQuantum { .. } => {
("Microsoft".to_string(), QuantumTechnology::TrappedIon)
}
QuantumPlatform::IonQ { .. } => ("IonQ".to_string(), QuantumTechnology::TrappedIon),
QuantumPlatform::Rigetti { .. } => {
("Rigetti".to_string(), QuantumTechnology::Superconducting)
}
QuantumPlatform::GoogleQuantumAI { .. } => {
("Google".to_string(), QuantumTechnology::Superconducting)
}
QuantumPlatform::Custom { .. } => (
"Custom".to_string(),
QuantumTechnology::Other("Custom".to_string()),
),
};
Ok(DeviceInfo {
device_id: format!("{platform:?}"),
provider,
technology,
specifications: DeviceSpecifications {
num_qubits: 20,
connectivity: ConnectivityInfo {
topology_type: TopologyType::Heavy,
coupling_map: vec![(0, 1), (1, 2), (2, 3)],
connectivity_matrix: Array2::eye(20),
},
gate_set: vec![
"X".to_string(),
"Y".to_string(),
"Z".to_string(),
"H".to_string(),
"CNOT".to_string(),
],
coherence_times: CoherenceTimes {
t1: (0..20).map(|i| (i, Duration::from_micros(100))).collect(),
t2: (0..20).map(|i| (i, Duration::from_micros(50))).collect(),
t2_echo: (0..20).map(|i| (i, Duration::from_micros(80))).collect(),
},
gate_times: [
("X".to_string(), Duration::from_nanos(20)),
("CNOT".to_string(), Duration::from_nanos(100)),
]
.iter()
.cloned()
.collect(),
error_rates: [
("single_qubit".to_string(), 0.001),
("two_qubit".to_string(), 0.01),
]
.iter()
.cloned()
.collect(),
},
current_status: DeviceStatus::Online,
calibration_date: Some(SystemTime::now()),
})
}
async fn run_gate_level_benchmarks(
&self,
_platform: &QuantumPlatform,
_config: &GateBenchmarkConfig,
) -> DeviceResult<GateLevelResults> {
Ok(default_gate_level_results())
}
async fn run_circuit_level_benchmarks(
&self,
_platform: &QuantumPlatform,
_config: &CircuitBenchmarkConfig,
) -> DeviceResult<CircuitLevelResults> {
Ok(default_circuit_level_results())
}
async fn run_algorithm_level_benchmarks(
&self,
_platform: &QuantumPlatform,
_config: &AlgorithmBenchmarkConfig,
) -> DeviceResult<AlgorithmLevelResults> {
Ok(default_algorithm_level_results())
}
async fn run_system_level_benchmarks(
&self,
platform: &QuantumPlatform,
_config: &SystemBenchmarkConfig,
) -> DeviceResult<SystemLevelResults> {
Ok(default_system_level_results(platform))
}
async fn perform_cross_platform_analysis(
&self,
platform_results: &HashMap<QuantumPlatform, PlatformBenchmarkResult>,
) -> DeviceResult<CrossPlatformAnalysis> {
Ok(compute_cross_platform_analysis(platform_results))
}
async fn perform_scirs2_analysis(
&self,
_platform_results: &HashMap<QuantumPlatform, PlatformBenchmarkResult>,
) -> DeviceResult<SciRS2AnalysisResult> {
Ok(default_scirs2_analysis())
}
async fn perform_resource_analysis(
&self,
platform_results: &HashMap<QuantumPlatform, PlatformBenchmarkResult>,
) -> DeviceResult<ResourceAnalysisResult> {
Ok(compute_resource_analysis(platform_results))
}
async fn perform_cost_analysis(
&self,
platform_results: &HashMap<QuantumPlatform, PlatformBenchmarkResult>,
) -> DeviceResult<CostAnalysisResult> {
Ok(compute_cost_analysis(platform_results))
}
async fn calculate_platform_performance_metrics(
&self,
gate_results: &GateLevelResults,
circuit_results: &CircuitLevelResults,
algorithm_results: &AlgorithmLevelResults,
system_results: &SystemLevelResults,
) -> DeviceResult<PlatformPerformanceMetrics> {
Ok(compute_performance_metrics(
gate_results,
circuit_results,
algorithm_results,
system_results,
))
}
async fn calculate_reliability_metrics(
&self,
gate_results: &GateLevelResults,
circuit_results: &CircuitLevelResults,
algorithm_results: &AlgorithmLevelResults,
) -> DeviceResult<ReliabilityMetrics> {
Ok(compute_reliability_metrics(
gate_results,
circuit_results,
algorithm_results,
))
}
async fn calculate_cost_metrics(
&self,
gate_results: &GateLevelResults,
circuit_results: &CircuitLevelResults,
algorithm_results: &AlgorithmLevelResults,
) -> DeviceResult<CostMetrics> {
Ok(compute_cost_metrics(
gate_results,
circuit_results,
algorithm_results,
))
}
async fn generate_optimization_recommendations(
&self,
platform_results: &HashMap<QuantumPlatform, PlatformBenchmarkResult>,
cross_platform_analysis: &CrossPlatformAnalysis,
_scirs2_analysis: &SciRS2AnalysisResult,
) -> DeviceResult<Vec<OptimizationRecommendation>> {
Ok(generate_recommendations_from_metrics(
platform_results,
cross_platform_analysis,
))
}
async fn perform_historical_comparison(
&self,
platform_results: &HashMap<QuantumPlatform, PlatformBenchmarkResult>,
) -> DeviceResult<Option<HistoricalComparisonResult>> {
let historical_data = self
.historical_data
.read()
.unwrap_or_else(|e| e.into_inner());
let baseline = historical_data.iter().next_back();
let baseline = match baseline {
Some(b) => b,
None => return Ok(None),
};
let mut baseline_comparison: Vec<super::results::MetricComparison> = Vec::new();
let mut trend_analysis: HashMap<String, super::results::TrendAnalysisResult> =
HashMap::new();
for (platform, current) in platform_results {
let prev = match baseline.platform_results.get(platform) {
Some(p) => p,
None => continue,
};
let pairs: [(&str, f64, f64); 4] = [
(
"overall_fidelity",
current.performance_metrics.overall_fidelity,
prev.performance_metrics.overall_fidelity,
),
(
"error_rate",
current.performance_metrics.error_rate,
prev.performance_metrics.error_rate,
),
(
"throughput",
current.performance_metrics.throughput,
prev.performance_metrics.throughput,
),
(
"availability",
current.performance_metrics.availability,
prev.performance_metrics.availability,
),
];
for (name, cur_val, base_val) in pairs {
let percentage_change = if base_val.abs() > f64::EPSILON {
(cur_val - base_val) / base_val * 100.0
} else if cur_val.abs() < f64::EPSILON {
0.0
} else {
100.0
};
let mag = percentage_change.abs();
let significance = (-mag / 50.0).exp().clamp(0.0, 1.0);
let metric_label = format!("{platform:?}.{name}");
baseline_comparison.push(super::results::MetricComparison {
metric_name: metric_label.clone(),
current_value: cur_val,
baseline_value: base_val,
percentage_change,
statistical_significance: significance,
});
let direction = if cur_val > base_val {
"increasing"
} else if cur_val < base_val {
"decreasing"
} else {
"flat"
};
trend_analysis.insert(
metric_label,
super::results::TrendAnalysisResult {
trend_detected: mag > 1.0,
trend_direction: direction.to_string(),
trend_strength: (mag / 100.0).clamp(0.0, 1.0),
trend_coefficients: vec![cur_val - base_val],
change_points: Vec::new(),
},
);
}
}
let mut metrics_map: HashMap<String, f64> = HashMap::new();
for (platform, result) in platform_results {
metrics_map.insert(
format!("{platform:?}.overall_fidelity"),
result.performance_metrics.overall_fidelity,
);
metrics_map.insert(
format!("{platform:?}.error_rate"),
result.performance_metrics.error_rate,
);
metrics_map.insert(
format!("{platform:?}.throughput"),
result.performance_metrics.throughput,
);
metrics_map.insert(
format!("{platform:?}.availability"),
result.performance_metrics.availability,
);
}
let snapshot = super::results::PerformanceSnapshot {
timestamp: SystemTime::now(),
metrics: metrics_map,
configuration: "current".to_string(),
};
if baseline_comparison.is_empty() {
return Ok(None);
}
Ok(Some(HistoricalComparisonResult {
baseline_comparison,
trend_analysis,
performance_evolution: vec![snapshot],
}))
}
async fn store_historical_result(&self, result: &UnifiedBenchmarkResult) {
let mut historical_data = self
.historical_data
.write()
.unwrap_or_else(|e| e.into_inner());
historical_data.push_back(result.clone());
if historical_data.len() > 10000 {
historical_data.pop_front();
}
}
async fn update_baselines(&self, result: &UnifiedBenchmarkResult) {
let home = std::env::var("HOME").unwrap_or_else(|_| "/tmp".to_string());
let dir = format!("{home}/.cache/quantrs2-baselines");
if let Err(e) = std::fs::create_dir_all(&dir) {
eprintln!("update_baselines: could not create cache dir {dir}: {e}");
return;
}
let file_path = format!("{dir}/{}.json", result.execution_id);
let mut snapshot: HashMap<String, serde_json::Value> = HashMap::new();
for (platform, pr) in &result.platform_results {
let m = &pr.performance_metrics;
let entry = serde_json::json!({
"overall_fidelity": m.overall_fidelity,
"error_rate": m.error_rate,
"throughput": m.throughput,
"availability": m.availability,
"avg_exec_ms": m.average_execution_time.as_millis(),
});
snapshot.insert(format!("{platform:?}"), entry);
}
match serde_json::to_vec_pretty(&snapshot) {
Ok(bytes) => {
if let Err(e) = std::fs::write(&file_path, bytes) {
eprintln!("update_baselines: could not write {file_path}: {e}");
}
}
Err(e) => {
eprintln!("update_baselines: serialisation error: {e}");
}
}
let mut baselines = self.baselines.write().unwrap_or_else(|e| e.into_inner());
for (platform, pr) in &result.platform_results {
let m = &pr.performance_metrics;
let ci_half = m.error_rate * 0.05; let baseline = PerformanceBaseline {
platform: platform.clone(),
metrics: vec![
super::types::BaselineMetricValue {
metric: super::types::BaselineMetric::Fidelity,
value: m.overall_fidelity,
confidence_interval: (
(m.overall_fidelity - ci_half).max(0.0),
(m.overall_fidelity + ci_half).min(1.0),
),
measurement_count: 1,
},
super::types::BaselineMetricValue {
metric: super::types::BaselineMetric::ErrorRate,
value: m.error_rate,
confidence_interval: (
(m.error_rate - ci_half).max(0.0),
m.error_rate + ci_half,
),
measurement_count: 1,
},
super::types::BaselineMetricValue {
metric: super::types::BaselineMetric::Throughput,
value: m.throughput,
confidence_interval: ((m.throughput * 0.9).max(0.0), m.throughput * 1.1),
measurement_count: 1,
},
],
last_updated: result.timestamp,
version: result.execution_id.clone(),
};
baselines.insert(format!("{platform:?}"), baseline);
}
}
async fn trigger_optimization(&self, result: &UnifiedBenchmarkResult) -> DeviceResult<()> {
let recommendations = &result.optimization_recommendations;
if recommendations.is_empty() {
return Ok(());
}
let mut improvements: HashMap<String, f64> = HashMap::new();
for r in recommendations {
*improvements
.entry(r.recommendation_type.clone())
.or_insert(0.0) += r.expected_improvement;
}
for (platform, platform_result) in &result.platform_results {
let metrics = &platform_result.performance_metrics;
if metrics.error_rate > 0.05 {
let _ = self.event_publisher.send(BenchmarkEvent::PerformanceAlert {
metric: format!("{platform:?}.error_rate"),
current_value: metrics.error_rate,
threshold: 0.05,
timestamp: SystemTime::now(),
});
}
if metrics.overall_fidelity < 0.90 {
let _ = self.event_publisher.send(BenchmarkEvent::PerformanceAlert {
metric: format!("{platform:?}.overall_fidelity"),
current_value: metrics.overall_fidelity,
threshold: 0.90,
timestamp: SystemTime::now(),
});
}
}
let _ = self
.event_publisher
.send(BenchmarkEvent::OptimizationCompleted {
execution_id: result.execution_id.clone(),
improvements,
timestamp: SystemTime::now(),
});
Ok(())
}
async fn generate_automated_reports(
&self,
result: &UnifiedBenchmarkResult,
) -> DeviceResult<()> {
let payload = serde_json::to_vec_pretty(result).map_err(|err| {
DeviceError::APIError(format!("failed to serialize benchmark result: {err}"))
})?;
let config = self
.config
.read()
.unwrap_or_else(|e| e.into_inner())
.clone();
for recipient in &config.reporting_config.automated_reports.recipients {
if let Some(path) = recipient.strip_prefix("file://") {
let dir = std::path::Path::new(path);
if let Err(err) = std::fs::create_dir_all(dir) {
return Err(DeviceError::APIError(format!(
"failed to create report directory {dir:?}: {err}"
)));
}
let file = dir.join(format!("benchmark_{}.json", result.execution_id));
if let Err(err) = std::fs::write(&file, &payload) {
return Err(DeviceError::APIError(format!(
"failed to write report {file:?}: {err}"
)));
}
}
}
let _ = self.event_publisher.send(BenchmarkEvent::PerformanceAlert {
metric: "automated_report.bytes".to_string(),
current_value: payload.len() as f64,
threshold: 0.0,
timestamp: SystemTime::now(),
});
Ok(())
}
fn get_system_info(&self) -> super::results::SystemInfo {
super::results::SystemInfo {
hostname: "localhost".to_string(),
operating_system: std::env::consts::OS.to_string(),
cpu_info: "Unknown".to_string(),
memory_total: 0,
disk_space: 0,
network_info: "Unknown".to_string(),
}
}
}
pub(crate) fn generate_recommendations_from_metrics(
platform_results: &HashMap<QuantumPlatform, PlatformBenchmarkResult>,
cross_platform_analysis: &CrossPlatformAnalysis,
) -> Vec<OptimizationRecommendation> {
let metrics_map: HashMap<QuantumPlatform, &PlatformPerformanceMetrics> = platform_results
.iter()
.map(|(p, r)| (p.clone(), &r.performance_metrics))
.collect();
generate_recommendations_from_perf_metrics(&metrics_map, cross_platform_analysis)
}
pub(crate) fn generate_recommendations_from_perf_metrics(
platform_metrics: &HashMap<QuantumPlatform, &PlatformPerformanceMetrics>,
cross_platform_analysis: &CrossPlatformAnalysis,
) -> Vec<OptimizationRecommendation> {
let mut recommendations: Vec<OptimizationRecommendation> = Vec::new();
const ERROR_RATE_THRESHOLD: f64 = 0.05;
const FIDELITY_THRESHOLD: f64 = 0.90;
const AVAILABILITY_THRESHOLD: f64 = 0.95;
const EXEC_TIME_SECS_THRESHOLD: f64 = 1.0;
const THROUGHPUT_THRESHOLD: f64 = 1.0;
for (platform, metrics) in platform_metrics {
let platform_label = format!("{platform:?}");
if metrics.error_rate > ERROR_RATE_THRESHOLD {
recommendations.push(OptimizationRecommendation {
recommendation_type: "error_mitigation".to_string(),
description: format!(
"Platform {platform_label} reports an error rate of {:.4} (threshold {:.2}). Apply zero-noise extrapolation, dynamical decoupling, or readout error mitigation to reduce systematic errors.",
metrics.error_rate, ERROR_RATE_THRESHOLD
),
expected_improvement: (metrics.error_rate - ERROR_RATE_THRESHOLD).max(0.0),
implementation_effort: "Medium".to_string(),
priority: 2,
});
}
if metrics.overall_fidelity < FIDELITY_THRESHOLD {
recommendations.push(OptimizationRecommendation {
recommendation_type: "calibration".to_string(),
description: format!(
"Platform {platform_label} fidelity {:.4} is below threshold {:.2}. Schedule recalibration of single- and two-qubit gates and refresh readout calibration.",
metrics.overall_fidelity, FIDELITY_THRESHOLD
),
expected_improvement: (FIDELITY_THRESHOLD - metrics.overall_fidelity).max(0.0),
implementation_effort: "Low".to_string(),
priority: 1,
});
}
let avg_secs = metrics.average_execution_time.as_secs_f64();
if avg_secs > EXEC_TIME_SECS_THRESHOLD {
recommendations.push(OptimizationRecommendation {
recommendation_type: "circuit_reduction".to_string(),
description: format!(
"Platform {platform_label} average execution time {avg_secs:.3}s exceeds threshold {EXEC_TIME_SECS_THRESHOLD:.2}s. Apply circuit transpilation passes (gate fusion, commutation analysis, and depth-aware routing)."
),
expected_improvement: ((avg_secs - EXEC_TIME_SECS_THRESHOLD)
/ avg_secs.max(f64::EPSILON))
.clamp(0.0, 1.0),
implementation_effort: "Medium".to_string(),
priority: 3,
});
}
if metrics.availability < AVAILABILITY_THRESHOLD {
recommendations.push(OptimizationRecommendation {
recommendation_type: "platform_redundancy".to_string(),
description: format!(
"Platform {platform_label} availability {:.3} is below threshold {:.2}. Configure failover to secondary platforms and enable retry policies.",
metrics.availability, AVAILABILITY_THRESHOLD
),
expected_improvement: (AVAILABILITY_THRESHOLD - metrics.availability).max(0.0),
implementation_effort: "Medium".to_string(),
priority: 2,
});
}
if metrics.throughput < THROUGHPUT_THRESHOLD && metrics.throughput > 0.0 {
recommendations.push(OptimizationRecommendation {
recommendation_type: "batching_optimization".to_string(),
description: format!(
"Platform {platform_label} throughput {:.3} ops/s is below threshold {THROUGHPUT_THRESHOLD:.2}. Batch jobs and submit in larger groups to amortize queue overhead.",
metrics.throughput
),
expected_improvement: ((THROUGHPUT_THRESHOLD - metrics.throughput)
/ THROUGHPUT_THRESHOLD)
.clamp(0.0, 1.0),
implementation_effort: "Low".to_string(),
priority: 4,
});
}
}
if platform_metrics.len() > 1 {
if let Some(best_for_fidelity) = cross_platform_analysis
.best_platform_per_metric
.get("fidelity")
{
recommendations.push(OptimizationRecommendation {
recommendation_type: "platform_routing".to_string(),
description: format!(
"Cross-platform analysis identifies {best_for_fidelity:?} as the best platform for fidelity. Route fidelity-critical workloads there and use other platforms for high-throughput jobs."
),
expected_improvement: 0.05,
implementation_effort: "Low".to_string(),
priority: 5,
});
}
}
if recommendations.is_empty() {
recommendations.push(OptimizationRecommendation {
recommendation_type: "monitoring".to_string(),
description: "All platform metrics are within configured thresholds. Continue periodic benchmarking to detect drift early.".to_string(),
expected_improvement: 0.0,
implementation_effort: "Low".to_string(),
priority: 9,
});
}
recommendations.sort_by_key(|r| r.priority);
recommendations
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
fn perf(
fidelity: f64,
error_rate: f64,
availability: f64,
avg_exec_secs: u64,
throughput: f64,
) -> PlatformPerformanceMetrics {
PlatformPerformanceMetrics {
overall_fidelity: fidelity,
average_execution_time: Duration::from_secs(avg_exec_secs),
throughput,
error_rate,
availability,
}
}
#[test]
fn test_recommendations_within_thresholds() {
let metrics = perf(0.99, 0.001, 0.99, 0, 100.0);
let mut platforms: HashMap<QuantumPlatform, &PlatformPerformanceMetrics> = HashMap::new();
platforms.insert(
QuantumPlatform::IBMQuantum {
device_name: "test".to_string(),
hub: None,
},
&metrics,
);
let cpa = CrossPlatformAnalysis {
platform_comparison: HashMap::new(),
best_platform_per_metric: HashMap::new(),
statistical_significance_tests: HashMap::new(),
};
let recs = generate_recommendations_from_perf_metrics(&platforms, &cpa);
assert_eq!(recs.len(), 1, "expected single info entry, got {recs:?}");
assert_eq!(recs[0].recommendation_type, "monitoring");
}
#[test]
fn test_recommendations_breach_thresholds() {
let metrics = perf(0.50, 0.20, 0.50, 5, 0.1);
let mut platforms: HashMap<QuantumPlatform, &PlatformPerformanceMetrics> = HashMap::new();
platforms.insert(
QuantumPlatform::IBMQuantum {
device_name: "test".to_string(),
hub: None,
},
&metrics,
);
let cpa = CrossPlatformAnalysis {
platform_comparison: HashMap::new(),
best_platform_per_metric: HashMap::new(),
statistical_significance_tests: HashMap::new(),
};
let recs = generate_recommendations_from_perf_metrics(&platforms, &cpa);
assert!(
recs.len() >= 5,
"expected >=5 recommendations, got {}: {recs:?}",
recs.len()
);
assert!(recs.iter().all(|r| r.recommendation_type != "monitoring"));
for w in recs.windows(2) {
assert!(w[0].priority <= w[1].priority, "not sorted: {recs:?}");
}
}
}