cengines

The ProjectQ compiler engines package.

projectq.cengines._basicmapper

The parent class from which all mappers should be derived.

projectq.cengines._basics

Module containing the basic definition of a compiler engine.

projectq.cengines._cmdmodifier

A CommandModifier engine that can be used to apply a user-defined transformation to all incoming commands.

projectq.cengines._ibm5qubitmapper

Contains a compiler engine to map to the 5-qubit IBM chip.

projectq.cengines._linearmapper

Mapper for a quantum circuit to a linear chain of qubits.

projectq.cengines._main

The main engine of every compiler engine pipeline, called MainEngine.

projectq.cengines._manualmapper

A compiler engine to add mapping information.

projectq.cengines._optimize

A local optimizer engine.

projectq.cengines._replacer

projectq.cengines._swapandcnotflipper

A compiler engine which flips the directionality of CNOTs according to the given connectivity graph.

projectq.cengines._tagremover

The TagRemover compiler engine.

projectq.cengines._testengine

TestEngine and DummyEngine.

projectq.cengines._twodmapper

Mapper for a quantum circuit to a 2D square grid.

projectq.cengines.AutoReplacer(...[, ...])

A compiler engine to automatically replace certain commands.

projectq.cengines.BasicEngine()

Basic compiler engine: All compiler engines are derived from this class.

projectq.cengines.BasicMapperEngine()

Parent class for all Mappers.

projectq.cengines.CommandModifier(cmd_mod_fun)

Compiler engine applying a user-defined transformation to all incoming commands.

projectq.cengines.CompareEngine()

Command list comparison compiler engine for testing purposes.

projectq.cengines.DecompositionRule(...[, ...])

A rule for breaking down specific gates into sequences of simpler gates.

projectq.cengines.DecompositionRuleSet([...])

A collection of indexed decomposition rules.

projectq.cengines.DummyEngine([save_commands])

DummyEngine used for testing.

projectq.cengines.ForwarderEngine(engine[, ...])

A ForwarderEngine is a trivial engine which forwards all commands to the next engine.

projectq.cengines.GridMapper(num_rows, ...)

Mapper to a 2-D grid graph.

projectq.cengines.IBM5QubitMapper([connections])

Mapper for the 5-qubit IBM backend.

projectq.cengines.InstructionFilter(filterfun)

A compiler engine that implements a user-defined is_available() method.

projectq.cengines.LastEngineException(engine)

Exception thrown when the last engine tries to access the next one.

projectq.cengines.LinearMapper(num_qubits[, ...])

Map a quantum circuit to a linear chain of nearest neighbour interactions.

projectq.cengines.LocalOptimizer([cache_size, m])

Circuit optimization compiler engine.

projectq.cengines.MainEngine([backend, ...])

The MainEngine class provides all functionality of the main compiler engine.

projectq.cengines.ManualMapper([map_fun])

Manual Mapper which adds QubitPlacementTags to Allocate gate commands according to a user-specified mapping.

projectq.cengines.NotYetMeasuredError

Exception raised when trying to access the measurement value of a qubit that has not yet been measured.

projectq.cengines.return_swap_depth(swaps)

Return the circuit depth to execute these swaps.

projectq.cengines.SwapAndCNOTFlipper(...)

Flip CNOTs and translates Swaps to CNOTs where necessary.

projectq.cengines.TagRemover([tags])

Compiler engine that remove temporary command tags.

projectq.cengines.UnsupportedEngineError

Exception raised when a non-supported compiler engine is encountered.

Submodules

_basicmapper

The parent class from which all mappers should be derived.

There is only one engine currently allowed to be derived from BasicMapperEngine. This allows the simulator to automatically translate logical qubit ids to mapped ids.

class projectq.cengines._basicmapper.BasicMapperEngine[source]

Parent class for all Mappers.

self.current_mapping

Keys are the logical qubit ids and values are the mapped qubit ids.

Type

dict

property current_mapping[source]

Access the current mapping.

receive(command_list)[source]

Receive a list of commands.

This implementation simply forwards all commands to the next compiler engine while adjusting the qubit IDs of measurement gates.

_basics

Module containing the basic definition of a compiler engine.

class projectq.cengines._basics.BasicEngine[source]

Basic compiler engine: All compiler engines are derived from this class.

It provides basic functionality such as qubit allocation/deallocation and functions that provide information about the engine’s position (e.g., next engine).

This information is provided by the MainEngine, which initializes all further engines.

next_engine

Next compiler engine (or the back-end).

Type

BasicEngine

main_engine

Reference to the main compiler engine.

Type

MainEngine

is_last_engine

True for the last engine, which is the back-end.

Type

bool

allocate_qubit(dirty=False)[source]

Return a new qubit as a list containing 1 qubit object (quantum register of size 1).

Allocates a new qubit by getting a (new) qubit id from the MainEngine, creating the qubit object, and then sending an AllocateQubit command down the pipeline. If dirty=True, the fresh qubit can be replaced by a pre-allocated one (in an unknown, dirty, initial state). Dirty qubits must be returned to their initial states before they are deallocated / freed.

All allocated qubits are added to the MainEngine’s set of active qubits as weak references. This allows proper clean-up at the end of the Python program (using atexit), deallocating all qubits which are still alive. Qubit ids of dirty qubits are registered in MainEngine’s dirty_qubits set.

Parameters

dirty (bool) – If True, indicates that the allocated qubit may be dirty (i.e., in an arbitrary initial state).

Returns

Qureg of length 1, where the first entry is the allocated qubit.

allocate_qureg(n_qubits)[source]

Allocate n qubits and return them as a quantum register, which is a list of qubit objects.

Parameters

n (int) – Number of qubits to allocate

Returns

Qureg of length n, a list of n newly allocated qubits.

deallocate_qubit(qubit)[source]

Deallocate a qubit (and sends the deallocation command down the pipeline).

If the qubit was allocated as a dirty qubit, add DirtyQubitTag() to Deallocate command.

