Skip to content

Commit a4873e0

Browse files
authored
qiskit qir by default (#630)
* feat: upgrade QIR backends to V2 output format and populate memory field
1 parent b43e101 commit a4873e0

File tree

149 files changed

+102959
-23156
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+102959
-23156
lines changed

azure-quantum/azure/quantum/qiskit/backends/backend.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,25 @@
3636
To install run: pip install azure-quantum[qiskit]"
3737
)
3838

39+
QIR_BASIS_GATES = [
40+
"x",
41+
"y",
42+
"z",
43+
"rx",
44+
"ry",
45+
"rz",
46+
"h",
47+
"swap",
48+
"cx",
49+
"cz",
50+
"reset",
51+
"s",
52+
"sdg",
53+
"t",
54+
"tdg",
55+
"measure",
56+
]
57+
3958

4059
class AzureBackendBase(Backend, SessionHost):
4160

@@ -280,7 +299,11 @@ def _azure_config(self) -> Dict[str, str]:
280299
"content_type": "qir.v1",
281300
"input_data_format": "qir.v1",
282301
"output_data_format": "microsoft.quantum-results.v2",
302+
"is_default": True,
283303
}
304+
305+
def _basis_gates(self) -> List[str]:
306+
return QIR_BASIS_GATES
284307

285308
def run(
286309
self,
@@ -429,6 +452,37 @@ def _translate_input(
429452

430453
return module.bitcode
431454

455+
def _estimate_cost_qir(self, circuits, shots, options={}):
456+
"""Estimate the cost for the given circuit."""
457+
config = self.configuration()
458+
input_params = self._get_input_params(options, shots=shots)
459+
460+
if not (isinstance(circuits, list)):
461+
circuits = [circuits]
462+
463+
to_qir_kwargs = input_params.pop(
464+
"to_qir_kwargs", config.azure.get("to_qir_kwargs", {"record_output": True})
465+
)
466+
targetCapability = input_params.pop(
467+
"targetCapability",
468+
self.options.get("targetCapability", "AdaptiveExecution"),
469+
)
470+
471+
if not input_params.pop("skipTranspile", False):
472+
# Set of gates supported by QIR targets.
473+
circuits = transpile(
474+
circuits, basis_gates=config.basis_gates, optimization_level=0
475+
)
476+
477+
478+
(module, _) = self._generate_qir(
479+
circuits, targetCapability, **to_qir_kwargs
480+
)
481+
482+
workspace = self.provider().get_workspace()
483+
target = workspace.get_targets(self.name())
484+
return target.estimate_cost(module, shots=shots)
485+
432486

433487
class AzureBackend(AzureBackendBase):
434488
"""Base class for interfacing with a backend in Azure Quantum"""

azure-quantum/azure/quantum/qiskit/backends/ionq.py

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
from qiskit.providers import Options, Provider
2121

2222
from qiskit_ionq.helpers import (
23-
ionq_basis_gates,
2423
GATESET_MAP,
2524
qiskit_circ_to_ionq_circ,
2625
)
@@ -77,6 +76,10 @@ def _azure_config(self) -> Dict[str, str]:
7776
}
7877
)
7978
return config
79+
80+
def estimate_cost(self, circuits, shots, options={}):
81+
"""Estimate the cost for the given circuit."""
82+
return self._estimate_cost_qir(circuits, shots, options)
8083

