Repository: Qiskit/qiskit

Issue:
​Cannot unroll identity matrix of more than 2 qubits when coupling_map is set
<!-- ⚠️ 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**: 0.14.1
- **Python version**: 3.8
- **Operating system**: both Windows and Linux

### What is the current behavior?

The `transpile` function fails to unroll an `UnitaryGate` containing an identity matrix of more than 2 qubits when the `backend` argument is set to be a remote quantum computer or the `coupling_map` argument is set.

### Steps to reproduce the problem

```
>>> import numpy as np
>>> from qiskit import IBMQ, QuantumCircuit, transpile
>>> from qiskit.extensions import UnitaryGate
>>> provider = IBMQ.load_account()
>>> backend = provider.get_backend('ibmq_london')  # arbitrary backend with at least 3 qubits
>>> circuit = QuantumCircuit(3)
>>> gate = UnitaryGate(np.eye(2 ** 3))
>>> circuit.append(gate, range(3))
<qiskit.circuit.instructionset.InstructionSet object at 0x7ff8b93a60d0>
>>> transpile(circuit, backend=backend)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/dist-packages/qiskit/compiler/transpile.py", line 210, in transpile    circuits = parallel_map(_transpile_circuit, list(zip(circuits, transpile_args)))
  File "/usr/local/lib/python3.8/dist-packages/qiskit/tools/parallel.py", line 105, in parallel_map
    return [task(values[0], *task_args, **task_kwargs)]
  File "/usr/local/lib/python3.8/dist-packages/qiskit/compiler/transpile.py", line 306, in _transpile_circuit
    return pass_manager.run(circuit, callback=transpile_config['callback'],
  File "/usr/local/lib/python3.8/dist-packages/qiskit/transpiler/passmanager.py", line 214, in run
    return self._run_single_circuit(circuits, output_name, callback)
  File "/usr/local/lib/python3.8/dist-packages/qiskit/transpiler/passmanager.py", line 277, in _run_single_circuit
    result = running_passmanager.run(circuit, output_name=output_name, callback=callback)
  File "/usr/local/lib/python3.8/dist-packages/qiskit/transpiler/runningpassmanager.py", line 115, in run
    dag = self._do_pass(pass_, dag, passset.options)
  File "/usr/local/lib/python3.8/dist-packages/qiskit/transpiler/runningpassmanager.py", line 145, in _do_pass
    dag = self._run_this_pass(pass_, dag)
  File "/usr/local/lib/python3.8/dist-packages/qiskit/transpiler/runningpassmanager.py", line 157, in _run_this_pass
    new_dag = pass_.run(dag)
  File "/usr/local/lib/python3.8/dist-packages/qiskit/transpiler/passes/basis/unroll_3q_or_more.py", line 54, in run
    decomposition = self.run(decomposition)  # recursively unroll
  File "/usr/local/lib/python3.8/dist-packages/qiskit/transpiler/passes/basis/unroll_3q_or_more.py", line 54, in run
    decomposition = self.run(decomposition)  # recursively unroll
  File "/usr/local/lib/python3.8/dist-packages/qiskit/transpiler/passes/basis/unroll_3q_or_more.py", line 39, in run
    raise QiskitError("Cannot unroll all 3q or more gates. "
qiskit.exceptions.QiskitError: 'Cannot unroll all 3q or more gates. No rule to expand instruction circuit9_dg.'
```

Notes:

- This bug only happens when the `backend` argument is set to be a remote quantum computer or the `coupling_map` argument is set to be a coupling map of a remote quantum computer. Calling `transpile(circuit, basis_gates=['u1', 'u2', 'u3', 'cx', 'id'])` works fine.
- This bug only happens when the `UnitaryGate` contains an identity matrix of more than 2 qubits.

### What is the expected behavior?

Successfully transpile the circuit.


Discussion:

Resolving patch:
diff --git a/qiskit/transpiler/passes/basis/unroll_3q_or_more.py b/qiskit/transpiler/passes/basis/unroll_3q_or_more.py
--- a/qiskit/transpiler/passes/basis/unroll_3q_or_more.py
+++ b/qiskit/transpiler/passes/basis/unroll_3q_or_more.py
@@ -36,6 +36,9 @@ def run(self, dag):
             # TODO: allow choosing other possible decompositions
             rule = node.op.definition
             if not rule:
+                if rule == []:  # empty node
+                    dag.remove_op_node(node)
+                    continue
                 raise QiskitError("Cannot unroll all 3q or more gates. "
                                   "No rule to expand instruction %s." %
                                   node.op.name)


Test patch:
diff --git a/test/python/transpiler/test_unroll_3q_or_more.py b/test/python/transpiler/test_unroll_3q_or_more.py
--- a/test/python/transpiler/test_unroll_3q_or_more.py
+++ b/test/python/transpiler/test_unroll_3q_or_more.py
@@ -13,13 +13,14 @@
 # that they have been altered from the originals.
 
 """Test the Unroll3qOrMore pass"""
-
+import numpy as np
 from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
 from qiskit.transpiler.passes import Unroll3qOrMore
 from qiskit.converters import circuit_to_dag, dag_to_circuit
 from qiskit.quantum_info.operators import Operator
 from qiskit.quantum_info.random import random_unitary
 from qiskit.test import QiskitTestCase
+from qiskit.extensions import UnitaryGate
 
 
 class TestUnroll3qOrMore(QiskitTestCase):
@@ -83,3 +84,15 @@ def test_decompose_unitary(self):
         after_dag = pass_.run(dag)
         after_circ = dag_to_circuit(after_dag)
         self.assertTrue(Operator(circuit).equiv(Operator(after_circ)))
+
+    def test_identity(self):
+        """Test unrolling of identity gate over 3qubits."""
+        qr = QuantumRegister(3, 'qr')
+        circuit = QuantumCircuit(qr)
+        gate = UnitaryGate(np.eye(2 ** 3))
+        circuit.append(gate, range(3))
+        dag = circuit_to_dag(circuit)
+        pass_ = Unroll3qOrMore()
+        after_dag = pass_.run(dag)
+        after_circ = dag_to_circuit(after_dag)
+        self.assertTrue(Operator(circuit).equiv(Operator(after_circ)))