Parameters

qubit (BasicQubit) – Qubit to deallocate.

Raises

ValueError – Qubit already deallocated. Caller likely has a bug.

is_available(cmd)[source]

Test whether a Command is supported by a compiler engine.

Default implementation of is_available: Ask the next engine whether a command is available, i.e., whether it can be executed by the next engine(s).

Parameters

cmd (Command) – Command for which to check availability.

Returns

True if the command can be executed.

Raises

LastEngineException – If is_last_engine is True but is_available is not implemented.

is_meta_tag_supported(meta_tag)[source]

Check if there is a compiler engine handling the meta tag.

Parameters
  • engine – First engine to check (then iteratively calls getNextEngine)

  • meta_tag – Meta tag class for which to check support

Returns

True if one of the further compiler engines is a meta tag handler, i.e., engine.is_meta_tag_handler(meta_tag) returns True.

Return type

supported (bool)

send(command_list)[source]

Forward the list of commands to the next engine in the pipeline.

class projectq.cengines._basics.ForwarderEngine(engine, cmd_mod_fun=None)[source]

A ForwarderEngine is a trivial engine which forwards all commands to the next engine.

It is mainly used as a substitute for the MainEngine at lower levels such that meta operations still work (e.g., with Compute).

receive(command_list)[source]

Forward all commands to the next engine.

exception projectq.cengines._basics.LastEngineException(engine)[source]

Exception thrown when the last engine tries to access the next one. (Next engine does not exist).

The default implementation of isAvailable simply asks the next engine whether the command is available. An engine which legally may be the last engine, this behavior needs to be adapted (see BasicEngine.isAvailable).

_cmdmodifier

A CommandModifier engine that can be used to apply a user-defined transformation to all incoming commands.

A CommandModifier engine can be used to, e.g., modify the tags of all commands which pass by (see the AutoReplacer for an example).

class projectq.cengines._cmdmodifier.CommandModifier(cmd_mod_fun)[source]

Compiler engine applying a user-defined transformation to all incoming commands.

CommandModifier is a compiler engine which applies a function to all incoming commands, sending on the resulting command instead of the original one.

receive(command_list)[source]

Receive a list of commands.

Receive a list of commands from the previous engine, modify all commands, and send them on to the next engine.

Parameters

command_list (list<Command>) – List of commands to receive and then (after modification) send on.

_ibm5qubitmapper

Contains a compiler engine to map to the 5-qubit IBM chip.

class projectq.cengines._ibm5qubitmapper.IBM5QubitMapper(connections=None)[source]

Mapper for the 5-qubit IBM backend.

Maps a given circuit to the IBM Quantum Experience chip.

Note

The mapper has to be run once on the entire circuit.

Warning

If the provided circuit cannot be mapped to the hardware layout without performing Swaps, the mapping procedure raises an Exception.

is_available(cmd)[source]

Check if the IBM backend can perform the Command cmd and return True if so.

Parameters

cmd (Command) – The command to check

receive(command_list)[source]

Receive a list of commands.

Receive a command list and, for each command, stores it until completion.

Parameters

command_list (list of Command objects) – list of commands to receive.

Raises

Exception – If mapping the CNOT gates to 1 qubit would require Swaps. The current version only supports remapping of CNOT gates without performing any Swaps due to the large costs associated with Swapping given the CNOT constraints.

_linearmapper

Mapper for a quantum circuit to a linear chain of qubits.

Input: Quantum circuit with 1 and 2 qubit gates on n qubits. Gates are assumed to be applied in parallel if they act

on disjoint qubit(s) and any pair of qubits can perform a 2 qubit gate (all-to-all connectivity)

Output: Quantum circuit in which qubits are placed in 1-D chain in which only nearest neighbour qubits can perform a 2

qubit gate. The mapper uses Swap gates in order to move qubits next to each other.

class projectq.cengines._linearmapper.LinearMapper(num_qubits, cyclic=False, storage=1000)[source]

Map a quantum circuit to a linear chain of nearest neighbour interactions.

Maps a quantum circuit to a linear chain of qubits with nearest neighbour interactions using Swap gates. It supports open or cyclic boundary conditions.

current_mapping[source]

Stores the mapping: key is logical qubit id, value is mapped qubit id from 0,…,self.num_qubits

cyclic

If chain is cyclic or not

Type

Bool

storage

Number of gate it caches before mapping.

Type

int

num_mappings

Number of times the mapper changed the mapping

Type

int

depth_of_swaps

Key are circuit depth of swaps, value is the number of such mappings which have been applied

Type

dict

num_of_swaps_per_mapping

Key are the number of swaps per mapping, value is the number of such mappings which have been applied

Type

dict

Note

  1. Gates are cached and only mapped from time to time. A FastForwarding gate doesn’t empty the cache, only a FlushGate does.

  2. Only 1 and two qubit gates allowed.

  3. Does not optimize for dirty qubits.

is_available(cmd)[source]

Only allows 1 or two qubit gates.

receive(command_list)[source]

Receive a list of commands.

Receive a command list and, for each command, stores it until we do a mapping (FlushGate or Cache of stored commands is full).

Parameters

command_list (list of Command objects) – list of commands to receive.

static return_new_mapping(num_qubits, cyclic, currently_allocated_ids, stored_commands, current_mapping)[source]

Build a mapping of qubits to a linear chain.

It goes through stored_commands and tries to find a mapping to apply these gates on a first come first served basis. More compilicated scheme could try to optimize to apply as many gates as possible between the Swaps.

Parameters
  • num_qubits (int) – Total number of qubits in the linear chain

  • cyclic (bool) – If linear chain is a cycle.

  • currently_allocated_ids (set of int) – Logical qubit ids for which the Allocate gate has already been processed and sent to the next engine but which are not yet deallocated and hence need to be included in the new mapping.

  • stored_commands (list of Command objects) – Future commands which should be applied next.

  • current_mapping – A current mapping as a dict. key is logical qubit id, value is placement id. If there are different possible maps, this current mapping is used to minimize the swaps to go to the new mapping by a heuristic.

