pyquil.api package¶
Sub-package for facilitating connections to the QVM / QPU.
- class pyquil.api.AbstractCompiler(*, quantum_processor: AbstractQuantumProcessor, timeout: float, client_configuration: QCSClient | None = None, quilc_client: QuilcClient | None = None)[source]¶
Bases:
ABC
The abstract interface for a compiler.
- get_version_info() Dict[str, Any] [source]¶
Return version information for this compiler and its dependencies.
- Returns:
Dictionary of version information.
- abstract native_quil_to_executable(nq_program: Program, **kwargs: Any) EncryptedProgram | Program [source]¶
Compile a native quil program to a binary executable.
- Parameters:
nq_program – Native quil to compile
- Returns:
An (opaque) binary executable
- class pyquil.api.BenchmarkConnection(*, timeout: float = 10.0, client_configuration: QCSClient | None = None)[source]¶
Bases:
AbstractBenchmarker
Represents a connection to a server that generates benchmarking data.
Client to communicate with the benchmarking data endpoint.
- Parameters:
timeout – Time limit for requests, in seconds.
client_configuration – Optional client configuration. If none is provided, a default one will be loaded.
- apply_clifford_to_pauli(clifford: Program, pauli_in: PauliTerm) PauliTerm [source]¶
Given a circuit that consists only of elements of the Clifford group, return its action on a PauliTerm.
In particular, for Clifford C, and Pauli P, this returns the PauliTerm representing CPC^{dagger}.
- Parameters:
clifford – A Program that consists only of Clifford operations.
pauli_in – A PauliTerm to be acted on by clifford via conjugation.
- Returns:
A PauliTerm corresponding to clifford * pauli_in * clifford^{dagger}
- generate_rb_sequence(depth: int, gateset: Sequence[Gate], seed: int | None = None, interleaver: Program | None = None) List[Program] [source]¶
Construct a randomized benchmarking experiment on the given qubits, decomposing into gateset. If interleaver is not provided, the returned sequence will have the form
C_1 C_2 … C_(depth-1) C_inv ,
where each C is a Clifford element drawn from gateset, C_{< depth} are randomly selected, and C_inv is selected so that the entire sequence composes to the identity. If an interleaver G (which must be a Clifford, and which will be decomposed into the native gateset) is provided, then the sequence instead takes the form
C_1 G C_2 G … C_(depth-1) G C_inv .
The JSON response is a list of lists of indices, or Nones. In the former case, they are the index of the gate in the gateset.
- Parameters:
depth – The number of Clifford gates to include in the randomized benchmarking experiment. This is different than the number of gates in the resulting experiment.
gateset – A list of pyquil gates to decompose the Clifford elements into. These must generate the clifford group on the qubits of interest. e.g. for one qubit [RZ(np.pi/2), RX(np.pi/2)].
seed – A positive integer used to seed the PRNG.
interleaver – A Program object that encodes a Clifford element.
- Returns:
A list of pyquil programs. Each pyquil program is a circuit that represents an element of the Clifford group. When these programs are composed, the resulting Program will be the randomized benchmarking experiment of the desired depth. e.g. if the return programs are called cliffords then sum(cliffords, Program()) will give the randomized benchmarking experiment, which will compose to the identity program.
- class pyquil.api.EncryptedProgram(program: str, memory_descriptors: Dict[str, ParameterSpec], ro_sources: Dict[MemoryReference, str], recalculation_table: List[str])[source]¶
Bases:
object
Encrypted binary, executable on a QPU.
- copy() EncryptedProgram [source]¶
Return a deep copy of this EncryptedProgram.
- memory_descriptors: Dict[str, ParameterSpec]¶
Descriptors for memory executable’s regions, mapped by name.
- program: str¶
String representation of an encrypted Quil program.
- recalculation_table: List[str]¶
A mapping from memory references to the original gate arithmetic.
- ro_sources: Dict[MemoryReference, str]¶
Readout sources, mapped by memory reference.
- class pyquil.api.ExecutionOptions¶
Bases:
object
- static builder()¶
- connection_strategy¶
- static default()¶
- timeout_seconds¶
- class pyquil.api.QAM[source]¶
Bases:
ABC
,Generic
[T
]Quantum Abstract Machine: This class acts as a generic interface describing how a classical computer interacts with a live quantum computer.
- abstract execute(executable: EncryptedProgram | Program, memory_map: Mapping[str, Sequence[int] | Sequence[float]] | None = None, **kwargs: Any) T [source]¶
Run an executable on a QAM, returning a handle to be used to retrieve results.
- Parameters:
executable – The executable program to be executed by the QAM.
memory_map – A mapping of memory regions to a list containing the values to be written into that memory region for the run.
- abstract get_result(execute_response: T) QAMExecutionResult [source]¶
Retrieve the results associated with a previous call to
QAM#execute
.- Parameters:
execute_response – The return value from a call to
execute
.
- run(executable: EncryptedProgram | Program, memory_map: Mapping[str, Sequence[int] | Sequence[float]] | None = None, **kwargs: Any) QAMExecutionResult [source]¶
Run an executable to completion on the QAM.
- class pyquil.api.QAMExecutionResult(executable: pyquil.api._abstract_compiler.EncryptedProgram | pyquil.quil.Program, data: ExecutionData)[source]¶
Bases:
object
- data: ExecutionData¶
The
ExecutionData
returned from the job. Consider usingQAMExecutionResult#register_map
orQAMExecutionResult#raw_readout_data
to get at the data in a more convenient format.
- executable: EncryptedProgram | Program¶
The executable corresponding to this result.
- property execution_duration_microseconds: float | None¶
Duration job held exclusive hardware access. Defaults to
None
when information is not available.
- get_memory_values() Mapping[str, MemoryValues] [source]¶
Get the final memory values for any memory region that was both read from and written to during execution. This method will only return the final value in memory after the job has completed. Because of this, memory values should not be used to get readout data. Instead, use get_register_map() or get_raw_readout_data().
- get_raw_readout_data() RawQVMReadoutData | RawQPUReadoutData [source]¶
Get the raw result data. This will be a flattened structure derived from
qcs_sdk.qvm.QVMResultData
orqcs_sdk.qpu.QPUResultData
depending on where the job was run. See their respective documentation for more information on the data format.This property should be used when running programs that use features like mid-circuit measurement and dynamic control flow on a QPU, since they can produce irregular result shapes that don’t necessarily fit in a rectangular matrix. If the program was run on a QVM, or doesn’t use those features, consider using the
register_map
property instead.
- get_register_map() Dict[str, ndarray | None] [source]¶
A mapping of a register name (ie. “ro”) to a
np.ndarray
containing the values for the register.Raises a
RegisterMatrixConversionError
if the inner execution data for any of the registers would result in a jagged matrix. QPU result data is captured per measure, meaning a value is returned for every measure to a memory reference, not just once per shot. This is often the case in programs that re-use qubits or dynamic control flow, where measurements to the same memory reference might occur multiple times in a shot, or be skipped conditionally. In these cases, building a matrix with one value per memory reference, per shot would necessitate making assumptions about the data that could skew the data in undesirable ways. Instead, it’s recommended to manually build a matrix from theQPUResultData
available on theraw_readout_data
property.Warning
An exception will _not_ be raised if the result data happens to fit a rectangular matrix, since it’s possible the register map is valid for some number of shots. Users should be aware of this possibility, especially when running programs that utilize qubit reuse or dynamic control flow.
- property readout_data: Mapping[str, ndarray | None]¶
Readout data returned from the QAM, keyed on the name of the readout register or post-processing node.
- class pyquil.api.QCSClient(tokens=None, api_url=None, auth_server=None, grpc_api_url=None, quilc_url=None, qvm_url=None)¶
Bases:
object
- api_url¶
- grpc_api_url¶
- static load(profile_name=None)¶
- static load_async(profile_name=None)¶
- quilc_url¶
- qvm_url¶
- class pyquil.api.QCSQuantumProcessor(quantum_processor_id: str, isa: InstructionSetArchitecture, noise_model: NoiseModel | None = None)[source]¶
Bases:
AbstractQuantumProcessor
An AbstractQuantumProcessor initialized with an
InstructionSetArchitecture
returned from the QCS API. Notably, this class is able to serialize aCompilerISA
based on the architecture instructions.Initialize a new QCSQuantumProcessor.
- Parameters:
quantum_processor_id – The id of the quantum processor.
isa – The QCS API
InstructionSetArchitecture
.noise_model – An optional
NoiseModel
for configuring a noisy quantum_processor on theQVM
.
- noise_model: NoiseModel | None¶
- quantum_processor_id: str¶
- qubit_topology() Graph [source]¶
The connectivity of qubits in this quantum_processor given as a NetworkX graph.
- to_compiler_isa() CompilerISA [source]¶
Construct an ISA suitable for targeting by compilation. This will raise an exception if the requested ISA is not supported by the quantum_processor.
- class pyquil.api.QPU(*, quantum_processor_id: str, priority: int = 1, timeout: float | None = 30.0, client_configuration: QCSClient | None = None, endpoint_id: str | None = None, execution_options: ExecutionOptions | None = None)[source]¶
Bases:
QAM
[QPUExecuteResponse
]A connection to the QPU.
- Parameters:
quantum_processor_id – Processor to run against.
priority – The priority with which to insert jobs into the QPU queue. Lower integers correspond to higher priority.
timeout – Time limit for requests, in seconds.
client_configuration – Optional client configuration. If none is provided, a default one will be loaded.
endpoint_id – Optional endpoint ID to be used for execution.
execution_options – The
ExecutionOptions
to use when executing a program. If provided, the options take precedence over the timeout and endpoint_id parameters.
- execute(executable: EncryptedProgram | Program, memory_map: Mapping[str, Sequence[int] | Sequence[float]] | None = None, execution_options: ExecutionOptions | None = None, **__: Any) QPUExecuteResponse [source]¶
Enqueue a job for execution on the QPU. Returns a
QPUExecuteResponse
, a job descriptor which should be passed directly toQPU.get_result
to retrieve results.- Param:
- execution_options: An optional ExecutionOptions enum that can be used
to configure how the job is submitted and retrieved from the QPU. If unset, an appropriate default will be used.
- get_result(execute_response: QPUExecuteResponse) QAMExecutionResult [source]¶
Retrieve results from execution on the QPU.
- property quantum_processor_id: str¶
ID of quantum processor targeted.
- class pyquil.api.QPUCompiler(*, quantum_processor_id: str, quantum_processor: AbstractQuantumProcessor, timeout: float = 10.0, client_configuration: QCSClient | None = None, api_options: TranslationOptions | None = None, quilc_client: QuilcClient | None = None)[source]¶
Bases:
AbstractCompiler
Client to communicate with the compiler and translation service.
Instantiate a new QPU compiler client.
- Parameters:
quantum_processor_id – Processor to target.
quantum_processor – Quantum processor to use as compilation target.
timeout – Time limit for requests, in seconds.
client_configuration – Optional client configuration. If none is provided, a default one will be loaded.
api_options – Options to pass to the QPU compiler API. See
qcs-sdk-python
for details.
- api_options: TranslationOptions | None¶
- get_calibration_program(force_refresh: bool = False) Program [source]¶
Get the Quil-T calibration program associated with the underlying QPU.
This will return a cached copy of the calibration program if present. Otherwise (or if forcing a refresh), it will fetch and store the calibration program from the QCS API.
A calibration program contains a number of DEFCAL, DEFWAVEFORM, and DEFFRAME instructions. In sum, those instructions describe how a Quil-T program should be translated into analog instructions for execution on hardware.
- Parameters:
force_refresh – Whether or not to fetch a new calibration program before returning.
- Returns:
A Program object containing the calibration definitions.
- native_quil_to_executable(nq_program: Program, *, api_options: TranslationOptions | None = None, **kwargs: Any) EncryptedProgram | Program [source]¶
Convert a native Quil program into an executable binary which can be executed by a QPU.
If api_options is provided, it overrides the options set on self.
- pyquil.api.QPUCompilerAPIOptions¶
alias of
TranslationOptions
- class pyquil.api.QVM(noise_model: NoiseModel | None = None, gate_noise: Tuple[float, float, float] | None = None, measurement_noise: Tuple[float, float, float] | None = None, random_seed: int | None = None, timeout: float = 10.0, client: QVMClient | None = None)[source]¶
Bases:
QAM
[QVMExecuteResponse
]A virtual machine that classically emulates the execution of Quil programs.
- Parameters:
noise_model – A noise model that describes noise to apply when emulating a program’s execution.
gate_noise – A tuple of three numbers [Px, Py, Pz] indicating the probability of an X, Y, or Z gate getting applied to each qubit after a gate application or reset. The default value of None indicates no noise.
measurement_noise – A tuple of three numbers [Px, Py, Pz] indicating the probability of an X, Y, or Z gate getting applied before a measurement. The default value of None indicates no noise.
random_seed – A seed for the QVM’s random number generators. Either None (for an automatically generated seed) or a non-negative integer.
timeout – Time limit for requests, in seconds.
client_configuration – Optional client configuration. If none is provided, a default one will be loaded.
- execute(executable: EncryptedProgram | Program, memory_map: Mapping[str, Sequence[int] | Sequence[float]] | None = None, **__: Any) QVMExecuteResponse [source]¶
Synchronously execute the input program to completion.
- get_result(execute_response: QVMExecuteResponse) QAMExecutionResult [source]¶
Return the results of execution on the QVM.
- class pyquil.api.QVMCompiler(*, quantum_processor: AbstractQuantumProcessor, timeout: float = 10.0, client_configuration: QCSClient | None = None, quilc_client: QuilcClient | None = None)[source]¶
Bases:
AbstractCompiler
Client to communicate with the compiler.
Client to communicate with compiler.
- Parameters:
quantum_processor – Quantum processor to use as compilation target.
timeout – Number of seconds to wait for a response from the client.
client_configuration – Optional client configuration. If none is provided, a default one will be loaded.
- native_quil_to_executable(nq_program: Program, **kwargs: Any) EncryptedProgram | Program [source]¶
Compile a native quil program to a binary executable.
- Parameters:
nq_program – Native quil to compile
- Returns:
An (opaque) binary executable
- class pyquil.api.QuantumComputer(*, name: str, qam: QAM[Any], compiler: AbstractCompiler, symmetrize_readout: bool = False)[source]¶
Bases:
object
A quantum computer for running quantum programs.
A quantum computer has various characteristics like supported gates, qubits, qubit topologies, gate fidelities, and more. A quantum computer also has the ability to run quantum programs.
A quantum computer can be a real Rigetti QPU that uses superconducting transmon qubits to run quantum programs, or it can be an emulator like the QVM with noise models and mimicked topologies.
- Parameters:
name – A string identifying this particular quantum computer.
qam – A quantum abstract machine which handles executing quantum programs. This dispatches to a QVM or QPU.
symmetrize_readout – Whether to apply readout error symmetrization. See
run_symmetrized_readout()
for a complete description.
- calibrate(experiment: Experiment) List[ExperimentResult] [source]¶
Perform readout calibration on the various multi-qubit observables involved in the provided
Experiment
.- Parameters:
experiment – The
Experiment
to calibrate readout error for.- Returns:
A list of
ExperimentResult
objects that contain the expectation values that correspond to the scale factors resulting from symmetric readout error.
- compile(program: Program, to_native_gates: bool = True, optimize: bool = True, *, protoquil: bool | None = None) EncryptedProgram | Program [source]¶
A high-level interface to program compilation.
Compilation currently consists of two stages. Please see the
AbstractCompiler
docs for more information. This function does all stages of compilation.Right now both
to_native_gates
andoptimize
must be either both set or both unset. More modular compilation passes may be available in the future.Additionally, a call to compile also calls the
reset
method if one is running on the QPU. This is a bit of a sneaky hack to guard against stale compiler connections, but shouldn’t result in any material hit to performance (especially when taking advantage of parametric compilation for hybrid applications).- Parameters:
program – A Program
to_native_gates – Whether to compile non-native gates to native gates.
optimize – Whether to optimize the program to reduce the number of operations.
protoquil – Whether to restrict the input program to and the compiled program to protoquil (executable on QPU). A value of
None
means defer to server.
- Returns:
An executable binary suitable for passing to
QuantumComputer.run()
.
- property quantum_processor: AbstractQuantumProcessor¶
The quantum processor associated with this quantum computer.
- qubit_topology() <module 'networkx.classes.graph' from '/home/docs/checkouts/readthedocs.org/user_builds/pyquil/envs/stable/lib/python3.10/site-packages/networkx/classes/graph.py'> [source]¶
Return a NetworkX graph representation of this QuantumComputer’s quantum_processor’s qubit connectivity.
See
AbstractQuantumProcessor.qubit_topology()
for more.
- qubits() List[int] [source]¶
Return a sorted list of this QuantumComputer’s quantum_processor’s qubits
See
AbstractQuantumProcessor.qubits()
for more.
- run(executable: EncryptedProgram | Program, memory_map: Mapping[str, Sequence[int] | Sequence[float]] | None = None, **kwargs: Any) QAMExecutionResult [source]¶
Run a quil executable. All parameters in the executable must have values applied using
Program#write_memory
.- Parameters:
executable – The program to run, previously compiled as needed for its target QAM.
memory_map – A mapping of memory regions to a list containing the values to be written into that memory region for the run.
- Returns:
execution result including readout data.
- run_experiment(experiment: Experiment, memory_map: Mapping[str, Sequence[int] | Sequence[float]] | None = None) List[ExperimentResult] [source]¶
Run an
Experiment
on a QVM or QPU backend. AnExperiment
is composed of:A main
Program
body (or ansatz).A collection of
ExperimentSetting
objects, each of which encodes a particular state preparation and measurement.A
SymmetrizationLevel
for enacting different readout symmetrization strategies.A number of shots to collect for each (unsymmetrized)
ExperimentSetting
.
Because the main
Program
is static from run to run of anExperiment
, we can leverage our platform’s Parametric Compilation feature. This means that theProgram
can be compiled only once, and the various alterations due to state preparation, measurement, and symmetrization can all be realized at runtime by providing amemory_map
. Thus, the steps in theexperiment
method are as follows:Generate a parameterized program corresponding to the
Experiment
(see theExperiment.generate_experiment_program()
method for more details on how it changes the main body program to support state preparation, measurement, and symmetrization).
Compile the parameterized program into a parametric (binary) executable, which contains declared variables that can be assigned at runtime.
For each
ExperimentSetting
in theExperiment
, we repeat the following:Build a collection of memory maps that correspond to the various state preparation, measurement, and symmetrization specifications.
Run the parametric executable on the QVM or QPU backend, providing the memory map to assign variables at runtime.
Extract the desired statistics from the classified bitstrings that are produced by the QVM or QPU backend, and package them in an
ExperimentResult
object.
Return the list of
ExperimentResult
objects.
This method is extremely useful shorthand for running near-term applications and algorithms, which often have this ansatz + settings structure.
- Parameters:
experiment – The
Experiment
to run.memory_map – A dictionary mapping declared variables / parameters to their values. The values are a list of floats or integers. Each float or integer corresponds to a particular classical memory register. The memory map provided to the
experiment
method corresponds to variables in the main body program that we would like to change at runtime (e.g. the variational parameters provided to the ansatz of the variational quantum eigensolver).
- Returns:
A list of
ExperimentResult
objects containing the statistics gathered according to the specifications of theExperiment
.
- run_symmetrized_readout(program: Program, trials: int, symm_type: int = 3, meas_qubits: List[int] | None = None) ndarray [source]¶
Run a quil program in such a way that the readout error is made symmetric. Enforcing symmetric readout error is useful in simplifying the assumptions in some near term error mitigation strategies, see
measure_observables
for more information.The simplest example is for one qubit. In a noisy quantum_processor, the probability of accurately reading the 0 state might be higher than that of the 1 state; due to e.g. amplitude damping. This makes correcting for readout more difficult. In the simplest case, this function runs the program normally
(trials//2)
times. The other half of the time, it will insert anX
gate prior to anyMEASURE
instruction and then flip the measured classical bit back. Overall this has the effect of symmetrizing the readout error.The details. Consider preparing the input bitstring
|i>
(in the computational basis) and measuring in the Z basis. Then the Confusion matrix for the readout error is specified by the probabilitiesp(j|i) := Pr(measured = j | prepared = i ).
In the case of a single qubit i,j in [0,1] then: there is no readout error if p(0|0) = p(1|1) = 1. the readout error is symmetric if p(0|0) = p(1|1) = 1 - epsilon. the readout error is asymmetric if p(0|0) != p(1|1).
If your quantum computer has this kind of asymmetric readout error then
qc.run_symmetrized_readout
will symmetrize the readout error.The readout error above is only asymmetric on a single bit. In practice the confusion matrix on n bits need not be symmetric, e.g. for two qubits p(ij|ij) != 1 - epsilon for all i,j. In these situations a more sophisticated means of symmetrization is needed; and we use orthogonal arrays (OA) built from Hadamard matrices.
The symmetrization types are specified by an int; the types available are: -1 – exhaustive symmetrization uses every possible combination of flips 0 – trivial that is no symmetrization 1 – symmetrization using an OA with strength 1 2 – symmetrization using an OA with strength 2 3 – symmetrization using an OA with strength 3 In the context of readout symmetrization the strength of the orthogonal array enforces the symmetry of the marginal confusion matrices.
By default a strength 3 OA is used; this ensures expectations of the form
<b_k . b_j . b_i>
for bits any bits i,j,k will have symmetric readout errors. Here expectation of a random variable x as is denote<x> = sum_i Pr(i) x_i
. It turns out that a strength 3 OA is also a strength 2 and strength 1 OA it also ensures<b_j . b_i>
and<b_i>
have symmetric readout errors for any bits b_j and b_i.- Parameters:
program – The program to run symmetrized readout on.
trials – The minimum number of times to run the program; it is recommend that this number should be in the hundreds or thousands. This parameter will be mutated if necessary.
symm_type – the type of symmetrization
meas_qubits – An advanced feature. The groups of measurement qubits. Only these qubits will be symmetrized over, even if the program acts on other qubits.
- Returns:
A numpy array of shape (trials, len(ro-register)) that contains 0s and 1s.
- to_compiler_isa() CompilerISA [source]¶
Return a
CompilerISA
for this QuantumComputer’s quantum_processor.See
AbstractQuantumProcessor.to_compiler_isa()
for more.
- class pyquil.api.WavefunctionSimulator(*, gate_noise: Tuple[float, float, float] | None = None, measurement_noise: Tuple[float, float, float] | None = None, random_seed: int | None = None, timeout: float = 10.0, client_configuration: QCSClient | None = None)[source]¶
Bases:
object
A simulator that propagates a wavefunction representation of a quantum state.
- Parameters:
gate_noise – A tuple of three numbers [Px, Py, Pz] indicating the probability of an X, Y, or Z gate getting applied to each qubit after a gate application or reset.
measurement_noise – A tuple of three numbers [Px, Py, Pz] indicating the probability of an X, Y, or Z gate getting applied before a measurement.
random_seed – A seed for the simulator’s random number generators. Either None (for an automatically generated seed) or a non-negative integer.
timeout – Time limit for requests, in seconds.
client_configuration – Optional client configuration. If none is provided, a default one will be loaded.
- static augment_program_with_memory_values(quil_program: Program, memory_map: Mapping[str, Sequence[int] | Sequence[float]]) Program [source]¶
- expectation(prep_prog: Program, pauli_terms: PauliSum | List[PauliTerm], memory_map: Dict[str, List[int | float]] | None = None) float | ndarray [source]¶
Calculate the expectation value of Pauli operators given a state prepared by prep_program.
If
pauli_terms
is aPauliSum
then the returned value is a singlefloat
, otherwise the returned value is an array of values, one for eachPauliTerm
in the list.Note
If your program contains measurements or noisy gates, this method may not do what you want. If the execution of
quil_program
is non-deterministic then the final wavefunction from which the expectation value is calculated only represents a stochastically generated sample and the wavefunctions returned by differentwavefunction
calls will generally be different.- Parameters:
prep_prog – A program that prepares the state on which we measure the expectation.
pauli_terms – A Pauli representation of a quantum operator.
memory_map –
An assignment of classical registers to values, representing an initial state for the QAM’s classical memory.
This is expected to be of type Dict[str, List[Union[int, float]]], where the keys are memory region names and the values are arrays of initialization data.
- Returns:
Either a float or array floats depending on
pauli_terms
.
- run_and_measure(quil_program: Program, qubits: List[int] | None = None, trials: int = 1, memory_map: Mapping[str, Sequence[int] | Sequence[float]] | None = None) ndarray [source]¶
Run a Quil program once to determine the final wavefunction, and measure multiple times.
Alternatively, consider using
wavefunction
and callingsample_bitstrings
on the resulting object.For a large wavefunction and a low-medium number of trials, use this function. On the other hand, if you’re sampling a small system many times you might want to use
Wavefunction.sample_bitstrings
.Note
If your program contains measurements or noisy gates, this method may not do what you want. If the execution of
quil_program
is non-deterministic then the final wavefunction from which the returned bitstrings are sampled itself only represents a stochastically generated sample and the outcomes sampled from differentrun_and_measure
calls generally sample different bitstring distributions.- Parameters:
quil_program – The program to run and measure
qubits – An optional list of qubits to measure. The order of this list is respected in the returned bitstrings. If not provided, all qubits used in the program will be measured and returned in their sorted order.
trials (int) – Number of times to sample from the prepared wavefunction.
memory_map –
An assignment of classical registers to values, representing an initial state for the QAM’s classical memory.
This is expected to be of type Dict[str, List[Union[int, float]]], where the keys are memory region names and the values are arrays of initialization data.
- Returns:
An array of measurement results (0 or 1) of shape (trials, len(qubits))
- wavefunction(quil_program: Program, memory_map: Mapping[str, Sequence[int] | Sequence[float]] | None = None) Wavefunction [source]¶
Simulate a Quil program and return the wavefunction.
Note
If your program contains measurements or noisy gates, this method may not do what you want. If the execution of
quil_program
is non-deterministic then the final wavefunction only represents a stochastically generated sample and the wavefunctions returned by differentwavefunction
calls will generally be different.- Parameters:
quil_program – A Quil program.
memory_map –
An assignment of classical registers to values, representing an initial state for the QAM’s classical memory.
This is expected to be of type Dict[str, List[Union[int, float]]], where the keys are memory region names and the values are arrays of initialization data.
- Returns:
A Wavefunction object representing the state of the QVM.
- pyquil.api.get_qc(name: str, *, as_qvm: bool | None = None, noisy: bool | None = None, compiler_timeout: float = 30.0, execution_timeout: float = 30.0, client_configuration: QCSClient | None = None, endpoint_id: str | None = None, quilc_client: QuilcClient | None = None, qvm_client: QVMClient | None = None) QuantumComputer [source]¶
Get a quantum computer.
A quantum computer is an object of type
QuantumComputer
and can be backed either by a QVM simulator (“Quantum/Quil Virtual Machine”) or a physical Rigetti QPU (“Quantum Processing Unit”) made of superconducting qubits.You can choose the quantum computer to target through a combination of its name and optional flags. There are multiple ways to get the same quantum computer. The following are equivalent:
>>> qc = get_qc("Aspen-M-3-qvm") >>> qc = get_qc("Aspen-M-3", as_qvm=True)
and will construct a simulator of an Aspen-M-3 lattice. We also provide a means for constructing generic quantum simulators that are not related to a given piece of Rigetti hardware:
>>> qc = get_qc("9q-square-qvm") >>> qc = get_qc("9q-square", as_qvm=True)
Finally, you can get request a QVM with “no” topology of a given number of qubits (technically, it’s a fully connected graph among the given number of qubits) with:
>>> qc = get_qc("5q-qvm") # or "6q-qvm", or "34q-qvm", ...
These less-realistic, fully-connected QVMs will also be more lenient on what types of programs they will
run
. Specifically, you do not need to do any compilation. For the other, realistic QVMs you must useqc.compile()
orqc.compiler.native_quil_to_executable()
prior toqc.run()
.The Rigetti QVM must be downloaded from https://www.rigetti.com/forest and run as a server alongside your python program. To use pyQuil’s built-in QVM, replace all
"-qvm"
suffixes with"-pyqvm"
:>>> qc = get_qc("5q-pyqvm")
Redundant flags are acceptable, but conflicting flags will raise an exception:
>>> qc = get_qc("9q-square-qvm") # qc is fully specified by its name >>> qc = get_qc("9q-square-qvm", as_qvm=True) # redundant, but ok >>> qc = get_qc("9q-square-qvm", as_qvm=False) # Error! Traceback (most recent call last): ValueError: The provided qc name indicates you are getting a QVM, but you have specified `as_qvm=False`
Use
list_quantum_computers()
to retrieve a list of known qc names.This method is provided as a convenience to quickly construct and use QVM’s and QPU’s. Power users may wish to have more control over the specification of a quantum computer (e.g. custom noise models, bespoke topologies, etc.). This is possible by constructing a
QuantumComputer
object by hand. Please refer to the documentation onQuantumComputer
for more information.- Parameters:
name – The name of the desired quantum computer. This should correspond to a name returned by
list_quantum_computers()
. Names ending in “-qvm” will return a QVM. Names ending in “-pyqvm” will return aPyQVM
. Names ending in “-noisy-qvm” will return a QVM with a noise model. Otherwise, we will return a QPU with the given name.as_qvm – An optional flag to force construction of a QVM (instead of a QPU). If specified and set to
True
, a QVM-backed quantum computer will be returned regardless of the name’s suffixnoisy – An optional flag to force inclusion of a noise model. If specified and set to
True
, a quantum computer with a noise model will be returned regardless of the name’s suffix. The generic QVM noise model is simple T1 and T2 noise plus readout error. Seedecoherence_noise_with_asymmetric_ro()
. Note, we currently do not support noise models based on QCS hardware; a value of True` will result in an error if the requested QPU is a QCS hardware QPU.compiler_timeout – Time limit for compilation requests, in seconds.
execution_timeout – Time limit for execution requests, in seconds.
client_configuration – Optional client configuration. If none is provided, a default one will be loaded. For more information on setting up QCS credentials, see documentation for using the QCS CLI: [https://docs.rigetti.com/qcs/guides/using-the-qcs-cli#configuring-credentials].
endpoint_id – Optional quantum processor endpoint ID, as used in the QCS API Docs.
- Returns:
A pre-configured QuantumComputer
- pyquil.api.list_quantum_computers(qpus: bool = True, qvms: bool = True, timeout: float = 10.0, client_configuration: QCSClient | None = None) List[str] [source]¶
List the names of available quantum computers
- Parameters:
qpus – Whether to include QPUs in the list.
qvms – Whether to include QVMs in the list.
timeout – Time limit for request, in seconds.
client_configuration – Optional client configuration. If none is provided, a default one will be loaded.
- pyquil.api.local_forest_runtime(*, host: str = '127.0.0.1', qvm_port: int = 5000, quilc_port: int = 5555, use_protoquil: bool = False) Iterator[Tuple[Popen | None, Popen | None]] [source]¶
A context manager for local QVM and QUIL compiler.
You must first have installed the qvm and quilc executables from the forest SDK. [https://www.rigetti.com/forest]
This context manager will ensure that the designated ports are not used, start up qvm and quilc proccesses if possible and terminate them when the context is exited. If one of the ports is in use, a
RuntimeWarning
will be issued and the qvm/quilc process won’t be started.Note
Only processes started by this context manager will be terminated on exit, no external process will be touched.
>>> from pyquil import get_qc, Program >>> from pyquil.gates import CNOT, Z >>> from pyquil.api import local_forest_runtime >>> >>> qvm = get_qc('9q-square-qvm') >>> prog = Program(Z(0), CNOT(0, 1)) >>> >>> with local_forest_runtime(): >>> results = qvm.run(prog)
- Parameters:
host – Host on which qvm and quilc should listen on.
qvm_port – Port which should be used by qvm.
quilc_port – Port which should be used by quilc.
use_protoquil – Restrict input/output to protoquil.
Warning
If
use_protoquil
is set toTrue
language features you need may be disabled. Please use it with caution.- Raises:
FileNotFoundError: If either executable is not installed.
- Returns:
The returned tuple contains two
subprocess.Popen
objects for the qvm and the quilc processes. If one of the designated ports is in use, the process won’t be started and the respective value in the tuple will beNone
.