# qat-core: Core data structures and Abstract classes¶

## Abstract classes¶

Following classes may be used to define new Plugins or QPUs.

class qat.plugins.AbstractPlugin(*args, **kwargs)

Abstract interface of a Plugin.

abstract compile(batch, specs)

Compiles a Batch into another Batch according to some hardware specs

do_post_processing()

Returns True iff the results need to be aggregated/post processed via the plugin.

serve(port, host_ip='localhost', server_type=None)

Runs the plugin inside a server

Parameters
• port (int) – the port on which to listen

• host_ip (str) – the url on which to publish the API. Optional. Defaults to ‘localhost’.

• server_type (str, optional) –

type of server. The different types of server are:

• ”simple”: single-thread server, accepts one connection at a time (default server type)

• ”pool”: multi-thread server, each connection runs in a thread, with a maximum of 10 running threads

• ”fork”: multi-process server, each connection runs in a new process

wrapper_post_process(results)

Call post process function and wrap the result in a PostProcessResult object

class qat.core.qpu.QPUHandler(plugins=None)

Abstract class describing the mininmal QPU interface.

The minimal interface is the implementation of the submit_job method:

This method should return a Result structure corresponding to the execution of a Job.

serve(port, host_ip='localhost', server_type=None)

Runs the QPU inside a server

Parameters
• port (int) – the port on which to listen

• host_ip (str) – the url on which to publish the API. Optional. Defaults to ‘localhost’.

• server_type (str, optional) –

type of server. The different types of server are:

• ”simple”: single-thread server, accepts one connection at a time (default server type)

• ”pool”: multi-thread server, each connection runs in a thread, with a maximum of 10 running threads

• ”fork”: multi-process server, each connection runs in a new process

submit(batch: qat.core.wrappers.batch.Batch, meta_data: Optional[dict] = None)qat.core.wrappers.result.BatchResult

Executes a batch of jobs and returns the corresponding list of Results.

Parameters

batch (Batch) – a batch of jobs. If a single job is provided, the job is embedded into a Batch, executed, and the first result is returned.

Returns

a batch result

Return type
abstract submit_job(job: qat.core.wrappers.job.Job)qat.core.wrappers.result.Result

Returns a Result structure corresponding to the execution of a Job.

Note

Notice that the job can be assumed to be already compiled/optimized.

This is the end of the pipe!

Parameters

job (Job) – the job to execute

Returns

a result

Return type

## Remote interfaces¶

QPUs and Plugins can be used in client/server mode. Any Plugin or QPU, once constructed, can be published via their serve method (see right above).

Once published, a client can connect and interact with them via one of the two following classes:

class qat.core.qpu.RemoteQPU(port=None, ip=None, connection=None, plugins=None)

RemoteQPUs are built from a port and an ip address. They behave similarly to a local QPU Handler but also allow adjunction of local Plugins. The information flow inside a RemoteQPU is comparable to the information flow inside a QPUHandler:

• when compiling a batch the batch goes through all the local plugins and is sent to the connection. The resulting batch is then returned to the user

• when submitting, the batch is compiled using the local plugins and then forwarded through the connection. The results are then post

processed by the local Plugins.

Parameters
• port (optional, int) – the port to connect to

• ip (optional, str) – the IP address to connect to

• plugins (list<qat.plugins.AbstractPlugins>) – a list of plugins. Optional. Defaults to None.

• connection (optional Thrift connection) – for internal use

class qat.core.plugins.RemotePlugin(port=None, ip=None, connection=None)

RemotePlugins are built from a port and an ip address.

Parameters
• port (optional, int) – a port to connect to

• ip (optional, str) – the IP address to connect to

• connection (optional, Thrift connection) – for internal use

## Batch and Job¶

Following are used to send a circuit or a set of circuit to a plugin or to a QPU. The circuit is then compiled or executed. The Job class is used to send a single Circuit to a QPU whereas the Batch class is used to send several Circuit objects at the same time.

class qat.core.Job(psi_0=None, **kwargs)

A high level wrapper for the Job thrift class.

Instance attributes:
• circuit (Circuit): circuit to execute

• schedule (Schedule): schedule to execute

• type (ProcessingType): type of Job

• observable (Observable, optional): the observable (required if job type is of type 1, i.e observable sampling)

• qubits (list<int>, optional): measured qubits

• nbshots (int): number of required shots: if 0, do maximal number of shots

• aggregate_data (bool): contract corresponding result object

• amp_threshold (float, optional): amplitude values under this threshold are considered null

differentiate(vname, method=None, **kwargs)

Generates a collection of variational jobs such that the sum of their energies equates the partial derivative of the job’s energy w.r.t to a given variable.

$\frac{\partial }{\partial \theta_j} \langle \psi(\theta) | H | \psi(\theta) \rangle = \sum_i \langle\psi_i(\theta) | H_i |\psi_i(\theta) \rangle$

where $$(|\psi\rangle, H)$$ is the input job and $$(|\psi_i\rangle, H_i)$$ are the output jobs.

\* **shift-rule** uses the chain rule for product differentiation together with a shift rule.

This method generates $$2k$$ jobs where $$k$$ is the number of rotations parametrized by the variable.