Returns: A new mapping as a dict. key is logical qubit id,

value is placement id

projectq.cengines._linearmapper.return_swap_depth(swaps)[source]

Return the circuit depth to execute these swaps.

Parameters

swaps (list of tuples) – Each tuple contains two integers representing the two IDs of the qubits involved in the Swap operation

Returns

Circuit depth to execute these swaps.

_main

The main engine of every compiler engine pipeline, called MainEngine.

class projectq.cengines._main.MainEngine(backend=None, engine_list=None, verbose=False)[source]

The MainEngine class provides all functionality of the main compiler engine.

It initializes all further compiler engines (calls, e.g., .next_engine=…) and keeps track of measurement results and active qubits (and their IDs).

next_engine

Next compiler engine (or the back-end).

Type

BasicEngine

main_engine

Self.

Type

MainEngine

active_qubits

WeakSet containing all active qubits

Type

WeakSet

dirty_qubits

Containing all dirty qubit ids

Type

Set

backend

Access the back-end.

Type

BasicEngine

mapper

Access to the mapper if there is one.

Type

BasicMapperEngine

n_engines

Current number of compiler engines in the engine list

Type

int

n_engines_max

Maximum number of compiler engines allowed in the engine list. Defaults to 100.

Type

int

flush(deallocate_qubits=False)[source]

Flush the entire circuit down the pipeline, clearing potential buffers (of, e.g., optimizers).

Parameters

deallocate_qubits (bool) – If True, deallocates all qubits that are still alive (invalidating references to them by setting their id to -1).

get_measurement_result(qubit)[source]

Return the classical value of a measured qubit, given that an engine registered this result previously.

See also setMeasurementResult.

Parameters

qubit (BasicQubit) – Qubit of which to get the measurement result.

Example

from projectq.ops import H, Measure
from projectq import MainEngine

eng = MainEngine()
qubit = eng.allocate_qubit()  # quantum register of size 1
H | qubit
Measure | qubit
eng.get_measurement_result(qubit[0]) == int(qubit)
get_new_qubit_id()[source]

Return a unique qubit id to be used for the next qubit allocation.

Returns

New unique qubit id.

Return type

new_qubit_id (int)

receive(command_list)[source]

Forward the list of commands to the first engine.

Parameters

command_list (list<Command>) – List of commands to receive (and then send on)

send(command_list)[source]

Forward the list of commands to the next engine in the pipeline.

It also shortens exception stack traces if self.verbose is False.

set_measurement_result(qubit, value)[source]

Register a measurement result.

The engine being responsible for measurement results needs to register these results with the master engine such that they are available when the user calls an int() or bool() conversion operator on a measured qubit.

Parameters
  • qubit (BasicQubit) – Qubit for which to register the measurement result.

  • value (bool) – Boolean value of the measurement outcome (True / False = 1 / 0 respectively).

exception projectq.cengines._main.NotYetMeasuredError[source]

Exception raised when trying to access the measurement value of a qubit that has not yet been measured.

exception projectq.cengines._main.UnsupportedEngineError[source]

Exception raised when a non-supported compiler engine is encountered.

_manualmapper

A compiler engine to add mapping information.

class projectq.cengines._manualmapper.ManualMapper(map_fun=<function ManualMapper.<lambda>>)[source]

Manual Mapper which adds QubitPlacementTags to Allocate gate commands according to a user-specified mapping.

map

The function which maps a given qubit id to its location. It gets set when initializing the mapper.

Type

function

receive(command_list)[source]

Receives a command list and passes it to the next engine, adding qubit placement tags to allocate gates.

Parameters

command_list (list of Command objects) – list of commands to receive.

_optimize

A local optimizer engine.

class projectq.cengines._optimize.LocalOptimizer(cache_size=5, m=None)[source]

Circuit optimization compiler engine.

LocalOptimizer is a compiler engine which optimizes locally (merging rotations, cancelling gates with their inverse) in a local window of user- defined size.

It stores all commands in a dict of lists, where each qubit has its own gate pipeline. After adding a gate, it tries to merge / cancel successive gates using the get_merged and get_inverse functions of the gate (if available). For examples, see BasicRotationGate. Once a list corresponding to a qubit contains >=m gates, the pipeline is sent on to the next engine.

receive(command_list)[source]

Receive a list of commands.

Receive commands from the previous engine and cache them. If a flush gate arrives, the entire buffer is sent on.

_replacer

_swapandcnotflipper

A compiler engine which flips the directionality of CNOTs according to the given connectivity graph.

It also translates Swap gates to CNOTs if necessary.

class projectq.cengines._swapandcnotflipper.SwapAndCNOTFlipper(connectivity)[source]

Flip CNOTs and translates Swaps to CNOTs where necessary.

Warning

This engine assumes that CNOT and Hadamard gates are supported by the following engines.

Warning

This engine cannot be used as a backend.

is_available(cmd)[source]

Check if the IBM backend can perform the Command cmd and return True if so.

Parameters

cmd (Command) – The command to check

receive(command_list)[source]

Receive a list of commands.

Receive a command list and if the command is a CNOT gate, it flips it using Hadamard gates if necessary; if it is a Swap gate, it decomposes it using 3 CNOTs. All other gates are simply sent to the next engine.

Parameters

command_list (list of Command objects) – list of commands to receive.

_tagremover

The TagRemover compiler engine.

A TagRemover engine removes temporary command tags (such as Compute/Uncompute), thus enabling optimization across meta statements (loops after unrolling, compute/uncompute, …)

class projectq.cengines._tagremover.TagRemover(tags=None)[source]

Compiler engine that remove temporary command tags.

TagRemover is a compiler engine which removes temporary command tags (see the tag classes such as LoopTag in projectq.meta._loop).

