Skip to content

Commit 8144a4d

Browse files
committed
fix usage of memory-maps
1 parent 4b2ff6d commit 8144a4d

File tree

2 files changed

+46
-54
lines changed

2 files changed

+46
-54
lines changed

pyquil_for_azure_quantum/__init__.py

Lines changed: 44 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@
3232
from numpy import split
3333
from pyquil.api import QAM, MemoryMap, QAMExecutionResult, QuantumComputer, get_qc
3434
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+
)
3640
from qcs_sdk.qvm import QVMResultData # pylint: disable=no-name-in-module
3741
from wrapt import ObjectProxy
3842

@@ -106,7 +110,7 @@ def compile(
106110
def run_batch(
107111
self,
108112
executable: AzureProgram,
109-
memory_map: MemoryMap,
113+
memory_maps: List[MemoryMap],
110114
**__kwargs: Any,
111115
) -> List[QAMExecutionResult]:
112116
"""Run a sequence of memory values through the program.
@@ -115,7 +119,7 @@ def run_batch(
115119
* [`AzureQuantumMachine.execute_with_memory_map_batch`][pyquil_for_azure_quantum.AzureQuantumMachine.execute_with_memory_map_batch]
116120
"""
117121
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)
119123

120124

121125
def get_qpu(qpu_name: str) -> AzureQuantumComputer:
@@ -262,7 +266,7 @@ def get_result(self, execute_response: AzureJob) -> QAMExecutionResult:
262266
data=data,
263267
)
264268

265-
def execute_with_memory_map_batch( # type: ignore
269+
def execute_with_memory_map_batch(
266270
self,
267271
executable: AzureProgram,
268272
memory_maps: Iterable[MemoryMap],
@@ -273,14 +277,14 @@ def execute_with_memory_map_batch( # type: ignore
273277
274278
Args:
275279
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.)
280284
name: An optional name for the job which will show up in the Azure Quantum UI.
281285
282286
Returns:
283-
A list of ``QAMExecutionResult`` objects, one for each set of parameters.
287+
A list of ``QAMExecutionResult`` objects, one for each ``MemoryMap``.
284288
285289
```pycon
286290
@@ -309,48 +313,36 @@ def execute_with_memory_map_batch( # type: ignore
309313
310314
```
311315
"""
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())})
322344
)
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+
),
334346
)
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+
]

test/test_e2e_no_qcs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ def test_run_batch(qc: AzureQuantumComputer) -> None:
7272
"""Test the ``run_batch`` interface which should be much faster than normal parametrization"""
7373
compiled = qc.compile(PARAMETRIZED)
7474

75-
memory_map: MemoryMap = {"theta": [0, np.pi, 2 * np.pi]}
76-
results = qc.run_batch(compiled, memory_map)
75+
executions = [{"theta": [value]} for value in [0, np.pi, 2 * np.pi]]
76+
results = qc.run_batch(compiled, executions)
7777

7878
results_0 = results[0].get_register_map().get("ro")
7979
assert results_0 is not None

0 commit comments

Comments
 (0)