\* **h-test** performs a Hadamard test and a modifies the observable to sample in order

to encode the appropriate post-selection induced by the Hadamard test. It generates $$k$$ jobs where $$k$$ is the number of rotations parametrized by the variable. These jobs have an additional qubit and have observables that are (at most) twice as large as the initial observable.

Parameters
• vname (str) – a variable name.

• method (str, optional) – the method to use. Default ‘shift-rule’.

• kwargs (dict) – any additional parameter that can be passed to the differentitation method.

Returns

a list of jobs

Return type

list<Job>

dump(fname)

Dumps the job in a binary file.

Parameters

fname (str) – the file name

classmethod from_thrift(tobject)

Builds a Job from a thrift job

get_variables()

Returns the set of all variables appearing in the job

Generates a collection of groups of jobs such that the sum of the energy of each group equates the partial derivative of the job’s energy w.r.t each of its variable.

The collection is returned as a map mapping variable names to job list.

This method has serveral backends, see differentiate() for more details.

Parameters
• method (str, optional) – the differentiation method

• kwargs (dict) – additional arguments passed to the differentiation method

Returns

a map associating variable names to list of jobs

Return type

map<str, list<Job>>

Loads the Job from a binary file.

Parameters

fname (str) – the file name

Returns

Job

property psi_0

Initial state

shift_qbits(offset)

Shifts the job’s qbits by a given offset. Consequently icreases the number of qubits of the job by the same offset.

Acts in place.

Parameters

offset (int) – the offset

Processing types for jobs are defined via an enum class:

class qat.comm.shared.ttypes.ProcessingType

Different types of processings of the final quantum state.

Possible values:
• SAMPLE=0: sampling in the computational basis

• OBSERVABLE=1: observable sampling

class qat.core.Batch(jobs=None, meta_data=None)

Simple higher level wrapper for the serializable Batch class.

Instance attributes:
• jobs (list<Job>): jobs composing the batch

• meta_data (dict<str, str>): meta data

dump(fname)

Dumps the Batch inside a file in binary format.

Parameters

fname (str) – the file name

classmethod from_thrift(tobject)

Builds a Batch object from a thrift batch

get_variables()

Returns the of all variables appearing in the Batch.

Loads a Batch from a file.

Parameters

fname (str) – the file name

Returns

Batch

## Observables¶

class qat.core.Observable(nqbits, matrix=None, pauli_terms=None, ising=None, constant_coeff=0.0, do_clean_up=True)

Class describing an observable (i.e some Hermitian operator) over the Hilbert space spanned by a list of qbits.

The observable is stored as a sum of Terms, each composed of a Pauli operator and a real coefficient. It is also possible to store it with an Ising object which represents an Ising Hamiltonian.

The purpose of this class is mainly to efficiently automatize the sampling of this observable on the final state obtained after a computation.

Construction:

An Observable object can be constructed in various ways:

using a matrix representation:

using a list of Term:

or using an Ising object from the Ising:

Parameters
• nqbits (int) – number of qubits

• matrix (np.array, optional) – the matrix representing the observable. Defaults to None.

• pauli_terms (list<Term>, optional) – the list of products of Pauli operators representing the observable. Defaults to None.

• ising (Ising, optional) – an object representing an Ising encoded problem

• constant_coeff (float) – a constant additive term

terms

the list of products of Pauli operators representing the observable.

Type

list<Term>

ising

represents an Ising encoded problem (present if terms is None)

Type

Ising, optional

constant_coeff

Type

float

nbqbits

the number of qbits on which the observable acts

Type

int

constant_coeff

Type

float

class qat.core.Term(coefficient, pauli_op, qbits)

Class describing a term in the Pauli basis of an observable. It basically consists in a pair (coeffcient, pauli operator).

This class supports Thrift serialization and can be transmitted directly to the to_job method of a circuit object.

Term are constructed as follows:

from qat.core import Term

term = Term(1., # Coefficient of the term
"XXY", # tensor of operators X, X, and Y
[1, 4, 7]) # over qubits 1, 4, and 7

Parameters
• coefficient (float) – the coefficient in front of the term

• pauli_op (str) – the Pauli operator specified as a string containing I, X, Y, and Z characters.

• qbits (list<int>) – the list of concerned qubits

coeff

the coefficient in front of the term

Type

float

op

the Pauli operator specified as a string containing I, X, Y, and Z characters.

Type

str

qbits

the list of concerned qubits

Type

list<int>

## Results¶

A result is composed of several samples or, is an observable is measured, of a scalar. The result data structure is Result

class qat.core.Result(lsb_first=False, nbqbits=None, value=None, values=None, **kwargs)

Simple higher level wrapper for the serializable Result class.

Parameters
• result (ThriftResult, optional) – result

• lsb_first (bool, optional) – whether to use convention with least significant bit first. Defaults to False.

• nbqbits (int, optional) – number of qubits, required if lsb_first is False. Defaults to None.

Instance attributes:
• raw_data (list<Sample>, optional): the raw data sampling, if requested

• value (float, optional): scalar output

• value_data (map<str, float>, optional): Informationon the scalar output (deviation, etc)

