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

Migrate to pyQuil v3 #107

Merged
merged 62 commits into from
Oct 24, 2022
Merged

Conversation

MarquessV
Copy link
Contributor

@MarquessV MarquessV commented Oct 4, 2022

Here are the changes required to get this plugin on to pyQuil v3! I'm including some of my own targeted questions as comments below.

@MarquessV MarquessV closed this Oct 4, 2022
@MarquessV MarquessV reopened this Oct 12, 2022
@MarquessV MarquessV changed the title Draft: Migrate to pyquil v3 Migrate to pyquil v3 Oct 12, 2022
@MarquessV MarquessV changed the title Migrate to pyquil v3 Draft: Migrate to pyQuil v3 Oct 12, 2022
@josh146 josh146 requested a review from AlbertMitjans October 12, 2022 20:19
@@ -190,7 +163,7 @@ def __init__(
self.calibrate_readout = calibrate_readout
self.wiring = {i: q for i, q in enumerate(self.qc.qubits())}

def expval(self, observable):
def expval(self, observable, shot_range=None, bin_size=None):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When parametric compilation is enabled, the expval for results from all devices (QVM, QPU, WFS) are calculated in the same way. However, when parametric compilation is disabled on the QPU device, we take a different approach to calculating the expval. Why would this differentiation exist, and can we consolidate the implementation across all devices?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly I don't know why are we doing this. It seems like we are creating and executing a new program from scratch, which is not very effective...

@josh146 do you know why we don't use the generated self._samples to compute the expectation value?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the logic inside the measure_observables function:
https://github.com/PennyLaneAI/pennylane-forest/blob/14709333ed6bb4fa134340f524d89aea44f3cb56/pennylane_forest/qpu.py#L255

It seems it uses a different logic to run the quantum program that the one defined in the generate_samples method of the QVMDevice class:
https://github.com/PennyLaneAI/pennylane-forest/blob/14709333ed6bb4fa134340f524d89aea44f3cb56/pennylane_forest/qvm.py#L230

Maybe we need to override this method in the QPUDevice class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a brief look at doing this while refactoring the devices, but quickly ran into a wall when I realized that the logic in expval is dependent on the observable parameter to generate the right PauliTerm for the Experiment passed to measure_observables.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would leave this as it is for now. We can create a follow-up issue saying that this should be optimised.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@antalszava antalszava Oct 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The QPU device allows operator estimation and uses measure_observables from PyQuil under the hood. This feature in the plugin is, however, not compatible with parametric compilation. Therefore, once parametric compilation is turned on, we're falling back to PennyLane's implementation using generate_samples.

A major shortcoming hinted at above too is that when doing operator estimation, we're effectively generating samples using both PennyLane's pipeline and using measure_observables - the first of which should not be done.

See #45 that has just been re-opened.

pennylane_forest/qpu.py Outdated Show resolved Hide resolved
Copy link
Contributor

@AlbertMitjans AlbertMitjans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments on the README.rst file

README.rst Outdated Show resolved Hide resolved
README.rst Outdated Show resolved Hide resolved
README.rst Outdated Show resolved Hide resolved
README.rst Outdated Show resolved Hide resolved
README.rst Outdated Show resolved Hide resolved
Copy link
Contributor

@AlbertMitjans AlbertMitjans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added more comments on the doc files

doc/devices/qpu.rst Show resolved Hide resolved
doc/devices/qpu.rst Outdated Show resolved Hide resolved
doc/devices/qpu.rst Show resolved Hide resolved
doc/devices/qvm.rst Show resolved Hide resolved
doc/devices/qvm.rst Show resolved Hide resolved
doc/devices/wavefunction.rst Show resolved Hide resolved
doc/devices/wavefunction.rst Outdated Show resolved Hide resolved
doc/index.rst Show resolved Hide resolved
Copy link
Contributor

@AlbertMitjans AlbertMitjans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments in the code. Still need to look at the tests.

pennylane_forest/qpu.py Outdated Show resolved Hide resolved
pennylane_forest/qpu.py Outdated Show resolved Hide resolved
@@ -190,7 +163,7 @@ def __init__(
self.calibrate_readout = calibrate_readout
self.wiring = {i: q for i, q in enumerate(self.qc.qubits())}

def expval(self, observable):
def expval(self, observable, shot_range=None, bin_size=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly I don't know why are we doing this. It seems like we are creating and executing a new program from scratch, which is not very effective...

@josh146 do you know why we don't use the generated self._samples to compute the expectation value?

@@ -190,7 +163,7 @@ def __init__(
self.calibrate_readout = calibrate_readout
self.wiring = {i: q for i, q in enumerate(self.qc.qubits())}

def expval(self, observable):
def expval(self, observable, shot_range=None, bin_size=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the logic inside the measure_observables function:
https://github.com/PennyLaneAI/pennylane-forest/blob/14709333ed6bb4fa134340f524d89aea44f3cb56/pennylane_forest/qpu.py#L255

It seems it uses a different logic to run the quantum program that the one defined in the generate_samples method of the QVMDevice class:
https://github.com/PennyLaneAI/pennylane-forest/blob/14709333ed6bb4fa134340f524d89aea44f3cb56/pennylane_forest/qvm.py#L230

Maybe we need to override this method in the QPUDevice class?

pennylane_forest/qpu.py Show resolved Hide resolved
pennylane_forest/qvm.py Outdated Show resolved Hide resolved
pennylane_forest/qvm.py Outdated Show resolved Hide resolved
pennylane_forest/device.py Outdated Show resolved Hide resolved
pennylane_forest/wavefunction.py Outdated Show resolved Hide resolved
@AlbertMitjans
Copy link
Contributor

The pennylane_forest/device.py file needs reformatting.

Please run black -l 100 pennylane_forest/.

MarquessV and others added 3 commits October 13, 2022 09:15
Co-authored-by: Albert Mitjans <a.mitjanscoma@gmail.com>
Co-authored-by: Albert Mitjans <a.mitjanscoma@gmail.com>
Co-authored-by: Albert Mitjans <a.mitjanscoma@gmail.com>
pennylane_forest/qc.py Outdated Show resolved Hide resolved
@@ -190,7 +163,7 @@ def __init__(
self.calibrate_readout = calibrate_readout
self.wiring = {i: q for i, q in enumerate(self.qc.qubits())}

def expval(self, observable):
def expval(self, observable, shot_range=None, bin_size=None):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a brief look at doing this while refactoring the devices, but quickly ran into a wall when I realized that the logic in expval is dependent on the observable parameter to generate the right PauliTerm for the Experiment passed to measure_observables.

@AlbertMitjans
Copy link
Contributor

AlbertMitjans commented Oct 19, 2022

I just realised that the github workflows run the tests using the quilc version 1.22.0.

Probably that is why some of the tests are passing locally but failing here.

I think we should change the following line in .github/workflows/tests.yml from:

      - name: Run Forest Quilc
        run: docker run --rm -d -p 5555:5555 rigetti/quilc:1.22.0 -R

to

      - name: Run Forest Quilc
        run: docker run --rm -d -p 5555:5555 rigetti/quilc -S

This line is duplicated under tests and integration-tests

We should probably change the line in .github/workflows/upload.yml too.

@AlbertMitjans
Copy link
Contributor

AlbertMitjans commented Oct 19, 2022

Regarding the docs, could you try updating the pyquil and pennylane versions in doc/requirements.txt to:

pyquil>=3.0.0,<4.0.0
pennylane>=0.18

Copy link
Contributor

@AlbertMitjans AlbertMitjans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update minimum pennylane version to 0.18 (ISWAP gate was added in the 0.18 release)

setup.py Outdated Show resolved Hide resolved
requirements.txt Outdated Show resolved Hide resolved
Copy link
Contributor

@AlbertMitjans AlbertMitjans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing job with the refactor!

Added some comments.

pennylane_forest/qc.py Outdated Show resolved Hide resolved
pennylane_forest/qc.py Outdated Show resolved Hide resolved
pennylane_forest/qc.py Show resolved Hide resolved
pennylane_forest/device.py Outdated Show resolved Hide resolved
pennylane_forest/qc.py Show resolved Hide resolved
pennylane_forest/qc.py Show resolved Hide resolved
@AlbertMitjans
Copy link
Contributor

There was a timeout error in the test_qvm.py:test_qubit_unitary test. Should we increase the timeout threshold?

@AlbertMitjans AlbertMitjans marked this pull request as ready for review October 21, 2022 07:01
@MarquessV MarquessV changed the title Draft: Migrate to pyQuil v3 Migrate to pyQuil v3 Oct 21, 2022
Copy link
Contributor

@AlbertMitjans AlbertMitjans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants