azure-quantum 2.1.2__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.2"
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,23 +37,37 @@ 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.
39
44
  QIR_BASIS_GATES = [
40
- "x",
41
- "y",
42
- "z",
45
+ "measure",
46
+ "reset",
47
+ "ccx",
48
+ "cx",
49
+ "cy",
50
+ "cz",
43
51
  "rx",
52
+ "rxx",
53
+ "crx",
44
54
  "ry",
55
+ "ryy",
56
+ "cry",
45
57
  "rz",
58
+ "rzz",
59
+ "crz",
46
60
  "h",
47
- "swap",
48
- "cx",
49
- "cz",
50
- "reset",
51
61
  "s",
52
62
  "sdg",
63
+ "swap",
53
64
  "t",
54
65
  "tdg",
55
- "measure",
66
+ "x",
67
+ "y",
68
+ "z",
69
+ "id",
70
+ "ch",
56
71
  ]
57
72
 
58
73
 
@@ -391,98 +406,141 @@ class AzureQirBackend(AzureBackendBase):
391
406
  return {}
392
407
 
393
408
  def _generate_qir(
394
- self, circuits, targetCapability, **to_qir_kwargs
395
- ) -> 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")
396
414
 
397
415
  config = self.configuration()
398
416
  # Barriers aren't removed by transpilation and must be explicitly removed in the Qiskit to QIR translation.
399
- emit_barrier_calls = "barrier" in config.basis_gates
400
- return to_qir_module(
401
- circuits,
402
- targetCapability,
403
- emit_barrier_calls=emit_barrier_calls,
404
- **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,
405
425
  )
406
426
 
407
- def _get_qir_str(self, circuits, targetCapability, **to_qir_kwargs) -> str:
408
- 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)
409
459
  return str(module)
410
460
 
411
461
  def _translate_input(
412
- self, circuits: List[QuantumCircuit], input_params: Dict[str, Any]
462
+ self, circuits: Union[QuantumCircuit, List[QuantumCircuit]], input_params: Dict[str, Any]
413
463
  ) -> bytes:
414
464
  """Translates the input values to the QIR expected by the Backend."""
415
465
  logger.info(f"Using QIR as the job's payload format.")
416
- config = self.configuration()
466
+ if not (isinstance(circuits, list)):
467
+ circuits = [circuits]
417
468
 
418
- # Override QIR translation parameters
419
- # We will record the output by default, but allow the backend to override this, and allow the user to override the backend.
420
- to_qir_kwargs = input_params.pop(
421
- "to_qir_kwargs", config.azure.get("to_qir_kwargs", {"record_output": True})
422
- )
423
- targetCapability = input_params.pop(
424
- "targetCapability",
425
- self.options.get("targetCapability", "AdaptiveExecution"),
426
- )
469
+ target_profile = self._get_target_profile(input_params)
427
470
 
428
471
  if logger.isEnabledFor(logging.DEBUG):
429
- qir = self._get_qir_str(circuits, targetCapability, **to_qir_kwargs)
472
+ qir = self._get_qir_str(circuits, target_profile, skip_transpilation=True)
430
473
  logger.debug(f"QIR:\n{qir}")
431
474
 
432
475
  # We'll transpile automatically to the supported gates in QIR unless explicitly skipped.
433
- if not input_params.pop("skipTranspile", False):
434
- # Set of gates supported by QIR targets.
435
- circuits = transpile(
436
- circuits, basis_gates=config.basis_gates, optimization_level=0
437
- )
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:
438
490
  # We'll only log the QIR again if we performed a transpilation.
439
491
  if logger.isEnabledFor(logging.DEBUG):
440
- qir = self._get_qir_str(circuits, targetCapability, **to_qir_kwargs)
492
+ qir = str(module)
441
493
  logger.debug(f"QIR (Post-transpilation):\n{qir}")
442
494
 
443
- (module, entry_points) = self._generate_qir(
444
- circuits, targetCapability, **to_qir_kwargs
445
- )
446
-
447
- if not "items" in input_params:
495
+ if "items" not in input_params:
448
496
  arguments = input_params.pop("arguments", [])
449
497
  input_params["items"] = [
450
498
  {"entryPoint": name, "arguments": arguments} for name in entry_points
451
499
  ]
452
500
 
453
- return module.bitcode
501
+ return str(module).encode("utf-8")
454
502
 
455
- def _estimate_cost_qir(self, circuits, shots, options={}):
503
+ def _estimate_cost_qir(
504
+ self, circuits: Union[QuantumCircuit, List[QuantumCircuit]], shots, options={}
505
+ ):
456
506
  """Estimate the cost for the given circuit."""
