azure-quantum 2.1.1__py3-none-any.whl → 2.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,4 +6,4 @@
6
6
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
7
7
  # --------------------------------------------------------------------------
8
8
 
9
- VERSION = "2.1.1"
9
+ VERSION = "2.2.0"
@@ -21,14 +21,15 @@ from abc import abstractmethod
21
21
  from azure.quantum.job.session import SessionHost
22
22
 
23
23
  try:
24
- from qiskit import QuantumCircuit, transpile
24
+ from qiskit import QuantumCircuit
25
25
  from qiskit.providers import BackendV1 as Backend
26
26
  from qiskit.providers import Options
27
27
  from qiskit.providers import Provider
28
28
  from qiskit.providers.models import BackendConfiguration
29
29
  from qiskit.qobj import QasmQobj, PulseQobj
30
- from pyqir import Module
31
- from qiskit_qir import to_qir_module
30
+ import pyqir as pyqir
31
+ from qsharp.interop.qiskit import QSharpBackend
32
+ from qsharp import TargetProfile
32
33
 
33
34
  except ImportError:
34
35
  raise ImportError(
@@ -36,6 +37,39 @@ except ImportError:
36
37
  To install run: pip install azure-quantum[qiskit]"
37
38
  )
38
39
 
40
+ # barrier is handled by an extra flag which will transpile
41
+ # them away if the backend doesn't support them. This has
42
+ # to be done as a special pass as the transpiler will not
43
+ # remove barriers by default.
44
+ QIR_BASIS_GATES = [
45
+ "measure",
46
+ "reset",
47
+ "ccx",
48
+ "cx",
49
+ "cy",
50
+ "cz",
51
+ "rx",
52
+ "rxx",
53
+ "crx",
54
+ "ry",
55
+ "ryy",
56
+ "cry",
57
+ "rz",
58
+ "rzz",
59
+ "crz",
60
+ "h",
61
+ "s",
62
+ "sdg",
63
+ "swap",
64
+ "t",
65
+ "tdg",
66
+ "x",
67
+ "y",
68
+ "z",
69
+ "id",
70
+ "ch",
71
+ ]
72
+
39
73
 
40
74
  class AzureBackendBase(Backend, SessionHost):
41
75
 
@@ -280,7 +314,11 @@ class AzureQirBackend(AzureBackendBase):
280
314
  "content_type": "qir.v1",
281
315
  "input_data_format": "qir.v1",
282
316
  "output_data_format": "microsoft.quantum-results.v2",
317
+ "is_default": True,
283
318
  }
319
+
320
+ def _basis_gates(self) -> List[str]:
321
+ return QIR_BASIS_GATES
284
322
 
285
323
  def run(
286
324
  self,
@@ -368,66 +406,140 @@ class AzureQirBackend(AzureBackendBase):
368
406
  return {}
369
407
 
370
408
  def _generate_qir(
371
- self, circuits, targetCapability, **to_qir_kwargs
372
- ) -> Tuple[Module, List[str]]:
409
+ self, circuits: List[QuantumCircuit], target_profile: TargetProfile, **kwargs
410
+ ) -> pyqir.Module:
411
+
412
+ if len(circuits) == 0:
413
+ raise ValueError("No QuantumCircuits provided")
373
414
 
374
415
  config = self.configuration()
375
416
  # Barriers aren't removed by transpilation and must be explicitly removed in the Qiskit to QIR translation.
