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

PyQVM #552

Merged
merged 48 commits into from Jan 24, 2019
Merged

PyQVM #552

merged 48 commits into from Jan 24, 2019

Conversation

mpharrigan
Copy link
Contributor

Simulate quantum programs without ever leaving the comfort of your python environment. Note: not as performant for large numbers of qubits as the QVM

Includes:

  • ReferenceWavefunctionSimulator
  • NumpyWavefunctionSimulator
  • ReferenceDensitySimulator

ReferenceXxxSimulators ported and cleaned up from https://github.com/rigetticomputing/reference-qvm

 - ReferenceWavefunctionSimulator
 - NumpyWavefunctionSimulator
 - ReferenceDensitySimulator
@ncrubin
Copy link
Contributor

ncrubin commented Oct 4, 2018

YAY!

Matthew Harrigan added 4 commits October 10, 2018 09:22
 - measure all qubits on a qc (not just the ones used in a program)
 - return as a dict instead of a 2d numpy array because of sparsely
   indexed qubits
 - remove classical addresses. You just get everything now
 - all the shimmy things in QAM are now "private". Don't use these
@willzeng
Copy link
Contributor

Adding a 👍for another use of this merge. Currently to make noise model templates it's very useful to have matrix representations of all the standard gates accessible in the library. Right now I'm using referenceqvm for this, but it would be better to have these are part of the standard library.

import numpy as np
import cmath

I = np.array([[1.0, 0.0], [0.0, 1.0]])
Copy link
Contributor

Choose a reason for hiding this comment

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

Should these be refactored to be attributes on the existing gate.py objects? This would reduce any namespace confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a good suggestion. I think I'm still leaning towards ^^ for the following reasons

  • freer to define matrices that aren't actually Quil instructions. cf P0
  • I personally think this is a good demonstration of how namespaces can be a honking great idea*

* from a python console try import this

pyquil/pyqvm.py Outdated
raise RuntimeError("Improper program - Jump Target not found in the "
"input program!")

def transition(self, run_and_measure=False):
Copy link
Contributor

Choose a reason for hiding this comment

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

This is missing CONVERT, EXCHANGE, LOAD, STORE, EQ, GT, GE, LT, LE.

self.wf_simulator.reset()
self.program_counter += 1

elif isinstance(instruction, Declare):
Copy link
Contributor

Choose a reason for hiding this comment

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

How does the offset get stored? Should we add a disclaimer that SHARING is not supported?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added

# Label; pass straight over
self.program_counter += 1

elif isinstance(instruction, JumpConditional):
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this work fine with the deferred measurement?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

what do you mean? what's being deferred?

else:
right_val = instruction.right

if isinstance(instruction, ClassicalAnd):
Copy link
Contributor

Choose a reason for hiding this comment

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

This is an approximation of the behavior that should happen. (e.g., it should not be possible to add two bits) Each instruction has roughly an "addressing mode" of supported data types.

@karalekas karalekas self-requested a review October 19, 2018 18:04
@karalekas
Copy link
Contributor

karalekas commented Oct 19, 2018

just jumping in here to say that we should think hard on what sort of API we want to expose as part of the pyQVM. merging this as is I think would cause confusion and add noise to the overall API exposed by pyquil.

if not isinstance(operator, PauliSum):
operator = PauliSum([operator])

sum = 0
Copy link
Contributor

Choose a reason for hiding this comment

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

return sum([_term_expectation(self.wf, term, n_qubits=self.n_qubits) for termin operator])

Copy link
Contributor

Choose a reason for hiding this comment

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

no list

@stevenheidel
Copy link
Contributor

This has an incredible test suite 🎉

@mpharrigan
Copy link
Contributor Author

@ncrubin gets all (most) of the credit for the test suite

@kmckiern
Copy link
Contributor

Have been using this a bit recently.

I would like to suggest that the API for using the pyQVM and the lisp QVM should be more similar. For example, if I want the wavefunction amplitudes from lisp QVM, I do this:

wf_sim = WavefunctionSimulator()
amplitudes = wf_sim.wavefunction(program).amplitudes

but on pyQVM, I do this:

wf_sim = PyQVM(n_qubits=n_qubits, quantum_simulator_type=NumpyWavefunctionSimulator)
amplitudes = wf_sim.execute(program).wf_simulator.wf

If someone wanted to write an app where the backend were interchangeable, this would cause difficulty.

@mpharrigan
Copy link
Contributor Author

WavefunctionSimulator should be analogous to NumpyWavefunctionSimulator and QVM should be analogous to PyQVM, so probably

wf_sim = NumpyWavefunctionSimulator(n_qubits)
amplitudes = wf_sim.do_program(program).wf

but we can also add a method wavefunction that returns a Wavefunction object.

Note that each simulator (NumpyWavefunctionSimulator, ReferenceWavefunctionSimulator, ReferenceDensitySimulator) support a common set of methods (ie do_program) but I currently didn't put any code to paper over the different "under the hood" representations (nd tensor, 1d array, 2d matrix resp). sim.wavefunction could help there

@stevenheidel
Copy link
Contributor

I'd like to echo Keri's comment - can we get to a point where simulators/QVMs have a smaller and more uniform interface?

@stylewarning
Copy link
Contributor

@mpharrigan (CC @karalekas) To what extent have Keri/Steven's comments been addressed? The PR is 4k lines now, and it doesn't show any new updates on that front. FWIW, "API confusion"/impedance mismatch between interfaces is my primary concern.

@mpharrigan
Copy link
Contributor Author

I'll open a follow-on ticket for implementing wavefunction() that returns a Wavefunction. It will sit atop the existing functionality

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.

None yet

7 participants