Removing tags is important (after having handled them if necessary) in order to enable optimizations across meta-function boundaries (compute/ action/uncompute or loops after unrolling)

receive(command_list)[source]

Receive a list of commands.

Receive a list of commands from the previous engine, remove all tags which are an instance of at least one of the meta tags provided in the constructor, and then send them on to the next compiler engine.

Parameters

command_list (list<Command>) – List of commands to receive and then (after removing tags) send on.

_testengine

TestEngine and DummyEngine.

class projectq.cengines._testengine.CompareEngine[source]

Command list comparison compiler engine for testing purposes.

CompareEngine is an engine which saves all commands. It is only intended for testing purposes. Two CompareEngine backends can be compared and return True if they contain the same commmands.

cache_cmd(cmd)[source]

Cache a command.

is_available(cmd)[source]

All commands are accepted by this compiler engine.

receive(command_list)[source]

Receive a list of commands.

Receive a command list and, for each command, stores it inside the cache before sending it to the next compiler engine.

Parameters

command_list (list of Command objects) – list of commands to receive.

class projectq.cengines._testengine.DummyEngine(save_commands=False)[source]

DummyEngine used for testing.

The DummyEngine forwards all commands directly to next engine. If self.is_last_engine == True it just discards all gates. By setting save_commands == True all commands get saved as a list in self.received_commands. Elements are appended to this list so they are ordered according to when they are received.

is_available(cmd)[source]

All commands are accepted by this compiler engine.

receive(command_list)[source]

Receive a list of commands.

Receive a command list and, for each command, stores it internally if requested before sending it to the next compiler engine.

Parameters

command_list (list of Command objects) – list of commands to receive.

_twodmapper

Mapper for a quantum circuit to a 2D square grid.

Input: Quantum circuit with 1 and 2 qubit gates on n qubits. Gates are assumed to be applied in parallel if they act

on disjoint qubit(s) and any pair of qubits can perform a 2 qubit gate (all-to-all connectivity)

Output: Quantum circuit in which qubits are placed in 2-D square grid in which only nearest neighbour qubits can

perform a 2 qubit gate. The mapper uses Swap gates in order to move qubits next to each other.

class projectq.cengines._twodmapper.GridMapper(num_rows, num_columns, mapped_ids_to_backend_ids=None, storage=1000, optimization_function=<function return_swap_depth>, num_optimization_steps=50)[source]

Mapper to a 2-D grid graph.

Mapped qubits on the grid are numbered in row-major order. E.g. for 3 rows and 2 columns:

0 - 1 | | 2 - 3 | | 4 - 5

The numbers are the mapped qubit ids. The backend might number the qubits on the grid differently (e.g. not row-major), we call these backend qubit ids. If the backend qubit ids are not row-major, one can pass a dictionary translating from our row-major mapped ids to these backend ids.

Note: The algorithm sorts twice inside each column and once inside each row.

current_mapping[source]

Stores the mapping: key is logical qubit id, value is backend qubit id.

storage

Number of gate it caches before mapping.

Type

int

num_rows

Number of rows in the grid

Type

int

num_columns

Number of columns in the grid

Type

int

num_qubits

num_rows x num_columns = number of qubits

Type

int

num_mappings

Number of times the mapper changed the mapping

Type

int

depth_of_swaps

Key are circuit depth of swaps, value is the number of such mappings which have been applied

Type

dict

num_of_swaps_per_mapping

Key are the number of swaps per mapping, value is the number of such mappings which have been applied

Type

dict

property current_mapping[source]

Access to the mapping stored inside the mapper engine.

is_available(cmd)[source]

Only allow 1 or two qubit gates.

receive(command_list)[source]

Receive a list of commands.

Receive a command list and, for each command, stores it until we do a mapping (FlushGate or Cache of stored commands is full).

Parameters

command_list (list of Command objects) – list of commands to receive.

return_swaps(old_mapping, new_mapping, permutation=None)[source]

Return the swap operation to change mapping.

Parameters
  • old_mapping – dict: keys are logical ids and values are mapped qubit ids

  • new_mapping – dict: keys are logical ids and values are mapped qubit ids

  • permutation – list of int from 0, 1, …, self.num_rows-1. It is used to permute the found perfect matchings. Default is None which keeps the original order.

Returns

List of tuples. Each tuple is a swap operation which needs to be applied. Tuple contains the two mapped qubit ids for the Swap.

Module contents

ProjectQ module containing all compiler engines.

class projectq.cengines.AutoReplacer(decomposition_rule_se, decomposition_chooser=<function AutoReplacer.<lambda>>)[source]

A compiler engine to automatically replace certain commands.

The AutoReplacer is a compiler engine which uses engine.is_available in order to determine which commands need to be replaced/decomposed/compiled further. The loaded setup is used to find decomposition rules appropriate for each command (e.g., setups.default).

__init__(decomposition_rule_se, decomposition_chooser=<function AutoReplacer.<lambda>>)[source]

Initialize an AutoReplacer.

Parameters

decomposition_chooser (function) – A function which, given the Command to decompose and a list of potential Decomposition objects, determines (and then returns) the ‘best’ decomposition.

The default decomposition chooser simply returns the first list element, i.e., calling

repl = AutoReplacer()

Amounts to

def decomposition_chooser(cmd, decomp_list):
    return decomp_list[0]


repl = AutoReplacer(decomposition_chooser)
receive(command_list)[source]

Receive a list of commands.

Receive a list of commands from the previous compiler engine and, if necessary, replace/decompose the gates according to the decomposition rules in the loaded setup.

Parameters

command_list (list<Command>) – List of commands to handle.

class projectq.cengines.BasicEngine[source]

Basic compiler engine: All compiler engines are derived from this class.

It provides basic functionality such as qubit allocation/deallocation and functions that provide information about the engine’s position (e.g., next engine).

This information is provided by the MainEngine, which initializes all further engines.

next_engine