• meta_data (map<str, str>): any information the QPU might want to transmit to the user (logs, resource usage, etc)

• has_statevector (bool): set to True iff the .statevector attribute is non-empty

• statevector: a low level description of the result. Usually contains a numpy array describing either a state vector or a probability distribution. Not always set.

Add sample to result. If required, reverts bit order.

Parameters
• state (int) – the index of the state in comput. basis

• amplitude (complex, optional) – a complex number for the amplitude

• probability (float, optional) – the probability

• err (float, optional) – the error on the probability estimate

• intermediate_measurements (IntermediateMeasurements, optional) – the intermediate measures

dump(fname)

Dumps the Result inside a file in binary format.

Parameters

fname (str) – the file name

classmethod from_thrift(tobject)

Builds a Result object from a thrift object

Loads a Result from a file.

Parameters

fname (str) – the file name

Returns

Result

property value

Scalar output - complex number

property values

Scalar output - complex number

wrap_samples(qreg_list)

Wraps the samples using a list of quantum registers Also serializes the underlying statevector object, if any

class qat.core.wrappers.result.Sample(qregs=None, amplitude=None, state=None, **kwargs)

Simple higher-level wrapper for the serializable Sample class.

Parameters

qregs (QRegister) – quantum register

Instance attributes:
• state (State): the measured state

• probability (float, optional): the probability of the state (infinite number of shots/samples, for simulators only), or frequency of the state (finite number of shots)

• amplitude (complex, optional): optionally (for simulators), the amplitude of the state

• intermediate_measurements (IntermediateMeasurement): list of intermediate measurements

• err (float, optional): optionally, the sampling error: if the number of samples is finite, it is the estimate of the standard error on the mean $$\varepsilon_{k}\equiv\sqrt{\langle\left(p_{k}-f_{k}\right)^{2}\rangle}$$, where $$p_k$$ is the true probability of obtaining state $$|k\rangle$$ and $$f_k$$ its estimate. if the number samples is infinite (simulator only), it is the error bar on the computed probability (for approximate simulators only, like stochastic simulators)

property amplitude

Returns the amplitude of the Sample (wrapped in a Python complex number)

classmethod from_thrift(tobject)

Builds a Sample object from a thrift object

set_qreg(qregs)

Sets the quantum register information for pretty display and cast of states

property state

Gets the state of the sample. The state may be wrapped in a State object

class qat.core.wrappers.result.State(int_msb_value, qregs=None)

Class representing a ‘classical’ state

Its __str__ method is overloaded to possibly take a QRegister type as format argument.

Parameters
• int_msb_value (int) – the state (integer, msb format)

• qregs (list<QRegister>, optional) – a list of QRegister to use for formatting purposes.

property bitstring

Returns a bitstring representation of the state

property int

Returns a msb representation of the state

property lsb_int

Returns a lsb reprensentation of the state

property value

Casts the state into a classical value using the information from the quantum registers

class qat.comm.shared.ttypes.IntermediateMeasurement(cbits=None, gate_pos=None, probability=None)

Data structure representing outcome of an intermediate measurement.

- cbits

list<bool> the list of classical bits resulting from the measurement

- gate_pos

int the position of the measurement in the circuit

- probability

optional, float, the probability of this precise measurement outcome

class qat.core.BatchResult(**kwargs)

Simple higher level wrapper for the serializable BatchResult class.

Parameters

kwargs (keyword arguments) – accepted arguments are results (a list of Result objects) and meta_data (a (str, str) map).

Instance attributes:
append(value)

Add a result in the list of results

Parameters

value (Result) –

dump(fname)

Dumps the BatchResult inside a file in binary format.

Parameters

fname (str) – the file name

extend(values)

Add several results in the list of results

Parameters

values (list<Result>) –

classmethod from_thrift(tobject)

Builds a BatchResult object from a thrift object

Loads a BatchResult from a file

Parameters

fname (str) – the file name

Returns

BatchResult

## Circuits¶

Here is the basic interface of the circuit class. For more information on the various attributes the circuit object, please refer to Circuits. For instance, one can easily concatenate two Circuit objects (as long as they have the same number of qubits):

cat_circuit = circuit1 + circuit2


Tensorial composition is implemented via an overloading of the __mult__ operator:

kron_circuit = circuit1 * circuit2


Among the other useful methods, we can find:

• the direct generation of a Job object from a circuit using various parameters:

job = circuit.to_job(job_type="SAMPLE", nbshots=1024, qubits=[0, 3, 7])

• (de)serialization of a circuit:

circuit.dump("my_circuit.circ")

• binding of an abstract variable:

new_circuit = circuit(theta=0.34)
# or, equivalently
new_circuit = circuit.bind_variables({theta: 0.34})

class qat.core.Circuit(ops=None, name=None, gateDic=None, nbqbits=None, nbcbits=0, _gate_set=None, has_matrices=None, var_dic=None, qregs=None, ancilla_map=None, _serialized_gate_set=None)

Simple higher level wrapper for the serializable Circuit class.

This wrapper provides high-level manipulation routines such as variable binding or iteration.

Circuits are usually built using the .to_circ method of the Program class, and are not designed to be built by hand.

