Optimizing the QuantumProgram or Circuit
The pyqonvert
package consists of a number of methods to optimize quantum circuits by reducing the number of gates in the circuit. These are packaged as Converters
, hence applied using the convert
function.
Available optimizers
IdentityRemover
- optimizes a quantum circuit or QuantumProgram by eliminating gates that are identified as identity below a certain specified tolerance. This optimizer takesidentity_tolerance
as an input.
# Initialization
optimizer = IdentityRemover(identity_tolerance=1e-9)
MultipleRotationGateSimplifier
- optimizes a quantum circuit or QuantumProgram by adding up identical rotation gates in separate DecompositionBlocks.
# Initialization
optimizer = MultipleRotationGateSimplifier()
CircuitParallelizer
- optimizes a quantum circuit or QuantumProgram by grouping operations into parallel execution blocks. Each parallel execution block is terminated by aPragmaStopParallelBlock
operation. The execution time of the parallel block is extracted from the properties of the input device.
# Initialization
optimizer = CircuitParallelizer()
SleepInserter
- adds aPragmaSleep
operation before or after a gate, depending on the user specified placement mode. ThePragmaSleep
will only be added to gates that involve at least one qubit from the input of the SleepInserter and are of the gate type specified in the input.
# Initialization
optimizer = SleepInserter(
gates = ["PauliZ"],
involved_qubits = [0,1],
sleep_time = 2.5,
placement = "after"
)
placement
is an optional argument set to "after"
by default.
NumericSingleQubitMultiplier
- optimizes a quantum circuit or a QuantumProgram by multiplying non-symbolic single-qubit-gates. As an argument, it takes inidentity_tolerance
that specifies a threshold below which gates are neglected as identity.
# Initialization
optimizer = NumericSingleQubitMultiplier(identity_tolerance=1e-9)
VirtualZGateReplacement
- applies virtual Z gate optimization. Provided that the natural two-qubit gate is diagonal in the Z-basis, theconverter
replaces RotateZ gates by virtual changes (rotations) of the qubit basis in the XY-Plane. This is done by replacing gates corresponding to rotation in XY-Plane withRotateXY
gate.
# Initialization
optimizer = VirtualZGateReplacement()
By default, the converter
adds RotateZ
gates at the end to undo the changes made to the qubit basis. This behavior can be modified by using the function apply_final_rotz
optimizer = VirtualZGateReplacement().apply_final_rotz(False)
Note that if RotateXY
gate is available in the device, the user is not required to use the VirtualZGateReplacement
converter. Simply running the gate decomposition routine produces the same effect as the optimizer.
Example
We give an example where we apply a series of optimizations on a quantum circuit.
from pyqonvert.optimization import (
IdentityRemover,
NumericSingleQubitMultiplier,
CircuitParallelizer,
)
from qoqo import devices, Circuit
from qoqo import operations as ops
# Initialize device
number_qubits = 2
device = devices.AllToAllDevice(
number_qubits, ["RotateZ", "RotateX", "SingleQubitGate"], ["CNOT"], 0.5
)
# Initialize circuit
circuit = Circuit()
circuit += ops.RotateZ(0, 1e-6)
circuit += ops.RotateZ(0, 0.5)
circuit += ops.RotateX(1, -1.0)
circuit += ops.RotateX(1, 2.0)
circuit += ops.CNOT(0, 1)
# List of converters
converters = [IdentityRemover(1e-5), NumericSingleQubitMultiplier(1e-5), CircuitParallelizer()]
# Optimizations
for converter in converters:
circuit = converter.convert(circuit, device, [])
Figure 1: Resulting circuit after the application of optimization converters.