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.
- azure/quantum/_client/_version.py +1 -1
- azure/quantum/cirq/service.py +7 -0
- azure/quantum/cirq/targets/quantinuum.py +1 -1
- azure/quantum/job/job.py +15 -1
- azure/quantum/qiskit/backends/backend.py +130 -35
- azure/quantum/qiskit/backends/ionq.py +65 -5
- azure/quantum/qiskit/backends/qci.py +35 -2
- azure/quantum/qiskit/backends/quantinuum.py +25 -4
- azure/quantum/qiskit/backends/rigetti.py +8 -1
- azure/quantum/qiskit/job.py +7 -16
- azure/quantum/qiskit/provider.py +18 -2
- azure/quantum/target/ionq.py +37 -12
- azure/quantum/target/microsoft/elements/dft/target.py +13 -1
- azure/quantum/target/microsoft/target.py +36 -9
- azure/quantum/target/params.py +1 -1
- azure/quantum/target/pasqal/target.py +16 -2
- azure/quantum/target/quantinuum.py +34 -9
- azure/quantum/target/rigetti/target.py +15 -2
- azure/quantum/target/solvers.py +7 -1
- azure/quantum/target/target.py +82 -0
- azure/quantum/target/target_factory.py +0 -2
- azure/quantum/version.py +1 -1
- azure/quantum/workspace.py +11 -8
- {azure_quantum-0.30.0.dist-info → azure_quantum-1.0.0.dist-info}/METADATA +3 -5
- {azure_quantum-0.30.0.dist-info → azure_quantum-1.0.0.dist-info}/RECORD +27 -55
- azure/quantum/_client/aio/__init__.py +0 -23
- azure/quantum/_client/aio/_client.py +0 -124
- azure/quantum/_client/aio/_configuration.py +0 -89
- azure/quantum/_client/aio/_patch.py +0 -20
- azure/quantum/_client/aio/operations/__init__.py +0 -29
- azure/quantum/_client/aio/operations/_operations.py +0 -1291
- azure/quantum/_client/aio/operations/_patch.py +0 -20
- azure/quantum/aio/__init__.py +0 -14
- azure/quantum/aio/_authentication/__init__.py +0 -9
- azure/quantum/aio/_authentication/_chained.py +0 -94
- azure/quantum/aio/_authentication/_default.py +0 -212
- azure/quantum/aio/_authentication/_token.py +0 -81
- azure/quantum/aio/job/__init__.py +0 -1
- azure/quantum/aio/job/base_job.py +0 -326
- azure/quantum/aio/job/job.py +0 -104
- azure/quantum/aio/optimization/__init__.py +0 -11
- azure/quantum/aio/optimization/online_problem.py +0 -17
- azure/quantum/aio/optimization/problem.py +0 -102
- azure/quantum/aio/optimization/streaming_problem.py +0 -280
- azure/quantum/aio/storage.py +0 -390
- azure/quantum/aio/target/__init__.py +0 -19
- azure/quantum/aio/target/ionq.py +0 -47
- azure/quantum/aio/target/quantinuum.py +0 -47
- azure/quantum/aio/target/solvers.py +0 -96
- azure/quantum/aio/target/target.py +0 -68
- azure/quantum/aio/target/target_factory.py +0 -72
- azure/quantum/aio/target/toshiba.py +0 -6
- azure/quantum/aio/workspace.py +0 -337
- {azure_quantum-0.30.0.dist-info → azure_quantum-1.0.0.dist-info}/WHEEL +0 -0
- {azure_quantum-0.30.0.dist-info → azure_quantum-1.0.0.dist-info}/top_level.txt +0 -0
azure/quantum/target/ionq.py
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
93
|
-
:type
|
|
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) *
|
|
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 *
|
|
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 *
|
|
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(
|
|
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(
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
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(
|
|
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]:
|
azure/quantum/target/params.py
CHANGED
|
@@ -180,7 +180,7 @@ class InputParams(InputParamsItem):
|
|
|
180
180
|
"""
|
|
181
181
|
Class to define input parameters.
|
|
182
182
|
|
|
183
|
-
This class allows to define
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
|
67
|
-
:type
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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 +
|
|
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
|
-
|
|
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(
|
|
197
|
+
return super().submit(
|
|
198
|
+
input_data=input_data,
|
|
199
|
+
name=name,
|
|
200
|
+
shots=shots,
|
|
201
|
+
input_params=input_params,
|
|
202
|
+
**kwargs
|
|
203
|
+
)
|
azure/quantum/target/solvers.py
CHANGED
|
@@ -98,7 +98,10 @@ class Solver(Target):
|
|
|
98
98
|
return data.to_blob()
|
|
99
99
|
|
|
100
100
|
def submit(
|
|
101
|
-
self,
|
|
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(
|
azure/quantum/target/target.py
CHANGED
|
@@ -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
azure/quantum/workspace.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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
|