qiskit/transpiler/passes/merge_adjacent_barriers.py
def _collect_potential_merges(dag, barriers):
        """
        Returns a dict of DAGNode : Barrier objects, where the barrier needs to be
        inserted where the corresponding DAGNode appears in the main DAG
        """
        # if only got 1 or 0 barriers then can't merge
        if len(barriers) < 2:
            return None

        # mapping from the node that will be the main barrier to the
        # barrier object that gets built up
        node_to_barrier_qubits = {}

        # Start from the first barrier
        current_barrier = barriers[0]
        end_of_barrier = current_barrier
        current_barrier_nodes = [current_barrier]

        current_qubits = set(current_barrier.qargs)
        current_ancestors = dag.ancestors(current_barrier)
        current_descendants = dag.descendants(current_barrier)

        barrier_to_add = Barrier(len(current_qubits))

        for next_barrier in barriers[1:]:

            # Remove all barriers that have already been included in this new barrier from the set
            # of ancestors/descendants as they will be removed from the new DAG when it is created
            next_ancestors = {nd for nd in dag.ancestors(next_barrier)
                              if nd not in current_barrier_nodes}
            next_descendants = {nd for nd in dag.descendants(next_barrier)
                                if nd not in current_barrier_nodes}
            next_qubits = set(next_barrier.qargs)

            if (
                    not current_qubits.isdisjoint(next_qubits)
                    and current_ancestors.isdisjoint(next_descendants)
                    and current_descendants.isdisjoint(next_ancestors)
            ):

                # can be merged
                current_ancestors = current_ancestors | next_ancestors
                current_descendants = current_descendants | next_descendants
                current_qubits = current_qubits | next_qubits

                # update the barrier that will be added back to include this barrier
                barrier_to_add = Barrier(len(current_qubits))

            else:
                # store the previously made barrier
                if barrier_to_add:
                    node_to_barrier_qubits[end_of_barrier] = current_qubits

                # reset the properties
                current_qubits = set(next_barrier.qargs)
                current_ancestors = dag.ancestors(next_barrier)
                current_descendants = dag.descendants(next_barrier)

                barrier_to_add = Barrier(len(current_qubits))
                current_barrier_nodes = []

            end_of_barrier = next_barrier
            current_barrier_nodes.append(end_of_barrier)

        if barrier_to_add:
            node_to_barrier_qubits[end_of_barrier] = current_qubits

        return node_to_barrier_qubits
def _collect_potential_merges(dag, barriers):
        """
        Returns a dict of DAGNode : Barrier objects, where the barrier needs to be
        inserted where the corresponding DAGNode appears in the main DAG
        """
        # if only got 1 or 0 barriers then can't merge
        if len(barriers) < 2:
            return None

        # mapping from the node that will be the main barrier to the
        # barrier object that gets built up
        node_to_barrier_qubits = {}

        # Start from the first barrier
        current_barrier = barriers[0]
        end_of_barrier = current_barrier
        current_barrier_nodes = [current_barrier]

        current_qubits = set(current_barrier.qargs)
        current_ancestors = dag.ancestors(current_barrier)
        current_descendants = dag.descendants(current_barrier)

        barrier_to_add = Barrier(len(current_qubits))

        for next_barrier in barriers[1:]:

            # Remove all barriers that have already been included in this new barrier from the set
            # of ancestors/descendants as they will be removed from the new DAG when it is created
            next_ancestors = {nd for nd in dag.ancestors(next_barrier)
                              if nd not in current_barrier_nodes}
            next_descendants = {nd for nd in dag.descendants(next_barrier)
                                if nd not in current_barrier_nodes}
            next_qubits = set(next_barrier.qargs)

            if (
                    not current_qubits.isdisjoint(next_qubits)
                    and current_ancestors.isdisjoint(next_descendants)
                    and current_descendants.isdisjoint(next_ancestors)
            ):

                # can be merged
                current_ancestors = current_ancestors | next_ancestors
                current_descendants = current_descendants | next_descendants
                current_qubits = current_qubits | next_qubits

                # update the barrier that will be added back to include this barrier
                barrier_to_add = Barrier(len(current_qubits))

            else:
                # store the previously made barrier
                if barrier_to_add:
                    node_to_barrier_qubits[end_of_barrier] = current_qubits

                # reset the properties
                current_qubits = set(next_barrier.qargs)
                current_ancestors = dag.ancestors(next_barrier)
                current_descendants = dag.descendants(next_barrier)

                barrier_to_add = Barrier(len(current_qubits))
                current_barrier_nodes = []

            end_of_barrier = next_barrier
            current_barrier_nodes.append(end_of_barrier)

        if barrier_to_add:
            node_to_barrier_qubits[end_of_barrier] = current_qubits

        return node_to_barrier_qubits
Returns a dict of DAGNode : Barrier objects, where the barrier needs to be
        inserted where the corresponding DAGNode appears in the main DAG