azure-quantum 0.30.0__py3-none-any.whl → 1.0.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.
Files changed (55) hide show
  1. azure/quantum/_client/_version.py +1 -1
  2. azure/quantum/cirq/service.py +7 -0
  3. azure/quantum/cirq/targets/quantinuum.py +1 -1
  4. azure/quantum/job/job.py +15 -1
  5. azure/quantum/qiskit/backends/backend.py +130 -35
  6. azure/quantum/qiskit/backends/ionq.py +65 -5
  7. azure/quantum/qiskit/backends/qci.py +35 -2
  8. azure/quantum/qiskit/backends/quantinuum.py +25 -4
  9. azure/quantum/qiskit/backends/rigetti.py +8 -1
  10. azure/quantum/qiskit/job.py +7 -16
  11. azure/quantum/qiskit/provider.py +18 -2
  12. azure/quantum/target/ionq.py +37 -12
  13. azure/quantum/target/microsoft/elements/dft/target.py +13 -1
  14. azure/quantum/target/microsoft/target.py +36 -9
  15. azure/quantum/target/params.py +1 -1
  16. azure/quantum/target/pasqal/target.py +16 -2
  17. azure/quantum/target/quantinuum.py +34 -9
  18. azure/quantum/target/rigetti/target.py +15 -2
  19. azure/quantum/target/solvers.py +7 -1
  20. azure/quantum/target/target.py +82 -0
  21. azure/quantum/target/target_factory.py +0 -2
  22. azure/quantum/version.py +1 -1
  23. azure/quantum/workspace.py +11 -8
  24. {azure_quantum-0.30.0.dist-info → azure_quantum-1.0.0.dist-info}/METADATA +3 -5
  25. {azure_quantum-0.30.0.dist-info → azure_quantum-1.0.0.dist-info}/RECORD +27 -55
  26. azure/quantum/_client/aio/__init__.py +0 -23
  27. azure/quantum/_client/aio/_client.py +0 -124
  28. azure/quantum/_client/aio/_configuration.py +0 -89
  29. azure/quantum/_client/aio/_patch.py +0 -20
  30. azure/quantum/_client/aio/operations/__init__.py +0 -29
  31. azure/quantum/_client/aio/operations/_operations.py +0 -1291
  32. azure/quantum/_client/aio/operations/_patch.py +0 -20
  33. azure/quantum/aio/__init__.py +0 -14
  34. azure/quantum/aio/_authentication/__init__.py +0 -9
  35. azure/quantum/aio/_authentication/_chained.py +0 -94
  36. azure/quantum/aio/_authentication/_default.py +0 -212
  37. azure/quantum/aio/_authentication/_token.py +0 -81
  38. azure/quantum/aio/job/__init__.py +0 -1
  39. azure/quantum/aio/job/base_job.py +0 -326
  40. azure/quantum/aio/job/job.py +0 -104
  41. azure/quantum/aio/optimization/__init__.py +0 -11
  42. azure/quantum/aio/optimization/online_problem.py +0 -17
  43. azure/quantum/aio/optimization/problem.py +0 -102
  44. azure/quantum/aio/optimization/streaming_problem.py +0 -280
  45. azure/quantum/aio/storage.py +0 -390
  46. azure/quantum/aio/target/__init__.py +0 -19
  47. azure/quantum/aio/target/ionq.py +0 -47
  48. azure/quantum/aio/target/quantinuum.py +0 -47
  49. azure/quantum/aio/target/solvers.py +0 -96
  50. azure/quantum/aio/target/target.py +0 -68
  51. azure/quantum/aio/target/target_factory.py +0 -72
  52. azure/quantum/aio/target/toshiba.py +0 -6
  53. azure/quantum/aio/workspace.py +0 -337
  54. {azure_quantum-0.30.0.dist-info → azure_quantum-1.0.0.dist-info}/WHEEL +0 -0
  55. {azure_quantum-0.30.0.dist-info → azure_quantum-1.0.0.dist-info}/top_level.txt +0 -0
@@ -3,8 +3,12 @@
3
3
  # Licensed under the MIT License.
4
4
  ##
5
5
  from typing import Any, Dict, List
6
+ from warnings import warn
6
7
 
7
- from azure.quantum.target.target import Target
8
+ from azure.quantum.target.target import (
9
+ Target,
10
+ _determine_shots_or_deprecated_num_shots,
11
+ )
8
12
  from azure.quantum.job.job import Job
9
13
  from azure.quantum.workspace import Workspace
10
14
  from azure.quantum._client.models import CostEstimate, UsageEvent
@@ -50,6 +54,8 @@ class IonQ(Target):
50
54
  "ionq.qpu.forte-1"
51
55
  )
52
56
 
57
+ _SHOTS_PARAM_NAME = "shots"
58
+
53
59
  def __init__(
54
60
  self,
55
61
  workspace: Workspace,
@@ -78,7 +84,7 @@ class IonQ(Target):
78
84
  self,
79
85
  circuit: Dict[str, Any] = None,
80
86
  name: str = "ionq-job",
81
- num_shots: int = None,
87
+ shots: int = None,
82
88
  input_params: Dict[str, Any] = None,
83
89
  **kwargs
84
90
  ) -> Job:
@@ -89,8 +95,8 @@ class IonQ(Target):
89
95
  :type circuit: Dict[str, Any]
90
96
  :param name: Job name
91
97
  :type name: str
92
- :param num_shots: Number of shots, defaults to None
93
- :type num_shots: int
98
+ :param shots: Number of shots, defaults to None
99
+ :type shots: int
94
100
  :param input_params: Optional input params dict
95
101
  :type input_params: Dict[str, Any]
96
102
  :return: Azure Quantum job
@@ -103,13 +109,18 @@ class IonQ(Target):
103
109
  )
104
110
  if input_params is None:
105
111
  input_params = {}
106
- if num_shots is not None:
107
- input_params = input_params.copy()
108
- input_params["shots"] = num_shots
109
112
 
113
+ num_shots = kwargs.pop("num_shots", None)
114
+
115
+ shots = _determine_shots_or_deprecated_num_shots(
116
+ shots=shots,
117
+ num_shots=num_shots,
118
+ )
119
+
110
120
  return super().submit(
111
121
  input_data=input_data,
112
122
  name=name,
123
+ shots=shots,
113
124
  input_params=input_params,
114
125
  **kwargs
115
126
  )
@@ -117,10 +128,11 @@ class IonQ(Target):
117
128
  def estimate_cost(
118
129
  self,
119
130
  circuit: Dict[str, Any],
120
- num_shots: int,
131
+ num_shots: int = None,
121
132
  price_1q: float = None,
122
133
  price_2q: float = None,
123
- min_price: float = None
134
+ min_price: float = None,
135
+ shots: int = None
124
136
  ) -> CostEstimate:
125
137
  """Estimate the cost of submitting a circuit to IonQ targets.
126
138
  Optionally, you can provide the number of gate and measurement operations
@@ -156,7 +168,20 @@ class IonQ(Target):
156
168
  :type price_2q: float, optional
157
169
  :param min_price: The minimum price for running a job.
158
170
  :type min_price: float, optional
171
+ :param shots: Number of shots, defaults to None
172
+ :type shots: int
159
173
  """
174
+
175
+ if num_shots is None and shots is None:
176
+ raise ValueError("The 'shots' parameter has to be specified")
177
+
178
+ if num_shots is not None:
179
+ warn(
180
+ "The 'num_shots' parameter will be deprecated. Please, use 'shots' parameter instead.",
181
+ category=DeprecationWarning,
182
+ )
183
+ shots = num_shots
184
+
160
185
  def is_1q_gate(gate: Dict[str, Any]):
161
186
  return "controls" not in gate and "control" not in gate
162
187
 
