feat: ionq minimal integration into cloud provider platform#725
feat: ionq minimal integration into cloud provider platform#725
Conversation
|
- Add IonQDevice dispatchers for version, connectivity_graph (all-to-all) in qplatform/device.py - Add IonQJob dispatchers for execution_time and job_status in qplatform/job.py - Add ionq/device.py workaround for qiskit_ionq bug that sets qubit count to device total instead of circuit size - Pass shots from params when loading IonQ jobs during polling (IonQ API omits shots in job details) - Add unit tests for all new IonQ qplatform functions and device patch
3f30ab0 to
dd6e062
Compare
There was a problem hiding this comment.
Pull request overview
Adds minimal IonQ support paths needed for running metriq-gym benchmarks through the qBraid provider layer, including device metadata utilities, job timing/status extraction, and a runtime workaround for an IonQ/qiskit_ionq conversion issue.
Changes:
- Add IonQ implementations for
version(),connectivity_graph(),execution_time(), andjob_status()in the qplatform utilities. - Patch IonQ device setup to bypass qiskit_ionq’s buggy conversion path by converting Qiskit circuits to QASM2 before submission.
- Add unit tests covering IonQ device metadata, connectivity, and job timing/status behavior.
Reviewed changes
Copilot reviewed 7 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
metriq_gym/qplatform/job.py |
Adds IonQJob handling for execution time and status extraction. |
metriq_gym/qplatform/device.py |
Adds IonQDevice handling for version and all-to-all connectivity graph. |
metriq_gym/run.py |
Patches IonQ devices at setup time; injects shots into load_job kwargs for IonQ result reconstruction. |
metriq_gym/ionq/device.py |
Introduces IonQDevice.run patch to force QASM2 submission when qiskit_ionq is installed. |
metriq_gym/ionq/__init__.py |
Adds IonQ package module. |
tests/unit/qplatform/test_job.py |
Adds IonQ job tests for execution time and status. |
tests/unit/qplatform/test_device.py |
Adds IonQ device tests for version/connectivity/metadata. |
tests/unit/ionq/test_device.py |
Adds tests for QASM2 conversion helper and device patching behavior. |
tests/unit/ionq/__init__.py |
Adds IonQ test package module. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
metriq_gym/qplatform/job.py
Outdated
| exec_time_ms = meta.get("execution_time") or meta.get("predicted_execution_time") | ||
| if exec_time_ms is None: |
metriq_gym/ionq/device.py
Outdated
| which correctly preserves the circuit's qubit count. | ||
| """ | ||
|
|
||
| import importlib |
tests/unit/ionq/test_device.py
Outdated
| def test_patched_device_converts_qiskit_to_qasm(self): | ||
| """After patching, Qiskit circuits should be converted to QASM2 strings.""" | ||
| from qbraid.runtime import IonQDevice | ||
|
|
||
| class FakeDevice: | ||
| pass | ||
|
|
||
| FakeDevice.run = IonQDevice.run | ||
| device = FakeDevice() | ||
|
|
||
| patch_ionq_device(device) | ||
|
|
||
| # The patched run should convert QC -> QASM before calling original | ||
| qc = QuantumCircuit(2, 2) | ||
| qc.h(0) | ||
| qc.measure([0, 1], [0, 1]) | ||
|
|
||
| # Directly test the conversion function instead of the full patch chain | ||
| result = _convert_qiskit_to_qasm2(qc) | ||
| assert isinstance(result, str) | ||
| assert "OPENQASM 2.0" in result | ||
|
|
metriq_gym/ionq/device.py
Outdated
| When qiskit_ionq is installed, qBraid's IonQDevice.run() uses qiskit_ionq's | ||
| transpilation path which sets the circuit qubit count to the device's total | ||
| qubit count (e.g. 29) rather than the circuit's actual qubit count. This | ||
| causes IonQ's simulator to reject circuits that would otherwise run fine. |
There was a problem hiding this comment.
Is this something we need to handle in metriq-gym, or raise it with qBraid?
There was a problem hiding this comment.
Ideally, we should raise an issue about this on the qBraid issues board.
cosenal
left a comment
There was a problem hiding this comment.
I tested it with
mgym job dispatch config.json -p ionq -d simulator
and config.json being
{
"benchmark_name": "WIT",
"num_qubits": 7,
"shots": 8192
}
I got 0.0 as a result for the expectation value, so something is wrong.
Two separate qBraid issues were causing it:
Both are now fixed with a centralized patch to qBraid's IonQJob class, but ideally, we would want another MR that actually patches qBraid for this. Thoughts, @cosenal ? |
Resolve uv.lock and pyproject.toml conflicts. Remove ionq extra from qbraid dependency to drop qiskit-ionq per qBraid/qBraid#1141 workaround.
Closes: #724
Example
Dispatch a small benchmark to IonQ simulator
Then poll the result (replace with your job ID)
Standalone script:
Using the IonQ Quantum Cloud platform, we can see that launching this job on the (free) simulator, that the result we get back is successful: