azure-quantum 2.2.0.dev6__py3-none-any.whl → 2.4.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/_client/py.typed +1 -0
- azure/quantum/argument_types/__init__.py +1 -1
- azure/quantum/cirq/service.py +0 -30
- azure/quantum/cirq/targets/ionq.py +0 -31
- azure/quantum/cirq/targets/quantinuum.py +0 -20
- azure/quantum/qiskit/backends/__init__.py +0 -5
- azure/quantum/qiskit/backends/backend.py +2 -19
- azure/quantum/qiskit/backends/ionq.py +0 -15
- azure/quantum/qiskit/backends/quantinuum.py +1 -32
- azure/quantum/qiskit/job.py +2 -8
- azure/quantum/target/ionq.py +0 -111
- azure/quantum/target/microsoft/elements/dft/job.py +108 -2
- azure/quantum/target/microsoft/elements/dft/target.py +158 -8
- azure/quantum/target/microsoft/target.py +0 -329
- azure/quantum/target/quantinuum.py +0 -123
- azure/quantum/target/rigetti/target.py +5 -0
- azure/quantum/target/target.py +1 -11
- azure/quantum/version.py +1 -1
- {azure_quantum-2.2.0.dev6.dist-info → azure_quantum-2.4.0.dist-info}/METADATA +3 -3
- {azure_quantum-2.2.0.dev6.dist-info → azure_quantum-2.4.0.dist-info}/RECORD +23 -28
- {azure_quantum-2.2.0.dev6.dist-info → azure_quantum-2.4.0.dist-info}/WHEEL +1 -1
- azure/quantum/qiskit/backends/microsoft.py +0 -149
- azure/quantum/qiskit/results/__init__.py +0 -0
- azure/quantum/qiskit/results/resource_estimator.py +0 -25
- azure/quantum/target/microsoft/__init__.py +0 -15
- azure/quantum/target/microsoft/job.py +0 -35
- azure/quantum/target/microsoft/result.py +0 -497
- {azure_quantum-2.2.0.dev6.dist-info → azure_quantum-2.4.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Marker file for PEP 561.
|
azure/quantum/cirq/service.py
CHANGED
|
@@ -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
|
|
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
|
|
azure/quantum/qiskit/job.py
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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)
|
azure/quantum/target/ionq.py
CHANGED
|
@@ -126,114 +126,3 @@ class IonQ(Target):
|
|
|
126
126
|
input_params=input_params,
|
|
127
127
|
**kwargs
|
|
128
128
|
)
|
|
129
|
-
|
|
130
|
-
def estimate_cost(
|
|
131
|
-
self,
|
|
132
|
-
circuit: Union[Dict[str, Any], Any],
|
|
133
|
-
num_shots: int = None,
|
|
134
|
-
price_1q: float = None,
|
|
135
|
-
price_2q: float = None,
|
|
136
|
-
min_price: float = None,
|
|
137
|
-
shots: int = None
|
|
138
|
-
) -> CostEstimate:
|
|
139
|
-
"""Estimate the cost of submitting a circuit to IonQ targets.
|
|
140
|
-
Optionally, you can provide the number of gate and measurement operations
|
|
141
|
-
manually.
|
|
142
|
-
The actual price charged by the provider may differ from this calculation.
|
|
143
|
-
|
|
144
|
-
Specify pricing details for your area to get most accurate results.
|
|
145
|
-
By default, this function charges depending on the target:
|
|
146
|
-
ionq.qpu.aria-1:
|
|
147
|
-
price_1q = 0.00022 USD for a single-qubit gate.
|
|
148
|
-
price_2q = 0.00098 USD for a two-qubit gate.
|
|
149
|
-
min_price = 1 USD, total minimum price per circuit.
|
|
150
|
-
|
|
151
|
-
For the most current pricing details, see
|
|
152
|
-
https://docs.microsoft.com/azure/quantum/provider-ionq#pricing
|
|
153
|
-
or find your workspace and view pricing options in the "Provider" tab
|
|
154
|
-
of your workspace: https://aka.ms/aq/myworkspaces
|
|
155
|
-
|
|
156
|
-
:param circuit: Quantum circuit in IonQ JSON format (for examples,
|
|
157
|
-
see: https://docs.ionq.com/#section/Sample-JSON-Circuits)
|
|
158
|
-
:type circuit: Dict[str, Any]
|
|
159
|
-
:param num_shots: Number of shots, defaults to None
|
|
160
|
-
:type num_shots: int
|
|
161
|
-
:param price_1q: The price of running a single-qubit gate
|
|
162
|
-
for one shot.
|
|
163
|
-
:type price_1q: float
|
|
164
|
-
:param price_2q: The price of running a double-qubit gate
|
|
165
|
-
for one shot.
|
|
166
|
-
:type price_2q: float
|
|
167
|
-
:param min_price: The minimum price for running a job.
|
|
168
|
-
:type min_price: float
|
|
169
|
-
:param shots: Number of shots, defaults to None
|
|
170
|
-
:type shots: int
|
|
171
|
-
"""
|
|
172
|
-
|
|
173
|
-
if num_shots is None and shots is None:
|
|
174
|
-
raise ValueError("The 'shots' parameter has to be specified")
|
|
175
|
-
|
|
176
|
-
if num_shots is not None:
|
|
177
|
-
warn(
|
|
178
|
-
"The 'num_shots' parameter will be deprecated. Please, use 'shots' parameter instead.",
|
|
179
|
-
category=DeprecationWarning,
|
|
180
|
-
)
|
|
181
|
-
shots = num_shots
|
|
182
|
-
|
|
183
|
-
# Get the costs for the gates depending on the provider if not specified
|
|
184
|
-
if price_1q is None:
|
|
185
|
-
price_1q = COST_1QUBIT_GATE_MAP[self.name]
|
|
186
|
-
|
|
187
|
-
if price_2q is None:
|
|
188
|
-
price_2q = COST_2QUBIT_GATE_MAP[self.name]
|
|
189
|
-
|
|
190
|
-
if min_price is None:
|
|
191
|
-
min_price = MIN_PRICE_MAP[self.name]
|
|
192
|
-
|
|
193
|
-
if (isinstance(circuit, Dict)):
|
|
194
|
-
def is_1q_gate(gate: Dict[str, Any]):
|
|
195
|
-
return "controls" not in gate and "control" not in gate
|
|
196
|
-
|
|
197
|
-
def is_multi_q_gate(gate):
|
|
198
|
-
return "controls" in gate or "control" in gate
|
|
199
|
-
|
|
200
|
-
def num_2q_gates(gate):
|
|
201
|
-
controls = gate.get("controls")
|
|
202
|
-
if controls is None or len(controls) == 1:
|
|
203
|
-
# Only one control qubit
|
|
204
|
-
return 1
|
|
205
|
-
# Multiple control qubits
|
|
206
|
-
return 6 * (len(controls) - 2)
|
|
207
|
-
|
|
208
|
-
gates = circuit.get("circuit", [])
|
|
209
|
-
N_1q = sum(map(is_1q_gate, gates))
|
|
210
|
-
N_2q = sum(map(num_2q_gates, filter(is_multi_q_gate, gates)))
|
|
211
|
-
|
|
212
|
-
else:
|
|
213
|
-
N_1q, N_2q, _ = Target._calculate_qir_module_gate_stats(circuit)
|
|
214
|
-
|
|
215
|
-
price = (price_1q * N_1q + price_2q * N_2q) * shots
|
|
216
|
-
price = max(price, min_price)
|
|
217
|
-
|
|
218
|
-
return CostEstimate(
|
|
219
|
-
events = [
|
|
220
|
-
UsageEvent(
|
|
221
|
-
dimension_id="gs1q",
|
|
222
|
-
dimension_name="1Q Gate Shot",
|
|
223
|
-
measure_unit="1q gate shot",
|
|
224
|
-
amount_billed=0.0,
|
|
225
|
-
amount_consumed=N_1q * shots,
|
|
226
|
-
unit_price=0.0
|
|
227
|
-
),
|
|
228
|
-
UsageEvent(
|
|
229
|
-
dimension_id="gs2q",
|
|
230
|
-
dimension_name="2Q Gate Shot",
|
|
231
|
-
measure_unit="2q gate shot",
|
|
232
|
-
amount_billed=0.0,
|
|
233
|
-
amount_consumed=N_2q * shots,
|
|
234
|
-
unit_price=0.0
|
|
235
|
-
)
|
|
236
|
-
],
|
|
237
|
-
currency_code="USD",
|
|
238
|
-
estimated_total=price
|
|
239
|
-
)
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import collections.abc
|
|
2
|
-
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Any, Dict, Union, Optional
|
|
3
4
|
from azure.quantum.job import JobFailedWithResultsError
|
|
5
|
+
from azure.quantum.job.base_job import BaseJob, ContentType
|
|
4
6
|
from azure.quantum.job.job import Job, DEFAULT_TIMEOUT
|
|
5
7
|
from azure.quantum._client.models import JobDetails
|
|
8
|
+
from azure.quantum.workspace import Workspace
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
6
11
|
|
|
7
12
|
class MicrosoftElementsDftJob(Job):
|
|
8
13
|
"""
|
|
@@ -62,4 +67,105 @@ class MicrosoftElementsDftJob(Job):
|
|
|
62
67
|
and "error" in failure_results["results"][0] \
|
|
63
68
|
and isinstance(failure_results["results"][0]["error"], dict) \
|
|
64
69
|
and "error_type" in failure_results["results"][0]["error"] \
|
|
65
|
-
and "error_message" 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
|
+
)
|