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 bitstring01
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 bitstring01
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
andp11
. 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 bitstring01
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.
- 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
toQubit
orint
(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.