IonQ Extension
IonQ 🔗 is a commercial trapped-ion quantum computing company that provides access to quantum hardware and simulators. The Strangeworks platform integrates directly with IonQ through the native qiskit-ionq SDK, allowing you to run quantum circuits on IonQ backends while tracking jobs on the Strangeworks platform.
Extensions allow you to use a provider's native SDK directly while benefiting from Strangeworks' job tracking, workspace management, and optional pay-as-you-go billing. This approach gives you the full power of the native SDK with the convenience of the Strangeworks platform.
pip install -U pip "strangeworks[qiskit-ionq]"
This installs the Strangeworks SDK with the qiskit-ionq extension, which includes the native IonQ provider and the Strangeworks integration layer.
Authentication
The IonQ extension supports two authentication modes:
Bring Your Own Key (BYOK)
Currently Available - Use your own IonQ API key directly. Your credentials never leave your environment and Strangeworks never stores or accesses your IonQ API key. Jobs are tracked on the Strangeworks platform, but billing goes directly through your IonQ account.
WORKSPACE_API_KEY=<WORKSPACE_API_KEY>
IONQ_API_KEY=<IONQ_API_KEY>
import os
import strangeworks
from strangeworks_extensions.products import Extension
# Set your IonQ API key
os.environ["IONQ_API_KEY"] = "<IONQ_API_KEY>"
# Authenticate with Strangeworks
strangeworks.authenticate(
api_key="<WORKSPACE_API_KEY>",
extensions=[Extension.QISKIT_IONQ]
)
Pay-As-You-Go (PAYG)
Pay-as-you-go billing through Strangeworks credits is coming soon for IonQ. This feature is currently in development.
When available, you'll be able to use Strangeworks credits to run jobs on IonQ backends, with Strangeworks managing billing and authentication on your behalf:
# Coming soon - PAYG mode
import strangeworks
from strangeworks_extensions.products import Extension
strangeworks.authenticate(
api_key="<WORKSPACE_API_KEY>",
extensions=[Extension.QISKIT_IONQ]
)
- Workspace API Key: Get this from your Strangeworks Portal homepage
- IonQ API Key: Required for BYOK mode. Contact IonQ to obtain an API key, or reach out to the Strangeworks team for assistance
Backends
Once authenticated, you can use the native qiskit-ionq provider to access IonQ backends:
from qiskit_ionq import IonQProvider
provider = IonQProvider()
# List all available backends
backends = provider.backends()
print("Available IonQ backends:")
for backend in backends:
print(f" - {backend.name}")
Available Backends
See IonQ Backends for the most up-to-date information on IonQ backends.
Quickstart
Hello World
Here's a simple example that creates a Bell state and runs it on the IonQ simulator using your IonQ API key:
import os
import strangeworks
from qiskit import QuantumCircuit
from qiskit_ionq import IonQProvider
from strangeworks_extensions.products import Extension
# Set your IonQ API key (BYOK mode)
os.environ["IONQ_API_KEY"] = "<IONQ_API_KEY>"
# Authenticate with Strangeworks
strangeworks.authenticate(
api_key="<WORKSPACE_API_KEY>",
extensions=[Extension.QISKIT_IONQ]
)
# Get the IonQ provider
provider = IonQProvider()
# Create a simple Bell state circuit
bell_circuit = QuantumCircuit(2)
bell_circuit.h(0)
bell_circuit.cx(0, 1)
bell_circuit.measure_all()
print("🤖 Executing Circuit on IonQ Simulator...\n")
# Select the IonQ simulator backend
backend = provider.get_backend("simulator")
# Submit the circuit
job = backend.run(bell_circuit, shots=1024)
# The job is now tracked on the Strangeworks Platform
print(f"⏳ Job submitted! Job ID: {job.job_id()}\n")
# Wait for results (this also updates the job status on Strangeworks)
result = job.result()
# Get measurement counts
counts = result.get_counts()
print(f"📊 Measurement Counts: {counts}\n")
🥳 Success! You can view your job details, including circuit visualization and results, in the portal.
😅 Something went wrong? Contact us at support@strangeworks.com for assistance.
- Develop on
simulatorto verify your circuits work correctly - Optimize your circuits (reduce depth, use native gates) before moving to hardware
- Test with a small number of shots on hardware first
- Scale to production runs once you've validated the results
Running on Hardware
To run on IonQ's quantum hardware, simply select a QPU backend instead of the simulator:
import os
import strangeworks
from qiskit import QuantumCircuit
from qiskit_ionq import IonQProvider
from strangeworks_extensions.products import Extension
# Set your IonQ API key
os.environ["IONQ_API_KEY"] = "<IONQ_API_KEY>"
strangeworks.authenticate(
api_key="<WORKSPACE_API_KEY>",
extensions=[Extension.QISKIT_IONQ]
)
provider = IonQProvider()
# Create your quantum circuit
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
# Get the IonQ Aria backend (or another available QPU)
backend = provider.get_backend("qpu.aria-1")
print(f"🤖 Submitting to IonQ Hardware: {backend.name}\n")
# Submit to hardware with fewer shots (hardware time is more expensive)
job = backend.run(circuit, shots=100)
print(f"⏳ Job ID: {job.job_id()}\n")
# Check job status (updates Strangeworks platform)
status = job.status()
print(f"Status: {status}\n")
# Wait for completion and get results (updates Strangeworks platform)
result = job.result()
counts = result.get_counts()
print(f"🎉 Hardware Results: {counts}\n")
Because Strangeworks never stores or accesses your IonQ API key (keeping your credentials secure), we cannot automatically poll IonQ to update job status. Job updates only occur when you call job.status() or job.result() in your script.
To ensure your jobs are properly tracked:
- Always retrieve results through the Strangeworks extension (don't fetch directly from IonQ)
- Call
job.status()periodically for long-running jobs to sync progress - Keep your script running until
job.result()completes to capture final results - Fetching results directly from IonQ (bypassing the extension) will leave jobs orphaned on the platform
- Hardware execution typically requires fewer shots than simulators due to cost considerations
- Job execution time varies based on queue depth and backend availability
- Billing is handled directly through your IonQ account (BYOK mode)
Advanced Features
Native Gates
IonQ backends support native gate sets that can be more efficient than the standard gate decomposition, especially on hardware. You can either transpile your circuits to native gates or build circuits directly with IonQ's native gates.
from qiskit import QuantumCircuit, transpile
from qiskit_ionq import IonQProvider
provider = IonQProvider()
backend_native = provider.get_backend("simulator", gateset="native")
# Create circuit with standard gates
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
# Transpile to IonQ native gates
native_circuit = transpile(circuit, backend=backend_native)
# Run the native circuit
job = backend_native.run(native_circuit, shots=1024)
result = job.result()
print(result.get_counts())
Alternatively, you can build circuits directly with IonQ's native gates:
from qiskit import QuantumCircuit
from qiskit_ionq import IonQProvider, GPIGate, GPI2Gate, MSGate
provider = IonQProvider()
backend = provider.get_backend("simulator", gateset="native")
# Build circuit with native gates
circuit = QuantumCircuit(2)
circuit.append(MSGate(0, 0), [0, 1]) # Entangling gate
circuit.append(GPIGate(0), [0]) # Single-qubit rotation
circuit.append(GPI2Gate(0), [1]) # Single-qubit rotation
circuit.measure_all()
job = backend.run(circuit, shots=1024)
print(job.get_counts())
- qis (default): Standard gate set - the IonQ compiler optimizes for you
- native: IonQ's hardware-native gates (GPI, GPI2, MS for Aria; ZZ for Forte) - gives you direct control
- You cannot mix standard gates and native gates in the same circuit
Error Mitigation
IonQ provides debiasing error mitigation on QPUs, which creates and runs symmetric variations of your circuit to reduce noise. This feature activates automatically for jobs with 500+ shots, or you can explicitly control it:
from qiskit import QuantumCircuit
from qiskit_ionq import IonQProvider, ErrorMitigation
provider = IonQProvider()
backend = provider.get_backend("qpu.aria-1")
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
# Debiasing activates automatically for 500+ shots on QPU
job = backend.run(circuit, shots=1000)
# Or explicitly control error mitigation
job = backend.run(
circuit,
shots=1000,
error_mitigation=ErrorMitigation.DEBIASING # Enable explicitly
)
# Get results (averaging method by default)
result = job.result()
print(f"Mitigated results: {result.get_counts()}")
# Or use sharpening aggregation for more definite outcomes
result_sharp = job.result(sharpen=True)
print(f"Sharpened results: {result_sharp.get_counts()}")
- Debiasing requires at least 500 shots to activate
- Available only on QPUs (not simulators)
- Two result aggregation methods: averaging (default) or sharpening (plurality voting)
- See the IonQ error mitigation docs for more details
Job Management
Check Job Status
# After submitting a job
job = backend.run(circuit, shots=1024)
# Check status
print(f"Job Status: {job.status()}")
print(f"Job ID: {job.job_id()}")
Retrieve Previous Jobs
from qiskit_ionq import IonQProvider
provider = IonQProvider()
backend = provider.get_backend("simulator")
# Get a specific job by ID
job = backend.retrieve_job("job-id-here")
# Check its status and get results
print(f"Status: {job.status()}")
result = job.result()
print(f"Counts: {result.get_counts()}")
All jobs submitted through the IonQ extension are tracked in the Strangeworks Portal, where you can:
- View job history and submission details
- Visualize circuits and results (once retrieved via the extension)
- Organize jobs with tags and projects
- Monitor usage and execution history
Note: Because we don't store your IonQ API key (security by design), job status and results are updated on the platform only when you call job.status() or job.result() in your code.