Repository: Qiskit/qiskit

Issue:
Cannot use resets in a circuit
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**: latest
- **Python version**:
- **Operating system**:

### What is the current behavior?
```
     ┌─────────┐     ┌─┐
q_0: ┤ unitary ├─|0>─┤M├
     └─────────┘     └╥┘
c: 1/═════════════════╩═
                      0 
```
gives:
```
~/miniconda3/envs/qiskit/lib/python3.7/site-packages/qiskit/quantum_info/operators/operator.py in _append_instruction(self, obj, qargs)
    526             # cannot compose this gate and raise an error.
    527             if obj.definition is None:
--> 528                 raise QiskitError('Cannot apply Instruction: {}'.format(obj.name))
    529             if not isinstance(obj.definition, QuantumCircuit):
    530                 raise QiskitError('Instruction "{}" '

QiskitError: 'Cannot apply Instruction: reset'
```

even if the backend supports it.  The code I am using used to work in previous versions.


### Steps to reproduce the problem



### What is the expected behavior?



### Suggested solutions





Discussion:
What operations are you running on that circuit to raise the error? That exception is being raised from trying to create an operator from something (I assume the circuit given it's erroring on reset). We probably just need to add special handling to the operator constructor to deal with reset instructions.

As far as I know everything in the circuit -> transpile -> assemble -> execute path works for reset (although there are some complaints about resets being removed during transpilation #5127, although that case isn't a hard failure it just optimizes away resets during a transpile)
It is a random 1Q unitary followed by a reset and meas (as the circuit shows), then passed to device using `execute`.  I can confirm the exact same code works on `0.23.2`.
Ok, that's what I needed to know, it's being raised by a transpile (that wasn't in the orriginal issue). This is actually a duplicate of #5543 (although it should be fixed by #5570) and we unfortunately backported a regression in 0.16.2 with #5655 (which I thought should have included the fix). Which means we'll need to fix it for real on the stable branch and push out a terra 0.16.3.
FWIW, this should work fine on master, it appears to just be a bug in that backport :(

Resolving patch:
diff --git a/qiskit/dagcircuit/dagcircuit.py b/qiskit/dagcircuit/dagcircuit.py
--- a/qiskit/dagcircuit/dagcircuit.py
+++ b/qiskit/dagcircuit/dagcircuit.py
@@ -1441,10 +1441,11 @@ def _collect_1q_runs(self):
                 while len(s) == 1 and \
                         s[0].type == "op" and \
                         len(s[0].qargs) == 1 and \
-                        len(s[0].cargs) == 0 and \
+                        not s[0].cargs and \
                         s[0].condition is None and \
+                        s[0] not in nodes_seen and \
                         not s[0].op.is_parameterized() and \
-                        isinstance(node.op, Gate):
+                        isinstance(s[0].op, Gate):
                     group.append(s[0])
                     nodes_seen.add(s[0])
                     s = self._multi_graph.successors(s[0]._node_id)


Test patch:
diff --git a/test/python/dagcircuit/test_dagcircuit.py b/test/python/dagcircuit/test_dagcircuit.py
--- a/test/python/dagcircuit/test_dagcircuit.py
+++ b/test/python/dagcircuit/test_dagcircuit.py
@@ -734,6 +734,21 @@ def test_dag_collect_1q_runs(self):
             else:
                 self.fail('Unknown run encountered')
 
+    def test_dag_no_reset_in_collect_1q_runs(self):
+        """Test a run does not include a reset instruction."""
+        dag = DAGCircuit()
+        qreg = QuantumRegister(1, 'qr')
+        creg = ClassicalRegister(1, 'cr')
+        dag.add_qreg(qreg)
+        dag.add_creg(creg)
+        dag.apply_operation_back(U1Gate(3.14), [qreg[0]])
+        dag.apply_operation_back(HGate(), [qreg[0]])
+        dag.apply_operation_back(Reset(), [qreg[0]])
+        dag.apply_operation_back(Measure(), [qreg[0]], [creg[0]])
+        runs = dag._collect_1q_runs()
+        self.assertEqual([[x.name for x in run] for run in runs],
+                         [['u1', 'h']])
+
     def test_dag_collect_1q_runs_start_with_conditional(self):
         """Test collect 1q runs with a conditional at the start of the run."""
         h_gate = HGate()