@@ -185,7 +210,7 @@ class IonQ(Target):
185
210
  N_1q = sum(map(is_1q_gate, gates))
186
211
  N_2q = sum(map(num_2q_gates, filter(is_multi_q_gate, gates)))
187
212
 
188
- price = (price_1q * N_1q + price_2q * N_2q) * num_shots
213
+ price = (price_1q * N_1q + price_2q * N_2q) * shots
189
214
  price = max(price, min_price)
190
215
 
191
216
  return CostEstimate(
@@ -195,7 +220,7 @@ class IonQ(Target):
195
220
  dimension_name="1Q Gate Shot",
196
221
  measure_unit="1q gate shot",
197
222
  amount_billed=0.0,
198
- amount_consumed=N_1q * num_shots,
223
+ amount_consumed=N_1q * shots,
199
224
  unit_price=0.0
200
225
  ),
201
226
  UsageEvent(
@@ -203,7 +228,7 @@ class IonQ(Target):
203
228
  dimension_name="2Q Gate Shot",
204
229
  measure_unit="2q gate shot",
205
230
  amount_billed=0.0,
206
- amount_consumed=N_2q * num_shots,
231
+ amount_consumed=N_2q * shots,
207
232
  unit_price=0.0
208
233
  )
209
234
  ],
@@ -1,3 +1,5 @@
1
+ import warnings
2
+
1
3
  from azure.quantum.job.base_job import ContentType
2
4
  from azure.quantum.job.job import Job
3
5
  from azure.quantum.target.target import Target
@@ -43,10 +45,20 @@ class MicrosoftElementsDft(Target):
43
45
  def submit(self,
44
46
  input_data: Any,
45
47
  name: str = "azure-quantum-dft-job",
48
+ shots: int = None,
46
49
  input_params: Union[Dict[str, Any], InputParams, None] = None,
47
50
  **kwargs) -> MicrosoftElementsDftJob:
51
+
52
+ if shots is not None:
53
+ warnings.warn("The 'shots' parameter is ignored in Microsoft Elements Dft job.")
48
54
 
49
- return super().submit(input_data, name, input_params, **kwargs)
55
+ return super().submit(
56
+ input_data=input_data,
57
+ name=name,
58
+ shots=shots,
59
+ input_params=input_params,
60
+ **kwargs
61
+ )
50
62
 
51
63
 
52
64
  @classmethod
@@ -3,8 +3,10 @@
3
3
  # Licensed under the MIT License.
4
4
  ##
5
5
  import re
6
+ import warnings
6
7
  from dataclasses import dataclass, field
7
- from typing import Any, Dict, Optional, Type, Union
8
+ from typing import Any, Dict, Optional, Type, Union, List
9
+
8
10
  from ...job import Job
9
11
  from ...job.base_job import ContentType
10
12
  from ...workspace import Workspace
@@ -12,8 +14,6 @@ from ..params import InputParams, InputParamsItem, AutoValidatingParams, \
12
14
  validating_field
13
15
  from ..target import Target
14
16
  from . import MicrosoftEstimatorJob
15
- from typing import List
16
-
17
17
 
18
18
  class QubitParams:
19
19
  GATE_US_E3 = "qubit_gate_us_e3"
@@ -377,11 +377,32 @@ class MicrosoftEstimator(Target):
377
377
  **kwargs
378
378
  )
379
379
 
380
- def submit(self,
381
- input_data: Any,
382
- name: str = "azure-quantum-job",
383
- input_params: Union[Dict[str, Any], InputParams, None] = None,
384
- **kwargs) -> Job:
380
+ def submit(
381
+ self,
382
+ input_data: Any,
383
+ name: str = "azure-quantum-job",
384
+ shots: int = None,
385
+ input_params: Union[Dict[str, Any], InputParams, None] = None,
386
+ **kwargs,
387
+ ) -> Job:
388
+ """
389
+ Submit an estimation job
390
+
391
+ :param input_data: Input data
392
+ :type input_data: Any
393
+ :param name: Job name
394
+ :type name: str
395
+ :param shots: Number of shots. Ignored in estimation. Defaults to None
396
+ :type shots: int
397
+ :param input_params: Input parameters
398
+ :type input_params: Dict[str, Any]
399
+ :return: Azure Quantum job
400
+ :rtype: Job
401
+ """
402
+
403
+ if shots is not None:
404
+ warnings.warn("The 'shots' parameter is ignored in resource estimation job.")
405
+
385
406
  try:
