qp.transforms.combine_global_phases¶
- combine_global_phases(tape)[source]¶
Combine all
qp.GlobalPhasegates into a singleqp.GlobalPhaseoperation.This transform returns a new circuit where all
qp.GlobalPhasegates in the original circuit (if exists) are removed, and a newqp.GlobalPhaseis added at the end of the list of operations with its phase being a total global phase computed as the algebraic sum of all global phases in the original circuit.- Parameters:
tape (QNode or QuantumScript or Callable) – the input circuit to be transformed.
- Returns:
the transformed circuit as described in
qp.transform.- Return type:
qnode (QNode) or quantum function (Callable) or tuple[List[QuantumScript], function]
Example
Suppose we want to combine all the global phase gates in a given quantum circuit. The
combine_global_phasestransform can be used to do this as follows:dev = qp.device("default.qubit", wires=3) @qp.transforms.combine_global_phases @qp.qnode(dev) def circuit(): qp.GlobalPhase(0.3, wires=0) qp.PauliY(wires=0) qp.Hadamard(wires=1) qp.CNOT(wires=(1,2)) qp.GlobalPhase(0.46, wires=2) return qp.expval(qp.X(0) @ qp.Z(1))
To check the result, let’s print out the circuit:
>>> print(qp.draw(circuit)()) 0: ──Y────╭GlobalPhase(0.76)─┤ ╭<X@Z> 1: ──H─╭●─├GlobalPhase(0.76)─┤ ╰<X@Z> 2: ────╰X─╰GlobalPhase(0.76)─┤
Usage with qjit
There are two key differences to note when using
combine_global_phaseswithqjit:combine_global_phasesmust be applied to a QNode. Quantum functions are not supported as input.When used with
qjit, thecombine_global_phasescompilation pass will merge operations surrounding control flow together, while those within the control flow are merged together separately (i.e., no formal loop-boundary optimizations).
Consider the following example:
import pennylane as qp n = 3 dev = qp.device('null.qubit', wires=n) @qp.qjit(keep_intermediate=True, capture=True) @qp.transforms.combine_global_phases @qp.qnode(dev) def circuit(): qp.GlobalPhase(0.1, wires = 2) qp.X(n-1) qp.GlobalPhase(0.1, wires = 1) qp.H(n-2) @qp.for_loop(0, 2) def loop(i): qp.GlobalPhase(0.1967, wires=i) qp.GlobalPhase(0.7691, wires=i) loop() qp.GlobalPhase(0.1, wires=0) qp.GlobalPhase(0.1, wires=0) return qp.expval(qp.Z(0))
The two
GlobalPhaseoperations within thefor_loopcontext will be merged together. However, they will not be merged together with theGlobalPhaseoperations that occur before and after thefor_loop.This behaviour is shown in the image below, where the application of
combine_global_phasesresults in twoGlobalPhaseinstances (one inside of afor_loopand the other from theGlobalPhaseinstances outside of thefor_loop).>>> qp.specs(circuit, level="device")().resources.gate_counts {'GlobalPhase': 3, 'Hadamard': 1, 'PauliX': 1} >>> print(qp.draw_graph(circuit)())