Next compiler engine (or the back-end).

Type

BasicEngine

main_engine

Reference to the main compiler engine.

Type

MainEngine

is_last_engine

True for the last engine, which is the back-end.

Type

bool

__init__()[source]

Initialize the basic engine.

Initializes local variables such as _next_engine, _main_engine, etc. to None.

allocate_qubit(dirty=False)[source]

Return a new qubit as a list containing 1 qubit object (quantum register of size 1).

Allocates a new qubit by getting a (new) qubit id from the MainEngine, creating the qubit object, and then sending an AllocateQubit command down the pipeline. If dirty=True, the fresh qubit can be replaced by a pre-allocated one (in an unknown, dirty, initial state). Dirty qubits must be returned to their initial states before they are deallocated / freed.

All allocated qubits are added to the MainEngine’s set of active qubits as weak references. This allows proper clean-up at the end of the Python program (using atexit), deallocating all qubits which are still alive. Qubit ids of dirty qubits are registered in MainEngine’s dirty_qubits set.

Parameters

dirty (bool) – If True, indicates that the allocated qubit may be dirty (i.e., in an arbitrary initial state).

Returns

Qureg of length 1, where the first entry is the allocated qubit.

allocate_qureg(n_qubits)[source]

Allocate n qubits and return them as a quantum register, which is a list of qubit objects.

Parameters

n (int) – Number of qubits to allocate

Returns

Qureg of length n, a list of n newly allocated qubits.

deallocate_qubit(qubit)[source]

Deallocate a qubit (and sends the deallocation command down the pipeline).

If the qubit was allocated as a dirty qubit, add DirtyQubitTag() to Deallocate command.

Parameters

qubit (BasicQubit) – Qubit to deallocate.

Raises

ValueError – Qubit already deallocated. Caller likely has a bug.

is_available(cmd)[source]

Test whether a Command is supported by a compiler engine.

Default implementation of is_available: Ask the next engine whether a command is available, i.e., whether it can be executed by the next engine(s).

Parameters

cmd (Command) – Command for which to check availability.

Returns

True if the command can be executed.

Raises

LastEngineException – If is_last_engine is True but is_available is not implemented.

is_meta_tag_supported(meta_tag)[source]

Check if there is a compiler engine handling the meta tag.

Parameters
  • engine – First engine to check (then iteratively calls getNextEngine)

  • meta_tag – Meta tag class for which to check support

Returns

True if one of the further compiler engines is a meta tag handler, i.e., engine.is_meta_tag_handler(meta_tag) returns True.

Return type

supported (bool)

send(command_list)[source]

Forward the list of commands to the next engine in the pipeline.

class projectq.cengines.BasicMapperEngine[source]

Parent class for all Mappers.

self.current_mapping

Keys are the logical qubit ids and values are the mapped qubit ids.

Type

dict

__init__()[source]

Initialize a BasicMapperEngine object.

property current_mapping[source]

Access the current mapping.

receive(command_list)[source]

Receive a list of commands.

This implementation simply forwards all commands to the next compiler engine while adjusting the qubit IDs of measurement gates.

class projectq.cengines.CommandModifier(cmd_mod_fun)[source]

Compiler engine applying a user-defined transformation to all incoming commands.

CommandModifier is a compiler engine which applies a function to all incoming commands, sending on the resulting command instead of the original one.

__init__(cmd_mod_fun)[source]

Initialize the CommandModifier.

Parameters

cmd_mod_fun (function) – Function which, given a command cmd, returns the command it should send instead.

Example

def cmd_mod_fun(cmd):
    cmd.tags += [MyOwnTag()]


compiler_engine = CommandModifier(cmd_mod_fun)
...
receive(command_list)[source]

Receive a list of commands.

Receive a list of commands from the previous engine, modify all commands, and send them on to the next engine.

Parameters

command_list (list<Command>) – List of commands to receive and then (after modification) send on.

class projectq.cengines.CompareEngine[source]

Command list comparison compiler engine for testing purposes.

CompareEngine is an engine which saves all commands. It is only intended for testing purposes. Two CompareEngine backends can be compared and return True if they contain the same commmands.

__init__()[source]

Initialize a CompareEngine object.

cache_cmd(cmd)[source]

Cache a command.

is_available(cmd)[source]

All commands are accepted by this compiler engine.

receive(command_list)[source]

Receive a list of commands.

Receive a command list and, for each command, stores it inside the cache before sending it to the next compiler engine.

Parameters

command_list (list of Command objects) – list of commands to receive.

class projectq.cengines.DecompositionRule(gate_class, gate_decomposer, gate_recognizer=<function DecompositionRule.<lambda>>)[source]

A rule for breaking down specific gates into sequences of simpler gates.

__init__(gate_class, gate_decomposer, gate_recognizer=<function DecompositionRule.<lambda>>)[source]

Initialize a DecompositionRule object.

Parameters
  • gate_class (type) –

    The type of gate that this rule decomposes.

    The gate class is redundant information used to make lookups faster when iterating over a circuit and deciding “which rules apply to this gate?” again and again.

    Note that this parameter is a gate type, not a gate instance. You supply gate_class=MyGate or gate_class=MyGate().__class__, not gate_class=MyGate().

  • gate_decomposer (function[projectq.ops.Command]) – Function which, given the command to decompose, applies a sequence of gates corresponding to the high-level function of a gate of type gate_class.

  • (function[projectq.ops.Command] (gate_recognizer) –

    boolean): A predicate that determines if the decomposition applies to the given command (on top of the filtering by gate_class).

    For example, a decomposition rule may only to apply rotation gates that rotate by a specific angle.

    If no gate_recognizer is given, the decomposition applies to all gates matching the gate_class.

class projectq.cengines.DecompositionRuleSet(rules=None, modules=None)[source]

A collection of indexed decomposition rules.

__init__(rules=None, modules=None)[source]

Initialize a DecompositionRuleSet object.

