Source code for qiskit.transpiler.passes.utils.remove_final_measurements

# -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2019.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Remove final measurements and barriers at the end of a circuit."""

from qiskit.transpiler.basepasses import TransformationPass
from qiskit.dagcircuit import DAGCircuit


[docs]class RemoveFinalMeasurements(TransformationPass): """Remove final measurements and barriers at the end of a circuit. This pass removes final barriers and final measurements, as well as the ClassicalRegisters they are connected to if the ClassicalRegister is unused. Measurements and barriers are considered final if they are followed by no other operations (aside from other measurements or barriers.) """
[docs] def run(self, dag): """Run the RemoveFinalMeasurements pass on `dag`. Args: dag (DAGCircuit): the DAG to be optimized. Returns: DAGCircuit: the optimized DAG. """ final_op_types = ['measure', 'barrier'] final_ops = [] cregs_to_remove = dict() clbits_with_final_measures = set() for candidate_node in dag.named_nodes(*final_op_types): is_final_op = True for _, child_successors in dag.bfs_successors(candidate_node): if any(suc.type == 'op' and suc.name not in final_op_types for suc in child_successors): is_final_op = False break if is_final_op: final_ops.append(candidate_node) if not final_ops: return dag new_dag = DAGCircuit() for node in final_ops: for carg in node.cargs: # Add the clbit that was attached to the measure we are removing clbits_with_final_measures.add(carg) dag.remove_op_node(node) # If the clbit is idle, add its register to list of registers we may remove for clbit in clbits_with_final_measures: if clbit in dag.idle_wires(): if clbit.register in cregs_to_remove: cregs_to_remove[clbit.register] += 1 else: cregs_to_remove[clbit.register] = 1 # Remove creg if all of its clbits were added above for key, val in zip(list(dag.cregs.keys()), list(dag.cregs.values())): if val in cregs_to_remove and cregs_to_remove[val] == val.size: del dag.cregs[key] # Fill new DAGCircuit for qreg in dag.qregs.values(): new_dag.add_qreg(qreg) for creg in dag.cregs.values(): new_dag.add_creg(creg) for node in dag.topological_op_nodes(): # copy the condition over too if node.condition: new_dag.apply_operation_back(node.op, qargs=node.qargs, cargs=node.cargs, condition=node.condition) else: new_dag.apply_operation_back(node.op, qargs=node.qargs, cargs=node.cargs) return new_dag