The simplest way to explore the content of a circuit is to use the .iterate_simple method that provides a user friendly sequence of instructions:

from qat.lang.AQASM import *
prog = Program()
cbits = prog.calloc(4)
qbits = prog.qalloc(4)
for qb in qbits:
H(qb)
RX(prog.new_var(float, "a")).ctrl(3)(qbits)
CNOT(qbits[0], qbits[1])
prog.measure(qbits[1])
prog.reset([qbits[3]], [cbits[2]])

circuit = prog.to_circ()

for op in circuit.iterate_simple():
print(op)

('H', [], [0])
('H', [], [1])
('H', [], [2])
('H', [], [3])
('C-C-C-RX', [<qat.core.variables.Variable object at 0x152f9fbcda20>], [0, 1, 2, 3])
('CNOT', [], [0, 1])
('MEASURE', [1], [1])
('RESET', [3], [2])

bind_variable(v_name, v_value, gate_set=None)

Bind variable v_name with value v_value. Returns a fresh circuit. If binding the variable result in a gate becoming fully defined, its matrix will be regenerated using the default gate set of pyAQASM (or using a custom gate set).

..warning:

For performances reasons, this method does not fully copy the circuit. In particular, modifying some portions of the resulting circuit will have a side effect of the initial circuit. To avoid this behavior, feel free to deepcopy the circuit beforehand.

Parameters
• v_name (str) – the variable name

• v_value (any) – the value

• gate_set (optional, GateSet) – a gate set to use to generate the matrices for freshly bound gates

Returns

a quantum circuit

Return type

Circuit

bind_variables(v_dictionary, gate_set=None, **kwargs)

Iterates bind_variable() over a dictionary of (names, values).

Parameters
• v_dictionary (map<str,any>) – the variable names/values dictionary

• gate_set (optional, GateSet) – a gate set to use to generate the matrices for freshly bound gates. If not None, the current gate set will be updated and used to fill the matrices

Returns

a quantum circuit.

Return type

Circuit

count(gate)

Return the number of occurences of a given gate.

Parameters

gate (str) – a gate name

Returns

a gate count

Return type

int

dag(dagger_from_params=None, **kwargs)

Computes the dagger of a circuit. This function:

• crawls the gate dictionary and replace subgates by their dagger

• clears the implementations of these subgates (i.e their matrices, subcircuits, etc)

• reverts the list of instructions of the circuit

Raises
• TypeError if the circuit contains non-unitary instructions – (i.e classical operations, measurements, etc)

• ValueError if the circuit contains a gate with no proper – syntax, or if gate name is not in the dagger_from_params map.

Parameters
• dagger_from_params (dict, optional) – a dictionary that maps gate names to callable that, given a set of parameters, returns the new parameters that implement the dagger of the gate (see example below)

• kwargs – any additional keyword arguments are fed to a Linker in order to re-generate the various matrices and subcircuits.

Example:

By default, the default gate set of pyAQASM is fully supported:

from qat.core.linking.util import dagger_circuit
# Building a simple circuit
from qat.lang.AQASM import *

prog = Program()
qbits = prog.qalloc(2)
H(qbits[0])
PH(1.22)(qbits[1])
RY(3.9).ctrl()(qbits)
CNOT(qbits)
circuit = prog.to_circ()

print("Circuit dagger:")
for op in circuit.dag():
print(op)

Circuit dagger:
Op(gate='CNOT', qbits=[0, 1], type=0, cbits=None, formula=None, remap=None)
Op(gate='_2', qbits=[0, 1], type=0, cbits=None, formula=None, remap=None)
Op(gate='_0', qbits=[1], type=0, cbits=None, formula=None, remap=None)
Op(gate='H', qbits=[0], type=0, cbits=None, formula=None, remap=None)


If the circuit contains custom asbtract gate, one can specify a way to change their parameters in order to invert them. The following examples shows how to define a $$ZZ$$ rotation and specify that one needs to flip the sign of its angle in order to invert it.

from qat.core.linking.util import dagger_circuit
# Building a simple circuit
from qat.lang.AQASM import *

ZZ = AbstractGate("ZZ", [float], arity=2)

prog = Program()
qbits = prog.qalloc(2)
H(qbits[0])
CNOT(qbits)
ZZ(5.334)(qbits)
circuit = prog.to_circ()

# If nothing is specified, the function will raise a ValueError
try:
dagger = circuit.dag()
except ValueError as excp:
print(excp)

dagger_from_params = {
"ZZ": lambda params: [- params[0]],
}
print("Circuit dagger (smarter):")
for op in circuit.dag(dagger_from_params):
print(op)

Circuit dagger (smarter):
Op(gate='_0', qbits=[0, 1], type=0, cbits=None, formula=None, remap=None)
Op(gate='CNOT', qbits=[0, 1], type=0, cbits=None, formula=None, remap=None)
Op(gate='H', qbits=[0], type=0, cbits=None, formula=None, remap=None)

display(**kwargs)

Calls the :fun:qat.core.console.display method on the circuit.

Parameters

kwargs (dict) – arguments passed to :fun:qat.core.console.display

dump(fname)

Dumps the circuit in a binary file (.circ)

