Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable more memory regions on the QVM #873

Merged
merged 14 commits into from
Aug 23, 2019
18 changes: 5 additions & 13 deletions pyquil/api/_qam.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import warnings

from abc import ABC, abstractmethod
from collections import defaultdict

from rpcq.messages import ParameterAref

Expand Down Expand Up @@ -54,7 +55,7 @@ def load(self, executable):

self._variables_shim = {}
self._executable = executable
self._bitstrings = None
self._memory_results = defaultdict(lambda: None)
self.status = 'loaded'
return self

Expand Down Expand Up @@ -104,12 +105,8 @@ def read_memory(self, *, region_name: str):
:return: A list of values of the appropriate type.
"""
assert self.status == 'done'
if region_name != "ro":
raise QAMError("Currently only allowed to read measurement data from ro.")
if self._bitstrings is None:
raise QAMError("Bitstrings have not yet been populated. Something has gone wrong.")

return self._bitstrings
return self._memory_results[region_name]

@_record_call
def read_from_memory_region(self, *, region_name: str):
Expand All @@ -125,13 +122,8 @@ def read_from_memory_region(self, *, region_name: str):
warnings.warn("pyquil.api._qam.QAM.read_from_memory_region is deprecated, please use "
"pyquil.api._qam.QAM.read_memory instead.",
DeprecationWarning)
assert self.status == 'done'
if region_name != "ro":
raise QAMError("Currently only allowed to read measurement data from ro.")
if self._bitstrings is None:
raise QAMError("Bitstrings have not yet been populated. Something has gone wrong.")

return self._bitstrings
self.read_memory(region_name=region_name)
ecpeterson marked this conversation as resolved.
Show resolved Hide resolved

@_record_call
def reset(self):
Expand All @@ -142,6 +134,6 @@ def reset(self):
"""
self._variables_shim = {}
self._executable = None
self._bitstrings = None
self._memory_results = defaultdict(lambda: None)

self.status = 'connected'
9 changes: 8 additions & 1 deletion pyquil/api/_qpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,17 @@ def run(self, run_priority: Optional[int] = None):
else:
bitstrings = None

self._bitstrings = bitstrings
self._memory_results = dict()
ecpeterson marked this conversation as resolved.
Show resolved Hide resolved
for aref, vals in self._variables_shim.items():
self._memory_results[aref] = [vals] * ro_sources[0].shape[0]
self._memory_results["ro"] = bitstrings
self._last_results = results

return self

def read_memory(self, *, region_name: str):
return super().read_memory(region_name=region_name)
ecpeterson marked this conversation as resolved.
Show resolved Hide resolved

def _get_buffers(self, job_id: str) -> Dict[str, np.ndarray]:
"""
Return the decoded result buffers for particular job_id.
Expand Down
14 changes: 6 additions & 8 deletions pyquil/api/_qvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,18 +510,16 @@ def run(self):
quil_program = apply_noise_model(quil_program, self.noise_model)

quil_program = self.augment_program_with_memory_values(quil_program)
try:
self._bitstrings = self.connection._qvm_run(quil_program=quil_program,

self._memory_results = self.connection._qvm_run(quil_program=quil_program,
classical_addresses=classical_addresses,
trials=trials,
measurement_noise=self.measurement_noise,
gate_noise=self.gate_noise,
random_seed=self.random_seed)['ro']
except KeyError:
warnings.warn("You are running a QVM program with no MEASURE instructions. "
"The result of this program will always be an empty array. Are "
"you sure you didn't mean to measure some of your qubits?")
self._bitstrings = np.zeros((trials, 0), dtype=np.int64)
random_seed=self.random_seed)

if "ro" not in self._memory_results or self._memory_results["ro"] == []:
self._memory_results["ro"] = np.zeros((trials, 0))
ecpeterson marked this conversation as resolved.
Show resolved Hide resolved

return self

Expand Down
4 changes: 2 additions & 2 deletions pyquil/pyqvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ def __init__(self, n_qubits, quantum_simulator_type: Type[AbstractQuantumSimulat
# private implementation details
self._qubit_to_ram = None # type: Dict[int, int]
self._ro_size = None # type :int
self._bitstrings = None # type: np.ndarray
self._memory_results = None # type: np.ndarray
ecpeterson marked this conversation as resolved.
Show resolved Hide resolved

self.rs = np.random.RandomState(seed=seed)
self.wf_simulator = quantum_simulator_type(n_qubits=n_qubits, rs=self.rs)
Expand All @@ -265,7 +265,7 @@ def load(self, executable):
# initialize program counter
self.program = program
self.program_counter = 0
self._bitstrings = None
self._memory_results = None

# clear RAM, although it's not strictly clear if this should happen here
self.ram = {}
Expand Down
6 changes: 3 additions & 3 deletions pyquil/tests/test_quantum_computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,15 +412,15 @@ def test_reset(forest):
aref = ParameterAref(name='theta', index=0)
assert qc.qam._variables_shim[aref] == np.pi
assert qc.qam._executable == p
assert qc.qam._bitstrings.shape == (1000, 1)
assert all([bit == 1 for bit in qc.qam._bitstrings])
assert qc.qam._memory_results["ro"].shape == (1000, 1)
assert all([bit == 1 for bit in qc.qam._memory_results["ro"]])
assert qc.qam.status == 'done'

qc.reset()

assert qc.qam._variables_shim == {}
assert qc.qam._executable is None
assert qc.qam._bitstrings is None
assert qc.qam._memory_results["ro"] is None
assert qc.qam.status == 'connected'


Expand Down