376
- emit_barrier_calls = "barrier" in config.basis_gates
377
- return to_qir_module(
378
- circuits,
379
- targetCapability,
380
- emit_barrier_calls=emit_barrier_calls,
381
- **to_qir_kwargs,
417
+ supports_barrier = "barrier" in config.basis_gates
418
+ skip_transpilation = kwargs.pop("skip_transpilation", False)
419
+
420
+ backend = QSharpBackend(
421
+ qiskit_pass_options={"supports_barrier": supports_barrier},
422
+ target_profile=target_profile,
423
+ skip_transpilation=skip_transpilation,
424
+ **kwargs,
382
425
  )
383
426
 
384
- def _get_qir_str(self, circuits, targetCapability, **to_qir_kwargs) -> str:
385
- module, _ = self._generate_qir(circuits, targetCapability, **to_qir_kwargs)
427
+ name = "batch"
428
+ if len(circuits) == 1:
429
+ name = circuits[0].name
430
+
431
+ if isinstance(circuits, list):
432
+ for value in circuits:
433
+ if not isinstance(value, QuantumCircuit):
434
+ raise ValueError("Input must be List[QuantumCircuit]")
435
+ else:
436
+ raise ValueError("Input must be List[QuantumCircuit]")
437
+
438
+ context = pyqir.Context()
439
+ llvm_module = pyqir.qir_module(context, name)
440
+ for circuit in circuits:
441
+ qir_str = backend.qir(circuit)
442
+ module = pyqir.Module.from_ir(context, qir_str)
443
+ entry_point = next(filter(pyqir.is_entry_point, module.functions))
444
+ entry_point.name = circuit.name
445
+ llvm_module.link(module)
446
+ err = llvm_module.verify()
447
+ if err is not None:
448
+ raise Exception(err)
449
+
450
+ return llvm_module
451
+
452
+ def _get_qir_str(
453
+ self,
454
+ circuits: List[QuantumCircuit],
455
+ target_profile: TargetProfile,
456
+ **to_qir_kwargs,
457
+ ) -> str:
458
+ module = self._generate_qir(circuits, target_profile, **to_qir_kwargs)
386
459
  return str(module)
387
460
 
388
461
  def _translate_input(
389
- self, circuits: List[QuantumCircuit], input_params: Dict[str, Any]
462
+ self, circuits: Union[QuantumCircuit, List[QuantumCircuit]], input_params: Dict[str, Any]
390
463
  ) -> bytes:
391
464
  """Translates the input values to the QIR expected by the Backend."""
392
465
  logger.info(f"Using QIR as the job's payload format.")
393
- config = self.configuration()
466
+ if not (isinstance(circuits, list)):
467
+ circuits = [circuits]
394
468
 
395
- # Override QIR translation parameters
396
- # We will record the output by default, but allow the backend to override this, and allow the user to override the backend.
397
- to_qir_kwargs = input_params.pop(
398
- "to_qir_kwargs", config.azure.get("to_qir_kwargs", {"record_output": True})
399
- )
400
- targetCapability = input_params.pop(
401
- "targetCapability",
402
- self.options.get("targetCapability", "AdaptiveExecution"),
403
- )
469
+ target_profile = self._get_target_profile(input_params)
404
470
 
405
471
  if logger.isEnabledFor(logging.DEBUG):
406
- qir = self._get_qir_str(circuits, targetCapability, **to_qir_kwargs)
472
+ qir = self._get_qir_str(circuits, target_profile, skip_transpilation=True)
407
473
  logger.debug(f"QIR:\n{qir}")
408
474
 
409
475
  # We'll transpile automatically to the supported gates in QIR unless explicitly skipped.
410
- if not input_params.pop("skipTranspile", False):
411
- # Set of gates supported by QIR targets.
412
- circuits = transpile(
413
- circuits, basis_gates=config.basis_gates, optimization_level=0
414
- )
476
+ skip_transpilation = input_params.pop("skipTranspile", False)
477
+
478
+ module = self._generate_qir(
479
+ circuits, target_profile, skip_transpilation=skip_transpilation
480
+ )
481
+
482
+ def get_func_name(func: pyqir.Function) -> str:
483
+ return func.name
484
+
485
+ entry_points = list(
486
+ map(get_func_name, filter(pyqir.is_entry_point, module.functions))
487
+ )
488
+
489
+ if not skip_transpilation:
415
490
  # We'll only log the QIR again if we performed a transpilation.
416
491
  if logger.isEnabledFor(logging.DEBUG):
417
- qir = self._get_qir_str(circuits, targetCapability, **to_qir_kwargs)
492
+ qir = str(module)
418
493
  logger.debug(f"QIR (Post-transpilation):\n{qir}")
419
494
 
420
- (module, entry_points) = self._generate_qir(
421
- circuits, targetCapability, **to_qir_kwargs
422
- )
423
-
424
- if not "items" in input_params:
495
+ if "items" not in input_params:
425
496
  arguments = input_params.pop("arguments", [])
426
497
  input_params["items"] = [
427
498
  {"entryPoint": name, "arguments": arguments} for name in entry_points
428
499
  ]
429
500
 
430
- return module.bitcode
501
+ return str(module).encode("utf-8")
502
+
503
+ def _estimate_cost_qir(
504
+ self, circuits: Union[QuantumCircuit, List[QuantumCircuit]], shots, options={}
505
+ ):
506
+ """Estimate the cost for the given circuit."""
507
+ input_params = self._get_input_params(options, shots=shots)
508
+
509
+ if not (isinstance(circuits, list)):
510
+ circuits = [circuits]
511
+
512
+ skip_transpilation = input_params.pop("skipTranspile", False)
513
+ target_profile = self._get_target_profile(input_params)
514
+ module = self._generate_qir(
515
+ circuits, target_profile, skip_transpilation=skip_transpilation
516
+ )
517
+
518
+ workspace = self.provider().get_workspace()
519
+ target = workspace.get_targets(self.name())
520
+ return target.estimate_cost(module, shots=shots)
521
+
522
+ def _get_target_profile(self, input_params) -> TargetProfile:
523
+ # Default to Adaptive_RI if not specified on the backend
524
+ # this is really just a safeguard in case the backend doesn't have a default
525
+ default_profile = self.options.get("target_profile", TargetProfile.Adaptive_RI)
526
+
527
+ # If the user is using the old targetCapability parameter, we'll warn them
528
+ # and use that value for now. This will be removed in the future.
529
+ if "targetCapability" in input_params:
530
+ warnings.warn(
531
+ "The 'targetCapability' parameter is deprecated and will be ignored in the future. "
532
+ "Please, use 'target_profile' parameter instead.",
533
+ category=DeprecationWarning,
534
+ )
535
+ cap = input_params.pop("targetCapability")
536
+ if cap == "AdaptiveExecution":
537
+ default_profile = TargetProfile.Adaptive_RI
538
+ else:
539
+ default_profile = TargetProfile.Base
540
+ # If the user specifies a target profile, use that.
541
+ # Otherwise, use the profile we got from the backend/targetCapability.
542
+ return input_params.pop("target_profile", default_profile)
431
543
 
432
544
 
433
545
  class AzureBackend(AzureBackendBase):
@@ -7,7 +7,7 @@ from azure.quantum import __version__
7
7
  from azure.quantum.qiskit.job import AzureQuantumJob
8
8
  from azure.quantum.target.ionq import IonQ
9
9
  from abc import abstractmethod
10
-
10
+ from qsharp import TargetProfile
11
11
  from qiskit import QuantumCircuit
12
12
 
13
13
  from .backend import (
@@ -20,7 +20,6 @@ from qiskit.providers.models import BackendConfiguration
20
20
  from qiskit.providers import Options, Provider
21
21
 
22
22
  from qiskit_ionq.helpers import (
23
- ionq_basis_gates,
24
23
  GATESET_MAP,
25
24
  qiskit_circ_to_ionq_circ,
26
25
  )
@@ -66,7 +65,7 @@ class IonQQirBackendBase(AzureQirBackend):
66
65
  **{
67
66
  cls._SHOTS_PARAM_NAME: _DEFAULT_SHOTS_COUNT,
68
67
  },
69
- targetCapability="BasicExecution",
68
+ target_profile=TargetProfile.Base,
70
69
  )
71
70
 
72
71
  def _azure_config(self) -> Dict[str, str]:
@@ -77,6 +76,10 @@ class IonQQirBackendBase(AzureQirBackend):
77
76
  }