457
- config = self.configuration()
458
507
  input_params = self._get_input_params(options, shots=shots)
459
508
 
460
509
  if not (isinstance(circuits, list)):
461
510
  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
511
 
478
- (module, _) = self._generate_qir(
479
- circuits, targetCapability, **to_qir_kwargs
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
480
516
  )
481
-
517
+
482
518
  workspace = self.provider().get_workspace()
483
519
  target = workspace.get_targets(self.name())
484
520
  return target.estimate_cost(module, shots=shots)
485
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)
543
+
486
544
 
487
545
  class AzureBackend(AzureBackendBase):
488
546
  """Base class for interfacing with a backend in Azure Quantum"""
@@ -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 (
@@ -65,7 +65,7 @@ class IonQQirBackendBase(AzureQirBackend):
65
65
  **{
66
66
  cls._SHOTS_PARAM_NAME: _DEFAULT_SHOTS_COUNT,
67
67
  },
68
- targetCapability="BasicExecution",
68
+ target_profile=TargetProfile.Base,
69
69
  )
70
70
 
71
71
  def _azure_config(self) -> Dict[str, str]:
@@ -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,6 +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
18
+
17
19
 
18
20
  if TYPE_CHECKING:
19
21
  from azure.quantum.qiskit import AzureQuantumProvider
@@ -43,7 +45,7 @@ class QCIBackend(AzureQirBackend):
43
45
  **{
44
46
  cls._SHOTS_PARAM_NAME: _DEFAULT_SHOTS_COUNT,
45
47
  },
46
- targetCapability="AdaptiveExecution",
48
+ target_profile=TargetProfile.Adaptive_RI,
47
49
  )
48
50
 
49
51
  def _azure_config(self) -> Dict[str, str]:
@@ -54,9 +56,12 @@ class QCIBackend(AzureQirBackend):
54
56
  }
55
57
  )
56
58
  return config
57
-
59
+
60
+ def _basis_gates(self) -> List[str]:
61
+ return super()._basis_gates() + ["barrier"]
62
+
58
63
  def run(
59
- self,
64
+ self,
60
65
  run_input=None,
61
66
  shots: int = None,
62
67
  **options,
@@ -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,23 +50,6 @@ QUANTINUUM_BASIS_GATES = [
50
50
  "reset",
51
51
  ]
52
52
 
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
53
 
71
54
  QUANTINUUM_PROVIDER_ID = "quantinuum"
72
55
  QUANTINUUM_PROVIDER_NAME = "Quantinuum"
@@ -77,7 +60,7 @@ def _get_n_qubits(name):
77
60
  if ".h1-" in name or "hqs-lt" in name:
78
61
  return 20
79
62
  if ".h2-" in name:
80
- return 32
63
+ return 56
81
64
  warnings.warn(
82
65
  UserWarning(f"Number of qubits not known for target {name}. Defaulting to 20."))
83
66
  return 20
@@ -101,7 +84,7 @@ class QuantinuumQirBackendBase(AzureQirBackend):
101
84
  **{
102
85
  cls._SHOTS_PARAM_NAME: _DEFAULT_SHOTS_COUNT
103
86
  },
104
- targetCapability="BasicExecution",
87
+ target_profile=TargetProfile.Adaptive_RI,
105
88
  )
106
89
 
107
90
  def _azure_config(self) -> Dict[str, str]:
@@ -112,9 +95,6 @@ class QuantinuumQirBackendBase(AzureQirBackend):
112
95
  }
113
96
  )
114
97
  return config
115
-
116
- def _basis_gates(self) -> List[str]:
117
- return QUANTINUUM_QIR_BASIS_GATES
118
98
 
119
99
  def _get_n_qubits(self, name):
120
100
  return _get_n_qubits(name)
@@ -11,6 +11,7 @@ from .backend import AzureQirBackend
11
11
 
12
12
  from qiskit.providers.models import BackendConfiguration
13
13
  from qiskit.providers import Options, Provider
14
+ from qsharp import TargetProfile
14
15
 
15
16
  if TYPE_CHECKING:
16
17
  from azure.quantum.qiskit import AzureQuantumProvider
@@ -40,7 +41,7 @@ class RigettiBackend(AzureQirBackend):
40
41
  other_options = {
41
42
  cls._SHOTS_PARAM_NAME: _DEFAULT_SHOTS_COUNT,
42
43
  }
