32
32
from numpy import split
33
33
from pyquil .api import QAM , MemoryMap , QAMExecutionResult , QuantumComputer , get_qc
34
34
from pyquil .quil import Program
35
- from qcs_sdk import ExecutionData , RegisterData , ResultData # pylint: disable=no-name-in-module
35
+ from qcs_sdk import ( # pylint: disable=no-name-in-module
36
+ ExecutionData ,
37
+ RegisterData ,
38
+ ResultData ,
39
+ )
36
40
from qcs_sdk .qvm import QVMResultData # pylint: disable=no-name-in-module
37
41
from wrapt import ObjectProxy
38
42
@@ -106,7 +110,7 @@ def compile(
106
110
def run_batch (
107
111
self ,
108
112
executable : AzureProgram ,
109
- memory_map : MemoryMap ,
113
+ memory_maps : List [ MemoryMap ] ,
110
114
** __kwargs : Any ,
111
115
) -> List [QAMExecutionResult ]:
112
116
"""Run a sequence of memory values through the program.
@@ -115,7 +119,7 @@ def run_batch(
115
119
* [`AzureQuantumMachine.execute_with_memory_map_batch`][pyquil_for_azure_quantum.AzureQuantumMachine.execute_with_memory_map_batch]
116
120
"""
117
121
qam = cast (AzureQuantumMachine , self .qam )
118
- return qam .execute_with_memory_map_batch (executable , [ memory_map ] )
122
+ return qam .execute_with_memory_map_batch (executable , memory_maps )
119
123
120
124
121
125
def get_qpu (qpu_name : str ) -> AzureQuantumComputer :
@@ -262,7 +266,7 @@ def get_result(self, execute_response: AzureJob) -> QAMExecutionResult:
262
266
data = data ,
263
267
)
264
268
265
- def execute_with_memory_map_batch ( # type: ignore
269
+ def execute_with_memory_map_batch (
266
270
self ,
267
271
executable : AzureProgram ,
268
272
memory_maps : Iterable [MemoryMap ],
@@ -273,14 +277,14 @@ def execute_with_memory_map_batch( # type: ignore
273
277
274
278
Args:
275
279
executable: The AzureProgram to run.
276
- memory_map : An iterable containing a ``MemoryMaps`` with desired mapping of parameter names to lists of parameter values.
277
- Each value is a list as long as the number of slots in the register. So if the register was ``DECLARE theta REAL[2]``
278
- then the key in the dictionary would be ``theta`` and the value would be a list of lists of length 2. The entire program
279
- will be run (for shot count) as many times as there are values in the list. **All values (outer lists) must be of the same length**.
280
+ memory_maps : An iterable containing ``MemoryMaps`` with desired mappings of parameter names to parameter values.
281
+ Each value is a list as long as the number of elements in the register. So if the register was ``DECLARE theta REAL[2]``
282
+ then the key in the dictionary would be ``theta`` and the value would be a list of length 2. The entire program
283
+ will be run (for shot count) once for each ``MemoryMap``. (If no memory maps are provided, the program will be run once.)
280
284
name: An optional name for the job which will show up in the Azure Quantum UI.
281
285
282
286
Returns:
283
- A list of ``QAMExecutionResult`` objects, one for each set of parameters .
287
+ A list of ``QAMExecutionResult`` objects, one for each ``MemoryMap`` .
284
288
285
289
```pycon
286
290
@@ -309,48 +313,36 @@ def execute_with_memory_map_batch( # type: ignore
309
313
310
314
```
311
315
"""
312
- results = []
313
- for memory_map in memory_maps :
314
- num_params = None
315
- for param_name , param_values in memory_map .items ():
316
- if num_params is None :
317
- num_params = len (param_values )
318
- elif num_params != len (param_values ):
319
- raise ValueError (
320
- "All parameter values must be of the same length. "
321
- f"{ param_name } has length { len (param_values )} but { num_params } were expected."
316
+ executable = executable .copy ()
317
+ input_params = InputParams (
318
+ count = executable .num_shots ,
319
+ skip_quilc = executable .skip_quilc ,
320
+ substitutions = memory_maps ,
321
+ )
322
+ job = self ._target .submit (
323
+ str (executable ),
324
+ name = name ,
325
+ input_params = input_params ,
326
+ )
327
+ azure_job = AzureJob (job = job , executable = executable )
328
+ combined_result = self .get_result (azure_job )
329
+ num_executions = len (memory_maps )
330
+
331
+ if num_executions in (0 , 1 ):
332
+ return combined_result
333
+
334
+ ro_matrix = combined_result .data .result_data .to_register_map ().get_register_matrix ("ro" )
335
+ if ro_matrix is None :
336
+ return []
337
+
338
+ return [
339
+ QAMExecutionResult (
340
+ executable ,
341
+ ExecutionData (
342
+ ResultData .from_qvm (
343
+ QVMResultData .from_memory_map (memory = {"ro" : RegisterData (split_result .tolist ())})
322
344
)
323
-
324
- executable = executable .copy ()
325
- input_params = InputParams (
326
- count = executable .num_shots ,
327
- skip_quilc = executable .skip_quilc ,
328
- substitutions = memory_map ,
329
- )
330
- job = self ._target .submit (
331
- str (executable ),
332
- name = name ,
333
- input_params = input_params ,
345
+ ),
334
346
)
335
- azure_job = AzureJob (job = job , executable = executable )
336
- combined_result = self .get_result (azure_job )
337
- if num_params is None or num_params == 1 :
338
- results .append (combined_result )
339
- continue
340
-
341
- ro_matrix = combined_result .data .result_data .to_register_map ().get_register_matrix ("ro" )
342
- if ro_matrix is None :
343
- continue
344
-
345
- results += [
346
- QAMExecutionResult (
347
- executable ,
348
- ExecutionData (
349
- ResultData .from_qvm (
350
- QVMResultData .from_memory_map (memory = {"ro" : RegisterData (split_result .tolist ())})
351
- )
352
- ),
353
- )
354
- for split_result in split (ro_matrix .to_ndarray (), num_params )
355
- ]
356
- return results
347
+ for split_result in split (ro_matrix .to_ndarray (), num_executions )
348
+ ]
0 commit comments