Parameters

fname (str) – the file name

static empty(nbqbits)

Generates an empty circuit

Parameters

nbqbits (int) – the number of qbits of the circuit

Returns

an empty circuit

Return type

Circuit

fill_matrices(gate_set, submatrices_only=True, include_default_gate_set=False)

Attaches matrices to gates according to the matrix generators in gate_set.

Parameters
• gate_set (GateSet) – a gate set specifying the matrix generators of the gates present in the circuit. Note that if some gate has no corresponding entry in the gate set or its signature has no matrix generator, no matrix will be attached to its definition.

• submatrices_only (bool) –

If set to True, only subgate will receive matrices. Default to True.

• include_default_gate_set (bool) – if set to True, the native gate set of pyAQASM will be included. Default to False.

classmethod from_thrift(tobject)

Builds a Circuit from a thrift circuit

property gate_set

The gate set used to generate the circuit

get_variables()

Returns the set of variables appearing in the circuit

insert_gate(position, gate, qbits, **kwargs)

Inserts a pyAQASM gate inside the circuit.

Parameters
• position (int) – index where to insert the gate

• gate (Gate) – a pyAQASM gate (or routine)

• qbits (list<int>) – a list of integers

• kwargs (dict) – all the keyword arguments are fed to the linker

iterate_simple(depth=None)

Iterates over the instructions of the circuit in a user friendly way.

The iterator yields tuples with explicit content. Each tuples starts with a keyword or a gate name, followed by the arguments of the instruction.

E.g, a measure of qubits 0 and 1 stored in cbits 2 and 3 would yield:

("MEASURE", [0, 1], [2, 3])


Loads a circuit from a binary (.circ) file.

Parameters

fname (str) – the file name

Returns

a circuit

Return type

Circuit

remove_locks()

Remove all lock/release placeholders of the circuit.

shift_qbits(offset)

Shift all the qbit indexes of the circuit by a given offset. Consequently increases the number of qbits by the same offset.

Acts in place.

Parameters

offset (int) – the offset

statistics()

Returns some statistics on the circuit.

The returned value is a dictionary with a very straightforward content.

Returns

a dictionary

Return type

dict

to_job(job_type='SAMPLE', qubits=None, nbshots=0, aggregate_data=True, amp_threshold=9.094947017729282e-13, **kwargs)

Generates a Job containing the circuit and some post processing information.

Parameters
• job_type (str) – possible values are “SAMPLE” for computational basis sampling of some qubits, or “OBS” for observable evaluation (see qat.core.Observable for more information about this mode).

• qubits (optional, list<int>, list<QRegister>) – the list of qubits to measure (in “SAMPLE” mode). If some quantum register is passed instead, all the qubits of the register will be measured. Moreover, if the register was “typed” (see qat.lang.AQASM.Program.qalloc() for more information), the results will be cast into the register type. Defaults to None, meaning all qubits are to be measured.

• nbshots (optional, int) – The number of shots to perform. Defaults to zero. If set to zero, the convention is that the QPU should do its best: a quantum processor will use the largest amount of shot authorized by its configuration, while a simulator will try to output all the possible states constained in the final distribution, together with their probabilities (and possible amplitudes).

• aggregate_data (optional, bool) – if set to True, and nbshots is not zero, the samples will be aggregated and their probability field will be used to store their observed frequencies of apparition. Defaults to True.

• amp_threshold (optional, double) – amplitude threshold under which states are not returned in the result structure. Useful to prune states that are unlikely to be measured out of the returned samples. Defaults to 1/2^40.

Keyword Arguments

observable (Observable) – see Observable. Used for the “OBS” mode only).

## Displaying circuits¶

Circuits could be displayed is a notebook or inside a terminal. To display a circuit in a terminal, you can use the function qat.core.console.display()

qat.core.console.display(circuit, max_depth=0, circuit_name=None, batchmode=False)

Displays a circuit on the terminal using ASCII art. By default, calls to sub-circuits are not inlined when displaying. You can display the content of a sub-circuit by increasing the maximal depth of inlining.

from qat.core.console import display
from qat.lang.AQASM import Program

# Define circuit
prog = Program()
qbits = prog.qalloc(5)
circ = prog.to_circ()

# Display circuit
display(circ)

display(circ, max_depth=1)

# Display full circuit
display(circ, max_depth=None)

Parameters
• circuit (Circuit) – displayed circuit

• max_depth (int, optional) – maximal depth of inlining (None is maximal)

• circuit_name (str, optional) – name of the circuit

• batchmode (bool, optional) – if this variable is set to True, this function will not wait for user input

Warning

Only GATETYPE operators can be visualized in a terminal. An exception is raised if your circuit contains measures, gates controlled classically, logic operators, …

The %qatdisplay magic can be used to display a circuit in a notebook or in an IPython terminal.

If myQLM Python magics has not been installed, please refer to the magic installation page to install this magic command

%qatdisplay circuit


## Hardware specifications¶

Hardware specifications are described by a the class HardwareSpecs

class qat.core.HardwareSpecs(**kwargs)

Simple higher level wrapper for the serializable HardwareSpecs class.

Instance attributes:
as_graph()

