Skip to content

Commit

Permalink
Merge branch 'master' into 1691-libquil
Browse files Browse the repository at this point in the history
  • Loading branch information
notmgsk authored Nov 22, 2023
2 parents be8e936 + 35acdcd commit dc36af6
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 20 deletions.
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,45 @@
# Changelog

## 4.1.1 (2023-11-15)

### Fixes

#### The ``execution_options`` property is now used for retrieving results if no overriding options were provided to the ``execute`` method. (#1694)

## 4.1.1-rc.0 (2023-11-15)

### Fixes

#### The ``execution_options`` property is now used for retrieving results if no overriding options were provided to the ``execute`` method. (#1694)

## 4.1.0 (2023-11-13)

### Features

#### update qcs-sdk-rust (#1683)

### Fixes

#### The `DefGate.matrix` property will no longer raise an exception when the matrix contains a mix of atomic and object types. (#1685)

#### Instruction types no longer return a superclass instance when using `copy.deepcopy` (#1689)

#### DefGate's no longer appear in the instructions list (#1688)

## 4.1.0-rc.5 (2023-11-13)

### Features

#### update qcs-sdk-rust (#1683)

### Fixes

#### The `DefGate.matrix` property will no longer raise an exception when the matrix contains a mix of atomic and object types. (#1685)

#### Instruction types no longer return a superclass instance when using `copy.deepcopy` (#1689)

#### DefGate's no longer appear in the instructions list (#1688)

## 4.1.0-rc.4 (2023-11-09)

### Features
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ p += MEASURE(0, ro[0])
p += MEASURE(1, ro[1])
p.wrap_in_numshots_loop(10)

qvm.run(p).readout_data['ro'].tolist()
qvm.run(p).get_register_map()['ro'].tolist()
```

The output of the above program should look something like the following,
Expand Down
4 changes: 2 additions & 2 deletions docs/source/advanced_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Below is an example that demonstrates how to use pyQuil in a multithreading scen
def run(program: Program):
return qc.run(qc.compile(program)).readout_data.get("ro")
return qc.run(qc.compile(program)).get_register_map().get("ro")
programs = [
Expand Down Expand Up @@ -445,7 +445,7 @@ We can run this program a few times to see what we get in the readout register `
qc = get_qc("2q-qvm")
branching_prog.wrap_in_numshots_loop(10)
result = qc.run(branching_prog)
print(result.readout_data['test_register'])
print(result.get_register_map()['test_register'])

.. testoutput:: control-flow
:hide:
Expand Down
4 changes: 2 additions & 2 deletions docs/source/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ an entangled state between qubits 0 and 1 (that's what the "CNOT" gate does). Fi

# run the program on a QVM
qc = get_qc('9q-square-qvm')
result = qc.run(qc.compile(p)).readout_data.get("ro")
result = qc.run(qc.compile(p)).get_register_map().get("ro")
print(result[0])
print(result[1])

Expand Down Expand Up @@ -182,7 +182,7 @@ the terminal windows where your servers are running, you should see output print

with local_forest_runtime():
qvm = get_qc('9q-square-qvm')
bitstrings = qvm.run(qvm.compile(prog)).readout_data.get("ro")
bitstrings = qvm.run(qvm.compile(prog)).get_register_map().get("ro")

In the following sections, we'll cover gates, program construction & execution, and go into detail about our Quantum
Virtual Machine, our QPUs, noise models and more. Let's start with the :ref:`basics`.
2 changes: 1 addition & 1 deletion docs/source/introducing_v4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ you should use the ``get_raw_readout_data`` method to access the raw data and bu
result = qc.run(exe)
try:
matrix = result.readout_data
matrix = result.get_register_map()
except RegisterMatrixConversionError:
matrix = process_raw_data(result.get_raw_readout_data())
Expand Down
16 changes: 8 additions & 8 deletions docs/source/noise.rst
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ state decays to the :math:`\ket{0}` state.
p.define_noisy_gate("I", [0], append_damping_to_gate(np.eye(2), damping_per_I))
p.wrap_in_numshots_loop(trials)
qc.qam.random_seed = int(num_I)
res = qc.run(p).readout_data.get("ro")
res = qc.run(p).get_register_map().get("ro")
results_damping.append([np.mean(res), np.std(res) / np.sqrt(trials)])

results_damping = np.array(results_damping)
Expand Down Expand Up @@ -537,7 +537,7 @@ good starting point.**
p.define_noisy_gate("CZ", [0, 1], corrupted_CZ)
p.wrap_in_numshots_loop(trials)
qc.qam.random_seed = jj
res = qc.run(p).readout_data.get("ro")
res = qc.run(p).get_register_map().get("ro")
results.append(res)

results = np.array(results)
Expand Down Expand Up @@ -706,7 +706,7 @@ gate noise, respectively.
MEASURE(0, ("ro", 0)),
MEASURE(1, ("ro", 1)),
])
bitstrings = qc.run(noisy).readout_data.get("ro")
bitstrings = qc.run(noisy).get_register_map().get("ro")

# Expectation of Z0 and Z1
z0, z1 = 1 - 2*np.mean(bitstrings, axis=0)
Expand Down Expand Up @@ -1002,7 +1002,7 @@ Example 1: Rabi sequence with noisy readout
p.define_noisy_readout(0, p00=p00, p11=p00)
ro = p.declare("ro", "BIT", 1)
p.measure(0, ro[0])
res = qc.run(p).readout_data.get("ro")
res = qc.run(p).get_register_map().get("ro")
results_rabi[jj, kk] = np.sum(res)

.. parsed-literal::
Expand Down Expand Up @@ -1149,7 +1149,7 @@ Pauli-Z moments that indicate the qubit correlations are corrupted (and correcte
)
ghz_prog.wrap_in_numshots_loop(10000)
print(ghz_prog)
results = qc.run(ghz_prog).readout_data.get("ro")
results = qc.run(ghz_prog).get_register_map().get("ro")

.. testoutput:: readout-noise

Expand All @@ -1167,7 +1167,7 @@ Pauli-Z moments that indicate the qubit correlations are corrupted (and correcte
noisy_ghz = header + ghz_prog
noisy_ghz.wrap_in_numshots_loop(10000)
print(noisy_ghz)
noisy_results = qc.run(noisy_ghz).readout_data.get("ro")
noisy_results = qc.run(noisy_ghz).get_register_map().get("ro")

.. testoutput:: readout-noise

Expand Down Expand Up @@ -1374,9 +1374,9 @@ we should always measure ``1``.

qc = get_qc("1q-qvm")
print("Without Noise:")
print(qc.run(p).readout_data.get("ro"))
print(qc.run(p).get_register_map().get("ro"))
print("With Noise:")
print(noisy_qc.run(p).readout_data.get("ro"))
print(noisy_qc.run(p).get_register_map().get("ro"))

.. testoutput:: global-error
:hide:
Expand Down
4 changes: 2 additions & 2 deletions docs/source/programs_and_gates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ program on the Quantum Virtual Machine (QVM). We just have to add a few lines to
qc = get_qc('1q-qvm') # You can make any 'nq-qvm' this way for any reasonable 'n'
executable = qc.compile(p)
result = qc.run(executable)
bitstrings = result.readout_data.get('ro')
bitstrings = result.get_register_map().get('ro')
print(bitstrings)

Congratulations! You just ran your program on the QVM. The returned value should be:
Expand Down Expand Up @@ -310,7 +310,7 @@ filled in for, say, 200 values between :math:`0` and :math:`2\pi`. We demonstrat
memory_map = {"theta": [theta]}

# Get the results of the run with the value we want to execute with
bitstrings = qc.run(executable, memory_map=memory_map).readout_data.get("ro")
bitstrings = qc.run(executable, memory_map=memory_map).get_register_map().get("ro")

# Store our results
parametric_measurements.append(bitstrings)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pyquil"
version = "4.1.0-rc.4"
version = "4.1.1"
description = "A Python library for creating Quantum Instruction Language (Quil) programs."
authors = ["Rigetti Computing <[email protected]>"]
readme = "README.md"
Expand Down
5 changes: 3 additions & 2 deletions pyquil/api/_qpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,17 @@ def execute(

memory_map = memory_map or {}
patch_values = build_patch_values(executable.recalculation_table, memory_map)
effective_execution_options = execution_options or self.execution_options

job_id = submit(
program=executable.program,
patch_values=patch_values,
quantum_processor_id=self.quantum_processor_id,
client=self._client_configuration,
execution_options=execution_options or self.execution_options,
execution_options=effective_execution_options,
)

return QPUExecuteResponse(_executable=executable, job_id=job_id, execution_options=execution_options)
return QPUExecuteResponse(_executable=executable, job_id=job_id, execution_options=effective_execution_options)

def get_result(self, execute_response: QPUExecuteResponse) -> QAMExecutionResult:
"""
Expand Down
76 changes: 75 additions & 1 deletion test/unit/test_qpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import numpy as np

from pyquil.api import ConnectionStrategy, ExecutionOptions, RegisterMatrixConversionError
from pyquil.api import ConnectionStrategy, ExecutionOptions, RegisterMatrixConversionError, ExecutionOptionsBuilder
from pyquil.api._qpu import QPU
from pyquil.api._abstract_compiler import EncryptedProgram
from pyquil.quil import Program
Expand Down Expand Up @@ -105,3 +105,77 @@ def test_qpu_execute_jagged_results(

assert raw_readout_data.mappings == {"ro[0]": "q0", "ro[1]": "q1"}
assert raw_readout_data.readout_values == {"q0": [1, 1], "q1": [1, 1, 1, 1]}


class TestQPUExecutionOptions:
@patch("pyquil.api._qpu.retrieve_results")
@patch("pyquil.api._qpu.submit")
def test_submit_with_class_options(
self, mock_submit: MagicMock, mock_retrieve_results: MagicMock, mock_encrypted_program: EncryptedProgram
):
"""
Asserts that a ``QPU``'s execution_options property is used for submission, appears in the returned
``QPUExecuteResponse``, and is used for retrieval of results when execution options are not provided to
``QPU.execute``.
"""
qpu = QPU(quantum_processor_id="test")
execution_options_builder = ExecutionOptionsBuilder()
execution_options_builder.timeout_seconds = 10.0
execution_options_builder.connection_strategy = ConnectionStrategy.endpoint_id("some-endpoint-id")
execution_options = execution_options_builder.build()
qpu.execution_options = execution_options

mock_submit.return_value = "some-job-id"
execute_response = qpu.execute(mock_encrypted_program)
assert execute_response.execution_options == qpu.execution_options

mock_retrieve_results.return_value = ExecutionResults(
{
"q0": ExecutionResult.from_register(Register.from_i32([1, 1])),
"q1": ExecutionResult.from_register(Register.from_i32([1, 1, 1, 1])),
}
)

qpu.get_result(execute_response)

mock_retrieve_results.assert_called_once_with(
job_id="some-job-id",
quantum_processor_id="test",
client=qpu._client_configuration,
execution_options=qpu.execution_options,
)

@patch("pyquil.api._qpu.retrieve_results")
@patch("pyquil.api._qpu.submit")
def test_submit_with_options(
self, mock_submit: MagicMock, mock_retrieve_results: MagicMock, mock_encrypted_program: EncryptedProgram
):
"""
Asserts that execution_options provided to ``QPU.execute`` are used for submission, appear in the returned
``QPUExecuteResponse``, and are used for retrieval of results.
"""
qpu = QPU(quantum_processor_id="test")

mock_submit.return_value = "some-job-id"
execution_options_builder = ExecutionOptionsBuilder()
execution_options_builder.timeout_seconds = 10.0
execution_options_builder.connection_strategy = ConnectionStrategy.endpoint_id("some-endpoint-id")
execution_options = execution_options_builder.build()
execute_response = qpu.execute(mock_encrypted_program, execution_options=execution_options)
assert execute_response.execution_options == execution_options

mock_retrieve_results.return_value = ExecutionResults(
{
"q0": ExecutionResult.from_register(Register.from_i32([1, 1])),
"q1": ExecutionResult.from_register(Register.from_i32([1, 1, 1, 1])),
}
)

qpu.get_result(execute_response)

mock_retrieve_results.assert_called_once_with(
job_id="some-job-id",
quantum_processor_id="test",
client=qpu._client_configuration,
execution_options=execution_options,
)

0 comments on commit dc36af6

Please sign in to comment.