use super::*;
#[no_mangle]
pub extern "C" fn dqcs_plugin_run(pdef: dqcs_handle_t, simulator: *const c_char) -> dqcs_return_t {
api_return_none(|| {
take!(pdef as PluginDefinition);
PluginState::run(&pdef, receive_str(simulator)?)
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_start(
pdef: dqcs_handle_t,
simulator: *const c_char,
) -> dqcs_handle_t {
api_return(0, || {
take!(pdef as PluginDefinition);
let simulator = receive_str(simulator)?.to_string();
Ok(insert(std::thread::spawn(move || {
std::panic::set_hook(Box::new(|info| {
eprintln!("{}", info);
}));
PluginState::run(&pdef, simulator)
})))
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_wait(pjoin: dqcs_handle_t) -> dqcs_return_t {
api_return_none(|| {
take!(pjoin as PluginJoinHandle);
pjoin.join().map_err(|_| oe_err("thread panicked")())?
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_send(
plugin: dqcs_plugin_state_t,
arb: dqcs_handle_t,
) -> dqcs_return_t {
api_return_none(|| {
resolve!(arb as pending ArbData);
clone!(arb_ob: ArbData = resolved arb);
plugin.resolve()?.send(arb_ob)?;
delete!(resolved arb);
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_recv(plugin: dqcs_plugin_state_t) -> dqcs_handle_t {
api_return(0, || Ok(insert(plugin.resolve()?.recv()?)))
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_allocate(
plugin: dqcs_plugin_state_t,
num_qubits: usize,
cq: dqcs_handle_t,
) -> dqcs_handle_t {
api_return(0, || {
let result = QubitReferenceSet::from(if cq != 0 {
resolve!(cq as pending ArbCmdQueue);
clone!(cq_ob: ArbCmdQueue = resolved cq);
let result = plugin
.resolve()?
.allocate(num_qubits, cq_ob.into_iter().collect())?;
delete!(resolved cq);
result
} else {
plugin.resolve()?.allocate(num_qubits, vec![])?
});
Ok(insert(result))
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_free(
plugin: dqcs_plugin_state_t,
qbset: dqcs_handle_t,
) -> dqcs_return_t {
api_return_none(|| {
resolve!(qbset as pending QubitReferenceSet);
clone!(qbset_ob: QubitReferenceSet = resolved qbset);
plugin.resolve()?.free(qbset_ob.into())?;
delete!(resolved qbset);
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_gate(
plugin: dqcs_plugin_state_t,
gate: dqcs_handle_t,
) -> dqcs_return_t {
api_return_none(|| {
resolve!(gate as pending Gate);
clone!(gate_ob: Gate = resolved gate);
plugin.resolve()?.gate(gate_ob)?;
delete!(resolved gate);
Ok(())
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_get_measurement(
plugin: dqcs_plugin_state_t,
qubit: dqcs_qubit_t,
) -> dqcs_handle_t {
api_return(0, || {
let qubit =
QubitRef::from_foreign(qubit).ok_or_else(oe_inv_arg("0 is not a valid qubit"))?;
Ok(insert(plugin.resolve()?.get_measurement(qubit)?))
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_get_cycles_since_measure(
plugin: dqcs_plugin_state_t,
qubit: dqcs_qubit_t,
) -> dqcs_cycle_t {
api_return(-1, || {
let qubit =
QubitRef::from_foreign(qubit).ok_or_else(oe_inv_arg("0 is not a valid qubit"))?;
Ok(plugin.resolve()?.get_cycles_since_measure(qubit)? as dqcs_cycle_t)
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_get_cycles_between_measures(
plugin: dqcs_plugin_state_t,
qubit: dqcs_qubit_t,
) -> dqcs_cycle_t {
api_return(-1, || {
let qubit =
QubitRef::from_foreign(qubit).ok_or_else(oe_inv_arg("0 is not a valid qubit"))?;
Ok(plugin.resolve()?.get_cycles_between_measures(qubit)? as dqcs_cycle_t)
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_advance(
plugin: dqcs_plugin_state_t,
cycles: dqcs_cycle_t,
) -> dqcs_cycle_t {
api_return(-1, || {
if cycles < 0 {
inv_arg("cannot advance by a negative number of cycles")
} else {
Ok(plugin.resolve()?.advance(cycles as u64)?.into())
}
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_get_cycle(plugin: dqcs_plugin_state_t) -> dqcs_cycle_t {
api_return(-1, || Ok(plugin.resolve()?.get_cycle()?.into()))
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_arb(
plugin: dqcs_plugin_state_t,
cmd: dqcs_handle_t,
) -> dqcs_handle_t {
api_return(0, || {
resolve!(cmd as pending ArbCmd);
clone!(cmd_ob: ArbCmd = resolved cmd);
let result = plugin.resolve()?.arb(cmd_ob)?;
delete!(resolved cmd);
Ok(insert(result))
})
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_random_u64(plugin: dqcs_plugin_state_t) -> dqcs_handle_t {
api_return(0, || Ok(plugin.resolve()?.random_u64()))
}
#[no_mangle]
pub extern "C" fn dqcs_plugin_random_f64(plugin: dqcs_plugin_state_t) -> c_double {
api_return(0.0, || Ok(plugin.resolve()?.random_f64()))
}