Skip to main content

clawft_kernel/
quantum_braket.rs

1//! AWS Braket backend stub targeting QuEra Aquila.
2//!
3//! EXPERIMENTAL (0.6.x). Interface-only — AWS SigV4 auth and the Braket AHS
4//! (Analog Hamiltonian Simulation) JSON body are deferred to a later release.
5//! See `.planning/development_notes/pasqal-integration.md` §13.
6//!
7//! Targets:
8//! - QuEra Aquila (256 atoms, Rydberg) via
9//!   `arn:aws:braket:us-east-1::device/qpu/quera/Aquila`
10//! - Braket local simulator (`braket_sv`) for dev
11//!
12//! Feature: `quantum-braket` (off by default).
13
14use async_trait::async_trait;
15
16use crate::quantum_backend::{
17    BackendStatus, EvolutionParams, JobHandle, JobStatus, QuantumBackend, QuantumError,
18    QuantumResults,
19};
20use crate::quantum_state::QuantumCognitiveState;
21
22/// Braket device selector (analog neutral-atom only — the trait doesn't model
23/// gate-based devices).
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub enum BraketDevice {
26    QueraAquila,
27    LocalSimulator,
28}
29
30impl BraketDevice {
31    pub fn arn(self) -> &'static str {
32        match self {
33            BraketDevice::QueraAquila => "arn:aws:braket:us-east-1::device/qpu/quera/Aquila",
34            BraketDevice::LocalSimulator => "local:braket/braket_ahs_sim",
35        }
36    }
37
38    pub fn max_qubits(self) -> usize {
39        match self {
40            BraketDevice::QueraAquila => 256,
41            BraketDevice::LocalSimulator => 40,
42        }
43    }
44}
45
46/// Configuration for the Braket backend.
47#[derive(Debug, Clone)]
48pub struct BraketConfig {
49    pub region: String,
50    pub s3_results_bucket: String,
51    pub s3_results_prefix: String,
52    pub device: BraketDevice,
53    /// Access key is read from the AWS credential chain in production; only
54    /// stored on the config for tests/mocks.
55    pub access_key_id: Option<String>,
56    pub secret_access_key: Option<String>,
57}
58
59impl Default for BraketConfig {
60    fn default() -> Self {
61        Self {
62            region: "us-east-1".into(),
63            s3_results_bucket: String::new(),
64            s3_results_prefix: "weftos-quantum/".into(),
65            device: BraketDevice::LocalSimulator,
66            access_key_id: None,
67            secret_access_key: None,
68        }
69    }
70}
71
72/// Stub Braket backend. Compiles and returns `NotImplemented` on submission.
73pub struct BraketBackend {
74    cfg: BraketConfig,
75}
76
77impl BraketBackend {
78    pub fn new(cfg: BraketConfig) -> Self {
79        Self { cfg }
80    }
81
82    pub fn config(&self) -> &BraketConfig {
83        &self.cfg
84    }
85}
86
87#[async_trait]
88impl QuantumBackend for BraketBackend {
89    fn name(&self) -> &'static str {
90        "braket"
91    }
92
93    fn max_qubits(&self) -> usize {
94        self.cfg.device.max_qubits()
95    }
96
97    async fn health_check(&self) -> Result<BackendStatus, QuantumError> {
98        Ok(BackendStatus {
99            name: "braket",
100            reachable: false,
101            queue_depth: None,
102            estimated_wait: None,
103            max_qubits: self.max_qubits(),
104        })
105    }
106
107    async fn submit_evolution(
108        &self,
109        _register: &[(String, [f64; 2])],
110        _state: &QuantumCognitiveState,
111        _params: EvolutionParams,
112    ) -> Result<JobHandle, QuantumError> {
113        Err(QuantumError::NotImplemented)
114    }
115
116    async fn poll(&self, _handle: &JobHandle) -> Result<JobStatus, QuantumError> {
117        Err(QuantumError::NotImplemented)
118    }
119
120    async fn get_results(
121        &self,
122        _handle: &JobHandle,
123    ) -> Result<Option<QuantumResults>, QuantumError> {
124        Err(QuantumError::NotImplemented)
125    }
126
127    async fn cancel(&self, _handle: &JobHandle) -> Result<(), QuantumError> {
128        Err(QuantumError::NotImplemented)
129    }
130}
131
132#[cfg(test)]
133mod tests {
134    use super::*;
135
136    #[test]
137    fn aquila_arn_is_correct_region() {
138        assert!(BraketDevice::QueraAquila.arn().contains("us-east-1"));
139        assert!(BraketDevice::QueraAquila.arn().contains("Aquila"));
140    }
141
142    #[test]
143    fn aquila_supports_256_qubits() {
144        assert_eq!(BraketDevice::QueraAquila.max_qubits(), 256);
145    }
146
147    #[test]
148    fn stub_submit_returns_not_implemented() {
149        let backend = BraketBackend::new(BraketConfig::default());
150        let state = QuantumCognitiveState::uniform(1, &[0]);
151        let rt = tokio::runtime::Builder::new_current_thread()
152            .enable_all()
153            .build()
154            .unwrap();
155        let err = rt
156            .block_on(backend.submit_evolution(&[], &state, EvolutionParams::default()))
157            .unwrap_err();
158        assert!(matches!(err, QuantumError::NotImplemented));
159    }
160}