meta¶
Contains meta statements which allow more optimal code while making it easier for users to write their code. Examples are with Compute, followed by an automatic uncompute or with Control, which allows the user to condition an entire code block upon the state of a qubit.
projectq.meta._compute |
Compute, Uncompute, CustomUncompute. |
projectq.meta._control |
Contains the tools to make an entire section of operations controlled. |
projectq.meta._dagger |
Tools to easily invert a sequence of gates. |
projectq.meta._dirtyqubit |
Defines the DirtyQubitTag meta tag. |
projectq.meta._logicalqubit |
Defines LogicalQubitIDTag to annotate a MeasureGate for mapped qubits. |
projectq.meta._loop |
Tools to implement loops. |
projectq.meta._util |
|
projectq.meta.Compute(engine) |
Start a compute-section. |
projectq.meta.ComputeTag |
Compute meta tag. |
projectq.meta.Control(engine, qubits) |
Condition an entire code block on the value of qubits being 1. |
projectq.meta.CustomUncompute(engine) |
Start a custom uncompute-section. |
projectq.meta.Dagger(engine) |
Invert an entire code block. |
projectq.meta.DirtyQubitTag |
Dirty qubit meta tag |
projectq.meta.drop_engine_after(prev_engine) |
Removes an engine from the singly-linked list of engines. |
projectq.meta.get_control_count(cmd) |
Return the number of control qubits of the command object cmd |
projectq.meta.insert_engine(prev_engine, …) |
Inserts an engine into the singly-linked list of engines. |
projectq.meta.LogicalQubitIDTag(logical_qubit_id) |
LogicalQubitIDTag for a mapped qubit to annotate a MeasureGate. |
projectq.meta.Loop(engine, num) |
Loop n times over an entire code block. |
projectq.meta.LoopTag(num) |
Loop meta tag |
projectq.meta.Uncompute(engine) |
Uncompute automatically. |
projectq.meta.UncomputeTag |
Uncompute meta tag. |
Submodules¶
_compute¶
Compute, Uncompute, CustomUncompute.
Contains Compute, Uncompute, and CustomUncompute classes which can be used to annotate Compute / Action / Uncompute sections, facilitating the conditioning of the entire operation on the value of a qubit / register (only Action needs controls). This file also defines the corresponding meta tags.
-
class
projectq.meta._compute.Compute(engine)[source]¶ Start a compute-section.
Example
with Compute(eng): do_something(qubits) action(qubits) Uncompute(eng) # runs inverse of the compute section
Warning
If qubits are allocated within the compute section, they must either be uncomputed and deallocated within that section or, alternatively, uncomputed and deallocated in the following uncompute section.
This means that the following examples are valid:
with Compute(eng): anc = eng.allocate_qubit() do_something_with_ancilla(anc) ... uncompute_ancilla(anc) del anc do_something_else(qubits) Uncompute(eng) # will allocate a new ancilla (with a different id) # and then deallocate it again
with Compute(eng): anc = eng.allocate_qubit() do_something_with_ancilla(anc) ... do_something_else(qubits) Uncompute(eng) # will deallocate the ancilla!
After the uncompute section, ancilla qubits allocated within the compute section will be invalid (and deallocated). The same holds when using CustomUncompute.
Failure to comply with these rules results in an exception being thrown.
-
class
projectq.meta._compute.ComputeEngine[source]¶ Adds Compute-tags to all commands and stores them (to later uncompute them automatically)
-
end_compute()[source]¶ End the compute step (exit the with Compute() - statement).
Will tell the Compute-engine to stop caching. It then waits for the uncompute instruction, which is when it sends all cached commands inverted and in reverse order down to the next compiler engine.
Raises: QubitManagementError– If qubit has been deallocated in Compute section which has not been allocated in Compute section
-
receive(command_list)[source]¶ - If in compute-mode: Receive commands and store deepcopy of each cmd.
- Add ComputeTag to received cmd and send it on.
Otherwise: send all received commands directly to next_engine.
Parameters: command_list (list<Command>) – List of commands to receive.
-
run_uncompute()[source]¶ Send uncomputing gates.
Sends the inverse of the stored commands in reverse order down to the next engine. And also deals with allocated qubits in Compute section. If a qubit has been allocated during compute, it will be deallocated during uncompute. If a qubit has been allocated and deallocated during compute, then a new qubit is allocated and deallocated during uncompute.
-
-
class
projectq.meta._compute.CustomUncompute(engine)[source]¶ Start a custom uncompute-section.
Example
with Compute(eng): do_something(qubits) action(qubits) with CustomUncompute(eng): do_something_inverse(qubits)
Raises: QubitManagementError– If qubits are allocated within Compute or within CustomUncompute context but are not deallocated.
-
exception
projectq.meta._compute.NoComputeSectionError[source]¶ Exception raised if uncompute is called but no compute section found.
-
projectq.meta._compute.Uncompute(engine)[source]¶ Uncompute automatically.
Example
with Compute(eng): do_something(qubits) action(qubits) Uncompute(eng) # runs inverse of the compute section
_control¶
Contains the tools to make an entire section of operations controlled.
Example
with Control(eng, qubit1):
H | qubit2
X | qubit3
-
class
projectq.meta._control.Control(engine, qubits)[source]¶ Condition an entire code block on the value of qubits being 1.
Example
with Control(eng, ctrlqubits): do_something(otherqubits)
_dagger¶
Tools to easily invert a sequence of gates.
with Dagger(eng):
H | qubit1
Rz(0.5) | qubit2
-
class
projectq.meta._dagger.Dagger(engine)[source]¶ Invert an entire code block.
Use it with a with-statement, i.e.,
with Dagger(eng): [code to invert]
Warning
If the code to invert contains allocation of qubits, those qubits have to be deleted prior to exiting the ‘with Dagger()’ context.
This code is NOT VALID:
with Dagger(eng): qb = eng.allocate_qubit() H | qb # qb is still available!!!
The correct way of handling qubit (de-)allocation is as follows:
with Dagger(eng): qb = eng.allocate_qubit() ... del qb # sends deallocate gate (which becomes an allocate)
_dirtyqubit¶
Defines the DirtyQubitTag meta tag.
_logicalqubit¶
Defines LogicalQubitIDTag to annotate a MeasureGate for mapped qubits.
_loop¶
Tools to implement loops.
Example
with Loop(eng, 4):
H | qb
Rz(M_PI/3.) | qb
-
class
projectq.meta._loop.Loop(engine, num)[source]¶ Loop n times over an entire code block.
Example
with Loop(eng, 4): # [quantum gates to be executed 4 times]
Warning
If the code in the loop contains allocation of qubits, those qubits have to be deleted prior to exiting the ‘with Loop()’ context.
This code is NOT VALID:
with Loop(eng, 4): qb = eng.allocate_qubit() H | qb # qb is still available!!!
The correct way of handling qubit (de-)allocation is as follows:
with Loop(eng, 4): qb = eng.allocate_qubit() ... del qb # sends deallocate gate
-
class
projectq.meta._loop.LoopEngine(num)[source]¶ Stores all commands and, when done, executes them num times if no loop tag handler engine is available. If there is one, it adds a loop_tag to the commands and sends them on.
-
receive(command_list)[source]¶ Receive (and potentially temporarily store) all commands.
Add LoopTag to all receiving commands and send to the next engine if a further engine is a LoopTag-handling engine. Otherwise store all commands (to later unroll them). Check that within the loop body, all allocated qubits have also been deallocated. If loop needs to be unrolled and ancilla qubits have been allocated within the loop body, then store a reference all these qubit ids (to change them when unrolling the loop)
Parameters: command_list (list<Command>) – List of commands to store and later unroll or, if there is a LoopTag-handling engine, add the LoopTag.
-
_util¶
-
projectq.meta._util.drop_engine_after(prev_engine)[source]¶ Removes an engine from the singly-linked list of engines.
Parameters: prev_engine (projectq.cengines.BasicEngine) – The engine just before the engine to drop. Returns: The dropped engine. Return type: Engine
-
projectq.meta._util.insert_engine(prev_engine, engine_to_insert)[source]¶ Inserts an engine into the singly-linked list of engines.
It also sets the correct main_engine for engine_to_insert.
Parameters: - prev_engine (projectq.cengines.BasicEngine) – The engine just before the insertion point.
- engine_to_insert (projectq.cengines.BasicEngine) – The engine to insert at the insertion point.
Module contents¶
The projectq.meta package features meta instructions which help both the user and the compiler in writing/producing efficient code. It includes, e.g.,
- Loop (with Loop(eng): …)
- Compute/Uncompute (with Compute(eng): …, […], Uncompute(eng))
- Control (with Control(eng, ctrl_qubits): …)
- Dagger (with Dagger(eng): …)
-
class
projectq.meta.Compute(engine)[source]¶ Start a compute-section.
Example
with Compute(eng): do_something(qubits) action(qubits) Uncompute(eng) # runs inverse of the compute section
Warning
If qubits are allocated within the compute section, they must either be uncomputed and deallocated within that section or, alternatively, uncomputed and deallocated in the following uncompute section.
This means that the following examples are valid:
with Compute(eng): anc = eng.allocate_qubit() do_something_with_ancilla(anc) ... uncompute_ancilla(anc) del anc do_something_else(qubits) Uncompute(eng) # will allocate a new ancilla (with a different id) # and then deallocate it again
with Compute(eng): anc = eng.allocate_qubit() do_something_with_ancilla(anc) ... do_something_else(qubits) Uncompute(eng) # will deallocate the ancilla!
After the uncompute section, ancilla qubits allocated within the compute section will be invalid (and deallocated). The same holds when using CustomUncompute.
Failure to comply with these rules results in an exception being thrown.
-
__init__(engine)[source]¶ Initialize a Compute context.
Parameters: engine (BasicEngine) – Engine which is the first to receive all commands (normally: MainEngine).
-
-
class
projectq.meta.Control(engine, qubits)[source]¶ Condition an entire code block on the value of qubits being 1.
Example
with Control(eng, ctrlqubits): do_something(otherqubits)
-
class
projectq.meta.CustomUncompute(engine)[source]¶ Start a custom uncompute-section.
Example
with Compute(eng): do_something(qubits) action(qubits) with CustomUncompute(eng): do_something_inverse(qubits)
Raises: QubitManagementError– If qubits are allocated within Compute or within CustomUncompute context but are not deallocated.-
__init__(engine)[source]¶ Initialize a CustomUncompute context.
Parameters: engine (BasicEngine) – Engine which is the first to receive all commands (normally: MainEngine).
-
-
class
projectq.meta.Dagger(engine)[source]¶ Invert an entire code block.
Use it with a with-statement, i.e.,
with Dagger(eng): [code to invert]
Warning
If the code to invert contains allocation of qubits, those qubits have to be deleted prior to exiting the ‘with Dagger()’ context.
This code is NOT VALID:
with Dagger(eng): qb = eng.allocate_qubit() H | qb # qb is still available!!!
The correct way of handling qubit (de-)allocation is as follows:
with Dagger(eng): qb = eng.allocate_qubit() ... del qb # sends deallocate gate (which becomes an allocate)
-
class
projectq.meta.LogicalQubitIDTag(logical_qubit_id)[source]¶ LogicalQubitIDTag for a mapped qubit to annotate a MeasureGate.
-
logical_qubit_id¶ Logical qubit id
Type: int
-
-
class
projectq.meta.Loop(engine, num)[source]¶ Loop n times over an entire code block.
Example
with Loop(eng, 4): # [quantum gates to be executed 4 times]
Warning
If the code in the loop contains allocation of qubits, those qubits have to be deleted prior to exiting the ‘with Loop()’ context.
This code is NOT VALID:
with Loop(eng, 4): qb = eng.allocate_qubit() H | qb # qb is still available!!!
The correct way of handling qubit (de-)allocation is as follows:
with Loop(eng, 4): qb = eng.allocate_qubit() ... del qb # sends deallocate gate
-
__init__(engine, num)[source]¶ Enter a looped section.
Parameters: - engine – Engine handling the commands (usually MainEngine)
- num (int) – Number of loop iterations
Example
with Loop(eng, 4): H | qb Rz(M_PI/3.) | qb
Raises: TypeError– If number of iterations (num) is not an integerValueError– If number of iterations (num) is not >= 0
-
-
projectq.meta.Uncompute(engine)[source]¶ Uncompute automatically.
Example
with Compute(eng): do_something(qubits) action(qubits) Uncompute(eng) # runs inverse of the compute section
-
projectq.meta.drop_engine_after(prev_engine)[source]¶ Removes an engine from the singly-linked list of engines.
Parameters: prev_engine (projectq.cengines.BasicEngine) – The engine just before the engine to drop. Returns: The dropped engine. Return type: Engine
-
projectq.meta.get_control_count(cmd)[source]¶ Return the number of control qubits of the command object cmd
-
projectq.meta.insert_engine(prev_engine, engine_to_insert)[source]¶ Inserts an engine into the singly-linked list of engines.
It also sets the correct main_engine for engine_to_insert.
Parameters: - prev_engine (projectq.cengines.BasicEngine) – The engine just before the insertion point.
- engine_to_insert (projectq.cengines.BasicEngine) – The engine to insert at the insertion point.