386
407
  from qiskit import QuantumCircuit, transpile
387
408
  from qiskit_qir import to_qir_module
@@ -393,7 +414,13 @@ class MicrosoftEstimator(Target):
393
414
  (module, _) = to_qir_module(input_data, record_output=False)
394
415
  input_data = module.bitcode
395
416
  finally:
396
- return super().submit(input_data, name, input_params, **kwargs)
417
+ return super().submit(
418
+ input_data=input_data,
419
+ name=name,
420
+ shots=shots,
421
+ input_params=input_params,
422
+ **kwargs
423
+ )
397
424
 
398
425
  @classmethod
399
426
  def _get_job_class(cls) -> Type[Job]:
@@ -180,7 +180,7 @@ class InputParams(InputParamsItem):
180
180
  """
181
181
  Class to define input parameters.
182
182
 
183
- This class allows to define inout parameters for non-batching and batching
183
+ This class allows to define input parameters for non-batching and batching
184
184
  jobs. The instance represents a batching job, if and only if num_items is
185
185
  set to some positive number less or equal to MAX_NUM_ITEMS.
186
186
 
@@ -64,6 +64,8 @@ class Pasqal(Target):
64
64
 
65
65
  target_names = tuple(target.value for target in PasqalTarget)
66
66
 
67
+ _SHOTS_PARAM_NAME = "count"
68
+
67
69
  def __init__(
68
70
  self,
69
71
  workspace: Workspace,
@@ -91,6 +93,7 @@ class Pasqal(Target):
91
93
  self,
92
94
  input_data: Any,
93
95
  name: str = "azure-quantum-job",
96
+ shots: int = None,
94
97
  input_params: Union[InputParams, None, Dict[str, Any]] = None,
95
98
  **kwargs,
96
99
  ) -> Job:
@@ -103,15 +106,26 @@ class Pasqal(Target):
103
106
  :type input_data: Any
104
107
  :param name: Job name
105
108
  :type name: str
109
+ :param shots: Number of shots, defaults to None
110
+ :type shots: int
106
111
  :param input_params: Input parameters, see :class:`azure.quantum.target.pasqal.InputParams` for details.
107
112
  :type input_params: Union[InputParams, None, Dict[str, Any]]
108
113
  :return: Azure Quantum job
109
114
  :rtype: Job
110
115
  """
116
+
111
117
  if isinstance(input_params, InputParams):
112
118
  typed_input_params = input_params
113
119
  input_params = {
114
- "runs": typed_input_params.runs,
120
+ self.__class__._SHOTS_PARAM_NAME: typed_input_params.runs,
115
121
  }
122
+
123
+ input_params = input_params or {}
116
124
 
117
- return super().submit(input_data, name, input_params, **kwargs)
125
+ return super().submit(
126
+ input_data=input_data,
127
+ name=name,
128
+ shots=shots,
129
+ input_params=input_params,
130
+ **kwargs
131
+ )
@@ -3,8 +3,12 @@
3
3
  # Licensed under the MIT License.
4
4
  ##
5
5
  from typing import Any, Dict
6
+ from warnings import warn
6
7
 
7
- from azure.quantum.target.target import Target
8
+ from azure.quantum.target.target import (
9
+ Target,
10
+ _determine_shots_or_deprecated_num_shots,
11
+ )
8
12
  from azure.quantum.job.job import Job
9
13
  from azure.quantum.workspace import Workspace
