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.

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)

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)

Initialize a Compute context.

Parameters:engine (BasicEngine) – Engine which is the first to receive all commands (normally: MainEngine).
class projectq.meta.ComputeTag

Compute meta tag.

class projectq.meta.Control(engine, qubits)

Condition an entire code block on the value of qubits being 1.

Example

with Control(eng, ctrlqubits):
        do_something(otherqubits)
__init__(engine, qubits)

Enter a controlled section.

Parameters:
  • engine – Engine which handles the commands (usually MainEngine)
  • qubits (list of Qubit objects) – Qubits to condition on

Enter the section using a with-statement:

with Control(eng, ctrlqubits):
        ...
class projectq.meta.CustomUncompute(engine)

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)

Initialize a CustomUncompute context.

Parameters:engine (BasicEngine) – Engine which is the first to receive all commands (normally: MainEngine).
class projectq.meta.Dagger(engine)

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)
__init__(engine)

Enter an inverted section.

Parameters:engine – Engine which handles the commands (usually MainEngine)

Example (executes an inverse QFT):

with Dagger(eng):
        QFT | qubits
class projectq.meta.DirtyQubitTag

Dirty qubit meta tag

class projectq.meta.Loop(engine, num)

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)

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
class projectq.meta.LoopTag(num)

Loop meta tag

__init__(num)
loop_tag_id = 0
projectq.meta.Uncompute(engine)

Uncompute automatically.

Example

with Compute(eng):
        do_something(qubits)
action(qubits)
Uncompute(eng) # runs inverse of the compute section
class projectq.meta.UncomputeTag

Uncompute meta tag.

projectq.meta.get_control_count(cmd)

Return the number of control qubits of the command object cmd