azure-quantum 2.2.0.dev5__tar.gz → 2.3.0__tar.gz

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.
Files changed (95) hide show
  1. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/PKG-INFO +1 -1
  2. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/_version.py +1 -1
  3. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/argument_types/__init__.py +1 -1
  4. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/cirq/service.py +0 -30
  5. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/cirq/targets/ionq.py +0 -31
  6. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/cirq/targets/quantinuum.py +0 -20
  7. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/qiskit/backends/__init__.py +0 -5
  8. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/qiskit/backends/backend.py +2 -19
  9. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/qiskit/backends/ionq.py +0 -15
  10. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/qiskit/backends/quantinuum.py +1 -32
  11. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/qiskit/job.py +2 -8
  12. azure-quantum-2.3.0/azure/quantum/target/ionq.py +128 -0
  13. azure-quantum-2.3.0/azure/quantum/target/microsoft/elements/dft/job.py +171 -0
  14. azure-quantum-2.3.0/azure/quantum/target/microsoft/elements/dft/target.py +236 -0
  15. azure-quantum-2.3.0/azure/quantum/target/microsoft/target.py +142 -0
  16. azure-quantum-2.3.0/azure/quantum/target/quantinuum.py +102 -0
  17. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/rigetti/target.py +5 -0
  18. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/target.py +1 -11
  19. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/version.py +1 -1
  20. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure_quantum.egg-info/PKG-INFO +1 -1
  21. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure_quantum.egg-info/SOURCES.txt +0 -6
  22. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure_quantum.egg-info/requires.txt +2 -2
  23. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/requirements-qiskit.txt +1 -1
  24. azure-quantum-2.2.0.dev5/azure/quantum/qiskit/backends/microsoft.py +0 -161
  25. azure-quantum-2.2.0.dev5/azure/quantum/qiskit/results/__init__.py +0 -0
  26. azure-quantum-2.2.0.dev5/azure/quantum/qiskit/results/resource_estimator.py +0 -25
  27. azure-quantum-2.2.0.dev5/azure/quantum/target/ionq.py +0 -239
  28. azure-quantum-2.2.0.dev5/azure/quantum/target/microsoft/__init__.py +0 -15
  29. azure-quantum-2.2.0.dev5/azure/quantum/target/microsoft/elements/dft/job.py +0 -65
  30. azure-quantum-2.2.0.dev5/azure/quantum/target/microsoft/elements/dft/target.py +0 -87
  31. azure-quantum-2.2.0.dev5/azure/quantum/target/microsoft/job.py +0 -35
  32. azure-quantum-2.2.0.dev5/azure/quantum/target/microsoft/result.py +0 -497
  33. azure-quantum-2.2.0.dev5/azure/quantum/target/microsoft/target.py +0 -471
  34. azure-quantum-2.2.0.dev5/azure/quantum/target/quantinuum.py +0 -225
  35. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/README.md +0 -0
  36. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/__init__.py +0 -0
  37. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_authentication/__init__.py +0 -0
  38. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_authentication/_chained.py +0 -0
  39. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_authentication/_default.py +0 -0
  40. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_authentication/_token.py +0 -0
  41. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/__init__.py +0 -0
  42. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/_client.py +0 -0
  43. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/_configuration.py +0 -0
  44. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/_patch.py +0 -0
  45. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/_serialization.py +0 -0
  46. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/_vendor.py +0 -0
  47. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/models/__init__.py +0 -0
  48. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/models/_enums.py +0 -0
  49. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/models/_models.py +0 -0
  50. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/models/_patch.py +0 -0
  51. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/operations/__init__.py +0 -0
  52. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/operations/_operations.py +0 -0
  53. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_client/operations/_patch.py +0 -0
  54. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_constants.py +0 -0
  55. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/_workspace_connection_params.py +0 -0
  56. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/argument_types/types.py +0 -0
  57. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/chemistry/__init__.py +0 -0
  58. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/cirq/__init__.py +0 -0
  59. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/cirq/job.py +0 -0
  60. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/cirq/targets/__init__.py +0 -0
  61. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/cirq/targets/target.py +0 -0
  62. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/job/__init__.py +0 -0
  63. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/job/base_job.py +0 -0
  64. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/job/filtered_job.py +0 -0
  65. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/job/job.py +0 -0
  66. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/job/job_failed_with_results_error.py +0 -0
  67. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/job/session.py +0 -0
  68. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/job/workspace_item.py +0 -0
  69. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/job/workspace_item_factory.py +0 -0
  70. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/qiskit/__init__.py +0 -0
  71. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/qiskit/backends/qci.py +0 -0
  72. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/qiskit/backends/rigetti.py +0 -0
  73. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/qiskit/provider.py +0 -0
  74. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/storage.py +0 -0
  75. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/__init__.py +0 -0
  76. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/microsoft/elements/__init__.py +0 -0
  77. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/microsoft/elements/dft/__init__.py +0 -0
  78. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/params.py +0 -0
  79. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/pasqal/__init__.py +0 -0
  80. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/pasqal/result.py +0 -0
  81. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/pasqal/target.py +0 -0
  82. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/rigetti/__init__.py +0 -0
  83. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/rigetti/result.py +0 -0
  84. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/target/target_factory.py +0 -0
  85. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure/quantum/workspace.py +0 -0
  86. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure_quantum.egg-info/dependency_links.txt +0 -0
  87. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/azure_quantum.egg-info/top_level.txt +0 -0
  88. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/requirements-cirq.txt +0 -0
  89. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/requirements-dev.txt +0 -0
  90. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/requirements-pulser.txt +0 -0
  91. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/requirements-qsharp.txt +0 -0
  92. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/requirements-quil.txt +0 -0
  93. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/requirements.txt +0 -0
  94. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/setup.cfg +0 -0
  95. {azure-quantum-2.2.0.dev5 → azure-quantum-2.3.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: azure-quantum
3
- Version: 2.2.0.dev5
3
+ Version: 2.3.0
4
4
  Summary: Python client for Azure Quantum
5
5
  Home-page: https://github.com/microsoft/azure-quantum-python
6
6
  Author: Microsoft
@@ -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.2.0.dev5"
9
+ VERSION = "2.3.0"
@@ -3,7 +3,7 @@
3
3
  # Licensed under the MIT License.
4
4
  ##
5
5
 
6
- """Defines argument types for Microsoft Estimator"""
6
+ """Defines argument types for QIR"""
7
7
 
8
8
  from .types import EmptyArray, Pauli, Range, Result
9
9
 
@@ -160,36 +160,6 @@ see https://aka.ms/AQ/Docs/AddProvider")
160
160
  name=name
161
161
  )
