sc_neurocore_engine/quantum/
bindings.rs1use pyo3::prelude::*;
12use pyo3::types::PyDict;
13
14use crate::quantum;
15
16#[pyfunction]
24#[pyo3(signature = (h_indices, h_values, j_i, j_j, j_values, spins, offset=0.0))]
25fn py_qa_ising_energy(
26 _py: Python<'_>,
27 h_indices: Vec<usize>,
28 h_values: Vec<f64>,
29 j_i: Vec<usize>,
30 j_j: Vec<usize>,
31 j_values: Vec<f64>,
32 spins: Vec<i8>,
33 offset: f64,
34) -> f64 {
35 let h: Vec<(usize, f64)> = h_indices.into_iter().zip(h_values).collect();
36 let j: Vec<((usize, usize), f64)> = j_i.into_iter().zip(j_j).zip(j_values).collect();
37 quantum::ising_energy(&h, &j, &spins, offset)
38}
39
40#[pyfunction]
42#[pyo3(signature = (h_indices, h_values, j_i, j_j, j_values, configs, offset=0.0))]
43fn py_qa_batch_ising_energy(
44 _py: Python<'_>,
45 h_indices: Vec<usize>,
46 h_values: Vec<f64>,
47 j_i: Vec<usize>,
48 j_j: Vec<usize>,
49 j_values: Vec<f64>,
50 configs: Vec<Vec<i8>>,
51 offset: f64,
52) -> Vec<f64> {
53 let h: Vec<(usize, f64)> = h_indices.into_iter().zip(h_values).collect();
54 let j: Vec<((usize, usize), f64)> = j_i.into_iter().zip(j_j).zip(j_values).collect();
55 quantum::batch_ising_energy(&h, &j, &configs, offset)
56}
57
58#[pyfunction]
62#[pyo3(signature = (h_indices, h_values, j_i, j_j, j_values, n_qubits, offset=0.0, n_sweeps=1000, num_reads=10, beta_start=0.1, beta_end=10.0, seed=42))]
63fn py_qa_simulated_annealing<'py>(
64 py: Python<'py>,
65 h_indices: Vec<usize>,
66 h_values: Vec<f64>,
67 j_i: Vec<usize>,
68 j_j: Vec<usize>,
69 j_values: Vec<f64>,
70 n_qubits: usize,
71 offset: f64,
72 n_sweeps: usize,
73 num_reads: usize,
74 beta_start: f64,
75 beta_end: f64,
76 seed: u64,
77) -> PyResult<Py<PyAny>> {
78 let h: Vec<(usize, f64)> = h_indices.into_iter().zip(h_values).collect();
79 let j: Vec<((usize, usize), f64)> = j_i.into_iter().zip(j_j).zip(j_values).collect();
80
81 let (best_spins, best_energy, all_energies, all_samples) = quantum::simulated_annealing(
82 &h, &j, n_qubits, offset, n_sweeps, num_reads, beta_start, beta_end, seed,
83 );
84
85 let dict = PyDict::new(py);
86 dict.set_item("best_spins", best_spins)?;
87 dict.set_item("best_energy", best_energy)?;
88 dict.set_item("energies", all_energies)?;
89 dict.set_item("samples", all_samples)?;
90 dict.set_item("n_sweeps", n_sweeps)?;
91 dict.set_item("num_reads", num_reads)?;
92 dict.set_item("backend", "rust")?;
93 Ok(dict.into_any().unbind())
94}
95
96#[pyfunction]
98#[allow(clippy::type_complexity)] fn py_qa_gauge_transform(
100 _py: Python<'_>,
101 h_indices: Vec<usize>,
102 h_values: Vec<f64>,
103 j_i: Vec<usize>,
104 j_j: Vec<usize>,
105 j_values: Vec<f64>,
106 gauge: Vec<i8>,
107) -> (Vec<(usize, f64)>, Vec<((usize, usize), f64)>) {
108 let h: Vec<(usize, f64)> = h_indices.into_iter().zip(h_values).collect();
109 let j: Vec<((usize, usize), f64)> = j_i.into_iter().zip(j_j).zip(j_values).collect();
110 quantum::gauge_transform(&h, &j, &gauge)
111}
112
113#[pyfunction]
115#[pyo3(signature = (n_qubits, n_gauges=10, seed=42))]
116fn py_qa_generate_gauges(
117 _py: Python<'_>,
118 n_qubits: usize,
119 n_gauges: usize,
120 seed: u64,
121) -> Vec<Vec<i8>> {
122 quantum::generate_gauges(n_qubits, n_gauges, seed)
123}
124
125#[pyfunction]
127#[pyo3(signature = (n_qubits, j_i, j_j, j_values, max_partition_size=64))]
128fn py_qa_greedy_partition(
129 _py: Python<'_>,
130 n_qubits: usize,
131 j_i: Vec<usize>,
132 j_j: Vec<usize>,
133 j_values: Vec<f64>,
134 max_partition_size: usize,
135) -> Vec<Vec<usize>> {
136 let j: Vec<((usize, usize), f64)> = j_i.into_iter().zip(j_j).zip(j_values).collect();
137 quantum::greedy_partition(n_qubits, &j, max_partition_size)
138}
139
140pub(crate) fn register(m: &Bound<'_, PyModule>) -> PyResult<()> {
141 m.add_function(wrap_pyfunction!(py_qa_ising_energy, m)?)?;
142 m.add_function(wrap_pyfunction!(py_qa_batch_ising_energy, m)?)?;
143 m.add_function(wrap_pyfunction!(py_qa_simulated_annealing, m)?)?;
144 m.add_function(wrap_pyfunction!(py_qa_gauge_transform, m)?)?;
145 m.add_function(wrap_pyfunction!(py_qa_generate_gauges, m)?)?;
146 m.add_function(wrap_pyfunction!(py_qa_greedy_partition, m)?)?;
147 Ok(())
148}