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}