10
14
  from azure.quantum._client.models import CostEstimate, UsageEvent
@@ -25,6 +29,8 @@ class Quantinuum(Target):
25
29
  "quantinuum.sim.h2-1e",
26
30
  )
27
31
 
32
+ _SHOTS_PARAM_NAME = "count"
33
+
28
34
  def __init__(
29
35
  self,
30
36
  workspace: Workspace,
@@ -53,7 +59,7 @@ class Quantinuum(Target):
53
59
  self,
54
60
  circuit: str = None,
55
61
  name: str = "quantinuum-job",
56
- num_shots: int = None,
62
+ shots: int = None,
57
63
  input_params: Dict[str, Any] = None,
58
64
  **kwargs
59
65
  ) -> Job:
@@ -63,8 +69,8 @@ class Quantinuum(Target):
63
69
  :type circuit: str
64
70
  :param name: Job name
65
71
  :type name: str
66
- :param num_shots: Number of shots, defaults to None
67
- :type num_shots: int
72
+ :param shots: Number of shots, defaults to None
73
+ :type shots: int
68
74
  :param input_params: Optional input params dict
69
75
  :type input_params: Dict[str, Any]
70
76
  :return: Azure Quantum job
@@ -77,13 +83,18 @@ class Quantinuum(Target):
77
83
  )
78
84
  if input_params is None:
79
85
  input_params = {}
80
- if num_shots is not None:
81
- input_params = input_params.copy()
82
- input_params["count"] = num_shots
86
+
87
+ num_shots = kwargs.pop("num_shots", None)
88
+
89
+ shots = _determine_shots_or_deprecated_num_shots(
90
+ shots=shots,
91
+ num_shots=num_shots,
92
+ )
83
93
 
84
94
  return super().submit(
85
95
  input_data=input_data,
86
96
  name=name,
97
+ shots=shots,
87
98
  input_params=input_params,
88
99
  **kwargs
89
100
  )
@@ -94,7 +105,8 @@ class Quantinuum(Target):
94
105
  num_shots: int = None,
95
106
  N_1q: int = None,
96
107
  N_2q: int = None,
97
- N_m: int = None
108
+ N_m: int = None,
109
+ shots: int = None,
98
110
  ) -> CostEstimate:
99
111
  """Estimate the cost in HQC for a given circuit.
100
112
  Optionally, you can provide the number of gate and measurement operations
@@ -119,9 +131,22 @@ class Quantinuum(Target):
119
131
  :param N_m: Number of measurement operations, if not specified,
120
132
  this is estimated from the circuit
121
133
  :type N_m: int, optional
134
+ :param shots: Number of shots for which to estimate costs
135
+ :type shots: int, optional
122
136
  :raises ImportError: If N_1q, N_2q and N_m are not specified,
123
137
  this will require a qiskit installation.
124
138
  """
139
+
140
+ if num_shots is None and shots is None:
141
+ raise ValueError("The 'shots' parameter has to be specified")
142
+
143
+ if num_shots is not None:
144
+ warn(
145
+ "The 'num_shots' parameter will be deprecated. Please, use 'shots' parameter instead.",
146
+ category=DeprecationWarning,
147
+ )
148
+ shots = num_shots
149
+
125
150
  if circuit is not None and (N_1q is None or N_2q is None or N_m is None):
126
151
  try:
127
152
  from qiskit.circuit.quantumcircuit import Qasm
@@ -160,7 +185,7 @@ class Quantinuum(Target):
160
185
  if is_syntax_checker_regex.match(self.name):
161
186
  HQC = 0.0
162
187
  else:
163
- HQC = 5 + num_shots * (N_1q + 10 * N_2q + 5 * N_m) / 5000
188
+ HQC = 5 + shots * (N_1q + 10 * N_2q + 5 * N_m) / 5000
164
189
 