78
77
  )
79
78
  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)
80
83
 
81
84
  def run(
82
85
  self,
@@ -103,7 +106,6 @@ class IonQSimulatorQirBackend(IonQQirBackendBase):
103
106
 
104
107
  def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
105
108
  """Base class for interfacing with an IonQ QIR Simulator backend"""
106
-
107
109
  default_config = BackendConfiguration.from_dict(
108
110
  {
109
111
  "backend_name": name,
@@ -112,7 +114,7 @@ class IonQSimulatorQirBackend(IonQQirBackendBase):
112
114
  "local": False,
113
115
  "coupling_map": None,
114
116
  "description": "IonQ simulator on Azure Quantum",
115
- "basis_gates": ionq_basis_gates,
117
+ "basis_gates": self._basis_gates(),
116
118
  "memory": False,
117
119
  "n_qubits": 29,
118
120
  "conditional": False,
@@ -135,7 +137,6 @@ class IonQAriaQirBackend(IonQQirBackendBase):
135
137
 
136
138
  def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
137
139
  """Base class for interfacing with an IonQ Aria QPU backend"""
138
-
139
140
  default_config = BackendConfiguration.from_dict(
140
141
  {
141
142
  "backend_name": name,
@@ -144,9 +145,9 @@ class IonQAriaQirBackend(IonQQirBackendBase):
144
145
  "local": False,
145
146
  "coupling_map": None,
146
147
  "description": "IonQ Aria QPU on Azure Quantum",
147
- "basis_gates": ionq_basis_gates,
148
+ "basis_gates": self._basis_gates(),
148
149
  "memory": False,
149
- "n_qubits": 23,
150
+ "n_qubits": 25,
150
151
  "conditional": False,
151
152
  "max_shots": 10000,
152
153
  "max_experiments": 1,
@@ -167,7 +168,6 @@ class IonQForteQirBackend(IonQQirBackendBase):
167
168
 
168
169
  def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
169
170
  """Base class for interfacing with an IonQ Forte QPU backend"""
170
-
171
171
  default_config = BackendConfiguration.from_dict(
172
172
  {
173
173
  "backend_name": name,
@@ -176,7 +176,7 @@ class IonQForteQirBackend(IonQQirBackendBase):
176
176
  "local": False,
177
177
  "coupling_map": None,
178
178
  "description": "IonQ Forte QPU on Azure Quantum",
179
- "basis_gates": ionq_basis_gates,
179
+ "basis_gates": self._basis_gates(),
180
180
  "memory": False,
181
181
  "n_qubits": 35,
182
182
  "conditional": False,
@@ -241,7 +241,7 @@ class IonQBackend(AzureBackend):
241
241
  "provider_id": "ionq",
242
242
  "input_data_format": "ionq.circuit.v1",
243
243
  "output_data_format": "ionq.quantum-results.v1",
244
- "is_default": True,
244
+ "is_default": False,
245
245
  }
246
246
 
247
247
  def _prepare_job_metadata(self, circuit, **kwargs):
@@ -316,15 +316,6 @@ class IonQSimulatorNativeBackend(IonQSimulatorBackend):
316
316
  kwargs["gateset"] = "native"
317
317
  super().__init__(name, provider, **kwargs)
318
318
 
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
-
328
319
 
329
320
  class IonQAriaBackend(IonQBackend):
330
321
  backend_names = ("ionq.qpu.aria-1", "ionq.qpu.aria-2")
@@ -398,27 +389,9 @@ class IonQAriaNativeBackend(IonQAriaBackend):
398
389
  kwargs["gateset"] = "native"
399
390
  super().__init__(name, provider, **kwargs)
400
391
 
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
-
410
392
 
411
393
  class IonQForteNativeBackend(IonQForteBackend):
412
394
  def __init__(self, name: str, provider: "AzureQuantumProvider", **kwargs):
413
395
  if "gateset" not in kwargs:
414
396
  kwargs["gateset"] = "native"
415
397
  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
@@ -3,36 +3,17 @@
3
3
  # Licensed under the MIT License.
4
4
  ##
5
5
 
6
- from typing import TYPE_CHECKING, Any, Dict, List
6
+ from typing import TYPE_CHECKING, Any, Dict, List, Union
7
7
  from azure.quantum.version import __version__
8
8
  from qiskit import QuantumCircuit
9
9
  from abc import abstractmethod
10
- from .backend import AzureQirBackend
10
+ from .backend import AzureQirBackend, QIR_BASIS_GATES
11
11
 
12
12
  from qiskit.providers.models import BackendConfiguration
13
13
  from qiskit.providers import Options, Provider
14
-
15
- QIR_BASIS_GATES = [
16
- "measure",
17
- "m",
18
- "ccx",
19
- "cx",
20
- "cz",
21
- "h",
22
- "reset",
23
- "rx",
24
- "ry",
25
- "rz",
26
- "s",
27
- "sdg",
28
- "swap",
29
- "t",
30
- "tdg",
31
- "x",
32
- "y",
33
- "z",
34
- "id",
35
- ]
14
+ from qsharp import TargetProfile
15
+ from qsharp.interop.qiskit import ResourceEstimatorBackend
16
+ import pyqir as pyqir
36
17
 
37
18
  if TYPE_CHECKING:
38
19
  from azure.quantum.qiskit import AzureQuantumProvider
@@ -55,7 +36,7 @@ class MicrosoftBackend(AzureQirBackend):
55
36
 
56
37
  @classmethod
57
38
  def _default_options(cls):
58
- return Options(targetCapability="AdaptiveExecution")
39
+ return Options(target_profile=TargetProfile.Adaptive_RI)
59
40
 
60
41
  def _azure_config(self) -> Dict[str, str]:
61
42
  config = super()._azure_config()
@@ -63,11 +44,65 @@ class MicrosoftBackend(AzureQirBackend):
63
44
  {
64
45
  "provider_id": "microsoft-qc",
65
46
  "output_data_format": "microsoft.resource-estimates.v1",
66
- "to_qir_kwargs": {"record_output": False},
67
47
  }
68
48
  )
69
49
  return config
70
50
 
51
+ def _translate_input(
52
+ self,
53
+ circuits: Union[QuantumCircuit, List[QuantumCircuit]],
54
+ input_params: Dict[str, Any],
55
+ ) -> bytes:
56
+ """Translates the input values to the QIR expected by the Backend."""
57
+ # All the logic is in the base class, but we need to override
58
+ # this method to ensure that the bitcode QIR format is used for RE.
59
+
60
+ # normal translation is to QIR text format in utf-8 encoded bytes
61
+ ir_byte_str = super()._translate_input(circuits, input_params)
62
+ # decode the utf-8 encoded bytes to a string
63
+ ir_str = ir_byte_str.decode('utf-8')
64
+ # convert the QIR text format to QIR bitcode format
65
+ module = pyqir.Module.from_ir(pyqir.Context(), ir_str)
66
+ return module.bitcode
67
+
68
+ def _generate_qir(
69
+ self, circuits: List[QuantumCircuit], target_profile: TargetProfile, **kwargs
70
+ ) -> pyqir.Module:
71
+ if len(circuits) == 0:
72
+ raise ValueError("No QuantumCircuits provided")
73
+
74
+ name = "circuits"
75
+ if isinstance(circuits, QuantumCircuit):
76
+ name = circuits.name
77
+ circuits = [circuits]
78
+ elif isinstance(circuits, list):
79
+ for value in circuits:
80
+ if not isinstance(value, QuantumCircuit):
81
+ raise ValueError(
82
+ "Input must be Union[QuantumCircuit, List[QuantumCircuit]]"
83
+ )
84
+ else:
85
+ raise ValueError(
86
+ "Input must be Union[QuantumCircuit, List[QuantumCircuit]]"
87
+ )
88
+
89
+ skip_transpilation = kwargs.pop("skip_transpilation", False)
90
+ backend = ResourceEstimatorBackend(
91
+ skip_transpilation=skip_transpilation, **kwargs
92
+ )
93
+ context = pyqir.Context()
94
+ llvm_module = pyqir.qir_module(context, name)
95
+ for circuit in circuits:
96
+ qir_str = backend.qir(circuit, target_profile=target_profile)
97
+ module = pyqir.Module.from_ir(context, qir_str)
98
+ llvm_module.link(module)
99
+
100
+ err = llvm_module.verify()
101
+ if err is not None:
102
+ raise Exception(err)
103
+
104
+ return llvm_module
105
+
71
106
 
72
107
  class MicrosoftResourceEstimationBackend(MicrosoftBackend):
73
108
  """Backend class for interfacing with the resource estimator target"""
@@ -77,7 +112,7 @@ class MicrosoftResourceEstimationBackend(MicrosoftBackend):
77
112
  @classmethod
78
113
  def _default_options(cls):
79
114
  return Options(
80
- targetCapability="AdaptiveExecution",
115
+ target_profile=TargetProfile.Adaptive_RI,
81
116
  errorBudget=1e-3,
82
117
  qubitParams={"name": "qubit_gate_ns_e3"},
83
118
  qecScheme={"name": "surface_code"}
@@ -3,7 +3,7 @@
3
3
  # Licensed under the MIT License.
4
4
  ##
5
5
 
6
- from typing import TYPE_CHECKING, Dict
6
+ from typing import TYPE_CHECKING, Dict, List
7
7
  from azure.quantum.version import __version__
8
8
  from azure.quantum.qiskit.job import AzureQuantumJob
9
9
  from abc import abstractmethod
@@ -14,28 +14,8 @@ from .backend import (
14
14
 
15
15
  from qiskit.providers.models import BackendConfiguration
16
16
  from qiskit.providers import Options, Provider
17
+ from qsharp import TargetProfile
17
18
 
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
19
 
40
20
  if TYPE_CHECKING:
41
21
  from azure.quantum.qiskit import AzureQuantumProvider
@@ -65,7 +45,7 @@ class QCIBackend(AzureQirBackend):
65
45
  **{
66
46
  cls._SHOTS_PARAM_NAME: _DEFAULT_SHOTS_COUNT,
67
47
  },
68
- targetCapability="AdaptiveExecution",
48
+ target_profile=TargetProfile.Adaptive_RI,
69
49
  )
70
50
 
71
51
  def _azure_config(self) -> Dict[str, str]:
@@ -76,9 +56,12 @@ class QCIBackend(AzureQirBackend):
76
56
  }
77
57
  )
78
58
  return config
79
-
59
+
60
+ def _basis_gates(self) -> List[str]:
61
+ return super()._basis_gates() + ["barrier"]
62
+
80
63
  def run(
81
- self,
64
+ self,
82
65
  run_input=None,
83
66
  shots: int = None,
84
67
  **options,
@@ -110,7 +93,7 @@ class QCISimulatorBackend(QCIBackend):
110
93
  "local": False,
111
94
  "coupling_map": None,
112
95
  "description": "QCI simulator on Azure Quantum",
113
- "basis_gates": QIR_BASIS_GATES,
96
+ "basis_gates": self._basis_gates(),
114
97
  "memory": False,
115
98
  "n_qubits": 29,
116
99
  "conditional": True,
@@ -142,7 +125,7 @@ class QCIQPUBackend(QCIBackend):
142
125
  "local": False,
143
126
  "coupling_map": None,
144
127
  "description": "QCI QPU on Azure Quantum",
145
- "basis_gates": QIR_BASIS_GATES,
128
+ "basis_gates": self._basis_gates(),
146
129
  "memory": False,
147
130
  "n_qubits": 11,
148
131
  "conditional": True,
@@ -15,7 +15,7 @@ from qiskit.providers.models import BackendConfiguration
15
15
  from qiskit.providers import Options
16
16
  from qiskit.providers import Provider
17
17
  from qiskit.qasm2 import dumps
18
-
18
+ from qsharp import TargetProfile
19
19
  import logging
20
20
 
21
21
  logger = logging.getLogger(__name__)
@@ -50,6 +50,7 @@ QUANTINUUM_BASIS_GATES = [
50
50
  "reset",
51
51
  ]
52
52
 
53
+
53
54
  QUANTINUUM_PROVIDER_ID = "quantinuum"
54
55
  QUANTINUUM_PROVIDER_NAME = "Quantinuum"
55
56
 
@@ -59,7 +60,7 @@ def _get_n_qubits(name):
59
60
  if ".h1-" in name or "hqs-lt" in name:
60
61
  return 20
61
62
  if ".h2-" in name:
62
- return 32
63
+ return 56
63
64
  warnings.warn(
64
65
  UserWarning(f"Number of qubits not known for target {name}. Defaulting to 20."))
65
66
  return 20
@@ -83,7 +84,7 @@ class QuantinuumQirBackendBase(AzureQirBackend):
83
84
  **{
84
85
  cls._SHOTS_PARAM_NAME: _DEFAULT_SHOTS_COUNT
85
86
  },
86
- targetCapability="BasicExecution",
87
+ target_profile=TargetProfile.Adaptive_RI,
87
88
  )
88
89
 
89
90
  def _azure_config(self) -> Dict[str, str]:
@@ -97,6 +98,10 @@ class QuantinuumQirBackendBase(AzureQirBackend):
97
98
 
98
99
  def _get_n_qubits(self, name):
99
100
  return _get_n_qubits(name)
101
+
102
+ def estimate_cost(self, circuits, shots, options={}):
103
+ """Estimate the cost for the given circuit."""
104
+ return self._estimate_cost_qir(circuits, shots, options)
100
105
 
101
106
 
102
107
  class QuantinuumSyntaxCheckerQirBackend(QuantinuumQirBackendBase):
@@ -118,7 +123,7 @@ class QuantinuumSyntaxCheckerQirBackend(QuantinuumQirBackendBase):
118
123
  "local": False,
119
124
  "coupling_map": None,
120
125
  "description": f"Quantinuum Syntax Checker on Azure Quantum",
121
- "basis_gates": QUANTINUUM_BASIS_GATES,
126
+ "basis_gates": self._basis_gates(),
122
127
  "memory": True,
123
128
  "n_qubits": self._get_n_qubits(name),
124
129
  "conditional": False,
@@ -155,7 +160,7 @@ class QuantinuumEmulatorQirBackend(QuantinuumQirBackendBase):
155
160
  "local": False,
156
161
  "coupling_map": None,
157
162
  "description": f"Quantinuum emulator on Azure Quantum",
158
- "basis_gates": QUANTINUUM_BASIS_GATES,
163
+ "basis_gates": self._basis_gates(),
159
164
  "memory": True,
160
165
  "n_qubits": self._get_n_qubits(name),
161
166
  "conditional": False,
@@ -192,7 +197,7 @@ class QuantinuumQPUQirBackend(QuantinuumQirBackendBase):
192
197
  "local": False,
193
198
  "coupling_map": None,
194
199
  "description": f"Quantinuum QPU on Azure Quantum",
195
- "basis_gates": QUANTINUUM_BASIS_GATES,
200
+ "basis_gates": self._basis_gates(),
196
201
  "memory": True,
197
202
  "n_qubits": self._get_n_qubits(name),
198
203
  "conditional": False,
@@ -236,7 +241,7 @@ class QuantinuumBackend(AzureBackend):
236
241
  "provider_id": self._provider_id,
237
242
  "input_data_format": "honeywell.openqasm.v1",
238
243
  "output_data_format": "honeywell.quantum-results.v1",
239
- "is_default": True,
244
+ "is_default": False,
240
245
  }
241
246
 
242
247
  def _translate_input(self, circuit):