Repository: Qiskit/qiskit

Issue:
Random-circuit conditional generation outputs incorrect typed comparison values
### Environment

- **Qiskit Terra version**: 0.23.2
- **Python version**: 3.10
- **Operating system**: macOS


### What is happening?

The output of `qiskit.circuit.random.random_circuit` for 64+ qubits with `conditional=True` can cause a variety of failures throughout transpilation, depending on the particular ordering of passes run.

### How can we reproduce the issue?

One minimal example, which triggers a bug via `StochasticSwap`:

```python
from qiskit import transpile
from qiskit.transpiler import CouplingMap
from qiskit.circuit.random import random_circuit

qc = random_circuit(71, 71, measure=True, conditional=True)  # seed irrelevant
transpile(qc, coupling_map=CouplingMap.from_line(qc.num_qubits), optimization_level=0)
```
produces
```text
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-bfcfe1cad076> in <module>
      4
      5 qc = random_circuit(71, 71, measure=True, conditional=True)  # seed irrelevant
----> 6 transpile(qc, coupling_map=CouplingMap.from_line(qc.num_qubits), optimization_level=0)

# ... snip ...

~/code/qiskit/terra/qiskit/transpiler/passes/routing/stochastic_swap.py in _layer_update(self, dag, layer, best_layout, best_depth, best_circuit)
    253             logger.debug("layer_update: there are no swaps in this layer")
    254         # Output this layer
--> 255         dag.compose(layer["graph"], qubits=best_layout.reorder_bits(dag.qubits))
    256
    257     def _mapper(self, circuit_graph, coupling_graph, trials=20):

~/code/qiskit/terra/qiskit/dagcircuit/dagcircuit.py in compose(self, other, qubits, clbits, front, inplace)
    828                 pass
    829             elif isinstance(nd, DAGOpNode):
--> 830                 condition = dag._map_condition(
    831                     edge_map, getattr(nd.op, "condition", None), dag.cregs.values()
    832                 )

~/code/qiskit/terra/qiskit/dagcircuit/dagcircuit.py in _map_condition(wire_map, condition, target_cregs)
    691                     # same as the cond_val since the new_creg is also a single Clbit.
    692                     new_cond_val = cond_val
--> 693                 elif 2 ** (cond_creg[:].index(bit)) & cond_val:
    694                     # If the conditional values of the Clbit 'bit' is 1 then the new_cond_val
    695                     # is updated such that the conditional value of the Clbit to which 'bit'

TypeError: ufunc 'bitwise_and' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
```

### What should happen?

No type errors during compilation.

### Any suggestions?

The problem is that `random_circuit` outputs `numpy.uint64` values for the comparisons, but some points in the compiler stack need to re-map conditions, and use bitmasks against Python's bigint `int` type.  The fixed-width Numpy types don't support this if the Python int they're masking / being masked by don't fit.  `random_circuit` should be outputting the correct `int` type; this is compelled by the newer `IfElseOp` form, but not the old form.


Discussion:

Resolving patch:
diff --git a/qiskit/circuit/random/utils.py b/qiskit/circuit/random/utils.py
--- a/qiskit/circuit/random/utils.py
+++ b/qiskit/circuit/random/utils.py
@@ -191,7 +191,8 @@ def random_circuit(
             ):
                 operation = gate(*parameters[p_start:p_end])
                 if is_cond:
-                    operation.condition = (cr, condition_values[c_ptr])
+                    # The condition values are required to be bigints, not Numpy's fixed-width type.
+                    operation.condition = (cr, int(condition_values[c_ptr]))
                     c_ptr += 1
                 qc._append(CircuitInstruction(operation=operation, qubits=qubits[q_start:q_end]))
         else:


Test patch:
diff --git a/test/python/circuit/test_random_circuit.py b/test/python/circuit/test_random_circuit.py
--- a/test/python/circuit/test_random_circuit.py
+++ b/test/python/circuit/test_random_circuit.py
@@ -13,7 +13,7 @@
 
 """Test random circuit generation utility."""
 
-from qiskit.circuit import QuantumCircuit
+from qiskit.circuit import QuantumCircuit, ClassicalRegister, Clbit
 from qiskit.circuit import Measure
 from qiskit.circuit.random import random_circuit
 from qiskit.converters import circuit_to_dag
@@ -63,3 +63,8 @@ def test_large_conditional(self):
         conditions = (getattr(instruction.operation, "condition", None) for instruction in circ)
         conditions = [x for x in conditions if x is not None]
         self.assertNotEqual(conditions, [])
+        for (register, value) in conditions:
+            self.assertIsInstance(register, (ClassicalRegister, Clbit))
+            # Condition values always have to be Python bigints (of which `bool` is a subclass), not
+            # any of Numpy's fixed-width types, for example.
+            self.assertIsInstance(value, int)