Motivation
QDMI currently provides a C API and a C tutorial for device implementations. As Rust adoption grows in the quantum computing ecosystem, official Rust bindings would lower the barrier for Rust-based quantum frameworks to integrate with QDMI.
We maintain Arvak, a Rust-native quantum compilation and orchestration platform. To use QDMI, we had to write our own FFI bindings — both for the client side (querying devices, submitting jobs) and the device side (implementing a QDMI device in Rust). These bindings are hand-written against the v1.2.1 headers and have been in production use.
What we'd contribute
A qdmi-rs crate (or qdmi-sys + qdmi split) providing:
1. Low-level FFI (qdmi-sys)
Direct mapping of all QDMI C types and functions:
- Status codes (
QDMI_STATUS → QdmiStatus enum with is_success())
- Opaque handles (
QDMI_Device, QDMI_Site, QDMI_Operation, QDMI_Job)
- All property enums (
QDMI_DEVICE_PROPERTY_T, QDMI_SITE_PROPERTY_T, QDMI_OPERATION_PROPERTY_T)
- Session parameter enums (
QDMI_SESSION_PARAMETER_T, QDMI_DEVICE_SESSION_PARAMETER_T)
- Job parameter/result enums (
QDMI_DEVICE_JOB_PARAMETER_T, QDMI_DEVICE_JOB_RESULT_T)
- All query function signatures (
qdmi_session_query_*, qdmi_device_query_*, etc.)
2. Safe Rust wrappers (qdmi)
Ergonomic Rust API over the raw FFI:
- Client side:
QdmiSession, QdmiDevice, QdmiJob with RAII (Drop-based cleanup)
- Device side: Trait-based device implementation — implement
QdmiDeviceImpl trait instead of exporting C function pointers manually
- Buffer-query pattern abstracted away (the two-call
NULL → allocate → query pattern is handled internally)
- Proper
Result<T, QdmiError> error handling instead of raw status code checking
3. Device implementation via Rust traits
Instead of manually exporting prefixed C symbols, a device author would:
use qdmi::device::{DeviceImpl, DeviceInfo, SiteInfo};
struct MyQuantumDevice { /* ... */ }
impl DeviceImpl for MyQuantumDevice {
fn name(&self) -> &str { "my-device" }
fn num_qubits(&self) -> u32 { 20 }
fn sites(&self) -> Vec<SiteInfo> { /* ... */ }
fn submit(&self, program: &str, shots: u32) -> Result<JobHandle, QdmiError> { /* ... */ }
}
// Macro generates the prefixed C exports
qdmi::export_device!(MyQuantumDevice);
Current state of our bindings
Our FFI bindings cover QDMI v1.2.1 completely:
Both are Apache-2.0 licensed and could serve as the starting point.
Benefits
- For QDMI: Broader adoption beyond C/C++ projects; Rust's safety guarantees reduce integration bugs
- For the ecosystem: Any Rust quantum framework can use QDMI without writing private FFI
- Maintenance: Bindings could be auto-generated from QDMI headers via
bindgen, staying in sync with releases
Happy to discuss scope and submit a PR. We could start with just qdmi-sys (raw FFI) and iterate on the safe wrapper API based on feedback.
Motivation
QDMI currently provides a C API and a C tutorial for device implementations. As Rust adoption grows in the quantum computing ecosystem, official Rust bindings would lower the barrier for Rust-based quantum frameworks to integrate with QDMI.
We maintain Arvak, a Rust-native quantum compilation and orchestration platform. To use QDMI, we had to write our own FFI bindings — both for the client side (querying devices, submitting jobs) and the device side (implementing a QDMI device in Rust). These bindings are hand-written against the v1.2.1 headers and have been in production use.
What we'd contribute
A
qdmi-rscrate (orqdmi-sys+qdmisplit) providing:1. Low-level FFI (
qdmi-sys)Direct mapping of all QDMI C types and functions:
QDMI_STATUS→QdmiStatusenum withis_success())QDMI_Device,QDMI_Site,QDMI_Operation,QDMI_Job)QDMI_DEVICE_PROPERTY_T,QDMI_SITE_PROPERTY_T,QDMI_OPERATION_PROPERTY_T)QDMI_SESSION_PARAMETER_T,QDMI_DEVICE_SESSION_PARAMETER_T)QDMI_DEVICE_JOB_PARAMETER_T,QDMI_DEVICE_JOB_RESULT_T)qdmi_session_query_*,qdmi_device_query_*, etc.)2. Safe Rust wrappers (
qdmi)Ergonomic Rust API over the raw FFI:
QdmiSession,QdmiDevice,QdmiJobwith RAII (Drop-based cleanup)QdmiDeviceImpltrait instead of exporting C function pointers manuallyNULL→ allocate → query pattern is handled internally)Result<T, QdmiError>error handling instead of raw status code checking3. Device implementation via Rust traits
Instead of manually exporting prefixed C symbols, a device author would:
Current state of our bindings
Our FFI bindings cover QDMI v1.2.1 completely:
adapters/arvak-adapter-qdmi/src/ffi.rs— all session/device/job query functionscrates/arvak-qdmi/src/ffi.rs— device property keys, site/operation properties, prefix-aware dlsym loadingBoth are Apache-2.0 licensed and could serve as the starting point.
Benefits
bindgen, staying in sync with releasesHappy to discuss scope and submit a PR. We could start with just
qdmi-sys(raw FFI) and iterate on the safe wrapper API based on feedback.