43
- return Options(targetCapability="BasicExecution", **other_options)
44
+ return Options(target_profile=TargetProfile.Base, **other_options)
44
45
 
45
46
  def _azure_config(self) -> Dict[str, str]:
46
47
  config = super()._azure_config()
@@ -212,15 +212,19 @@ class AzureQuantumJob(JobV1):
212
212
 
213
213
  @staticmethod
214
214
  def _qir_to_qiskit_bitstring(obj):
215
- """Convert the data structure from Azure into the "schema" used by Qiskit """
215
+ """Convert the data structure from Azure into the "schema" used by Qiskit"""
216
216
  if isinstance(obj, str) and not re.match(r"[\d\s]+$", obj):
217
217
  obj = ast.literal_eval(obj)
218
218
 
219
219
  if isinstance(obj, tuple):
220
220
  # the outermost implied container is a tuple, and each item is
221
- # associated with a classical register. Azure and Qiskit order the
222
- # registers in opposite directions, so reverse here to match.
223
- return " ".join([AzureQuantumJob._qir_to_qiskit_bitstring(term) for term in reversed(obj)])
221
+ # associated with a classical register.
222
+ return " ".join(
223
+ [
224
+ AzureQuantumJob._qir_to_qiskit_bitstring(term)
225
+ for term in obj
226
+ ]
227
+ )
224
228
  elif isinstance(obj, list):
225
229
  # a list is for an individual classical register
226
230
  return "".join([str(bit) for bit in obj])
@@ -59,12 +59,16 @@ class IonQ(Target):
59
59
  name: str = "ionq.simulator",
60
60
  input_data_format: str = "ionq.circuit.v1",
61
61
  output_data_format: str = "ionq.quantum-results.v1",
62
- capability: str = "BasicExecution",
62
+ capability: str = "",
63
63
  provider_id: str = "IonQ",
64
64
  content_type: str = "application/json",
65
65
  encoding: str = "",
66
- **kwargs
66
+ target_profile: Union[str, "TargetProfile"] = "Base",
67
+ **kwargs,
67
68
  ):
69
+ if capability:
70
+ msg = "The 'capability' parameter is not used for the Quantinuum target."
71
+ warn(msg, DeprecationWarning)
68
72
  super().__init__(
69
73
  workspace=workspace,
70
74
  name=name,
@@ -74,7 +78,8 @@ class IonQ(Target):
74
78
  provider_id=provider_id,
75
79
  content_type=content_type,
76
80
  encoding=encoding,
77
- **kwargs
81
+ target_profile=target_profile,
82
+ **kwargs,
78
83
  )
79
84
 
80
85
  def submit(
@@ -392,6 +392,7 @@ class MicrosoftEstimator(Target):
392
392
  output_data_format="microsoft.resource-estimates.v1",
393
393
  provider_id="microsoft-qc",
394
394
  content_type=ContentType.json,
395
+ target_profile="Adaptive_RI",
395
396
  **kwargs
396
397
  )
397
398
 
@@ -422,14 +423,21 @@ class MicrosoftEstimator(Target):
422
423
  warnings.warn("The 'shots' parameter is ignored in resource estimation job.")
423
424
 
424
425
  try:
425
- from qiskit import QuantumCircuit, transpile
426
- from qiskit_qir import to_qir_module
427
- from qiskit_qir.visitor import SUPPORTED_INSTRUCTIONS
426
+ from qiskit import QuantumCircuit
427
+ from qsharp import TargetProfile
428
+ from qsharp.interop.qiskit import ResourceEstimatorBackend
429
+ from pyqir import Context, Module
430
+
428
431
  if isinstance(input_data, QuantumCircuit):
429
- input_data = transpile(input_data,
430
- basis_gates=SUPPORTED_INSTRUCTIONS,
431
- optimization_level=0)
432
- (module, _) = to_qir_module(input_data, record_output=False)
432
+ backend = ResourceEstimatorBackend()
433
+ target_profile = TargetProfile.from_str(self.target_profile)
434
+ qir_str = backend.qir(input_data, target_profile=target_profile)
435
+ context = Context()
436
+ module = Module.from_ir(context, qir_str)
437
+
438
+ err = module.verify()
439
+ if err is not None:
440
+ raise Exception(err)
433
441
  input_data = module.bitcode
434
442
  finally:
435
443
  return super().submit(
@@ -80,9 +80,10 @@ class Pasqal(Target):
80
80
  name: Union[PasqalTarget, str] = PasqalTarget.SIM_EMU_TN,
81
81
  input_data_format: str = "pasqal.pulser.v1",
82
82
  output_data_format: str = "pasqal.pulser-results.v1",
83
- capability: str = "BasicExecution",
83
+ capability: str = "",
84
84
  provider_id: str = "pasqal",
85
85
  encoding: str = "",
86
+ target_profile: Union[str, "TargetProfile"] = "Base",
86
87
  **kwargs,
87
88
  ):
88
89
  """
@@ -102,7 +103,12 @@ class Pasqal(Target):
102
103
  :type provider_id: str
103
104
  :param encoding: "Content-Encoding" attribute value to set on input blob (ex. "gzip")
104
105
  :type encoding: str
106
+ :param target_profile: Target QIR profile.
107
+ :type target_profile: str | TargetProfile
105
108
  """
109
+ if capability:
110
+ msg = "The 'capability' parameter is not used for the Quantinuum target."
111
+ warn(msg, DeprecationWarning)
106
112
 
107
113
  super().__init__(
108
114
  workspace=workspace,
@@ -2,7 +2,7 @@
2
2
  # Copyright (c) Microsoft Corporation.
3
3
  # Licensed under the MIT License.
4
4
  ##
5
- from typing import Any, Dict
5
+ from typing import Any, Dict, Union
6
6
  from warnings import warn
7
7
 
8
8
  from azure.quantum.target.target import (
@@ -12,7 +12,6 @@ from azure.quantum.target.target import (
12
12
  from azure.quantum.job.job import Job
13
13
  from azure.quantum.workspace import Workspace
14
14
  from azure.quantum._client.models import CostEstimate, UsageEvent
15
- from typing import Union
16
15
 
17
16
 
18
17
  class Quantinuum(Target):
@@ -35,12 +34,16 @@ class Quantinuum(Target):
35
34
  name: str = "quantinuum.sim.h1-1sc",
36
35
  input_data_format: str = "honeywell.openqasm.v1",
37
36
  output_data_format: str = "honeywell.quantum-results.v1",
38
- capability: str = "AdaptiveExecution",
37
+ capability: str = "",
39
38
  provider_id: str = "quantinuum",
40
39
  content_type: str = "application/qasm",
41
40
  encoding: str = "",
41
+ target_profile: Union[str, "TargetProfile"] = "Adaptive_RI",
42
42
  **kwargs
43
43
  ):
44
+ if capability:
45
+ msg = "The 'capability' parameter is not used for the Quantinuum target."
46
+ warn(msg, DeprecationWarning)
44
47
  super().__init__(
45
48
  workspace=workspace,
46
49
  name=name,
@@ -50,6 +53,7 @@ class Quantinuum(Target):
50
53
  provider_id=provider_id,
51
54
  content_type=content_type,
52
55
  encoding=encoding,
56
+ target_profile=target_profile,
53
57
  **kwargs
54
58
  )
55
59
 
@@ -14,6 +14,7 @@ __all__ = [
14
14
  from dataclasses import dataclass
15
15
  from enum import Enum
16
16
  from typing import Union, Any, Dict, List, Optional
17
+ from warnings import warn
17
18
 
18
19
  from ..target import Target
19
20
  from ... import Job
@@ -137,9 +138,10 @@ class Rigetti(Target):
137
138
  name: Union[RigettiTarget, str] = RigettiTarget.QVM,
138
139
  input_data_format: str = "rigetti.quil.v1",
139
140
  output_data_format: str = "rigetti.quil-results.v1",
140
- capability: str = "BasicExecution",
141
+ capability: str = "",
141
142
  provider_id: str = "rigetti",
142
143
  encoding: str = "",
144
+ target_profile: Union[str, "TargetProfile"] = "Base",
143
145
  **kwargs,
144
146
  ):
145
147
  """
@@ -159,8 +161,12 @@ class Rigetti(Target):
159
161
  :type provider_id: str
160
162
  :param encoding: "Content-Encoding" attribute value to set on input blob (ex. "gzip")
161
163
  :type encoding: str
164
+ :param target_profile: Target QIR profile.
165
+ :type target_profile: str | TargetProfile
162
166
  """
163
-
167
+ if capability:
168
+ msg = "The 'capability' parameter is not used for the Quantinuum target."
169
+ warn(msg, DeprecationWarning)
164
170
  super().__init__(
165
171
  workspace=workspace,
166
172
  name=name,
@@ -170,6 +176,7 @@ class Rigetti(Target):
170
176
  provider_id=provider_id,
171
177
  content_type="text/plain",
172
178
  encoding=encoding,
179
+ target_profile=target_profile,
173
180
  **kwargs,
174
181
  )
175
182
 
@@ -68,7 +68,8 @@ class Target(abc.ABC, SessionHost):
68
68
  content_type: ContentType = ContentType.json,
69
69
  encoding: str = "",
70
70
  average_queue_time: Union[float, None] = None,
71
- current_availability: str = ""
71
+ current_availability: str = "",
72
+ target_profile: Union[str, "TargetProfile"] = "Base",
72
73
  ):
73
74
  """
74
75
  Initializes a new target.
@@ -81,7 +82,7 @@ class Target(abc.ABC, SessionHost):
81
82
  :type input_data_format: str
82
83
  :param output_data_format: Format of output data (ex. "microsoft.resource-estimates.v1")
83
84
  :type output_data_format: str
84
- :param capability: QIR capability
85
+ :param capability: QIR capability. Deprecated, use `target_profile`
85
86
  :type capability: str
86
87
  :param provider_id: Id of provider (ex. "microsoft-qc")
87
88
  :type provider_id: str
@@ -93,6 +94,8 @@ class Target(abc.ABC, SessionHost):
93
94
  :type average_queue_time: float
94
95
  :param current_availability: Set current availability (for internal use)
95
96
  :type current_availability: str
97
+ :param target_profile: Target QIR profile.
98
+ :type target_profile: str | TargetProfile
96
99
  """
97
100
  if not provider_id and "." in name:
98
101
  provider_id = name.split(".")[0]
@@ -106,6 +109,7 @@ class Target(abc.ABC, SessionHost):
106
109
  self.encoding = encoding
107
110
  self._average_queue_time = average_queue_time
108
111
  self._current_availability = current_availability
112
+ self.target_profile = target_profile
109
113
 
110
114
  def __repr__(self):
111
115
  return f"<Target name=\"{self.name}\", \
@@ -255,8 +259,17 @@ target '{self.name}' of provider '{self.provider_id}' not found."
255
259
  input_params["arguments"] = input_params.get("arguments", [])
256
260
  targetCapability = input_params.get("targetCapability", kwargs.pop("target_capability", self.capability))
257
261
  if targetCapability:
262
+ warnings.warn(
263
+ "The 'targetCapability' parameter is deprecated and will be ignored in the future. "
264
+ "Please, use 'target_profile' parameter instead.",
265
+ category=DeprecationWarning,
266
+ )
258
267
  input_params["targetCapability"] = targetCapability
259
- input_data = input_data._repr_qir_(target=self.name, target_capability=targetCapability)
268
+ if target_profile := input_params.get(
269
+ "target_profile", kwargs.pop("target_profile", self.target_profile)
270
+ ):
271
+ input_params["target_profile"] = target_profile
272
+ input_data = input_data._repr_qir_(target=self.name)
260
273
  else:
261
274
  input_data_format = kwargs.pop("input_data_format", self.input_data_format)
262
275
  output_data_format = kwargs.pop("output_data_format", self.output_data_format)
azure/quantum/version.py CHANGED
@@ -5,4 +5,4 @@
5
5
  # Copyright (c) Microsoft Corporation. All rights reserved.
6
6
  # Licensed under the MIT License.
7
7
  ##
8
- __version__ = "2.1.2"
8
+ __version__ = "2.2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: azure-quantum
3
- Version: 2.1.2
3
+ Version: 2.2.0
4
4
  Summary: Python client for Azure Quantum
5
5
  Home-page: https://github.com/microsoft/azure-quantum-python
6
6
  Author: Microsoft
@@ -26,8 +26,8 @@ Requires-Dist: azure-devtools<2.0,>=1.2.0; extra == "all"
26
26
  Requires-Dist: graphviz>=0.20.1; extra == "all"
27
27
  Requires-Dist: pulser<0.19,>=0.18; extra == "all"
28
28
  Requires-Dist: qiskit-ionq<0.6,>=0.5; extra == "all"
29
- Requires-Dist: qiskit-qir<0.6,>=0.5; extra == "all"
30
- Requires-Dist: qiskit<2.0,>=1.0; extra == "all"
29
+ Requires-Dist: qsharp[qiskit]<2.0,>=1.9.0; extra == "all"
30
+ Requires-Dist: pyqir<0.11,>=0.10.6; extra == "all"
31
31
  Requires-Dist: Markdown<4.0,>=3.4.1; extra == "all"
32
32
  Requires-Dist: python-markdown-math<1.0,>=0.8.0; extra == "all"
33
33
  Requires-Dist: qsharp<2.0,>=1.0.33; extra == "all"
@@ -43,8 +43,8 @@ Provides-Extra: pulser
43
43
  Requires-Dist: pulser<0.19,>=0.18; extra == "pulser"
44
44
  Provides-Extra: qiskit
45
45
  Requires-Dist: qiskit-ionq<0.6,>=0.5; extra == "qiskit"
46
- Requires-Dist: qiskit-qir<0.6,>=0.5; extra == "qiskit"
47
- Requires-Dist: qiskit<2.0,>=1.0; extra == "qiskit"
46
+ Requires-Dist: qsharp[qiskit]<2.0,>=1.9.0; extra == "qiskit"
47
+ Requires-Dist: pyqir<0.11,>=0.10.6; extra == "qiskit"
48
48
  Requires-Dist: Markdown<4.0,>=3.4.1; extra == "qiskit"
49
49
  Requires-Dist: python-markdown-math<1.0,>=0.8.0; extra == "qiskit"
50
50
  Provides-Extra: qsharp
@@ -2,7 +2,7 @@ azure/quantum/__init__.py,sha256=Za8xZY4lzFkW8m4ero-bqrfN437D2NRukM77ukb4GPM,508
2
2
  azure/quantum/_constants.py,sha256=nDL_QrGdI_Zz_cvTB9nVgfE7J6A_Boo1ollMYqsiEBs,3499
3
3
  azure/quantum/_workspace_connection_params.py,sha256=KoT90U89Dj6pVwAKp_ENJL1hyTF0oQe7w0QioOGvjXg,21685
4
4
  azure/quantum/storage.py,sha256=_4bMniDk9LrB_K5CQwuCivJFZXdmhRvU2b6Z3xxXw9I,12556
5
- azure/quantum/version.py,sha256=UKyDm7olfca_jl4kfZ2YJWPOicc_dGHFVc4HIlN0Fxo,235
5
+ azure/quantum/version.py,sha256=TnDCYSdtFyry__XYbh4tqN_uFRjxSp9rlHSAEAQYfY0,235
6
6
  azure/quantum/workspace.py,sha256=1__iZTe59ozAsAGJ4nECxmk_211Dm8ALJi-MFIdrg4o,23438
7
7
  azure/quantum/_authentication/__init__.py,sha256=bniNZlS0hMIjO_y7DevGBAS6MixyA5pbPHcdGipUWM4,236
8
8
  azure/quantum/_authentication/_chained.py,sha256=0rdohB_fVGFHUhlly9sGxqQTBTZGpGxtlBqNHDFbAqE,4848
@@ -14,7 +14,7 @@ azure/quantum/_client/_configuration.py,sha256=5uktKtZxoVVAoSyeL0VNGS9AfPERp-9rU
14
14
  azure/quantum/_client/_patch.py,sha256=YTV6yZ9bRfBBaw2z7v4MdzR-zeHkdtKkGb4SU8C25mE,694
15
15
  azure/quantum/_client/_serialization.py,sha256=KJSS6KWgnKcz-cENQCmWZ9Ziv303lnBbLwFIpYZeKFU,81097
16
16
  azure/quantum/_client/_vendor.py,sha256=h8ByiyZ4cCQyFxqnuhTQdv1Rms3dVjKsrgZDzwMcSJ0,996
17
- azure/quantum/_client/_version.py,sha256=qvePw7MpAjzl2NlBoHDo0GGUX4XuuZjihqAuUURVLNc,495
17
+ azure/quantum/_client/_version.py,sha256=Ugb4E4_TnbHI-G9DlVpP7Ury0IKbr0EDFsfNmY4GwJg,495
18
18
  azure/quantum/_client/models/__init__.py,sha256=c1PRpzNsQTcDk4GkrFMMIlwNQQa2c0p5N0Lzd-23YBA,2100
19
19
  azure/quantum/_client/models/_enums.py,sha256=omj_B8_E8ONzTHg5hLgDlFYibRRbdr9sEN298im_otA,2977
20
20
  azure/quantum/_client/models/_models.py,sha256=wktCM5oBVfwQetNoHobL1wNsC3knXV-HmqBq_Q77Kw4,41810
@@ -41,38 +41,38 @@ azure/quantum/job/session.py,sha256=EEJVKEEB5g0yyH963aaR0GY0Cd0axrX-49gwDWxBcfE,
41
41
  azure/quantum/job/workspace_item.py,sha256=lyBIJCtUfIZMGJYJkX7Se8IDnXhXe4JU0RnqzSuhhI4,1380
42
42
  azure/quantum/job/workspace_item_factory.py,sha256=QRWyrtgcKZqUucJOFi9V_SYMV3lj6S74tGRrPtk3NE0,1200
43
43
  azure/quantum/qiskit/__init__.py,sha256=gjKsmRwtVNcbbsuOvy2wT0ASELh5NXGmuwaEwjZcVQo,314
44
- azure/quantum/qiskit/job.py,sha256=zrm1HHW_9A9DG8XFO-y7xDZtsbuS64C8etFaF8XWotE,14888
44
+ azure/quantum/qiskit/job.py,sha256=_pKIwMuEOXNzXhl7X79Uzq1EbOtxmNI7u_r3ybzGn34,14868
45
45
  azure/quantum/qiskit/provider.py,sha256=kbZJgDX-hI-AD5rQfik4JHNnNd74oyfrKYauosqBRxw,10966
46
46
  azure/quantum/qiskit/backends/__init__.py,sha256=DBC6GgYa5Y0p5xu5ADqlOXs7zp8_RDTJ86qKhuzXfG0,1118
47
- azure/quantum/qiskit/backends/backend.py,sha256=nj4gYDPxp91uA_JfStnpJFU7hSw15Nsz8--9wmHFMXc,22024
48
- azure/quantum/qiskit/backends/ionq.py,sha256=bDL7Oy85nK1iMbOlbhxOc8izBOqFGpZ593jCQ6PoMjg,14406
49
- azure/quantum/qiskit/backends/microsoft.py,sha256=7Nw-z8KoIBOBXbP8aqhmhAeW9TENrwwkZk6LD31M9F0,3478
50
- azure/quantum/qiskit/backends/qci.py,sha256=_t6IVUGe4LXzXSLLADwpvic2JTNxOSCsRl0s4zx3K7c,4656
51
- azure/quantum/qiskit/backends/quantinuum.py,sha256=bwmhcZEnj71LMWT31six-WnZJ_b-YqP0VxzCZwnsa9g,13910
52
- azure/quantum/qiskit/backends/rigetti.py,sha256=3XYr5C37MhGH6fm7LHX3UQ6BGYlSN9-q61Xd8WHEX5U,4112
47
+ azure/quantum/qiskit/backends/backend.py,sha256=qE0mt03sI2DsSZ7WWPshkeg8CqIYotIobMiLaRcVVn8,24126
48
+ azure/quantum/qiskit/backends/ionq.py,sha256=YYR6ELJ7VMw2kUSMQ0VTART0ykJvGgYTQDbfAFdx8Do,14438
49
+ azure/quantum/qiskit/backends/microsoft.py,sha256=okn5J1Ddcmg2_8pSjrn1uykp6p7tLw1sQCkoeo0HTXw,5540
50
+ azure/quantum/qiskit/backends/qci.py,sha256=c0YK-znG8TSAnFmeszo7mpKhM624QHszTQoapOqOvHg,4794
51
+ azure/quantum/qiskit/backends/quantinuum.py,sha256=wR0oxE9UmZyy73hnhWnG8XvPIaPAA3h77brhqUXBsfk,13654
52
+ azure/quantum/qiskit/backends/rigetti.py,sha256=lTsa0UjPdsAZUvvfnBge7H22TvA7c-_3fU09ZTA4ARs,4146
53
53
  azure/quantum/qiskit/results/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
54
  azure/quantum/qiskit/results/resource_estimator.py,sha256=pAP5ZpVxdzNekQ_qXfSdSKYWWuqL_Vq7WK6pWU4wbEQ,814
55
55
  azure/quantum/target/__init__.py,sha256=F0nIEJdlbczmxAdtvPDWf8J1Y33_XjPzloliHeWpJos,689
56
- azure/quantum/target/ionq.py,sha256=cJ7jZHN8HSLvlxCSY6hNHf1dFog40PmVLfJ_PT5eVo4,8068
56
+ azure/quantum/target/ionq.py,sha256=saPRhYlwyx0tLEtJHWR0K5tE7CUjwnXu_ay17sCKM_Y,8317
57
57
  azure/quantum/target/params.py,sha256=oI-35HUEMCskNjpxCJU3tjL664K-TxqAg5LA5xU0nso,9130
58
- azure/quantum/target/quantinuum.py,sha256=Fe84Mf927Bd4UrebOa0qx4qOH7SqOAlFE6zR42ioYec,7937
59
- azure/quantum/target/target.py,sha256=GChB4kzTlETgLHlH8zIMPJX5W5m1GoOkrNqiCHw3R70,16281
58
+ azure/quantum/target/quantinuum.py,sha256=dogWB2u6XUOhg0VZVoI9GbvDeHa-EQtl05N_iJExEUg,8169
59
+ azure/quantum/target/target.py,sha256=jmrFY_CqYAQCMWEfs05MxHq_mUOSyqUGmBwl2cg0XUo,16989
60
60
  azure/quantum/target/target_factory.py,sha256=jjZ9zxWaNDkcvslKV02GSP8rtXwStJ7EmVXQSOFh_j8,5266
61
61
  azure/quantum/target/microsoft/__init__.py,sha256=36kM2YlWv69AzAfUA5wMdWyYRSaCMwX2Ajhffpzx67g,570
62
62
  azure/quantum/target/microsoft/job.py,sha256=GM4OA-rxFUqQzsH8V59pVc4BmBaPYvd99E26pyPwxto,1249
63
63
  azure/quantum/target/microsoft/result.py,sha256=AntJptXKHNRdRR6oxhTlKKPOJVSU7u9fIfH2GXJqfx0,18784
64
- azure/quantum/target/microsoft/target.py,sha256=D7KS3AH-sjD1MVXL-J0SG61aGdWlrTZNT9JicjJzWeE,17879
64
+ azure/quantum/target/microsoft/target.py,sha256=UoWZzD6sLrWKUQnFKfeYHvUdXWvIsMPv0YtsmubCDL0,18123
65
65
  azure/quantum/target/microsoft/elements/__init__.py,sha256=gVVpaN5086iuBnajtvTjSd7MLExtnsR6RDCmcgz6xpE,70
66
66
  azure/quantum/target/microsoft/elements/dft/__init__.py,sha256=kCXOA9HT-gb23An-A0eyktlB66VoH6EwNO4gPM97l3U,224
67
67
  azure/quantum/target/microsoft/elements/dft/job.py,sha256=REDLDF6-HBwB4OxUMrgKfZWCE6W7RWj7HKhiYeH1a-E,2936
68
68
  azure/quantum/target/microsoft/elements/dft/target.py,sha256=IeFDVh3SqDsQOZmd9UKhl1Qu0ChkOEIHHb5fC5x4YGE,2556
69
69
  azure/quantum/target/pasqal/__init__.py,sha256=qbe6oWTQTsnTYwY3xZr32z4AWaYIchx71bYlqC2rQqw,348
70
70
  azure/quantum/target/pasqal/result.py,sha256=SUvpnrtgvCGiepmNpyifW8b4p14-SZZ1ToCC0NAdIwg,1463
71
- azure/quantum/target/pasqal/target.py,sha256=DMt2uYeCeaUFh7vlnf687VOoRStXCWL-6Mk_Dub8anI,4833
71
+ azure/quantum/target/pasqal/target.py,sha256=K_vqavov6gvS84voRKeBx9pO8g4LrtWrlZ5-RMLWozw,5139
72
72
  azure/quantum/target/rigetti/__init__.py,sha256=I1vyzZBYGI540pauTqJd0RSSyTShGqkEL7Yjo25_RNY,378
73
73
  azure/quantum/target/rigetti/result.py,sha256=65mtAZxfdNrTWNjWPqgfwt2BZN6Nllo4g_bls7-Nm68,2334
74
- azure/quantum/target/rigetti/target.py,sha256=ymfJX6khTfe6H26pxvbNgIVbd9cldP1OQ5CsF2PQHp0,7059
75
- azure_quantum-2.1.2.dist-info/METADATA,sha256=v0yXxkGbBzJagpju4FMPhwjV1gKXhA4X86YvAOenDgw,7339
76
- azure_quantum-2.1.2.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
77
- azure_quantum-2.1.2.dist-info/top_level.txt,sha256=S7DhWV9m80TBzAhOFjxDUiNbKszzoThbnrSz5MpbHSQ,6
78
- azure_quantum-2.1.2.dist-info/RECORD,,
74
+ azure/quantum/target/rigetti/target.py,sha256=75yGp8RYXGX9NWOkqoY_9L7FtUcAlD5KPj92wTn1zYg,7418
75
+ azure_quantum-2.2.0.dist-info/METADATA,sha256=BXXM2KPKaIzZNP-6KONkBkciorjonJNe-IWWsL9mRLY,7357
76
+ azure_quantum-2.2.0.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
77
+ azure_quantum-2.2.0.dist-info/top_level.txt,sha256=S7DhWV9m80TBzAhOFjxDUiNbKszzoThbnrSz5MpbHSQ,6
78
+ azure_quantum-2.2.0.dist-info/RECORD,,