Parameters
  • list[DecompositionRule] (rules) – Initial decomposition rules.

  • modules (iterable[ModuleWithDecompositionRuleSet]) – A list of things with an “all_defined_decomposition_rules” property containing decomposition rules to add to the rule set.

add_decomposition_rule(rule)[source]

Add a decomposition rule to the rule set.

Parameters

rule (DecompositionRuleGate) – The decomposition rule to add.

add_decomposition_rules(rules)[source]

Add some decomposition rules to a decomposition rule set.

class projectq.cengines.DummyEngine(save_commands=False)[source]

DummyEngine used for testing.

The DummyEngine forwards all commands directly to next engine. If self.is_last_engine == True it just discards all gates. By setting save_commands == True all commands get saved as a list in self.received_commands. Elements are appended to this list so they are ordered according to when they are received.

__init__(save_commands=False)[source]

Initialize a DummyEngine.

Parameters

save_commands (default = False) – If True, commands are saved in self.received_commands.

is_available(cmd)[source]

All commands are accepted by this compiler engine.

receive(command_list)[source]

Receive a list of commands.

Receive a command list and, for each command, stores it internally if requested before sending it to the next compiler engine.

Parameters

command_list (list of Command objects) – list of commands to receive.

class projectq.cengines.ForwarderEngine(engine, cmd_mod_fun=None)[source]

A ForwarderEngine is a trivial engine which forwards all commands to the next engine.

It is mainly used as a substitute for the MainEngine at lower levels such that meta operations still work (e.g., with Compute).

__init__(engine, cmd_mod_fun=None)[source]

Initialize a ForwarderEngine.

Parameters
  • engine (BasicEngine) – Engine to forward all commands to.

  • cmd_mod_fun (function) – Function which is called before sending a command. Each command cmd is replaced by the command it returns when getting called with cmd.

receive(command_list)[source]

Forward all commands to the next engine.

class projectq.cengines.GridMapper(num_rows, num_columns, mapped_ids_to_backend_ids=None, storage=1000, optimization_function=<function return_swap_depth>, num_optimization_steps=50)[source]

Mapper to a 2-D grid graph.

Mapped qubits on the grid are numbered in row-major order. E.g. for 3 rows and 2 columns:

0 - 1 | | 2 - 3 | | 4 - 5

The numbers are the mapped qubit ids. The backend might number the qubits on the grid differently (e.g. not row-major), we call these backend qubit ids. If the backend qubit ids are not row-major, one can pass a dictionary translating from our row-major mapped ids to these backend ids.

Note: The algorithm sorts twice inside each column and once inside each row.

current_mapping[source]

Stores the mapping: key is logical qubit id, value is backend qubit id.

storage

Number of gate it caches before mapping.

Type

int

num_rows

Number of rows in the grid

Type

int

num_columns

Number of columns in the grid

Type

int

num_qubits

num_rows x num_columns = number of qubits

Type

int

num_mappings

Number of times the mapper changed the mapping

Type

int

depth_of_swaps

Key are circuit depth of swaps, value is the number of such mappings which have been applied

Type

dict

num_of_swaps_per_mapping

Key are the number of swaps per mapping, value is the number of such mappings which have been applied

Type

dict

__init__(num_rows, num_columns, mapped_ids_to_backend_ids=None, storage=1000, optimization_function=<function return_swap_depth>, num_optimization_steps=50)[source]

Initialize a GridMapper compiler engine.

Parameters
  • num_rows (int) – Number of rows in the grid

  • num_columns (int) – Number of columns in the grid.

  • mapped_ids_to_backend_ids (dict) – Stores a mapping from mapped ids which are 0,…,self.num_qubits-1 in row-major order on the grid to the corresponding qubit ids of the backend. Key: mapped id. Value: corresponding backend id. Default is None which means backend ids are identical to mapped ids.

  • storage – Number of gates to temporarily store

  • optimization_function – Function which takes a list of swaps and returns a cost value. Mapper chooses a permutation which minimizes this cost. Default optimizes for circuit depth.

  • num_optimization_steps (int) – Number of different permutations to of the matching to try and minimize the cost.

Raises

RuntimeError – if incorrect mapped_ids_to_backend_ids parameter

property current_mapping[source]

Access to the mapping stored inside the mapper engine.

is_available(cmd)[source]

Only allow 1 or two qubit gates.

receive(command_list)[source]

Receive a list of commands.

Receive a command list and, for each command, stores it until we do a mapping (FlushGate or Cache of stored commands is full).

Parameters

command_list (list of Command objects) – list of commands to receive.

return_swaps(old_mapping, new_mapping, permutation=None)[source]

Return the swap operation to change mapping.

Parameters
  • old_mapping – dict: keys are logical ids and values are mapped qubit ids

  • new_mapping – dict: keys are logical ids and values are mapped qubit ids

  • permutation – list of int from 0, 1, …, self.num_rows-1. It is used to permute the found perfect matchings. Default is None which keeps the original order.

Returns

List of tuples. Each tuple is a swap operation which needs to be applied. Tuple contains the two mapped qubit ids for the Swap.

class projectq.cengines.IBM5QubitMapper(connections=None)[source]

Mapper for the 5-qubit IBM backend.

Maps a given circuit to the IBM Quantum Experience chip.

Note

The mapper has to be run once on the entire circuit.

Warning

If the provided circuit cannot be mapped to the hardware layout without performing Swaps, the mapping procedure raises an Exception.

__init__(connections=None)[source]

Initialize an IBM 5-qubit mapper compiler engine.

Resets the mapping.

is_available(cmd)[source]

Check if the IBM backend can perform the Command cmd and return True if so.

Parameters

cmd (Command) – The command to check

receive(command_list)[source]

Receive a list of commands.

Receive a command list and, for each command, stores it until completion.

Parameters

command_list (list of Command objects) – list of commands to receive.

Raises

