QUDORA SDK
The QUDORA Software Development Kit (SDK) enables an interaction with quantum devices hosted on the QUDORA Cloud from Python code.
The included Qiskit-provider allows direct execution of Qiskit-QuantumCircuits on the QUDORA Cloud quantum devices.
Installation
Qiskit Provider (default)
pip install qudora-sdk
With CUDA-Q support
pip install qudora-sdk[cudaq]
This installs the CUDA-Q Python package and the QUDORA target plugin, enabling direct submission of CUDA-Q kernels to the QUDORA Cloud.
Qiskit-Provider Usage
This section explains the usage of the included Qiskit-provider to access QUDORA Cloud quantum devices. In order to use the provider an API-Token from the QUDORA Cloud is required. Such a token can be generated here.
Access to Quantum Devices
To authenticate with the QUDORA Cloud the provider requires the generated API-Token, which is here called my-example-token.
from qudora_sdk.qiskit import QUDORAProvider
provider = QUDORAProvider(token="my-example-token")
If the authentication was successful, all available quantum devices can be listed.
print(provider.backends())
Selecting a particular backend is done with the get_backend() function.
backend = provider.get_backend('QVLS Simulator')
Running Qiskit-QuantumCircuits
The quantum devices can execute QuantumCircuit-objects written with Qiskit. More information about writing circuits with qiskit can be found here.
Previously created Backend-objects have a run()-function to submit circuits to a selected backend.
qc = QuantumCircuit(2,2)
qc.h(0)
qc.cx(0,1)
qc.measure(0,0)
qc.measure(1,1)
job = backend.run(qc, job_name='My example job')
The job object represents a job in the QUDORA Cloud. Its status can be retrieved by calling job.status().
To obtain the result of a job, the result() function can be called. This function will wait until the job finishes and return the measurement results.
result = job.result()
print(result)
Mid-circuit measurements and if statements based on Qiskit's dynamic circuits are also supported. See below for a simple example:
qc = QuantumCircuit(1,1)
qc.h(0)
qc.measure(0,0)
with qc.if_test((0, 1)):
qc.x(0)
qc.measure(0,0)
(!) Note about mid-circuit measurements
Mid-circuit measurements are supported, but there is a small caveat. For our backends, measurements include an implicit reset. That means that the following two circuits are equivalent on our backends:
qc.measure(0, 0)
and
qc.measure(0, 0)
qc.reset(0)
In other words: qubits do not preserve their state after a measurement. This deviation from the standard rules of quantum mechanics is due to the nature of our trapped-ion qubits and how the measurement process is implemented. Should you need access to the post-measurement state, you can manually reset the qubit to the post-measurement state by using the dynamic circuit given in the example above.
The support of qiskit dynamic circuits allows users to try out sophisticated error-correction schemes and analyse their performance against a realistic noise model.
Customised Settings
A backend has parameters (mostly used for noise models), which you can modify to your needs.
You can list all available settings using the show_available_settings()-method.
backend.show_available_settings()
To run a job with custom settings, you can pass a settings dictionary to the run() method.
custom_settings = {
'measurement_error_probability': 0.005,
'two_qubit_gate_noise_strength': 1.0
}
job = backend.run(qc, job_name='Job with custom settings', backend_settings=custom_settings)
CUDA-Q Usage
The QUDORA SDK includes a CUDA-Q target that allows submitting quantum programs to the QUDORA Cloud directly from CUDA-Q.
Setting the Target
import cudaq
cudaq.set_target("qudora",
api_key="my-example-token",
url="https://api.qudora.com/",
machine="Qamelion",
)
Alternatively, the API key can also be placed in the environment variable CUDAQ_QUDORA_CREDENTIALS.
Running Non-Adaptive Circuits
For circuits without mid-circuit measurement feedback, use cudaq.sample:
@cudaq.kernel
def bell():
q = cudaq.qvector(2)
h(q[0])
cx(q[0], q[1])
mz(q)
result = cudaq.sample(bell, shots_count=1000)
print(result)
Running Adaptive Circuits
For circuits with mid-circuit measurements and classical control flow, use cudaq.run. The kernel must return a value:
@cudaq.kernel
def teleport() -> bool:
q = cudaq.qvector(3)
x(q[0]) # state to teleport
h(q[1])
cx(q[1], q[2]) # Bell pair
cx(q[0], q[1]) # Bell measurement
h(q[0])
m0 = mz(q[0])
m1 = mz(q[1])
if m1:
x(q[2]) # corrections
if m0:
z(q[2])
return mz(q[2])
results = cudaq.run(teleport, shots_count=100)
print(f"Teleported qubit measured 1 in {sum(results)}/{len(results)} shots")
(!) Note about Mid-Circuit Measurements
The same caveat as for the Qiskit provider applies: measurements include an implicit reset on QUDORA backends.
When using cudaq.run, prefer returning the mid-circuit measurement result variable directly rather than re-measuring the qubit:
# Correct: return the MCM result variable
m = mz(q[0])
# ... use m for control flow ...
return m # returns the value measured at mz time
# Avoid: re-measuring after MCM gives |0⟩ due to reset
m = mz(q[0])
return mz(q[0]) # always False — qubit was reset to |0⟩
LICENSE
Copyright (C) 2026 QUDORA GmbH
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.
Metadata
Release files for qudora-sdk 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| qudora_sdk-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / qudora_sdk-2.0.0-py3-none-any.whl
| Download URL | qudora_sdk-2.0.0-py3-none-any.whl |
|---|---|
| Size | 116.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
55b6d880d93de8d1069e6dc07a8f509d56ec8ab08a6455cd34ce802cad8cf08b
|
|
BLAKE2b-256 checksum How to use checksums |
e0c3dd3b5db65c91649d8dc498dedc31a79f974aba9937d560dbc5d468720a6f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.8
|