162
162
 
163
- def estimate_cost(
164
- self,
165
- program: cirq.Circuit,
166
- repetitions: int,
167
- target: str = None,
168
- param_resolver: cirq.ParamResolverOrSimilarType = cirq.ParamResolver({}),
169
- **kwargs
170
- ):
171
- """
172
- Estimate the cost for a given circuit.
173
-
174
- :param program: Cirq program or circuit
175
- :type program: cirq.Circuit
176
- :param repetitions: Number of measurement repetitions
177
- :type repetitions: int
178
- :param target: Target name, defaults to default_target
179
- :type target: str
180
- :param param_resolver: Cirq parameters, defaults to `cirq.ParamResolver({})`
181
- :type param_resolver: cirq.ParamResolverOrSimilarType
182
- """
183
-
184
- # Resolve parameters
185
- resolved_circuit = cirq.resolve_parameters(program, param_resolver)
186
- target = self.get_target(name=target)
187
- return target.estimate_cost(
188
- program=resolved_circuit,
189
- repetitions=repetitions,
190
- **kwargs
191
- )
192
-
193
163
  def run(
194
164
  self,
195
165
  program: cirq.Circuit,
@@ -119,37 +119,6 @@ are not installed, throw error with installation instructions."""
119
119
  job_dict = self._client._create_job_dict(azure_job)
120
120
  return CirqIonqJob(client=self._client, job_dict=job_dict)
121
121
 
122
- def estimate_cost(
123
- self,
124
- program: "cirq.Circuit",
125
- repetitions: int,
126
- price_1q: float = None,
127
- price_2q: float = None,
128
- min_price: float = None) -> float:
129
- """Estimate cost for running this program
130
-
131
- :param program: Cirq quantum program
132
- :type program: cirq.Circuit
133
- :param repetitions: Number of repetitions
134
- :type repetitions: int
135
- :param price_1q: The price of running a single-qubit gate.
136
- :type price_1q: float, optional
137
- :param price_2q: The price of running a double-qubit gate.
138
- :type price_2q: float, optional
139
- :param min_price: The minimum price for running a job.
140
- :type min_price: float, optional
141
- :return: Price estimate
142
- :rtype: float
143
- """
144
- serialized_program = self._translate_cirq_circuit(program)
145
- return super().estimate_cost(
146
- serialized_program.body,
147
- repetitions,
148
- price_1q=price_1q,
149
- price_2q=price_2q,
150
- min_price=min_price
151
- )
152
-
153
122
  def submit(
154
123
  self,
155
124
  program: "cirq.Circuit",
@@ -74,26 +74,6 @@ class QuantinuumTarget(Quantinuum, CirqTarget):
74
74
  meas.gate.key: [q.x for q in meas.qubits] for meas in measurements
75
75
  }
76
76
 
77
- def estimate_cost(
78
- self,
79
- program: str,
80
- repetitions: int
81
- ) -> float:
82
- """Estimate cost for running this program
83
-
84
- :param program: Cirq quantum program
85
- :type program: str, optional
86
- :param repetitions: Number of repetitions
87
- :type repetitions: int, optional
88
- :return: Price estimate in HQC
89
- :rtype: float
90
- """
91
- serialized_program = self._translate_circuit(program)
92
- return super().estimate_cost(
93
- circuit=serialized_program,
94
- shots=repetitions
95
- )
96
-
97
77
  def submit(
98
78
  self,
99
79
  program: "cirq.Circuit",
@@ -37,11 +37,6 @@ from azure.quantum.qiskit.backends.qci import (
37
37
  QCIQPUBackend,
38
38
  )
39
39
 
40
- from azure.quantum.qiskit.backends.microsoft import (
41
- MicrosoftBackend,
42
- MicrosoftResourceEstimationBackend,
43
- )
44
-
45
40
  from .backend import AzureBackendBase
46
41
 
47
42
  __all__ = [
@@ -440,6 +440,8 @@ class AzureQirBackend(AzureBackendBase):
440
440
  for circuit in circuits:
441
441
  qir_str = backend.qir(circuit)
442
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
443
445
  llvm_module.link(module)
444
446
  err = llvm_module.verify()
445
447
  if err is not None:
@@ -498,25 +500,6 @@ class AzureQirBackend(AzureBackendBase):
498
500
 
499
501
  return str(module).encode("utf-8")
500
502
 
501
- def _estimate_cost_qir(
502
- self, circuits: Union[QuantumCircuit, List[QuantumCircuit]], shots, options={}
503
- ):
504
- """Estimate the cost for the given circuit."""
505
- input_params = self._get_input_params(options, shots=shots)
506
-
507
- if not (isinstance(circuits, list)):
508
- circuits = [circuits]
509
-
510
- skip_transpilation = input_params.pop("skipTranspile", False)
511
- target_profile = self._get_target_profile(input_params)
512
- module = self._generate_qir(
513
- circuits, target_profile, skip_transpilation=skip_transpilation
514
- )
515
-
516
- workspace = self.provider().get_workspace()
517
- target = workspace.get_targets(self.name())
518
- return target.estimate_cost(module, shots=shots)
519
-
520
503
  def _get_target_profile(self, input_params) -> TargetProfile:
521
504
  # Default to Adaptive_RI if not specified on the backend
522
505
  # this is really just a safeguard in case the backend doesn't have a default
@@ -77,10 +77,6 @@ class IonQQirBackendBase(AzureQirBackend):
77
77
  )
78
78
  return config
79
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)
83
-
84
80
  def run(
85
81
  self,
86
82
  run_input: Union[QuantumCircuit, List[QuantumCircuit]] = [],
@@ -265,17 +261,6 @@ class IonQBackend(AzureBackend):
265
261
  def gateset(self):
266
262
  return self.configuration().gateset
267
263
 
268
- def estimate_cost(self, circuit, shots):
269
- """Estimate the cost for the given circuit."""
270
- ionq_circ, _, _ = qiskit_circ_to_ionq_circ(circuit, gateset=self.gateset())
271
- input_data = {
272
- "qubits": circuit.num_qubits,
273
- "circuit": ionq_circ,
274
- }
275
- workspace = self.provider().get_workspace()
276
- target = workspace.get_targets(self.name())
277
- return target.estimate_cost(input_data, shots=shots)
278
-
279
264
 
280
265
  class IonQSimulatorBackend(IonQBackend):
281
266
  backend_names = ("ionq.simulator",)
@@ -60,7 +60,7 @@ def _get_n_qubits(name):
60
60
  if ".h1-" in name or "hqs-lt" in name:
61
61
  return 20
62
62
  if ".h2-" in name:
63
- return 32
63
+ return 56
64
64
  warnings.warn(
65
65
  UserWarning(f"Number of qubits not known for target {name}. Defaulting to 20."))
66
66
  return 20
@@ -99,10 +99,6 @@ class QuantinuumQirBackendBase(AzureQirBackend):
99
99
  def _get_n_qubits(self, name):
100
100
  return _get_n_qubits(name)
101
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)
105
-
106
102
 
107
103
  class QuantinuumSyntaxCheckerQirBackend(QuantinuumQirBackendBase):
108
104
  backend_names = (
@@ -248,33 +244,6 @@ class QuantinuumBackend(AzureBackend):
248
244
  """Translates the input values to the format expected by the AzureBackend."""
249
245
  return dumps(circuit)
250
246
 
251
- def estimate_cost(
252
- self, circuit: QuantumCircuit, shots: int = None, count: int = None
253
- ):
254
- """Estimate cost for running this circuit
255
-
256
- :param circuit: Qiskit quantum circuit
257
- :type circuit: QuantumCircuit
258
- :param shots: Shot count
259
- :type shots: int
260
- :param count: Shot count (alternative to 'shots')
261
- :type count: int
262
- """
263
- if count is not None:
264
- warnings.warn(
265
- "The 'count' parameter will be deprecated. Please, use 'shots' parameter instead.",
266
- category=DeprecationWarning,
267
- )
268
- shots = count
269
-
270
- if shots is None:
271
- raise ValueError("Missing input argument 'shots'.")
272
-
273
- input_data = dumps(circuit)
274
- workspace = self.provider().get_workspace()
275
- target = workspace.get_targets(self.name())
276
- return target.estimate_cost(input_data, shots=shots)
277
-
278
247
  def _get_n_qubits(self, name):
279
248
  return _get_n_qubits(name)
280
249
 
@@ -19,7 +19,6 @@ import ast
19
19
  import json
20
20
  import re
21
21
  from azure.quantum import Job
22
- from azure.quantum.qiskit.results.resource_estimator import make_estimator_result
23
22
 
24
23
  import logging
25
24
  logger = logging.getLogger(__name__)
@@ -38,7 +37,6 @@ MICROSOFT_OUTPUT_DATA_FORMAT = "microsoft.quantum-results.v1"
38
37
  MICROSOFT_OUTPUT_DATA_FORMAT_V2 = "microsoft.quantum-results.v2"
39
38
  IONQ_OUTPUT_DATA_FORMAT = "ionq.quantum-results.v1"
40
39
  QUANTINUUM_OUTPUT_DATA_FORMAT = "honeywell.quantum-results.v1"
41
- RESOURCE_ESTIMATOR_OUTPUT_DATA_FORMAT = "microsoft.resource-estimates.v1"
42
40
 
43
41
  class AzureQuantumJob(JobV1):
44
42
  def __init__(
@@ -96,10 +94,7 @@ class AzureQuantumJob(JobV1):
96
94
  "error_data" : None if self._azure_job.details.error_data is None else self._azure_job.details.error_data.as_dict()
97
95
  }
98
96
 
99
- if self._azure_job.details.output_data_format == RESOURCE_ESTIMATOR_OUTPUT_DATA_FORMAT:
100
- return make_estimator_result(result_dict)
101
- else:
102
- return Result.from_dict(result_dict)
97
+ return Result.from_dict(result_dict)
103
98
 
104
99
  def cancel(self):
105
100
  """Attempt to cancel the job."""
@@ -218,8 +213,7 @@ class AzureQuantumJob(JobV1):
218
213
 
219
214
  if isinstance(obj, tuple):
220
215
  # 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.
216
+ # associated with a classical register.
223
217
  return " ".join(
224
218
  [
225
219
  AzureQuantumJob._qir_to_qiskit_bitstring(term)
@@ -0,0 +1,128 @@
1
+ ##
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License.
4
+ ##
5
+ from typing import Any, Dict, List
6
+ from warnings import warn
7
+
8
+ from azure.quantum.target.target import (
9
+ Target,
10
+ _determine_shots_or_deprecated_num_shots,
11
+ )
12
+ from azure.quantum.job.job import Job
13
+ from azure.quantum.workspace import Workspace
14
+ from azure.quantum._client.models import CostEstimate, UsageEvent
15
+ from typing import Union
16
+
17
+ COST_1QUBIT_GATE_MAP = {
18
+ "ionq.simulator" : 0.0,
19
+ "ionq.qpu.aria-1" : 0.0002205,
20
+ "ionq.qpu.aria-2" : 0.0002205,
21
+ "ionq.qpu.forte-1" : 0.0002205
22
+ }
23
+
24
+ COST_2QUBIT_GATE_MAP = {
25
+ "ionq.simulator" : 0.0,
26
+ "ionq.qpu.aria-1" : 0.00098,
27
+ "ionq.qpu.aria-2" : 0.00098,
28
+ "ionq.qpu.forte-1" : 0.00098
29
+ }
30
+
31
+ MIN_PRICE_MAP = {
32
+ "ionq.simulator" : 0.0,
33
+ "ionq.qpu.aria-1" : 97.5,
34
+ "ionq.qpu.aria-2" : 97.5,
35
+ "ionq.qpu.forte-1" : 97.5
36
+ }
37
+
38
+ def int_to_bitstring(k: int, num_qubits: int, measured_qubit_ids: List[int]):
39
+ # flip bitstring to convert to little Endian
40
+ bitstring = format(int(k), f"0{num_qubits}b")[::-1]
41
+ # flip bitstring to convert back to big Endian
42
+ return "".join([bitstring[n] for n in measured_qubit_ids])[::-1]
43
+
44
+
45
+ class IonQ(Target):
46
+ """IonQ target."""
47
+ target_names = (
48
+ "ionq.simulator",
49
+ "ionq.qpu.aria-1",
50
+ "ionq.qpu.aria-2",
51
+ "ionq.qpu.forte-1"
52
+ )
53
+
54
+ _SHOTS_PARAM_NAME = "shots"
55
+
56
+ def __init__(
57
+ self,
58
+ workspace: Workspace,
59
+ name: str = "ionq.simulator",
60
+ input_data_format: str = "ionq.circuit.v1",
61
+ output_data_format: str = "ionq.quantum-results.v1",
62
+ capability: str = "",
63
+ provider_id: str = "IonQ",
64
+ content_type: str = "application/json",
65
+ encoding: str = "",
66
+ target_profile: Union[str, "TargetProfile"] = "Base",
67
+ **kwargs,
68
+ ):
69
+ if capability:
70
+ msg = "The 'capability' parameter is not used for the Quantinuum target."
71
+ warn(msg, DeprecationWarning)
72
+ super().__init__(
73
+ workspace=workspace,
74
+ name=name,
75
+ input_data_format=input_data_format,
76
+ output_data_format=output_data_format,
77
+ capability=capability,
78
+ provider_id=provider_id,
79
+ content_type=content_type,
80
+ encoding=encoding,
81
+ target_profile=target_profile,
82
+ **kwargs,
83
+ )
84
+
85
+ def submit(
86
+ self,
87
+ circuit: Dict[str, Any] = None,
88
+ name: str = "ionq-job",
89
+ shots: int = None,
90
+ input_params: Dict[str, Any] = None,
91
+ **kwargs
92
+ ) -> Job:
93
+ """Submit an IonQ circuit (JSON format)
94
+
95
+ :param circuit: Quantum circuit in IonQ JSON format (for examples,
96
+ see: https://docs.ionq.com/#section/Sample-JSON-Circuits)
97
+ :type circuit: Dict[str, Any]
98
+ :param name: Job name
99
+ :type name: str
100
+ :param shots: Number of shots, defaults to None
101
+ :type shots: int
102
+ :param input_params: Optional input params dict
103
+ :type input_params: Dict[str, Any]
104
+ :return: Azure Quantum job
105
+ :rtype: Job
106
+ """
107
+ input_data = kwargs.pop("input_data", circuit)
108
+ if input_data is None:
109
+ raise ValueError(
110
+ "Either the `circuit` parameter or the `input_data` parameter must have a value."
111
+ )
112
+ if input_params is None:
113
+ input_params = {}
114
+
115
+ num_shots = kwargs.pop("num_shots", None)
116
+
117
+ shots = _determine_shots_or_deprecated_num_shots(
118
+ shots=shots,
119
+ num_shots=num_shots,
120
+ )
121
+
122
+ return super().submit(
123
+ input_data=input_data,
124
+ name=name,
125
+ shots=shots,
126
+ input_params=input_params,
127
+ **kwargs
128
+ )
@@ -0,0 +1,171 @@
1
+ import collections.abc
2
+ import logging
3
+ from typing import Any, Dict, Union, Optional
4
+ from azure.quantum.job import JobFailedWithResultsError
5
+ from azure.quantum.job.base_job import BaseJob, ContentType
6
+ from azure.quantum.job.job import Job, DEFAULT_TIMEOUT
7
+ from azure.quantum._client.models import JobDetails
8
+ from azure.quantum.workspace import Workspace
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ class MicrosoftElementsDftJob(Job):
13
+ """
14
+ A dedicated job class for jobs from the microsoft.dft target.
15
+ """
16
+
17
+ def __init__(self, workspace, job_details: JobDetails, **kwargs):
18
+ """Azure Quantum Job that is submitted to a given Workspace.
19
+
20
+ :param workspace: Workspace instance to submit job to
21
+ :type workspace: Workspace
22
+ :param job_details: Job details model,
23
+ contains Job ID, name and other details
24
+ :type job_details: JobDetails
25
+ """
26
+ super().__init__(workspace, job_details, **kwargs)
27
+
28
+
29
+ def get_results(self, timeout_secs: float = DEFAULT_TIMEOUT) -> Dict[str, Any]:
30
+ """Get job results by downloading the results blob from the
31
+ storage container linked via the workspace.
32
+
33
+ :param timeout_secs: Timeout in seconds, defaults to 300
34
+ :type timeout_secs: float
35
+ :raises: :class:`RuntimeError` if job execution failed.
36
+ :raises: :class:`azure.quantum.job.JobFailedWithResultsError` if job execution failed,
37
+ but failure results could still be retrieved.
38
+ :return: Results dictionary.
39
+ """
40
+
41
+ try:
42
+ job_results = super().get_results(timeout_secs)
43
+ return job_results
44
+ except JobFailedWithResultsError as e:
45
+ failure_results = e.get_failure_results()
46
+ if MicrosoftElementsDftJob._is_dft_failure_results(failure_results):
47
+ error = failure_results["results"][0]["error"]
48
+ message = f'{e.get_message()} Error type: {error["error_type"]}. Message: {error["error_message"]}'
49
+ raise JobFailedWithResultsError(message, failure_results) from None
50
+
51
+
52
+ @classmethod
53
+ def _allow_failure_results(cls) -> bool:
54
+ """
55
+ Allow to download job results even if the Job status is "Failed".
56
+ """
57
+ return True
58
+
59
+
60
+ @staticmethod
61
+ def _is_dft_failure_results(failure_results: Union[Dict[str, Any], str]) -> bool:
62
+ return isinstance(failure_results, dict) \
63
+ and "results" in failure_results \
64
+ and isinstance(failure_results["results"], collections.abc.Sequence) \
65
+ and len(failure_results["results"]) > 0 \
66
+ and isinstance(failure_results["results"][0], dict) \
67
+ and "error" in failure_results["results"][0] \
68
+ and isinstance(failure_results["results"][0]["error"], dict) \
69
+ and "error_type" in failure_results["results"][0]["error"] \
70
+ and "error_message" in failure_results["results"][0]["error"]
71
+
72
+ @classmethod
73
+ def from_input_data_container(
74
+ cls,
75
+ workspace: "Workspace",
76
+ name: str,
77
+ target: str,
78
+ input_data: bytes,
79
+ batch_input_blobs: Dict[str, bytes],
80
+ content_type: ContentType = ContentType.json,
81
+ blob_name: str = "inputData",
82
+ encoding: str = "",
83
+ job_id: str = None,
84
+ container_name: str = None,
85
+ provider_id: str = None,
86
+ input_data_format: str = None,
87
+ output_data_format: str = None,
88
+ input_params: Dict[str, Any] = None,
89
+ session_id: Optional[str] = None,
90
+ **kwargs
91
+ ) -> "BaseJob":
92
+ """Create a new Azure Quantum job based on a list of input_data.
93
+
94
+ :param workspace: Azure Quantum workspace to submit the input_data to
95
+ :type workspace: Workspace
96
+ :param name: Name of the job
97
+ :type name: str
98
+ :param target: Azure Quantum target
99
+ :type target: str
100
+ :param input_data: Raw input data to submit
101
+ :type input_data: Dict
102
+ :param blob_name: Dict of Input data json to gives a table of contents
103
+ :type batch_input_blobs: Dict
104
+ :param blob_name: Dict of QcSchema Data where the key is the blob name to store it in the container
105
+ :type blob_name: str
106
+ :param content_type: Content type, e.g. "application/json"
107
+ :type content_type: ContentType
108
+ :param encoding: input_data encoding, e.g. "gzip", defaults to empty string
109
+ :type encoding: str
110
+ :param job_id: Job ID, defaults to None
111
+ :type job_id: str
112
+ :param container_name: Container name, defaults to None
113
+ :type container_name: str
114
+ :param provider_id: Provider ID, defaults to None
115
+ :type provider_id: str
116
+ :param input_data_format: Input data format, defaults to None
117
+ :type input_data_format: str
118
+ :param output_data_format: Output data format, defaults to None
119
+ :type output_data_format: str
120
+ :param input_params: Input parameters, defaults to None
121
+ :type input_params: Dict[str, Any]
122
+ :param input_params: Input params for job
123
+ :type input_params: Dict[str, Any]
124
+ :return: Azure Quantum Job
125
+ :rtype: Job
126
+ """
127
+ # Generate job ID if not specified
128
+ if job_id is None:
129
+ job_id = cls.create_job_id()
130
+
131
+ # Create container if it does not yet exist
132
+ container_uri = workspace.get_container_uri(
133
+ job_id=job_id,
134
+ container_name=container_name
135
+ )
136
+ logger.debug(f"Container URI: {container_uri}")
137
+
138
+ # Upload Input Data
139
+ input_data_uri = cls.upload_input_data(
140
+ container_uri=container_uri,
141
+ input_data=input_data,
142
+ content_type=content_type,
143
+ blob_name=blob_name,
144
+ encoding=encoding,
145
+ )
146
+
147
+ # Upload data to container
148
+ for blob_name, input_data_item in batch_input_blobs.items():
149
+ cls.upload_input_data(
150
+ container_uri=container_uri,
151
+ input_data=input_data_item,
152
+ content_type=content_type,
153
+ blob_name=blob_name,
154
+ encoding=encoding,
155
+ )
156
+
157
+ # Create and submit job
158
+ return cls.from_storage_uri(
159
+ workspace=workspace,
160
+ job_id=job_id,
161
+ target=target,
162
+ input_data_uri=input_data_uri,
163
+ container_uri=container_uri,
164
+ name=name,
165
+ input_data_format=input_data_format,
166
+ output_data_format=output_data_format,
167
+ provider_id=provider_id,
168
+ input_params=input_params,
169
+ session_id=session_id,
170
+ **kwargs
171
+ )