Exception – If mapping the CNOT gates to 1 qubit would require Swaps. The current version only supports remapping of CNOT gates without performing any Swaps due to the large costs associated with Swapping given the CNOT constraints.

class projectq.cengines.InstructionFilter(filterfun)[source]

A compiler engine that implements a user-defined is_available() method.

The InstructionFilter is a compiler engine which changes the behavior of is_available according to a filter function. All commands are passed to this function, which then returns whether this command can be executed (True) or needs replacement (False).

__init__(filterfun)[source]

Initialize an InstructionFilter object.

Initializer: The provided filterfun returns True for all commands which do not need replacement and False for commands that do.

Parameters

filterfun (function) – Filter function which returns True for available commands, and False otherwise. filterfun will be called as filterfun(self, cmd).

is_available(cmd)[source]

Test whether a Command is supported by a compiler engine.

Specialized implementation of BasicBackend.is_available: Forwards this call to the filter function given to the constructor.

Parameters

cmd (Command) – Command for which to check availability.

receive(command_list)[source]

Receive a list of commands.

This implementation simply forwards all commands to the next engine.

Parameters

command_list (list<Command>) – List of commands to receive.

exception projectq.cengines.LastEngineException(engine)[source]

Exception thrown when the last engine tries to access the next one. (Next engine does not exist).

The default implementation of isAvailable simply asks the next engine whether the command is available. An engine which legally may be the last engine, this behavior needs to be adapted (see BasicEngine.isAvailable).

__init__(engine)[source]

Initialize the exception.

class projectq.cengines.LinearMapper(num_qubits, cyclic=False, storage=1000)[source]

Map a quantum circuit to a linear chain of nearest neighbour interactions.

Maps a quantum circuit to a linear chain of qubits with nearest neighbour interactions using Swap gates. It supports open or cyclic boundary conditions.

current_mapping[source]

Stores the mapping: key is logical qubit id, value is mapped qubit id from 0,…,self.num_qubits

cyclic

If chain is cyclic or not

Type

Bool

storage

Number of gate it caches before mapping.

Type

int

num_mappings

Number of times the mapper changed the mapping

Type

int

depth_of_swaps

Key are circuit depth of swaps, value is the number of such mappings which have been applied

Type

dict

num_of_swaps_per_mapping

Key are the number of swaps per mapping, value is the number of such mappings which have been applied

Type

dict

Note

  1. Gates are cached and only mapped from time to time. A FastForwarding gate doesn’t empty the cache, only a FlushGate does.

  2. Only 1 and two qubit gates allowed.

  3. Does not optimize for dirty qubits.

__init__(num_qubits, cyclic=False, storage=1000)[source]

Initialize a LinearMapper compiler engine.

Parameters
  • num_qubits (int) – Number of physical qubits in the linear chain

  • cyclic (bool) – If 1D chain is a cycle. Default is False.

  • storage (int) – Number of gates to temporarily store, default is 1000

is_available(cmd)[source]

Only allows 1 or two qubit gates.

receive(command_list)[source]

Receive a list of commands.

Receive a command list and, for each command, stores it until we do a mapping (FlushGate or Cache of stored commands is full).

Parameters

command_list (list of Command objects) – list of commands to receive.

static return_new_mapping(num_qubits, cyclic, currently_allocated_ids, stored_commands, current_mapping)[source]

Build a mapping of qubits to a linear chain.

It goes through stored_commands and tries to find a mapping to apply these gates on a first come first served basis. More compilicated scheme could try to optimize to apply as many gates as possible between the Swaps.

Parameters
  • num_qubits (int) – Total number of qubits in the linear chain

  • cyclic (bool) – If linear chain is a cycle.

  • currently_allocated_ids (set of int) – Logical qubit ids for which the Allocate gate has already been processed and sent to the next engine but which are not yet deallocated and hence need to be included in the new mapping.

  • stored_commands (list of Command objects) – Future commands which should be applied next.

  • current_mapping – A current mapping as a dict. key is logical qubit id, value is placement id. If there are different possible maps, this current mapping is used to minimize the swaps to go to the new mapping by a heuristic.

Returns: A new mapping as a dict. key is logical qubit id,

value is placement id

class projectq.cengines.LocalOptimizer(cache_size=5, m=None)[source]

Circuit optimization compiler engine.

LocalOptimizer is a compiler engine which optimizes locally (merging rotations, cancelling gates with their inverse) in a local window of user- defined size.

It stores all commands in a dict of lists, where each qubit has its own gate pipeline. After adding a gate, it tries to merge / cancel successive gates using the get_merged and get_inverse functions of the gate (if available). For examples, see BasicRotationGate. Once a list corresponding to a qubit contains >=m gates, the pipeline is sent on to the next engine.

__init__(cache_size=5, m=None)[source]

Initialize a LocalOptimizer object.

Parameters

cache_size (int) – Number of gates to cache per qubit, before sending on the first gate.

receive(command_list)[source]

Receive a list of commands.

Receive commands from the previous engine and cache them. If a flush gate arrives, the entire buffer is sent on.

class projectq.cengines.MainEngine(backend=None, engine_list=None, verbose=False)[source]

The MainEngine class provides all functionality of the main compiler engine.

It initializes all further compiler engines (calls, e.g., .next_engine=…) and keeps track of measurement results and active qubits (and their IDs).

next_engine

Next compiler engine (or the back-end).

Type

BasicEngine

main_engine

Self.

Type

MainEngine

active_qubits

WeakSet containing all active qubits

Type

WeakSet

dirty_qubits

Containing all dirty qubit ids

Type

Set

backend

Access the back-end.

Type

BasicEngine

mapper

Access to the mapper if there is one.

Type

BasicMapperEngine

n_engines

Current number of compiler engines in the engine list

Type

int

n_engines_max

Maximum number of compiler engines allowed in the engine list. Defaults to 100.

Type

int

__init__(backend=None, engine_list=None, verbose=False)[source]

Initialize the main compiler engine and all compiler engines.