8184
def run(
8285
self,
@@ -103,7 +106,6 @@ class IonQSimulatorQirBackend(IonQQirBackendBase):
103106

104107
def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
105108
"""Base class for interfacing with an IonQ QIR Simulator backend"""
106-
107109
default_config = BackendConfiguration.from_dict(
108110
{
109111
"backend_name": name,
@@ -112,7 +114,7 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
112114
"local": False,
113115
"coupling_map": None,
114116
"description": "IonQ simulator on Azure Quantum",
115-
"basis_gates": ionq_basis_gates,
117+
"basis_gates": self._basis_gates(),
116118
"memory": False,
117119
"n_qubits": 29,
118120
"conditional": False,
@@ -135,7 +137,6 @@ class IonQAriaQirBackend(IonQQirBackendBase):
135137

136138
def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
137139
"""Base class for interfacing with an IonQ Aria QPU backend"""
138-
139140
default_config = BackendConfiguration.from_dict(
140141
{
141142
"backend_name": name,
@@ -144,7 +145,7 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
144145
"local": False,
145146
"coupling_map": None,
146147
"description": "IonQ Aria QPU on Azure Quantum",
147-
"basis_gates": ionq_basis_gates,
148+
"basis_gates": self._basis_gates(),
148149
"memory": False,
149150
"n_qubits": 23,
150151
"conditional": False,
@@ -167,7 +168,6 @@ class IonQForteQirBackend(IonQQirBackendBase):
167168

168169
def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
169170
"""Base class for interfacing with an IonQ Forte QPU backend"""
170-
171171
default_config = BackendConfiguration.from_dict(
172172
{
173173
"backend_name": name,
@@ -176,7 +176,7 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
176176
"local": False,
177177
"coupling_map": None,
178178
"description": "IonQ Forte QPU on Azure Quantum",
179-
"basis_gates": ionq_basis_gates,
179+
"basis_gates": self._basis_gates(),
180180
"memory": False,
181181
"n_qubits": 35,
182182
"conditional": False,
@@ -241,7 +241,7 @@ def _azure_config(self) -> Dict[str, str]:
241241
"provider_id": "ionq",
242242
"input_data_format": "ionq.circuit.v1",
243243
"output_data_format": "ionq.quantum-results.v1",
244-
"is_default": True,
244+
"is_default": False,
245245
}
246246

247247
def _prepare_job_metadata(self, circuit, **kwargs):
@@ -316,15 +316,6 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
316316
kwargs["gateset"] = "native"
317317
super().__init__(name, provider, **kwargs)
318318

319-
def _azure_config(self) -> Dict[str, str]:
320-
config = super()._azure_config()
321-
config.update(
322-
{
323-
"is_default": False,
324-
}
325-
)
326-
return config
327-
328319

329320
class IonQAriaBackend(IonQBackend):
330321
backend_names = ("ionq.qpu.aria-1", "ionq.qpu.aria-2")
@@ -398,27 +389,9 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
398389
kwargs["gateset"] = "native"
399390
super().__init__(name, provider, **kwargs)
400391

401-
def _azure_config(self) -> Dict[str, str]:
402-
config = super()._azure_config()
403-
config.update(
404-
{
405-
"is_default": False,
406-
}
407-
)
408-
return config
409-
410392

411393
class IonQForteNativeBackend(IonQForteBackend):
412394
def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
413395
if "gateset" not in kwargs:
414396
kwargs["gateset"] = "native"
415397
super().__init__(name, provider, **kwargs)
416-
417-
def _azure_config(self) -> Dict[str, str]:
418-
config = super()._azure_config()
419-
config.update(
420-
{
421-
"is_default": False,
422-
}
423-
)
424-
return config

azure-quantum/azure/quantum/qiskit/backends/qci.py

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,6 @@
1515
from qiskit.providers.models import BackendConfiguration
1616
from qiskit.providers import Options, Provider
1717

18-
QIR_BASIS_GATES = [
19-
"measure",
20-
"m",
21-
"barrier",
22-
"cx",
23-
"cz",
24-
"h",
25-
"reset",
26-
"rx",
27-
"ry",
28-
"rz",
29-
"s",
30-
"sdg",
31-
"swap",
32-
"t",
33-
"tdg",
34-
"x",
35-
"y",
36-
"z",
37-
"id",
38-
]
39-
4018
if TYPE_CHECKING:
4119
from azure.quantum.qiskit import AzureQuantumProvider
4220

@@ -110,7 +88,7 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
11088
"local": False,
11189
"coupling_map": None,
11290
"description": "QCI simulator on Azure Quantum",
113-
"basis_gates": QIR_BASIS_GATES,
91+
"basis_gates": self._basis_gates(),
11492
"memory": False,
11593
"n_qubits": 29,
11694
"conditional": True,
@@ -142,7 +120,7 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
142120
"local": False,
143121
"coupling_map": None,
144122
"description": "QCI QPU on Azure Quantum",
145-
"basis_gates": QIR_BASIS_GATES,
123+
"basis_gates": self._basis_gates(),
146124
"memory": False,
147125
"n_qubits": 11,
148126
"conditional": True,

azure-quantum/azure/quantum/qiskit/backends/quantinuum.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,24 @@
5050
"reset",
5151
]
5252

53+
QUANTINUUM_QIR_BASIS_GATES = [
54+
"x",
55+
"y",
56+
"z",
57+
"rx",
58+
"ry",
59+
"rz",
60+
"h",
61+
"cx",
62+
"cz",
63+
"reset",
64+
"s",
65+
"sdg",
66+
"t",
67+
"tdg",
68+
"measure",
69+
]
70+
5371
QUANTINUUM_PROVIDER_ID = "quantinuum"
5472
QUANTINUUM_PROVIDER_NAME = "Quantinuum"
5573

@@ -94,9 +112,16 @@ def _azure_config(self) -> Dict[str, str]:
94112
}
95113
)
96114
return config
115+
116+
def _basis_gates(self) -> List[str]:
117+
return QUANTINUUM_QIR_BASIS_GATES
97118

98119
def _get_n_qubits(self, name):
99120
return _get_n_qubits(name)
121+
122+
def estimate_cost(self, circuits, shots, options={}):
123+
"""Estimate the cost for the given circuit."""
124+
return self._estimate_cost_qir(circuits, shots, options)
100125

101126

102127
class QuantinuumSyntaxCheckerQirBackend(QuantinuumQirBackendBase):
@@ -118,7 +143,7 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
118143
"local": False,
119144
"coupling_map": None,
120145
"description": f"Quantinuum Syntax Checker on Azure Quantum",
121-
"basis_gates": QUANTINUUM_BASIS_GATES,
146+
"basis_gates": self._basis_gates(),
122147
"memory": True,
123148
"n_qubits": self._get_n_qubits(name),
124149
"conditional": False,
@@ -155,7 +180,7 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
155180
"local": False,
156181
"coupling_map": None,
157182
"description": f"Quantinuum emulator on Azure Quantum",
158-
"basis_gates": QUANTINUUM_BASIS_GATES,
183+
"basis_gates": self._basis_gates(),
159184
"memory": True,
160185
"n_qubits": self._get_n_qubits(name),
161186
"conditional": False,
@@ -192,7 +217,7 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
192217
"local": False,
193218
"coupling_map": None,
194219
"description": f"Quantinuum QPU on Azure Quantum",
195-
"basis_gates": QUANTINUUM_BASIS_GATES,
220+
"basis_gates": self._basis_gates(),
196221
"memory": True,
197222
"n_qubits": self._get_n_qubits(name),
198223
"conditional": False,
@@ -236,7 +261,7 @@ def _azure_config(self) -> Dict[str, str]:
236261
"provider_id": self._provider_id,
237262
"input_data_format": "honeywell.openqasm.v1",
238263
"output_data_format": "honeywell.quantum-results.v1",
239-
"is_default": True,
264+
"is_default": False,
240265
}
241266

242267
def _translate_input(self, circuit):

azure-quantum/azure/quantum/qiskit/backends/rigetti.py

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,6 @@
1212
from qiskit.providers.models import BackendConfiguration
1313
from qiskit.providers import Options, Provider
1414

15-
QIR_BASIS_GATES = [
16-
"measure",
17-
"m",
18-
"cx",
19-
"cz",
20-
"h",
21-
"reset",
22-
"rx",
23-
"ry",
24-
"rz",
25-
"s",
26-
"sdg,"
27-
"t",
28-
"tdg",
29-
"x",
30-
"y",
31-
"z",
32-
"id",
33-
]
34-
3515
if TYPE_CHECKING:
3616
from azure.quantum.qiskit import AzureQuantumProvider
3717

@@ -85,7 +65,7 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
8565
"local": False,
8666
"coupling_map": None,
8767
"description": "Rigetti simulator on Azure Quantum",
88-
"basis_gates": QIR_BASIS_GATES,
68+
"basis_gates": self._basis_gates(),
8969
"memory": True,
9070
"n_qubits": RigettiTarget.num_qubits(name),
9171
"conditional": False,
@@ -117,7 +97,7 @@ def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
11797
"local": False,
11898
"coupling_map": None,
11999
"description": "Rigetti QPU on Azure Quantum",
120-
"basis_gates": QIR_BASIS_GATES,
100+
"basis_gates": self._basis_gates(),
121101
"memory": True,
122102
"n_qubits": RigettiTarget.num_qubits(name),
123103
"conditional": False,

0 commit comments

Comments
 (0)