ket/c_api/
execution.rs

1// SPDX-FileCopyrightText: 2024 Evandro Chagas Ribeiro da Rosa <evandro@quantuloop.com>
2// SPDX-FileCopyrightText: 2024 2024 Otávio Augusto de Santana Jatobá <otavio.jatoba@grad.ufsc.br>
3//
4// SPDX-License-Identifier: Apache-2.0
5
6use crate::execution::*;
7
8#[repr(C)]
9#[derive(Debug, Clone)]
10pub struct BatchCExecution {
11    submit_execution: fn(*const u8, usize, *const u8, usize),
12    get_results: fn(data: &mut *const u8, len: &mut usize),
13}
14
15impl BatchExecution for BatchCExecution {
16    fn submit_execution(
17        &mut self,
18        logical_circuit: &[Instruction<LogicalQubit>],
19        physical_circuit: Option<&[Instruction<PhysicalQubit>]>,
20    ) {
21        let logical_circuit = serde_json::to_vec(logical_circuit).unwrap();
22        let physical_circuit = serde_json::to_vec(&physical_circuit).unwrap();
23        (self.submit_execution)(
24            logical_circuit.as_ptr(),
25            logical_circuit.len(),
26            physical_circuit.as_ptr(),
27            physical_circuit.len(),
28        );
29    }
30
31    fn get_results(&mut self) -> ResultData {
32        let mut buffer = std::ptr::null();
33        let mut len: usize = 0;
34        (self.get_results)(&mut buffer, &mut len);
35        let buffer = unsafe { std::slice::from_raw_parts(buffer, len) };
36        serde_json::from_slice(buffer).unwrap()
37    }
38}
39
40#[no_mangle]
41/// # Safety
42pub unsafe extern "C" fn ket_make_configuration(
43    num_qubits: usize,
44    batch_execution: *const BatchCExecution,
45    measure: i32,
46    sample: i32,
47    exp_value: i32,
48    dump: i32,
49    define_qpu: bool,
50    coupling_graph: *const (usize, usize),
51    coupling_graph_size: usize,
52    u4_gate: i32,
53    u2_gates: i32,
54    result: &mut *mut Configuration,
55) -> i32 {
56    let execution: Option<QuantumExecution> = if batch_execution.is_null() {
57        None
58    } else {
59        Some(QuantumExecution::Batch(Box::new(unsafe {
60            (*batch_execution).clone()
61        })))
62    };
63
64    let qpu = if define_qpu {
65        let coupling_graph = if coupling_graph_size == 0 {
66            None
67        } else {
68            let coupling_graph = std::slice::from_raw_parts(coupling_graph, coupling_graph_size);
69            Some(coupling_graph.to_owned())
70        };
71
72        let u4_gate = match u4_gate {
73            0 => U4Gate::CX,
74            1 => U4Gate::CZ,
75            _ => panic!("undefined U4 gate type"),
76        };
77
78        let u2_gates = match u2_gates {
79            0 => U2Gates::All,
80            1 => U2Gates::ZYZ,
81            2 => U2Gates::RzSx,
82            _ => panic!("undefined U2 gate set"),
83        };
84        Some(QPU::new(coupling_graph, num_qubits, u2_gates, u4_gate))
85    } else {
86        None
87    };
88
89    *result = Box::into_raw(Box::new(Configuration {
90        num_qubits,
91        execution,
92        qpu,
93        measure: FeatureStatus::from(measure),
94        sample: FeatureStatus::from(sample),
95        exp_value: FeatureStatus::from(exp_value),
96        dump: FeatureStatus::from(dump),
97    }));
98
99    0
100}