use std::ffi::{c_char, CStr};
use crate::{Dense, DenseGPU, DenseGPUBlock, DenseV2, Sparse, SparseV2};
use ket::{error::KetError, process::QPUConfig};
use crate::quantum_execution::QubitManager;
#[no_mangle]
pub unsafe extern "C" fn kbw_make_configuration(
num_qubits: usize,
simulator: *const c_char,
use_live: bool,
decompose: bool,
gradient: bool,
coupling_graph_json: *const c_char,
qpu_config: &mut *mut QPUConfig,
) -> i32 {
let Ok(simulator) = (unsafe { CStr::from_ptr(simulator).to_str() }) else {
return KetError::ExecutionFailed.error_code();
};
let mut simulator = simulator.to_lowercase();
simulator.retain(|c| !c.is_whitespace());
let Ok(Ok(coupling_graph)) = unsafe { CStr::from_ptr(coupling_graph_json) }
.to_str()
.map(serde_json::from_str)
else {
return KetError::SerdeError.error_code();
};
let config = match simulator.as_str() {
"densev1" => {
make_config::<Dense>(num_qubits, use_live, decompose, coupling_graph, gradient)
}
"dense" | "densev2" => {
make_config::<DenseV2>(num_qubits, use_live, decompose, coupling_graph, gradient)
}
"densegpu" => {
if num_qubits
< std::env::var("KBW_BLOCK_SIZE")
.unwrap_or_default()
.parse::<usize>()
.unwrap_or(20)
{
make_config::<DenseGPU>(num_qubits, use_live, decompose, coupling_graph, gradient)
} else {
make_config::<DenseGPUBlock>(
num_qubits,
use_live,
decompose,
coupling_graph,
gradient,
)
}
}
"sparse" => {
make_config::<Sparse>(num_qubits, use_live, decompose, coupling_graph, gradient)
}
"sparsev2" => {
make_config::<SparseV2>(num_qubits, use_live, decompose, coupling_graph, gradient)
}
_ => Err(KetError::ExecutionFailed),
};
match config {
Ok(config) => {
*qpu_config = Box::into_raw(Box::new(config));
KetError::Success.error_code()
}
Err(err) => err.error_code(),
}
}
fn make_config<S>(
num_qubits: usize,
use_live: bool,
decompose: bool,
coupling_graph: Option<Vec<(usize, usize)>>,
gradient: bool,
) -> Result<QPUConfig, KetError>
where
S: crate::quantum_execution::QuantumExecution + 'static,
QubitManager<S>: ket::execution::LiveExecution + ket::execution::BatchExecution,
{
if coupling_graph.is_none() && use_live {
QubitManager::<S>::make_live_config(num_qubits, decompose)
} else {
QubitManager::<S>::make_batch_config(num_qubits, decompose, coupling_graph, gradient)
}
}
const BUILD_INFO: &str = build_info::format!("{} v{} [{} {}]", $.crate_info.name, $.crate_info.version, $.compiler, $.target);
#[no_mangle]
pub const extern "C" fn kbw_build_info(msg: &mut *const u8, size: &mut usize) -> i32 {
let bytes = BUILD_INFO.as_bytes();
*size = bytes.len();
*msg = bytes.as_ptr();
KetError::Success.error_code()
}