quantrs2_device/cloud/provider_optimizations/
googleoptimizer_traits.rs1use super::traits::ProviderOptimizer;
15use super::types::*;
16use crate::prelude::CloudProvider;
17use crate::DeviceResult;
18use std::collections::HashMap;
19use std::time::Duration;
20use uuid::Uuid;
21
22const GOOGLE_PER_GATE_QUBIT_USD: f64 = 0.00090;
30
31const GOOGLE_PER_JOB_FEE_USD: f64 = 0.50;
33
34#[derive(Debug, Clone, Copy)]
39struct GoogleProcessorSpec {
40 name: &'static str,
41 qubit_count: usize,
42 cz_fidelity: f64,
44 sqrt_iswap_fidelity: f64,
46 relative_queue_depth: f64,
48 queue_latency_s: f64,
50}
51
52const GOOGLE_PROCESSORS: &[GoogleProcessorSpec] = &[
53 GoogleProcessorSpec {
54 name: "google_sycamore_weber",
55 qubit_count: 53,
56 cz_fidelity: 0.994,
57 sqrt_iswap_fidelity: 0.992,
58 relative_queue_depth: 0.60,
59 queue_latency_s: 120.0,
60 },
61 GoogleProcessorSpec {
62 name: "google_sycamore_rainbow",
63 qubit_count: 23,
64 cz_fidelity: 0.991,
65 sqrt_iswap_fidelity: 0.989,
66 relative_queue_depth: 0.45,
67 queue_latency_s: 90.0,
68 },
69 GoogleProcessorSpec {
70 name: "google_willow",
71 qubit_count: 105,
72 cz_fidelity: 0.997,
73 sqrt_iswap_fidelity: 0.996,
74 relative_queue_depth: 0.80,
75 queue_latency_s: 180.0,
76 },
77];
78
79fn select_google_processor(
82 qubit_count: usize,
83 min_fidelity: f64,
84) -> Option<&'static GoogleProcessorSpec> {
85 GOOGLE_PROCESSORS
86 .iter()
87 .filter(|p| {
88 p.qubit_count >= qubit_count
89 && p.cz_fidelity >= min_fidelity
90 && p.sqrt_iswap_fidelity >= min_fidelity
91 })
92 .max_by(|a, b| {
93 let score_a = a.cz_fidelity - a.relative_queue_depth * 0.05;
95 let score_b = b.cz_fidelity - b.relative_queue_depth * 0.05;
96 score_a
97 .partial_cmp(&score_b)
98 .unwrap_or(std::cmp::Ordering::Equal)
99 })
100}
101
102impl ProviderOptimizer for GoogleOptimizer {
107 fn optimize_workload(
115 &self,
116 workload: &WorkloadSpec,
117 ) -> DeviceResult<OptimizationRecommendation> {
118 let qubit_count = workload.circuit_characteristics.qubit_count;
119 let shots = workload.execution_requirements.shots;
120 let min_fidelity = workload
121 .circuit_characteristics
122 .coherence_requirements
123 .min_gate_fidelity;
124 let circuit_depth = workload.circuit_characteristics.circuit_depth;
125
126 let primary = select_google_processor(qubit_count, min_fidelity).ok_or_else(|| {
127 crate::DeviceError::InvalidInput(format!(
128 "No Google Quantum AI processor can accommodate {qubit_count} qubits \
129 with CZ / √iSWAP fidelity ≥ {min_fidelity:.3}"
130 ))
131 })?;
132
133 let use_rem = circuit_depth > 20;
134
135 let recommended_config = ExecutionConfig {
136 provider: CloudProvider::Google,
137 backend: primary.name.to_string(),
138 optimization_settings: OptimizationSettings {
139 circuit_optimization: CircuitOptimizationSettings {
140 gate_fusion: true,
141 gate_cancellation: true,
142 circuit_compression: true,
143 transpilation_level: TranspilationLevel::Advanced,
144 error_mitigation: ErrorMitigationSettings {
145 zero_noise_extrapolation: false,
146 readout_error_mitigation: use_rem,
147 gate_error_mitigation: false,
148 decoherence_mitigation: false,
149 crosstalk_mitigation: false,
150 },
151 },
152 hardware_optimization: HardwareOptimizationSettings {
153 qubit_mapping: QubitMappingStrategy::TopologyAware,
154 routing_optimization: RoutingOptimizationStrategy::NoiseAware,
155 calibration_optimization: CalibrationOptimizationStrategy::RealTime,
156 noise_adaptation: NoiseAdaptationStrategy::ModelBased,
157 },
158 ..OptimizationSettings::default()
159 },
160 ..ExecutionConfig::default()
161 };
162
163 let cost_estimate = compute_google_cost(shots, circuit_depth, qubit_count, primary);
164 let perf_prediction = compute_google_performance(workload, primary);
165
166 let alternatives: Vec<AlternativeRecommendation> = GOOGLE_PROCESSORS
167 .iter()
168 .filter(|p| {
169 p.name != primary.name
170 && p.qubit_count >= qubit_count
171 && p.cz_fidelity >= min_fidelity
172 })
173 .map(|p| {
174 let alt_cost = compute_google_cost(shots, circuit_depth, qubit_count, p);
175 let alt_perf = compute_google_performance(workload, p);
176 AlternativeRecommendation {
177 alternative_id: Uuid::new_v4().to_string(),
178 config: ExecutionConfig {
179 provider: CloudProvider::Google,
180 backend: p.name.to_string(),
181 optimization_settings: OptimizationSettings::default(),
182 ..ExecutionConfig::default()
183 },
184 trade_offs: TradeOffAnalysis {
185 performance_impact: alt_perf.expected_fidelity
186 - perf_prediction.expected_fidelity,
187 cost_impact: alt_cost.total_cost - cost_estimate.total_cost,
188 reliability_impact: 0.0,
189 complexity_impact: 0.0,
190 trade_off_summary: format!(
191 "{} — {}-qubit, queue depth {:.0}%, Δcost ${:+.4}, Δfidelity {:+.4}",
192 p.name,
193 p.qubit_count,
194 p.relative_queue_depth * 100.0,
195 alt_cost.total_cost - cost_estimate.total_cost,
196 alt_perf.expected_fidelity - perf_prediction.expected_fidelity
197 ),
198 },
199 use_case_suitability: alt_perf.success_probability,
200 }
201 })
202 .collect();
203
204 let rationale = format!(
205 "Selected Google Quantum AI processor {} ({} qubits) as the best option \
206 for {qubit_count} qubits with CZ fidelity ≥ {min_fidelity:.3}. \
207 CZ fidelity: {:.4}, √iSWAP fidelity: {:.4}. \
208 REM: {}. Estimated cost: ${:.4}.",
209 primary.name,
210 primary.qubit_count,
211 primary.cz_fidelity,
212 primary.sqrt_iswap_fidelity,
213 if use_rem { "enabled" } else { "disabled" },
214 cost_estimate.total_cost,
215 );
216
217 Ok(OptimizationRecommendation {
218 recommendation_id: Uuid::new_v4().to_string(),
219 workload_id: workload.workload_id.clone(),
220 provider: CloudProvider::Google,
221 recommended_config,
222 optimization_strategies: self.get_optimization_strategies(),
223 expected_performance: perf_prediction,
224 cost_estimate,
225 confidence_score: 0.80,
226 rationale,
227 alternative_recommendations: alternatives,
228 })
229 }
230
231 fn get_provider(&self) -> CloudProvider {
232 CloudProvider::Google
233 }
234
235 fn get_optimization_strategies(&self) -> Vec<OptimizationStrategy> {
236 vec![
237 OptimizationStrategy::CircuitOptimization,
238 OptimizationStrategy::PerformanceOptimization,
239 OptimizationStrategy::ResourceProvisioning,
240 ]
241 }
242
243 fn predict_performance(
244 &self,
245 workload: &WorkloadSpec,
246 config: &ExecutionConfig,
247 ) -> DeviceResult<PerformancePrediction> {
248 let processor = GOOGLE_PROCESSORS
249 .iter()
250 .find(|p| p.name == config.backend)
251 .unwrap_or(&GOOGLE_PROCESSORS[0]);
252 Ok(compute_google_performance(workload, processor))
253 }
254
255 fn estimate_cost(
256 &self,
257 workload: &WorkloadSpec,
258 config: &ExecutionConfig,
259 ) -> DeviceResult<CostEstimate> {
260 let processor = GOOGLE_PROCESSORS
261 .iter()
262 .find(|p| p.name == config.backend)
263 .unwrap_or(&GOOGLE_PROCESSORS[0]);
264 Ok(compute_google_cost(
265 workload.execution_requirements.shots,
266 workload.circuit_characteristics.circuit_depth,
267 workload.circuit_characteristics.qubit_count,
268 processor,
269 ))
270 }
271}
272
273fn compute_google_cost(
278 shots: usize,
279 circuit_depth: usize,
280 qubit_count: usize,
281 processor: &GoogleProcessorSpec,
282) -> CostEstimate {
283 let gate_qubit_ops = shots as f64 * circuit_depth as f64 * qubit_count as f64;
285 let execution_cost = gate_qubit_ops * GOOGLE_PER_GATE_QUBIT_USD;
286 let total = execution_cost + GOOGLE_PER_JOB_FEE_USD;
287 let uncertainty = total * 0.25; CostEstimate {
290 total_cost: total,
291 cost_breakdown: CostBreakdown {
292 execution_cost,
293 queue_cost: 0.0,
294 storage_cost: 0.0,
295 network_cost: 0.0,
296 overhead_cost: GOOGLE_PER_JOB_FEE_USD,
297 discount_applied: 0.0,
298 },
299 cost_model: CostModel::PayPerUse,
300 uncertainty_range: (total - uncertainty, total + uncertainty),
301 cost_optimization_opportunities: vec![CostOptimizationOpportunity {
302 opportunity_type: CostOptimizationType::ResourceRightSizing,
303 potential_savings: total * 0.20,
304 implementation_effort: 0.30,
305 description: "Reduce circuit depth with Cirq optimisation passes \
306 (gate cancellation, two-qubit compilation) to lower the \
307 gate-qubit operation count."
308 .to_string(),
309 }],
310 }
311}
312
313fn compute_google_performance(
314 workload: &WorkloadSpec,
315 processor: &GoogleProcessorSpec,
316) -> PerformancePrediction {
317 let cc = &workload.circuit_characteristics;
318 let shots = workload.execution_requirements.shots;
319
320 let cz_layers = (cc.circuit_depth / 2).max(1) as f64;
322 let expected_fidelity = processor.cz_fidelity.powf(cz_layers).clamp(0.01, 1.0);
323 let success_probability = (expected_fidelity * 0.975).clamp(0.0, 1.0);
324
325 let exec_s = shots as f64 * 0.001;
327
328 PerformancePrediction {
329 execution_time: Duration::from_secs_f64(exec_s),
330 queue_time: Duration::from_secs_f64(processor.queue_latency_s),
331 total_time: Duration::from_secs_f64(exec_s + processor.queue_latency_s),
332 success_probability,
333 expected_fidelity,
334 resource_utilization: ResourceUtilizationPrediction {
335 cpu_utilization: 0.04,
336 memory_utilization: 0.10,
337 quantum_resource_utilization: cc.qubit_count as f64 / processor.qubit_count as f64,
338 network_utilization: 0.02,
339 storage_utilization: 0.01,
340 },
341 bottlenecks: Vec::new(),
342 confidence_interval: (success_probability * 0.90, success_probability * 1.05),
343 }
344}