pyquil.quil module

Module for creating and defining Quil programs.

class pyquil.quil.Program(*instructions: Union[pyquil.quilbase.AbstractInstruction, pyquil.quilbase.DefGate, pyquil.quil.Program, List[Any], Tuple[Any, ...], str, Generator[Any, Any, Any]])[source]

Bases: object

A list of pyQuil instructions that comprise a quantum program.

>>> from pyquil import Program
>>> from pyquil.gates import H, CNOT
>>> p = Program()
>>> p += H(0)
>>> p += CNOT(0, 1)
calibrate(instruction: pyquil.quilbase.AbstractInstruction, previously_calibrated_instructions: Optional[Set[pyquil.quilbase.AbstractInstruction]] = None) List[pyquil.quilbase.AbstractInstruction][source]

Expand an instruction into its calibrated definition.

If a calibration definition matches the provided instruction, then the definition body is returned with appropriate substitutions made for parameters and qubit arguments. If no calibration definition matches, then the original instruction is returned. Calibrations are performed recursively, so that if a calibrated instruction produces an instruction that has a corresponding calibration, it will be expanded, and so on. If a cycle is encountered, a CalibrationError is raised.

Parameters
  • instruction – An instruction.

  • previously_calibrated_instructions – A set of instructions that are the results of calibration expansions in the direct ancestry of instruction. Used to catch cyclic calibration expansions.

Returns

A list of instructions, with the active calibrations expanded.

property calibrations: List[Union[pyquil.quilbase.DefCalibration, pyquil.quilbase.DefMeasureCalibration]]

A list of Quil-T calibration definitions.

copy() pyquil.quil.Program[source]

Perform a shallow copy of this program.

QuilAtom and AbstractInstruction objects should be treated as immutable to avoid strange behavior when performing a copy.

Returns

a new Program

copy_everything_except_instructions() pyquil.quil.Program[source]

Copy all the members that live on a Program object.

Returns

a new Program

dagger(inv_dict: Optional[Any] = None, suffix: str = '-INV') pyquil.quil.Program[source]

Creates the conjugate transpose of the Quil program. The program must contain only gate applications.

Note: the keyword arguments inv_dict and suffix are kept only for backwards compatibility and have no effect.

Returns

The Quil program’s inverse

property declarations: Dict[str, pyquil.quilbase.Declare]

A mapping from declared region names to their declarations.

declare(name: str, memory_type: str = 'BIT', memory_size: int = 1, shared_region: Optional[str] = None, offsets: Optional[Iterable[Tuple[int, str]]] = None) pyquil.quilatom.MemoryReference[source]

DECLARE a quil variable

This adds the declaration to the current program and returns a MemoryReference to the base (offset = 0) of the declared memory.

Note

This function returns a MemoryReference and cannot be chained like some of the other Program methods. Consider using inst(DECLARE(...)) if you would like to chain methods, but please be aware that you must create your own MemoryReferences later on.

Parameters
  • name – Name of the declared variable

  • memory_type – Type of the declared memory: ‘BIT’, ‘REAL’, ‘OCTET’ or ‘INTEGER’

  • memory_size – Number of array elements in the declared memory.

  • shared_region – You can declare a variable that shares its underlying memory with another region. This allows aliasing. For example, you can interpret an array of measured bits as an integer.

  • offsets – If you are using shared_region, this allows you to share only a part of the parent region. The offset is given by an array type and the number of elements of that type. For example, DECLARE target-bit BIT SHARING real-region OFFSET 1 REAL 4 BIT will let you use target-bit to poke into the fourth bit of the second real from the leading edge of real-region.

Returns

a MemoryReference to the start of the declared memory region, ie a memory reference to name[0].

defgate(name: str, matrix: Union[List[List[Any]], numpy.ndarray, numpy.matrix], parameters: Optional[List[pyquil.quilatom.Parameter]] = None) pyquil.quil.Program[source]

Define a new static gate.

Note

The matrix elements along each axis are ordered by bitstring. For two qubits the order is 00, 01, 10, 11, where the the bits are ordered in reverse by the qubit index, i.e., for qubits 0 and 1 the bitstring 01 indicates that qubit 0 is in the state 1. See also the related docs in the WavefunctionSimulator Overview.

Parameters
  • name – The name of the gate.

  • matrix – List of lists or Numpy 2d array.

  • parameters – list of parameters that are used in this gate

Returns

The Program instance.

define_noisy_gate(name: str, qubit_indices: Sequence[int], kraus_ops: Sequence[Any]) pyquil.quil.Program[source]

Overload a static ideal gate with a noisy one defined in terms of a Kraus map.

Note

The matrix elements along each axis are ordered by bitstring. For two qubits the order is 00, 01, 10, 11, where the the bits are ordered in reverse by the qubit index, i.e., for qubits 0 and 1 the bitstring 01 indicates that qubit 0 is in the state 1. See also the related docs in the WavefunctionSimulator Overview.

Parameters
  • name – The name of the gate.

  • qubit_indices – The qubits it acts on.

  • kraus_ops – The Kraus operators.

Returns

The Program instance

define_noisy_readout(qubit: Union[int, pyquil.quilatom.QubitPlaceholder], p00: float, p11: float) pyquil.quil.Program[source]

For this program define a classical bit flip readout error channel parametrized by p00 and p11. This models the effect of thermal noise that corrupts the readout signal after it has interrogated the qubit.

Parameters
  • qubit – The qubit with noisy readout.

  • p00 – The probability of obtaining the measurement result 0 given that the qubit is in state 0.

  • p11 – The probability of obtaining the measurement result 1 given that the qubit is in state 1.

Returns

The Program with an appended READOUT-POVM Pragma.

property defined_gates: List[pyquil.quilbase.DefGate]

A list of defined gates on the program.

property frames: Dict[pyquil.quilatom.Frame, pyquil.quilbase.DefFrame]

A mapping from Quil-T frames to their definitions.

gate(name: str, params: Iterable[Union[Expression, MemoryReference, numpy.int64, int, float, complex]], qubits: Iterable[Union[pyquil.quilatom.Qubit, pyquil.quilatom.QubitPlaceholder]]) Program[source]

Add a gate to the program.

Note

The matrix elements along each axis are ordered by bitstring. For two qubits the order is 00, 01, 10, 11, where the the bits are ordered in reverse by the qubit index, i.e., for qubits 0 and 1 the bitstring 01 indicates that qubit 0 is in the state 1. See also the related docs in the WavefunctionSimulator Overview.

Parameters
  • name – The name of the gate.

  • params – Parameters to send to the gate.

  • qubits – Qubits that the gate operates on.

Returns

The Program instance

get_calibration(instr: pyquil.quilbase.AbstractInstruction) Optional[Union[pyquil.quilbase.DefCalibration, pyquil.quilbase.DefMeasureCalibration]][source]

Get the calibration corresponding to the provided instruction.

Parameters

instr – An instruction.

Returns

A matching Quil-T calibration definition, if one exists.

get_qubits(indices: bool = True) Set[Union[pyquil.quilatom.Qubit, pyquil.quilatom.QubitPlaceholder, pyquil.quilatom.FormalArgument, int]][source]

Returns all of the qubit indices used in this program, including gate applications and allocated qubits. e.g.

>>> p = Program()
>>> p.inst(("H", 1))
>>> p.get_qubits()
{1}
>>> q = QubitPlaceholder()
>>> p.inst(H(q))
>>> len(p.get_qubits())
2
Parameters

indices – Return qubit indices as integers intead of the wrapping Qubit object

Returns

A set of all the qubit indices used in this program

if_then(classical_reg: Union[pyquil.quilatom.MemoryReference, Tuple[str, int], List[Any], str], if_program: pyquil.quil.Program, else_program: Optional[pyquil.quil.Program] = None) pyquil.quil.Program[source]

If the classical register at index classical reg is 1, run if_program, else run else_program.

Equivalent to the following construction:

IF [c]:
   instrA...
ELSE:
   instrB...
=>
  JUMP-WHEN @THEN [c]
  instrB...
  JUMP @END
  LABEL @THEN
  instrA...
  LABEL @END
Parameters
  • classical_reg – The classical register to check as the condition

  • if_program – A Quil program to execute if classical_reg is 1

  • else_program – A Quil program to execute if classical_reg is 0. This argument is optional and defaults to an empty Program.

Returns

The Quil Program with the branching instructions added.

inst(*instructions: Union[pyquil.quilbase.AbstractInstruction, pyquil.quilbase.DefGate, pyquil.quil.Program, List[Any], Tuple[Any, ...], str, Generator[Any, Any, Any]]) pyquil.quil.Program[source]

Mutates the Program object by appending new instructions.

This function accepts a number of different valid forms, e.g.

>>> p = Program()
>>> p.inst(H(0)) # A single instruction
>>> p.inst(H(0), H(1)) # Multiple instructions
>>> p.inst([H(0), H(1)]) # A list of instructions
>>> p.inst(H(i) for i in range(4)) # A generator of instructions
>>> p.inst(("H", 1)) # A tuple representing an instruction
>>> p.inst("H 0") # A string representing an instruction
>>> q = Program()
>>> p.inst(q) # Another program
It can also be chained:
>>> p = Program()
>>> p.inst(H(0)).inst(H(1))
Parameters

instructions – A list of Instruction objects, e.g. Gates

Returns

self for method chaining

property instructions: List[pyquil.quilbase.AbstractInstruction]

Fill in any placeholders and return a list of quil AbstractInstructions.

is_protoquil(quilt: bool = False) bool[source]

Protoquil programs may only contain gates, Pragmas, and RESET. It may not contain classical instructions or jumps.

Returns

True if the Program is Protoquil, False otherwise

is_supported_on_qpu() bool[source]

Whether the program can be compiled to the hardware to execute on a QPU. These Quil programs are more restricted than Protoquil: for instance, RESET must be before any gates or MEASUREs, and MEASURE on a qubit must be after any gates on that qubit.

Returns

True if the Program is supported Quil, False otherwise

match_calibrations(instr: pyquil.quilbase.AbstractInstruction) Optional[pyquil.quiltcalibrations.CalibrationMatch][source]

Attempt to match a calibration to the provided instruction.

Note: preference is given to later calibrations, i.e. in a program with

DEFCAL X 0:

<a>

DEFCAL X 0:

<b>

the second calibration, with body <b>, would be the calibration matching X 0.

Parameters

instr – An instruction.

Returns

a CalibrationMatch object, if one can be found.

measure(qubit: Union[pyquil.quilatom.Qubit, pyquil.quilatom.QubitPlaceholder, pyquil.quilatom.FormalArgument, int], classical_reg: Optional[Union[pyquil.quilatom.MemoryReference, Tuple[str, int], List[Any], str]]) pyquil.quil.Program[source]

Measures a qubit at qubit_index and puts the result in classical_reg

Parameters
  • qubit – The qubit to measure.

  • classical_reg – The classical register to measure into, or None.

Returns

The Quil Program with the appropriate measure instruction appended, e.g. MEASURE 0 [1]

measure_all(*qubit_reg_pairs: Tuple[Union[pyquil.quilatom.Qubit, pyquil.quilatom.QubitPlaceholder, pyquil.quilatom.FormalArgument, int], Optional[Union[pyquil.quilatom.MemoryReference, Tuple[str, int], List[Any], str]]]) pyquil.quil.Program[source]

Measures many qubits into their specified classical bits, in the order they were entered. If no qubit/register pairs are provided, measure all qubits present in the program into classical addresses of the same index.

Parameters

qubit_reg_pairs – Tuples of qubit indices paired with classical bits.

Returns

The Quil Program with the appropriate measure instructions appended, e.g.

MEASURE 0 [1]
MEASURE 1 [2]
MEASURE 2 [3]
no_noise() pyquil.quil.Program[source]

Prevent a noisy gate definition from being applied to the immediately following Gate instruction.

Returns

Program

out(*, calibrations: Optional[bool] = True) str[source]

Serializes the Quil program to a string suitable for submitting to the QVM or QPU.

pop() pyquil.quilbase.AbstractInstruction[source]

Pops off the last instruction.

Returns

The instruction that was popped.

prepend_instructions(instructions: Iterable[pyquil.quilbase.AbstractInstruction]) pyquil.quil.Program[source]

Prepend instructions to the beginning of the program.

reset(qubit_index: Optional[int] = None) pyquil.quil.Program[source]

Reset all qubits or just a specific qubit at qubit_index.

Parameters

qubit_index – The address of the qubit to reset. If None, reset all qubits.

Returns

The Quil Program with the appropriate reset instruction appended, e.g. RESET 0

property waveforms: Dict[str, pyquil.quilbase.DefWaveform]

A mapping from waveform names to their corresponding definitions.

while_do(classical_reg: Union[pyquil.quilatom.MemoryReference, Tuple[str, int], List[Any], str], q_program: pyquil.quil.Program) pyquil.quil.Program[source]

While a classical register at index classical_reg is 1, loop q_program

Equivalent to the following construction:

WHILE [c]:
   instr...
=>
  LABEL @START
  JUMP-UNLESS @END [c]
  instr...
  JUMP @START
  LABEL @END
Parameters
  • classical_reg (MemoryReferenceDesignator) – The classical register to check

  • q_program (Program) – The Quil program to loop.

Returns

The Quil Program with the loop instructions added.

wrap_in_numshots_loop(shots: int) pyquil.quil.Program[source]

Wraps a Quil program in a loop that re-runs the same program many times.

Note: this function is a prototype of what will exist in the future when users will be responsible for writing this loop instead of having it happen automatically.

Parameters

shots – Number of iterations to loop through.

write_memory(*, region_name: str, value: Union[int, float, Sequence[int], Sequence[float]], offset: Optional[int] = None) pyquil.quil.Program[source]
pyquil.quil.address_qubits(program: pyquil.quil.Program, qubit_mapping: Optional[Dict[pyquil.quilatom.QubitPlaceholder, Union[pyquil.quilatom.Qubit, int]]] = None) pyquil.quil.Program[source]

Takes a program which contains placeholders and assigns them all defined values.

Either all qubits must be defined or all undefined. If qubits are undefined, you may provide a qubit mapping to specify how placeholders get mapped to actual qubits. If a mapping is not provided, integers 0 through N are used.

This function will also instantiate any label placeholders.

Parameters
  • program – The program.

  • qubit_mapping – A dictionary-like object that maps from QubitPlaceholder to Qubit or int (but not both).

Returns

A new Program with all qubit and label placeholders assigned to real qubits and labels.

pyquil.quil.get_classical_addresses_from_program(program: pyquil.quil.Program) Dict[str, List[int]][source]

Returns a sorted list of classical addresses found in the MEASURE instructions in the program.

Parameters

program – The program from which to get the classical addresses.

Returns

A mapping from memory region names to lists of offsets appearing in the program.

pyquil.quil.get_default_qubit_mapping(program: pyquil.quil.Program) Dict[Union[pyquil.quilatom.Qubit, pyquil.quilatom.QubitPlaceholder], pyquil.quilatom.Qubit][source]

Takes a program which contains qubit placeholders and provides a mapping to the integers 0 through N-1.

The output of this function is suitable for input to address_qubits().

Parameters

program – A program containing qubit placeholders

Returns

A dictionary mapping qubit placeholder to an addressed qubit from 0 through N-1.

pyquil.quil.instantiate_labels(instructions: Iterable[pyquil.quilbase.AbstractInstruction]) List[pyquil.quilbase.AbstractInstruction][source]

Takes an iterable of instructions which may contain label placeholders and assigns them all defined values.

Returns

list of instructions with all label placeholders assigned to real labels.

pyquil.quil.merge_programs(prog_list: Sequence[pyquil.quil.Program]) pyquil.quil.Program[source]

Merges a list of pyQuil programs into a single one by appending them in sequence. If multiple programs in the list contain the same gate and/or noisy gate definition with identical name, this definition will only be applied once. If different definitions with the same name appear multiple times in the program list, each will be applied once in the order of last occurrence.

Parameters

prog_list – A list of pyquil programs

Returns

a single pyQuil program

pyquil.quil.merge_with_pauli_noise(prog_list: Iterable[pyquil.quil.Program], probabilities: Sequence[float], qubits: Sequence[int]) pyquil.quil.Program[source]

Insert pauli noise channels between each item in the list of programs. This noise channel is implemented as a single noisy identity gate acting on the provided qubits. This method does not rely on merge_programs and so avoids the inclusion of redundant Kraus Pragmas that would occur if merge_programs was called directly on programs with distinct noisy gate definitions.

Parameters
  • prog_list – an iterable such as a program or a list of programs. If a program is provided, a single noise gate will be applied after each gate in the program. If a list of programs is provided, the noise gate will be applied after each program.

  • probabilities – The 4^num_qubits list of probabilities specifying the desired pauli channel. There should be either 4 or 16 probabilities specified in the order I, X, Y, Z or II, IX, IY, IZ, XI, XX, XY, etc respectively.

  • qubits – a list of the qubits that the noisy gate should act on.

Returns

A single program with noisy gates inserted between each element of the program list.

pyquil.quil.percolate_declares(program: pyquil.quil.Program) pyquil.quil.Program[source]

Move all the DECLARE statements to the top of the program. Return a fresh object.

Parameters

program – Perhaps jumbled program.

Returns

Program with DECLAREs all at the top and otherwise the same sorted contents.

pyquil.quil.validate_protoquil(program: pyquil.quil.Program, quilt: bool = False) None[source]

Ensure that a program is valid ProtoQuil or Quil-T, otherwise raise a ValueError. Protoquil is a subset of Quil which excludes control flow and classical instructions.

Parameters
  • quilt – Validate the program as Quil-T.

  • program – The Quil program to validate.

pyquil.quil.validate_supported_quil(program: pyquil.quil.Program) None[source]

Ensure that a program is supported Quil which can run on any QPU, otherwise raise a ValueError. We support a global RESET before any gates, and MEASUREs on each qubit after any gates on that qubit. PRAGMAs and DECLAREs are always allowed.

Parameters

program – The Quil program to validate.