Source code for bqskit.passes.util.fill

"""This module implements the FillSingleQuditGatesPass class."""
from __future__ import annotations

import logging

from bqskit.compiler.basepass import BasePass
from bqskit.compiler.passdata import PassData
from bqskit.ir.circuit import Circuit
from bqskit.ir.point import CircuitPoint


_logger = logging.getLogger(__name__)


[docs] class FillSingleQuditGatesPass(BasePass): """ A pass that inserts single-qudit gates around multi-qudit gates. This pass will preserve the multi-qudit gates in the circuit and then place single-qudit unitary gates around those gates. """
[docs] async def run(self, circuit: Circuit, data: PassData) -> None: """Perform the pass's operation, see :class:`BasePass` for more.""" _logger.debug('Filling circuit with single-qudit gates.') complete_circuit = Circuit(circuit.num_qudits, circuit.radixes) sq_gate = data.gate_set.get_general_sq_gate() id_params = sq_gate.identity_as_params((circuit.radixes[0],)) # Add general gate as identity on every qudit to start for qudit_index in range(circuit.num_qudits): complete_circuit.append_gate(sq_gate, qudit_index, id_params) for cycle, op in circuit.operations_with_cycles(): # Single-qudit gates get converted to general gates if op.num_qudits == 1: # Check for already existing single-qudit gates last_point = complete_circuit.last_on(op.location[0]) if last_point is not None: last_op = complete_circuit[last_point] if last_op.num_qudits == 1: # Merge single-qudit gates if one already exists utry = op.get_unitary() @ last_op.get_unitary() last_op.params = sq_gate.calc_params(utry) continue # Otherwise just add general gate params = sq_gate.calc_params(op.get_unitary()) complete_circuit.append_gate(sq_gate, op.location, params) else: # Multi-qudit gates get added as is complete_circuit.append(op) # Add additional sq gates where there is none between mq gates qudits_needing_single_qudit_gates = set(op.location) for p in circuit.next(CircuitPoint(cycle, op.location[0])): if circuit[p].num_qudits == 1: qudits_needing_single_qudit_gates.remove(p.qudit) for qudit in qudits_needing_single_qudit_gates: complete_circuit.append_gate(sq_gate, qudit, id_params) circuit.become(complete_circuit)