Skip to content

Commit

Permalink
Enable more memory regions on the QVM (#873)
Browse files Browse the repository at this point in the history
  • Loading branch information
ecpeterson authored and karalekas committed Aug 23, 2019
1 parent e424d86 commit dc2b4ac
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 27 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ Changelog
readout symmetrization (@joshcombes, gh-919).
- The ProtoQuil restrictions built in to PyQVM have been removed
(@ecpeterson, gh-874).
- Add the ability to query for other memory regions after both QPU and QVM
runs. This removes a previously unnecessary restriction on the QVM, although
`ro` remains the only QPU-writeable memory region during Quil execution
(@ecpeterson, gh-873).

### Bugfixes

Expand Down
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
return self.read_memory(region_name=region_name)

@_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'
7 changes: 6 additions & 1 deletion pyquil/api/_qpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##############################################################################
from collections import defaultdict
import uuid
import warnings
from typing import Dict, List, Optional, Tuple, Union
Expand Down Expand Up @@ -168,8 +169,12 @@ def run(self, run_priority: Optional[int] = None):
else:
bitstrings = None

self._bitstrings = bitstrings
self._memory_results = defaultdict(lambda: None)
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 _get_buffers(self, job_id: str) -> Dict[str, np.ndarray]:
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), dtype=np.int64)

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 @@ -186,7 +186,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: Dict[str, np.ndarray]

self.rs = np.random.RandomState(seed=seed)
self.wf_simulator = quantum_simulator_type(n_qubits=n_qubits, rs=self.rs)
Expand All @@ -201,7 +201,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 @@ -536,15 +536,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

0 comments on commit dc2b4ac

Please sign in to comment.