mindquantum.algorithm.compiler.rules.neighbor_canceler 源代码

# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
"""Neighbor canceler compiler rule."""
from mindquantum.utils.type_value_check import _check_input_type

from ..dag import DAGCircuit, GateNode, try_merge
from .basic_rule import BasicCompilerRule, KroneckerSeqCompiler
from .compiler_logger import CompileLog as CLog
from .compiler_logger import LogIndentation


# pylint: disable=too-many-nested-blocks,too-many-branches,too-few-public-methods
[文档]class SimpleNeighborCanceler(BasicCompilerRule): """Merge two nearby gate if possible.""" def __init__(self): """Initialize a neighbor canceler compiler rule.""" super().__init__("SimpleNeighborCanceler") def _canceler(self, current_node, fc_pair_consided, dag_circuit): """Merge two gate.""" compiled = False for local in current_node.local: if not current_node.child: continue child_node = current_node.child[local] fc_pair = (current_node, child_node) if fc_pair in fc_pair_consided: continue fc_pair_consided.add(fc_pair) if not isinstance(child_node, GateNode): continue if isinstance(current_node, GateNode): compiled = self._merge_two_gates(current_node, child_node, fc_pair_consided, dag_circuit) or compiled compiled = self._canceler(child_node, fc_pair_consided, dag_circuit) or compiled return compiled
[文档] def do(self, dag_circuit: DAGCircuit) -> bool: """ Apply neighbor canceler compiler rule. Args: dag_circuit (:class:`~.algorithm.compiler.DAGCircuit`): The DAG graph of quantum circuit. """ _check_input_type("dag_circuit", DAGCircuit, dag_circuit) fc_pair_consided = set() compiled = False CLog.log(f"Running {CLog.R1(self.rule_name)}.", 1, self.log_level) with LogIndentation() as _: for current_node in dag_circuit.head_node.values(): compiled = self._canceler(current_node, fc_pair_consided, dag_circuit) or compiled if compiled: CLog.log(f"{CLog.R1(self.rule_name)}: {CLog.P('successfully compiled')}.", 1, self.log_level) else: CLog.log(f"{CLog.R1(self.rule_name)}: nothing happened.", 1, self.log_level) return compiled
def _merge_two_gates(self, current_node: GateNode, child_node: GateNode, fc_pair_consided, dag_circuit): """Merge two gates.""" compiled = False state, res, global_phase = try_merge(current_node, child_node) if not state: return False compiled = True with LogIndentation() as _: CLog.log( f"{CLog.R1(self.rule_name)}: merge {CLog.B(current_node.gate)} and {CLog.B(child_node.gate)}.", 2, self.log_level, ) if global_phase: dag_circuit.global_phase.coeff += global_phase.coeff for node in res: compiled = self._canceler(node, fc_pair_consided, dag_circuit) or compiled return compiled
[文档]class FullyNeighborCanceler(KroneckerSeqCompiler): """Merge neighbor gate until we cannot merge anymore gates.""" def __init__(self): """Initialize fully neighbor canceler compile rule.""" rule_set = [SimpleNeighborCanceler()] super().__init__(rule_set) self.rule_name = "FullyNeighborCanceler"