Source code for qibo.transpiler.optimizer
from typing import Optional
import networkx as nx
from qibo import gates
from qibo.backends import Backend, _check_backend
from qibo.config import log, raise_error
from qibo.models import Circuit
from qibo.transpiler.abstract import Optimizer
[docs]class Preprocessing(Optimizer):
"""Pad the circuit with unused qubits to match the number of physical qubits.
Args:
connectivity (:class:`networkx.Graph`): Hardware connectivity.
"""
def __init__(self, connectivity: Optional[nx.Graph] = None):
self.connectivity = connectivity
def __call__(self, circuit: Circuit) -> Circuit:
if not all(qubit in self.connectivity.nodes for qubit in circuit.wire_names):
default_wire_names = list(self.connectivity.nodes)[: circuit.nqubits]
log.warning(
f"Some wire_names in the circuit are not in the connectivity graph. Using wire name {default_wire_names}."
)
circuit.wire_names = default_wire_names
physical_qubits = self.connectivity.number_of_nodes()
logical_qubits = circuit.nqubits
if logical_qubits > physical_qubits:
raise_error(
ValueError,
f"The number of qubits in the circuit ({logical_qubits}) "
+ f"can't be greater than the number of physical qubits ({physical_qubits}).",
)
if logical_qubits == physical_qubits:
return circuit
new_wire_names = circuit.wire_names + list(
self.connectivity.nodes - circuit.wire_names
)
new_circuit = Circuit(nqubits=physical_qubits, wire_names=new_wire_names)
for gate in circuit.queue:
new_circuit.add(gate)
return new_circuit
[docs]class Rearrange(Optimizer):
"""Rearranges gates using ``qibo``'s fusion algorithm.
May reduce number of :class:`qibo.gates.SWAP` when fixing for connectivity
but this has not been tested.
Args:
max_qubits (int, optional): Maximum number of qubits to fuse.
Defaults to :math:`1`.
"""
def __init__(self, max_qubits: int = 1):
self.max_qubits = max_qubits
def __call__(self, circuit: Circuit, backend: Optional[Backend] = None) -> Circuit:
backend = _check_backend(backend)
fused_circuit = circuit.fuse(max_qubits=self.max_qubits)
new = circuit.__class__(nqubits=circuit.nqubits, wire_names=circuit.wire_names)
for fgate in fused_circuit.queue:
if isinstance(fgate, gates.FusedGate):
new.add(gates.Unitary(fgate.matrix(backend), *fgate.qubits))
else:
new.add(fgate)
return new