Skip to main content

qcs_sdk/qpu/
isa.rs

1use qcs_api_client_openapi::models::{
2    Architecture, Characteristic, Edge, Family, InstructionSetArchitecture, Node, Operation,
3    OperationSite, Parameter,
4};
5use rigetti_pyo3::{
6    create_init_submodule, py_function_sync_async, py_wrap_data_struct, py_wrap_error,
7    py_wrap_union_enum,
8    pyo3::{
9        exceptions::{PyRuntimeError, PyValueError},
10        prelude::*,
11        types::{PyFloat, PyInt, PyList, PyString},
12        Py,
13    },
14    wrap_error, ToPythonError,
15};
16
17use qcs::qpu::get_isa;
18
19use crate::client::PyQcsClient;
20
21create_init_submodule! {
22    classes: [
23        PyFamily,
24        PyEdge,
25        PyNode,
26        PyArchitecture,
27        PyCharacteristic,
28        PyParameter,
29        PyOperationSite,
30        PyOperation,
31        PyInstructionSetArchitecture
32    ],
33    errors: [
34        SerializeISAError,
35        GetISAError
36    ],
37    funcs: [
38        py_get_instruction_set_architecture,
39        py_get_instruction_set_architecture_async
40    ],
41}
42
43wrap_error!(RustSerializeIsaError(serde_json::Error));
44py_wrap_error!(isa, RustSerializeIsaError, SerializeISAError, PyValueError);
45
46wrap_error!(RustGetIsaError(qcs::qpu::GetIsaError));
47py_wrap_error!(isa, RustGetIsaError, GetISAError, PyRuntimeError);
48
49py_wrap_union_enum! {
50    PyFamily(Family) as "Family" {
51        none: None,
52        full: Full,
53        aspen: Aspen,
54        ankaa: Ankaa,
55        unknown: Unknown => String
56    }
57}
58
59py_wrap_data_struct! {
60    PyEdge(Edge) as "Edge" {
61        node_ids: Vec<i64> => Py<PyList>
62    }
63}
64
65py_wrap_data_struct! {
66    PyNode(Node) as "Node" {
67        node_id: i64 => Py<PyInt>
68    }
69}
70
71py_wrap_data_struct! {
72    PyArchitecture(Architecture) as "Architecture" {
73        edges: Vec<Edge> => Vec<PyEdge>,
74        family: Option<Box<Family>> => Option<PyFamily>,
75        nodes: Vec<Node> => Vec<PyNode>
76    }
77}
78
79py_wrap_data_struct! {
80    PyCharacteristic(Characteristic) as "Characteristic" {
81        error: Option<f64> => Option<Py<PyFloat>>,
82        name: String => Py<PyString>,
83        node_ids: Option<Vec<i64>> => Option<Py<PyList>>,
84        parameter_values: Option<Vec<f64>> => Option<Py<PyList>>,
85        timestamp: String => Py<PyString>,
86        value: f64 => Py<PyFloat>
87    }
88}
89
90py_wrap_data_struct! {
91    PyParameter(Parameter) as "Parameter" {
92        name: String => Py<PyString>
93    }
94}
95
96py_wrap_data_struct! {
97    PyOperationSite(OperationSite) as "OperationSite" {
98        characteristics: Vec<Characteristic> => Vec<PyCharacteristic>,
99        node_ids: Vec<i64> => Py<PyList>
100    }
101}
102
103py_wrap_data_struct! {
104    PyOperation(Operation) as "Operation" {
105        characteristics: Vec<Characteristic> => Vec<PyCharacteristic>,
106        name: String => Py<PyString>,
107        node_count: Option<i64> => Option<Py<PyInt>>,
108        parameters: Vec<Parameter> => Vec<PyParameter>,
109        sites: Vec<OperationSite> => Vec<PyOperationSite>
110    }
111}
112
113py_wrap_data_struct! {
114    PyInstructionSetArchitecture(InstructionSetArchitecture) as "InstructionSetArchitecture" {
115        architecture: Box<Architecture> => PyArchitecture,
116        benchmarks: Vec<Operation> => Vec<PyOperation>,
117        instructions: Vec<Operation> => Vec<PyOperation>,
118        name: String => Py<PyString>
119    }
120}
121
122#[pymethods]
123impl PyInstructionSetArchitecture {
124    #[staticmethod]
125    pub fn from_raw(json: String) -> PyResult<Self> {
126        let isa = serde_json::from_str(&json)
127            .map_err(RustSerializeIsaError::from)
128            .map_err(RustSerializeIsaError::to_py_err)?;
129        Ok(Self(isa))
130    }
131
132    #[pyo3(signature = (pretty = false))]
133    pub fn json(&self, pretty: bool) -> PyResult<String> {
134        let data = {
135            if pretty {
136                serde_json::to_string_pretty(&self.0)
137            } else {
138                serde_json::to_string(&self.0)
139            }
140        }
141        .map_err(RustSerializeIsaError::from)
142        .map_err(RustSerializeIsaError::to_py_err)?;
143        Ok(data)
144    }
145}
146
147py_function_sync_async! {
148    #[pyfunction]
149    #[pyo3(signature = (quantum_processor_id, client = None))]
150    async fn get_instruction_set_architecture(
151        quantum_processor_id: String,
152        client: Option<PyQcsClient>,
153    ) -> PyResult<PyInstructionSetArchitecture> {
154        let client = PyQcsClient::get_or_create_client(client);
155
156        get_isa(&quantum_processor_id, &client)
157            .await
158            .map(PyInstructionSetArchitecture::from)
159            .map_err(RustGetIsaError::from)
160            .map_err(RustGetIsaError::to_py_err)
161    }
162}