Returns a networkx.Graph object corresponding to the topology. This function calls the method to_nx() of the class Topology

from qat.devices import RIGETTI_ASPEN

# Cast the device into a networkx graph
nx_graph = RIGETTI_ASPEN.as_graph()

Returns

graph describing the topology of this hardware specs

Return type

networkx.Graph

as_quameleon()

Returns a QuameleonPlugin instance enforcing the device’s connectivity for easy inclusion in a QLM stack

from qat.devices import RIGETTI_ASPEN
from qat.qpus import get_default_qpu

# Create a stack
stack = RIGETTI_ASPEN.as_quameleon() | get_default_qpu()
print(stack)

QuameleonPlugin | PyLinalg

Returns

Quameleon plugin

Return type

QuameleonPlugin

dump(fname)

Dumps the HardwareSpecs inside a file in binary format.

Parameters

fname (str) – the file name

classmethod from_thrift(tobject)

Builds a HardwareSpecs object from a thrift object

Loads a HardwareSpecs from a file.

Parameters

fname (str) – the file name

Returns

HardwareSpecs

property nbqbits

Number of qubits composing the hardware

property topology

Topology of the hardware

class qat.core.Topology(is_directed=False, **kwargs)

Simple higher-level wrapper for the serializable Topology class.

Parameters
• topology (ThriftTopology, optional) – serializable object describing the topology

• is_directed (bool, optional) – set the topology directed or undirected (used if your topology is Custom). If your topology is undirected, any qubit of a pair is either a control or a target qubit, otherwise, only one qubit of the pair is the control qubit. The topology is, by default, undirected

• type (TopologyType, optional) – type of the topology (All to All, LNN or Custom)

• graph (dict<int, list<int>>, optional) – graph describing the topology (required iff the topology is Custom). Any key of this dictionary corresponds to the index of a control qubit and each linked value corresponds to indexes of qubits which can be target of this control qubit

Update connectivity between qubits. The topology will be set to CUSTOM (if needed). Use this method if a two qubits gate can be applied between qubits of indexes qb1 and qb2

Note

If your topology is directed, the first argument is the control qubit.

Parameters
• qb1 (int) – index of the first qubit

• qb2 (int) – index of the second qubit

dump(fname)

Dumps the Toplogy inside a file in binary format.

Parameters

fname (str) – the file name

static from_nx(nx_graph, vmap=None)

Builds a Topology object from a networkx Graph

Parameters
• nx_graph (networkx.Graph) – a networkx Graph

• vmap (optional, dict) – if set, the dictionary is update with a map that maps graph nodes to qubit indexes

classmethod from_thrift(tobject, init_none=False)

Builds a Topology object from a thrift topology object

Loads a Topology from a file.

Parameters

fname (str) – the file name

Returns

Topology

to_nx()

Cast the Topology object into a networkx graph.

Returns

a networkx graph

Return type

nx.Graph

class qat.core.TopologyType

This class is a enumeration describing the type of a Topology. Currently, there are three types of topologies:

All To All (ALL_TO_ALL)

This type describes topologies for which two-qubit gates can be applied on any pair of qubits

from qat.core import Topology, TopologyType

all_to_all = Topology(type=TopologyType.ALL_TO_ALL)


Linear (LNN)

This type describes topologies for which two-qubit gates can only be applied on qubits having consecutive indexes (i.e. a two-qubit gate can only be applied on the qubits of indexes $$i$$ and $$i \pm 1$$)

from qat.core import Topology, TopologyType

lnn = Topology(type=TopologyType.LNN)


Custom (CUSTOM)

This type describes a custom topology. Objects of type Topology having a custom topology type must have a graph

from qat.core import Topology, TopologyType

# Init topology
custom = Topology(type=TopologyType.CUSTOM)

# Graph definition


## Gate set and gate signatures¶

These classes are core classes hidden behind qat.lang.AQASM.gates.AbstractGate class.

class qat.core.gate_set.GateSignature(name, arg_types, arity=None, matrix_generator=None, circuit_generator=None)

GateSignatures describe gate constructors. They are defined via a constructor name and a list of argument types.

Parameters
• name (str) – the name of the gate

• arg_types (list<type>) – a list of python types describing the types of the arguments. Supported types are: int, float, str, np.matrix, np.ndarray, list.

• arity (int, optional) – the arity of the gate is known in advance

• matrix_generator (func, optional) – a function that generates the gates matrix when provided with a set of parameters

• circuit_generator (func, optional) – a function that generates a Circuit implementing the gate when provided with a set of parameters

get_circuit(*args)

Generates a circuit corresponding to a set of parameters.

Parameters

*args (list<Any>) – a list of parameters

get_matrix(*args)

Returns the matrix corresponding to a set of parameters.

Parameters

*args (list<Any>) – a list of parameters

set_circuit_generator(gen)

Sets the circuit generator.

Parameters

gen (fun) – a function that generates a Circuit given the appropriate parameters

set_matrix_generator(gen)

Sets the matrix generator.

Parameters

gen (fun) – a function that generates a numpy matrix given the appropriate parameters

class qat.core.gate_set.GateSet(dictio=None)