165
190
  return CostEstimate(
166
191
  events=[
@@ -134,6 +134,8 @@ class Rigetti(Target):
134
134
 
135
135
  target_names = tuple(target.value for target in RigettiTarget)
136
136
 
137
+ _SHOTS_PARAM_NAME = "count"
138
+
137
139
  def __init__(
138
140
  self,
139
141
  workspace: Workspace,
@@ -161,6 +163,7 @@ class Rigetti(Target):
161
163
  self,
162
164
  input_data: Any,
163
165
  name: str = "azure-quantum-job",
166
+ shots: int = None,
164
167
  input_params: Union[InputParams, None, Dict[str, Any]] = None,
165
168
  **kwargs,
166
169
  ) -> Job:
@@ -173,6 +176,8 @@ class Rigetti(Target):
173
176
  :type input_data: Any
174
177
  :param name: Job name
175
178
  :type name: str
179
+ :param shots: Number of shots, defaults to None
180
+ :type shots: int
176
181
  :param input_params: Input parameters, see :class:`azure.quantum.target.rigetti.InputParams` for details.
177
182
  :type input_params: Union[InputParams, None, Dict[str, Any]]
178
183
  :return: Azure Quantum job
@@ -181,10 +186,18 @@ class Rigetti(Target):
181
186
  if isinstance(input_params, InputParams):
182
187
  typed_input_params = input_params
183
188
  input_params = {
184
- "count": typed_input_params.count,
189
+ Rigetti._SHOTS_PARAM_NAME: typed_input_params.count,
185
190
  "skipQuilc": typed_input_params.skip_quilc,
186
191
  }
187
192
  if typed_input_params.substitutions is not None:
188
193
  input_params["substitutions"] = typed_input_params.substitutions
194
+ elif input_params is None:
195
+ input_params = {}
189
196
 
190
- return super().submit(input_data, name, input_params, **kwargs)
197
+ return super().submit(
198
+ input_data=input_data,
199
+ name=name,
200
+ shots=shots,
201
+ input_params=input_params,
202
+ **kwargs
203
+ )
@@ -98,7 +98,10 @@ class Solver(Target):
98
98
  return data.to_blob()
99
99
 
100
100
  def submit(
101
- self, problem: Union[str, "Problem"]) -> Job:
101
+ self,
102
+ problem: Union[str, "Problem"],
103
+ shots: int = None
104
+ ) -> Job:
102
105
  """Submits a job to execution to the associated
103
106
  Azure Quantum Workspace.
104
107
 
@@ -107,6 +110,9 @@ class Solver(Target):
107
110
  or the URL of an Azure Storage Blob where the serialized version
108
111
  of a Problem has been uploaded.
109
112
  """
113
+ if shots is not None:
114
+ warnings.warn("The 'shots' parameter is ignored for solver job.")
115
+
110
116
  from azure.quantum.optimization import Problem
111
117
  if isinstance(problem, Problem):
112
118
  return super().submit(
@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Any, Dict, Optional, Union, Type, Protocol, r
6
6
  import io
7
7
  import json
8
8
  import abc
9
+ import warnings
9
10
 
10
11
  from azure.quantum._client.models import TargetStatus, SessionDetails
11
12
  from azure.quantum._client.models._enums import SessionJobFailurePolicy
@@ -27,6 +28,9 @@ class QirRepresentable(Protocol):
27
28
 
28
29
 
29
30
  class Target(abc.ABC, SessionHost):
31
+
32
+ _QSHARP_USER_AGENT = "azure-quantum-qsharp"
33
+
30
34
  """Azure Quantum Target."""
31
35
  # Target IDs that are compatible with this Target class.
32
36
  # This variable is used by TargetFactory. To set the default
@@ -39,6 +43,10 @@ class Target(abc.ABC, SessionHost):
39
43
  # submit and get_job method.
40
44
  target_names = ()
41
45
 
46
+ # Name of the provider's input parameter which specifies number of shots for a submitted job.
47
+ # If None, target will not pass this input parameter.
48
+ _SHOTS_PARAM_NAME = None
49
+
42
50
  def __init__(
43
51
  self,
44
52
  workspace: "Workspace",
@@ -101,6 +109,13 @@ avg. queue time={self._average_queue_time} s, {self._current_availability}>"
101
109
  The job class used by submit and get_job. The default is Job.
102
110
  """
103
111
  return Job
112
+
113
+ @classmethod
114
+ def _can_send_shots_input_param(cls) -> bool:
115
+ """
116
+ Tells if provider's target class is able to specify shots number for its jobs.
117
+ """
118
+ return cls._SHOTS_PARAM_NAME is not None
104
119
 
105
120
  def refresh(self):
106
121
  """Update the target availability and queue time"""
@@ -150,6 +165,7 @@ target '{self.name}' of provider '{self.provider_id}' not found."
150
165
  self,
151
166
  input_data: Any,
152
167
  name: str = "azure-quantum-job",
168
+ shots: int = None,
153
169
  input_params: Union[Dict[str, Any], InputParams, None] = None,
154
170
  **kwargs
155
171
  ) -> Job:
@@ -162,6 +178,8 @@ target '{self.name}' of provider '{self.provider_id}' not found."
162
178
  :type input_data: Any
163
179
  :param name: Job name
164
180
  :type name: str
181
+ :param shots: Number of shots, defaults to None
182
+ :type shots: int
165
183
  :param input_params: Input parameters
166
184
  :type input_params: Dict[str, Any]
167
185
  :return: Azure Quantum job
@@ -182,6 +200,10 @@ target '{self.name}' of provider '{self.provider_id}' not found."
182
200
  input_data_format = kwargs.pop("input_data_format", "qir.v1")
183
201
  output_data_format = kwargs.pop("output_data_format", self._qir_output_data_format())
184
202
  content_type = kwargs.pop("content_type", "qir.v1")
203
+ # setting UserAgent header to indicate Q# submission
204
+ # TODO: this is a temporary solution. We should be setting the User-Agent header
205
+ # on per-job basis as targets of different types could be submitted using the same Workspace object
206
+ self.workspace.append_user_agent(self._QSHARP_USER_AGENT)
185
207
 
186
208
  def _get_entrypoint(input_data):
187
209
  # TODO: this method should be part of QirRepresentable protocol
@@ -200,6 +222,36 @@ target '{self.name}' of provider '{self.provider_id}' not found."
200
222
  input_data_format = kwargs.pop("input_data_format", self.input_data_format)
201
223
  output_data_format = kwargs.pop("output_data_format", self.output_data_format)
202
224
  content_type = kwargs.pop("content_type", self.content_type)
225
+ # re-setting UserAgent header to None for passthrough
226
+ self.workspace.append_user_agent(None)
227
+
228
+ # Set shots number, if possible.
229
+ if self._can_send_shots_input_param():
230
+ input_params_shots = input_params.pop(self.__class__._SHOTS_PARAM_NAME, None)
231
+
232
+ # If there is a parameter conflict, choose 'shots'.
233
+ if shots is not None and input_params_shots is not None:
234
+ warnings.warn(
235
+ f"Parameter 'shots' conflicts with the '{self.__class__._SHOTS_PARAM_NAME}' field of the 'input_params' "
236
+ "parameter. Please, provide only one option for setting shots. Defaulting to 'shots' parameter."
237
+ )
238
+ final_shots = shots
239
+
240
+ # The 'shots' parameter has highest priority.
241
+ elif shots is not None:
242
+ final_shots = shots
243
+ # if 'shots' parameter is not specified, try a provider-specific option.
244
+ elif input_params_shots is not None:
245
+ warnings.warn(
246
+ f"Field '{self.__class__._SHOTS_PARAM_NAME}' from the 'input_params' parameter is subject to change in future versions. "
247
+ "Please, use 'shots' parameter instead."
248
+ )
249
+ final_shots = input_params_shots
250
+ else:
251
+ final_shots = None
252
+
253
+ if final_shots is not None:
254
+ input_params[self.__class__._SHOTS_PARAM_NAME] = final_shots
203
255
 
204
256
  encoding = kwargs.pop("encoding", self.encoding)
205
257
  blob = self._encode_input_data(data=input_data)
@@ -241,3 +293,33 @@ target '{self.name}' of provider '{self.provider_id}' not found."
241
293
 
242
294
  def _get_azure_provider_id(self) -> str:
243
295
  return self.provider_id
296
+
297
+
298
+ def _determine_shots_or_deprecated_num_shots(
299
+ shots: int = None,
300
+ num_shots: int = None,
301
+ ) -> int:
302
+ """
303
+ This helper function checks if the deprecated 'num_shots' parameter is specified.
304
+ In earlier versions it was possible to pass this parameter to specify shots number for a job,
305
+ but now we only check for it for compatibility reasons.
306
+ """
307
+ final_shots = None
308
+ if shots is not None and num_shots is not None:
309
+ warnings.warn(
310
+ "Both 'shots' and 'num_shots' parameters were specified. Defaulting to 'shots' parameter. "
311
+ "Please, use 'shots' since 'num_shots' will be deprecated.",
312
+ category=DeprecationWarning,
313
+ )
314
+ final_shots = shots
315
+
316
+ elif shots is not None:
317
+ final_shots = shots
318
+ elif num_shots is not None:
319
+ warnings.warn(
320
+ "The 'num_shots' parameter will be deprecated. Please, use 'shots' parameter instead.",
321
+ category=DeprecationWarning,
322
+ )
323
+ final_shots = num_shots
324
+
325
+ return final_shots
@@ -3,7 +3,6 @@
3
3
  # Licensed under the MIT License.
4
4
  ##
5
5
  import warnings
6
- import asyncio
7
6
  from typing import Any, Dict, List, TYPE_CHECKING, Union, Type
8
7
  from azure.quantum.target import *
9
8
 
@@ -63,7 +62,6 @@ class TargetFactory:
63
62
  for _t in t.__subclasses__() + [t]
64
63
  if hasattr(_t, "target_names")
65
64
  for name in _t.target_names
66
- if not asyncio.iscoroutinefunction(_t.submit)
67
65
  }
68
66
 
69
67
  def _target_cls(self, provider_id: str, name: str):
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__ = "0.30.0"
8
+ __version__ = "1.0.0"
@@ -218,21 +218,24 @@ class Workspace:
218
218
  full_user_agent = f"{full_user_agent}-{env_app_id}" if full_user_agent else env_app_id
219
219
  return full_user_agent
220
220
 
221
- def append_user_agent(self, value: str):
221
+ def append_user_agent(self, value: Union[str, None]):
222
222
  """
223
223
  Append a new value to the Workspace's UserAgent and re-initialize the
224
224
  QuantumClient. The values are appended using a dash.
225
225
 
226
226
  :param value: UserAgent value to add, e.g. "azure-quantum-<plugin>"
227
227
  """
228
- if value not in (self._user_agent or ""):
228
+ new_user_agent = None
229
+
230
+ if value is not None and value not in (self._user_agent or ""):
229
231
  new_user_agent = f"{self._user_agent}-{value}" if self._user_agent else value
230
- if new_user_agent != self._user_agent:
231
- self._user_agent = new_user_agent
232
- # We need to recreate the client for it to
233
- # pick the new UserAgent
234
- if self._client is not None:
235
- self._client = self._create_client()
232
+
233
+ if new_user_agent != self._user_agent:
234
+ self._user_agent = new_user_agent
235
+ # We need to recreate the client for it to
236
+ # pick the new UserAgent
237
+ if self._client is not None:
238
+ self._client = self._create_client()
236
239
 
237
240
  def _get_top_level_items_client(self) -> TopLevelItemsOperations:
238
241
  return self._client.top_level_items