Getting started

Pre-requisites

To make full use of pyQuil, you’ll want to have both the Quantum Virtual Machine (QVM) and the Quil Compiler (quilc) installed. If you don’t have those installed yet, refer to Rigetti’s guide on installing the Quil SDK locally.

Note

If you’re running from a Rigetti-provisioned JupyterLab IDE, the Quil SDK is already installed. Continue to Run your first program.

Upgrading or installing pyQuil

Before you install, it’s recommended to activate a Python virtual environment. Then, install pyQuil using pip:

pip install pyquil

For those of you that already have pyQuil, you can upgrade with:

pip install --upgrade pyquil

If you would like to stay up to date with the latest changes and bug fixes, you can also opt to install a pre-release version of pyQuil with:

pip install --pre pyquil

Note

pyQuil requires Python 3.9 or later.

Note

Some of pyQuil’s core dependencies are powered by Rust. These dependencies have been pre-built for the most common platforms so that building from source isn’t required. However, if you are on a less common platform, or choose to build pyQuil from source, you will need to install Rust.

Setting up requisite servers for pyQuil

To get started with pyQuil, quilc and qvm should both be running in server mode. If you have them installed locally you can run them in their own terminal windows. First launch quilc:

quilc -S

Then, in another terminal window, launch the QVM:

qvm -S

Note

For more information about the QVM and the compiler, refer to their respective manual pages by using man quilc and man qvm.

That’s it! You’re all set up to run pyQuil locally. Your programs will make requests to these server endpoints to compile your Quil programs to native Quil, and to simulate those programs on the QVM.

Run your first program

Now that the QVM and the Quil compiler are running, you can start running pyQuil programs!

The program we will create prepares a fully entangled state between two qubits, called a Bell State. This state is in an equal superposition between \(\ket{00}\) and \(\ket{11}\), meaning that it’s equally likely that a measurement will result in measuring both qubits in the ground state or both qubits in the excited state.

First, import the essentials:

from pyquil import Program, get_qc
from pyquil.gates import *
from pyquil.quilbase import Declare

The Program class allows us to build a Quil program. get_qc() connects us to a QuantumComputer, which specifies what our program should run on (see: The quantum computer). We’ve also imported all (*) gates from the pyquil.gates module, which allows us to add operations to our program (Programs and gates). Declare allows us to declare classical memory regions so that we can receive data from the QuantumComputer.

Next, let’s construct the Bell State program.

p = Program(
    Declare("ro", "BIT", 2),
    H(0),
    CNOT(0, 1),
    MEASURE(0, ("ro", 0)),
    MEASURE(1, ("ro", 1)),
).wrap_in_numshots_loop(10)

We’ve accomplished this by driving qubit 0 into a superposition state (that’s what the “H” gate does), and then creating an entangled state between qubits 0 and 1 (that’s what the “CNOT” gate does). Finally, we’ll want to run our program:

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

Warning

If you run into an error running your program, or it hangs indefinitely when compiling, make sure that the quilc and QVM servers are running and reachable. First, review the pre-requisites section and if that fails, see the troubleshooting steps.

Compare the two arrays of measurement results. The results will be consistent between the qubits and random from shot to shot.

qc is a simulated quantum computer. We’ve told our QVM to run the program specified above ten times and return the results to us.

The calls to compile and run will make a request to the two servers we started up in the previous section: first, to the quilc server instance to compile the Quil program into native Quil optimized for the target device, and then to the qvm server instance to simulate and return measurement results of the program 10 times. If you open up the terminal windows where your servers are running, you should see output printed to the console regarding the requests you just made.

Note

pyQuil also provides the local_forest_runtime() context manager to ensure both quilc and qvm servers are running by starting them as subprocesses if they aren’t already.

from pyquil import get_qc, Program
from pyquil.gates import CNOT, Z, MEASURE
from pyquil.api import local_forest_runtime
from pyquil.quilbase import Declare

prog = Program(
    Declare("ro", "BIT", 2),
    Z(0),
    CNOT(0, 1),
    MEASURE(0, ("ro", 0)),
    MEASURE(1, ("ro", 1)),
).wrap_in_numshots_loop(10)

with local_forest_runtime():
    qvm = get_qc('9q-square-qvm')
    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 Programs and gates.