Gate sets represent collections of GateSignature.

Parameters

dictio (dict) – a (str, GateSignature) dictionary

Adds a new GateSignature in the GateSet. If the signature redefines a gate, a GateSyntaxRedefinition is raised.

Parameters

signa (GateSignature) – a gate signature

union(new_gate_set)

Compute the union of the gate set with another gate set

Parameters

new_gate_set (GateSet) – another gate set

Returns

the union of both gate sets

Return type

GateSet

class qat.core.gate_set.GateSyntaxRedefinition(name)

Exception raised when a GateSyntax is redefined in a GateSet

## Variables and expressions¶

When defining variational circuit, pyAQASM provides its own way to declare variables (via the qat.lang.AQASM.Program.new_var() method). However, it is possible to turn most parts of a Job into a parametrized quantity using qat.core.Variable objects.

class qat.core.Variable(name, var_type=<class 'float'>)

Class for typed variables. Variables can be used in any python arithmetic expression to build an ArithExpression object.

Parameters
• name (str) – the variable name

• var_type (type) – the variable type. Default to float.

Note

For now, the var_type argument is simply ignored.

Warning

Variable with names that can be cast to numerical values are forbidden.

differentiate(other_var)

Differentiate a variable w.r.t. a variable.

from qat.core import Variable
a, b = Variable("a"), Variable("b")
print(a.differentiate("a"))
print(a.differentiate("b"))

1
0

Parameters

other_var (str) – a variable name

Returns

either 0 or 1

Return type

numbers.Number

get_variables()

Returns a singleton containing the name of the variable .

to_thrift()

Generates a thrift RPN version of the expression. This is used to store the expression in a serializable format.

from qat.core import Variable
a, b = Variable("a"), Variable("b")
expr = a + b
print(expr)
print(expr.to_thrift())

(a + b)
+ a b

class qat.core.variables.ArithExpression(symbol, *children)

Class to represent arbitrary arithmetic expressions.

This class is not designed to be instantiated by hand. Expressions are constructed by calling a Symbol object on one or several variables.

Additionally, expressions (and variables) have their numeric operator overloaded (i.e +, -, etc).

from qat.core.variables import cos, Variable

a = Variable("a")
print(type(cos))
expr = cos(a)
print(type(expr))

<class 'qat.core.variables.Symbol'>
<class 'qat.core.variables.ArithExpression'>

Parameters
• symbol (Symbol) – the symbol labeling the node

• children (list) – the list of children of the node. These could be variables, expressions, or constants

differentiate(other_var)

Differentiate an expression w.r.t. to a variable.

from qat.core.variables import cos, Variable

a = Variable("a")
expr = a * cos(a)
print(expr.differentiate("a"))

((a * -(sin(a))) + cos(a))

Parameters

other_var (str) – a variable name

Returns

an arithmetic expression

Return type

ArithExpression

static from_string(thrift_string, var_dic=None)

Builds an arithmetic expression out of a RPN string.

Effectively the inverse of the to_thrift method.

from qat.core.variables import ArithExpression

expr = ArithExpression.from_string("+ a b")
print(expr)

(a + b)

Parameters
• thrift_string (str) – a RPN string

• var_dic (optional, dict) – a dictionary of variables as found in a Circuit

get_variables()

Returns the set of variables appearing inside the expression.

Returns

a set of variable indexes

Return type

set<int>

pretty_print(depth=0)

Pretty prints the expression for debugging (mostly)

to_thrift()

Generates a thrift RPN version of the expression.

See Variable method with the same name.

Returns

a string representation

Return type

str

It is possible to extend the set of symbols supported by this abstract expression mecanics by extending the list of a symbols with a new qat.core.variables.Symbol. The only constraint is that the new symbols should have a fixed arity that is known in advance.

class qat.core.variables.Symbol(token, evaluator, arity, infix=False, pretty_token=None, diff=None)

A simple structure to describe labels in the AST of an arithmetic expression.

A symbol requires:
• a token representing the symbol

• a proper python function that implements the symbol for numerical values

• an arity (i.e a number of arguments)

For instance, the cos symbol of this module is declared as follows, where the diff field can be omitted if one wouldn’t need differentiation:

from qat.core.variables import Symbol
import numpy as np
cos = Symbol("cos", np.cos, 1, diff=lambda x, dx: -sin(x) * dx)
print(cos)
print(type(cos))
print(cos(np.pi))

cos
<class 'qat.core.variables.Symbol'>
-1.0


Its __call__ operator is overloaded in order to behave as the underlying function for numeric values and to build an ArithExpression when called on abstract expressions or variables.

Parameters
• token (str) – the token corresponding to the symbol

• evaluator (callable) – the proper function underlying the symbol (i.e the semantic)

• arity (int) – the expected arguments of the symbol

• infix (bool) – If set to True, the symbol will be displayed in infix format (only allowed when arity=2). Defaults to False.

• pretty_token (optional, str) – If set, the pretty token will be used when displaying the symbol.

Defined symbols can be accessed via the ALL_SYMBOLS module variable:

from qat.core.variables import ALL_SYMBOLS

for token, symbol in ALL_SYMBOLS.items():
print(token, symbol.evaluator, symbol.arity)