Sets ‘next_engine’- and ‘main_engine’-attributes of all compiler engines and adds the back-end as the last engine.

Parameters
  • backend (BasicEngine) – Backend to send the compiled circuit to.

  • engine_list (list<BasicEngine>) – List of engines / backends to use as compiler engines. Note: The engine list must not contain multiple mappers (instances of BasicMapperEngine). Default: projectq.setups.default.get_engine_list()

  • verbose (bool) – Either print full or compact error messages. Default: False (i.e. compact error messages).

Example

from projectq import MainEngine

eng = MainEngine()  # uses default engine_list and the Simulator

Instead of the default engine_list one can use, e.g., one of the IBM setups which defines a custom engine_list useful for one of the IBM chips

Example

import projectq.setups.ibm as ibm_setup
from projectq import MainEngine

eng = MainEngine(engine_list=ibm_setup.get_engine_list())
# eng uses the default Simulator backend

Alternatively, one can specify all compiler engines explicitly, e.g.,

Example

from projectq.cengines import (
    TagRemover,
    AutoReplacer,
    LocalOptimizer,
    DecompositionRuleSet,
)
from projectq.backends import Simulator
from projectq import MainEngine

rule_set = DecompositionRuleSet()
engines = [AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3)]
eng = MainEngine(Simulator(), engines)
flush(deallocate_qubits=False)[source]

Flush the entire circuit down the pipeline, clearing potential buffers (of, e.g., optimizers).

Parameters

deallocate_qubits (bool) – If True, deallocates all qubits that are still alive (invalidating references to them by setting their id to -1).

get_measurement_result(qubit)[source]

Return the classical value of a measured qubit, given that an engine registered this result previously.

See also setMeasurementResult.

Parameters

qubit (BasicQubit) – Qubit of which to get the measurement result.

Example

from projectq.ops import H, Measure
from projectq import MainEngine

eng = MainEngine()
qubit = eng.allocate_qubit()  # quantum register of size 1
H | qubit
Measure | qubit
eng.get_measurement_result(qubit[0]) == int(qubit)
get_new_qubit_id()[source]

Return a unique qubit id to be used for the next qubit allocation.

Returns

New unique qubit id.

Return type

new_qubit_id (int)

receive(command_list)[source]

Forward the list of commands to the first engine.

Parameters

command_list (list<Command>) – List of commands to receive (and then send on)

send(command_list)[source]

Forward the list of commands to the next engine in the pipeline.

It also shortens exception stack traces if self.verbose is False.

set_measurement_result(qubit, value)[source]

Register a measurement result.

The engine being responsible for measurement results needs to register these results with the master engine such that they are available when the user calls an int() or bool() conversion operator on a measured qubit.

Parameters
  • qubit (BasicQubit) – Qubit for which to register the measurement result.

  • value (bool) – Boolean value of the measurement outcome (True / False = 1 / 0 respectively).

class projectq.cengines.ManualMapper(map_fun=<function ManualMapper.<lambda>>)[source]

Manual Mapper which adds QubitPlacementTags to Allocate gate commands according to a user-specified mapping.

map

The function which maps a given qubit id to its location. It gets set when initializing the mapper.

Type

function

__init__(map_fun=<function ManualMapper.<lambda>>)[source]

Initialize the mapper to a given mapping.

If no mapping function is provided, the qubit id is used as the location.

Parameters

map_fun (function) – Function which, given the qubit id, returns an integer describing the physical location (must be constant).

receive(command_list)[source]

Receives a command list and passes it to the next engine, adding qubit placement tags to allocate gates.

Parameters

command_list (list of Command objects) – list of commands to receive.

exception projectq.cengines.NotYetMeasuredError[source]

Exception raised when trying to access the measurement value of a qubit that has not yet been measured.

class projectq.cengines.SwapAndCNOTFlipper(connectivity)[source]

Flip CNOTs and translates Swaps to CNOTs where necessary.

Warning

This engine assumes that CNOT and Hadamard gates are supported by the following engines.

Warning

This engine cannot be used as a backend.

__init__(connectivity)[source]

Initialize the engine.

Parameters

connectivity (set) – Set of tuples (c, t) where if (c, t) is an element of the set means that a CNOT can be performed between the physical ids (c, t) with c being the control and t being the target qubit.

is_available(cmd)[source]

Check if the IBM backend can perform the Command cmd and return True if so.

Parameters

cmd (Command) – The command to check

receive(command_list)[source]

Receive a list of commands.

Receive a command list and if the command is a CNOT gate, it flips it using Hadamard gates if necessary; if it is a Swap gate, it decomposes it using 3 CNOTs. All other gates are simply sent to the next engine.

Parameters

command_list (list of Command objects) – list of commands to receive.

class projectq.cengines.TagRemover(tags=None)[source]

Compiler engine that remove temporary command tags.

TagRemover is a compiler engine which removes temporary command tags (see the tag classes such as LoopTag in projectq.meta._loop).

Removing tags is important (after having handled them if necessary) in order to enable optimizations across meta-function boundaries (compute/ action/uncompute or loops after unrolling)

__init__(tags=None)[source]

Initialize a TagRemover object.

Parameters

tags – A list of meta tag classes (e.g., [ComputeTag, UncomputeTag]) denoting the tags to remove

receive(command_list)[source]

Receive a list of commands.

Receive a list of commands from the previous engine, remove all tags which are an instance of at least one of the meta tags provided in the constructor, and then send them on to the next compiler engine.

Parameters

command_list (list<Command>) – List of commands to receive and then (after removing tags) send on.

exception projectq.cengines.UnsupportedEngineError[source]

Exception raised when a non-supported compiler engine is encountered.

projectq.cengines.return_swap_depth(swaps)[source]

Return the circuit depth to execute these swaps.

Parameters

swaps (list of tuples) – Each tuple contains two integers representing the two IDs of the qubits involved in the Swap operation

Returns

Circuit depth to execute these swaps.