diff --git a/qiskit/dagcircuit/dagcircuit.py b/qiskit/dagcircuit/dagcircuit.py index c5a97c09113f..01c99a13906c 100644 --- a/qiskit/dagcircuit/dagcircuit.py +++ b/qiskit/dagcircuit/dagcircuit.py @@ -786,17 +786,30 @@ def idle_wires(self, ignore=None): Yields: Bit: Bit in idle wire. + + Raises: + DAGCircuitError: If the DAG is invalid """ if ignore is None: - ignore = [] + ignore = set() + ignore_set = set(ignore) for wire in self._wires: - nodes = [ - node - for node in self.nodes_on_wire(wire, only_ops=True) - if node.op.name not in ignore - ] - if len(nodes) == 0: - yield wire + if not ignore: + try: + child = next(self.successors(self.input_map[wire])) + except StopIteration as e: + raise DAGCircuitError( + "Invalid dagcircuit input node %s has no output" % self.input_map[wire] + ) from e + if isinstance(child, DAGOutNode): + yield wire + else: + for node in self.nodes_on_wire(wire, only_ops=True): + if node.op.name not in ignore_set: + # If we found an op node outside of ignore we can stop iterating over the wire + break + else: + yield wire def size(self): """Return the number of operations.""" diff --git a/qiskit/transpiler/passes/utils/remove_final_measurements.py b/qiskit/transpiler/passes/utils/remove_final_measurements.py index 5bf156970203..35ad1eb6972f 100644 --- a/qiskit/transpiler/passes/utils/remove_final_measurements.py +++ b/qiskit/transpiler/passes/utils/remove_final_measurements.py @@ -34,25 +34,16 @@ def run(self, dag): Returns: DAGCircuit: the optimized DAG. """ - final_op_types = ["measure", "barrier"] + final_op_types = {"measure", "barrier"} final_ops = [] cregs_to_remove = dict() clbits_with_final_measures = set() clbit_registers = {clbit: creg for creg in dag.cregs.values() for clbit in creg} - 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( - isinstance(suc, DAGOpNode) 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) + for qubit in dag.qubits: + op_node = next(dag.predecessors(dag.output_map[qubit])) + if isinstance(op_node, DAGOpNode) and op_node.op.name in final_op_types: + final_ops.append(op_node) if not final_ops: return dag @@ -77,10 +68,4 @@ def run(self, dag): if val in cregs_to_remove and cregs_to_remove[val] == val.size: del dag.cregs[key] - new_dag = dag._copy_circuit_metadata() - - for node in dag.topological_op_nodes(): - # copy the condition over too - new_dag.apply_operation_back(node.op, qargs=node.qargs, cargs=node.cargs) - - return new_dag + return dag