+ <cyfunction <lambda> at 0x14598d56aa70> 2
* <cyfunction <lambda> at 0x14598d56ac00> 2
- <cyfunction <lambda> at 0x14598d56ad90> 2
UMINUS <cyfunction <lambda> at 0x14598d56af20> 1
/ <cyfunction <lambda> at 0x14598d579110> 2
** <cyfunction <lambda> at 0x14598d5792a0> 2
cos <ufunc 'cos'> 1
sin <ufunc 'sin'> 1
exp <ufunc 'exp'> 1
sqrt <ufunc 'sqrt'> 1
heaviside <cyfunction <lambda> at 0x14598d579750> 3
ln <ufunc 'log'> 1


For instance, the following piece of code adds a new symbol that represents the min between two numeric values.

from qat.core.variables import Variable, Symbol, ALL_SYMBOLS

# token will "min"
# underlying function is the standard min
# it has arity 2
# it is not an infix operator
my_min = Symbol("min", min, 2, infix=False)

# This step is necessary if we want to be able to bind variables in expressions containing min
ALL_SYMBOLS["min"] = my_min

a, b = Variable("a"), Variable("b")

expr = my_min(a, b)
print(expr)
print(expr(a=3))
print(expr(a=3, b=4))

min(a,b)
min(3,b)
3


Warning

If you create a Symbol in your environment, but choose to send it for evaluation to a remote QLM, the remote environment will not be aware of this new Symbol and the expression evaluation might fail.

## Various methods and tools¶

qat.core.formula_eval.evaluate(formula_str, tab)

Evaluate a logical formula stored in prefix format inside a string.

Parameters
• formula_str (str) – a string

• tab (list<bool>) – a list of values of the cbits

Returns

bool

qat.core.circuit_builder.matrix_util.get_predef_generator()

Returns a map of all the matrices of constant gates in the default gate set

qat.core.circuit_builder.matrix_util.get_param_generator()

Returns a map containing the 4 default parametrized gates generators

qat.core.circuit_builder.matrix_util.default_gate_set()

Generates a fresh default gate set

## Plugins & Junctions¶

class qat.plugins.Junction(collective=False)

Junctions are elements of a stack that allow for iterations inside a QLM stack. They implement the standard QPU interface (submit, submit_job, etc), but can be seen as some kind of iterative plugin that delegates execution of jobs to the lower part of the stack.

Junctions can be composed via the pipe operator to be included saemlessly into QLM stacks.

Parameters

collective (bool, optional) – if set to True, the .run method will receive the full batch. If set to False, .run will receive the jobs one by one. Defaults to False.

execute(qlm_object)

Executes a new Job or Batch back using the lower part of the stack.

Parameters

qlm_object (Job or Batch) – the qlm object to transmit down the stack

Returns

a Result structure corresponding to the transmitted Job or Batch

Return type
abstract run(initial_object, meta_data)

This function will be called upon the reception of a fresh abstract QLM object (e.g a Job or a Batch depending the Junction configuration)

Warning

This is an abstract method with no default implementation. You should build your own junction by inheriting from this class and implementing your own .run method.

Parameters
• qlm_object (Job or Batch) – the initial abstract QLM object. The type depends on the constructor parameter collective: if set to True, a Batch will be provided. If False, a Job.

• meta_data (dict) – the meta data of the initial batch. This is helpful to transmit arguments from the client to the Junction

Returns

this method should return a Result or BatchResult depending on the collective constructor parameter

Return type
class qat.plugins.Optimizer(collective=False, **binding_kwargs)

A particulized Junction that provides a higher level, QLM independant interface to perform variational optimization.

Instead of providing a .execute method, it provides a .evaluate method that takes a map of <variablename, value> and returns a float.

The administrative burden on binding the variables of the abstract job and fetching the result’s value is done by the class itself, under the hood.

Parameters
• collective (optional, bool) – see Junction class constructor arguments

• **binding_kwargs (dict) – a collection of arguments passed to the variable binding method of the job. E.g gate set, matrix generation parameters, etc.

evaluate(values)

Bind variables into the abstract job/batch, execute the job/batch and return the “value” field of the returned Result object or the sum of the result values if a BatchResult is returned.

Parameters

values (dict) – a dictionary of values (str, float)

Returns

a floating point number or a complex, depending on the structure of the Job

Return type

float or complex

abstract optimize(var_names)

This function will be called upon the reception of a fresh abstract QLM object (e.g a Job or a Batch depending the Junction configuration).

Upon reception of a fresh QLM object (Job, Batch), the object is stored in the self.job attribute, and this method is called with as single argument the list of all the variables appearing inside the object.

Warning

This is an abstract method with no default implementation. You should build your own optimizer by inheriting from this class and implementing your own .optimize method.

Parameters

var_names (list) – the list of variables to optimize upon

Returns

this method should return a triplet of values with:

• the optimal value found (this will correspond to the .value field in the final result object)

• the optimal values of the parameters (these will be stored in the meta_data using the “parameters” key in the final result object)

• any additional information (these will be also stored in the meta_data field using the “optimizer_data” key)

Return type

(float, list/np.ndarray, object)