We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`random_circuit` does not include mid-circuit measurements
### What should we add?

`qiskit.circuit.utils.random_circuit` has a keyword argument `measure=False` that allows opt-in inclusion of an end-of-circuit measurement of all qubits: https://github.com/Qiskit/qiskit-terra/blob/ad7e609d10b02fd98090b0fac132113f329825b6/qiskit/circuit/random/utils.py#L50

It would be good to also be able to generalize this to be able to generate circuits which can additionally (and optionally) make of use mid-circuit measurement.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `qiskit/circuit/random/utils.py`
Content:
```
1 # This code is part of Qiskit.
2 #
3 # (C) Copyright IBM 2017.
4 #
5 # This code is licensed under the Apache License, Version 2.0. You may
6 # obtain a copy of this license in the LICENSE.txt file in the root directory
7 # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8 #
9 # Any modifications or derivative works of this code must retain this
10 # copyright notice, and modified files need to carry a notice indicating
11 # that they have been altered from the originals.
12 
13 """Utility functions for generating random circuits."""
14 
15 import numpy as np
16 
17 from qiskit.circuit import ClassicalRegister, QuantumCircuit, CircuitInstruction
18 from qiskit.circuit import Reset
19 from qiskit.circuit.library import standard_gates
20 from qiskit.circuit.exceptions import CircuitError
21 
22 
23 def random_circuit(
24     num_qubits, depth, max_operands=4, measure=False, conditional=False, reset=False, seed=None
25 ):
26     """Generate random circuit of arbitrary size and form.
27 
28     This function will generate a random circuit by randomly selecting gates
29     from the set of standard gates in :mod:`qiskit.extensions`. For example:
30 
31     .. plot::
32        :include-source:
33 
34        from qiskit.circuit.random import random_circuit
35 
36        circ = random_circuit(2, 2, measure=True)
37        circ.draw(output='mpl')
38 
39     Args:
40         num_qubits (int): number of quantum wires
41         depth (int): layers of operations (i.e. critical path length)
42         max_operands (int): maximum qubit operands of each gate (between 1 and 4)
43         measure (bool): if True, measure all qubits at the end
44         conditional (bool): if True, insert middle measurements and conditionals
45         reset (bool): if True, insert middle resets
46         seed (int): sets random seed (optional)
47 
48     Returns:
49         QuantumCircuit: constructed circuit
50 
51     Raises:
52         CircuitError: when invalid options given
53     """
54     if num_qubits == 0:
55         return QuantumCircuit()
56     if max_operands < 1 or max_operands > 4:
57         raise CircuitError("max_operands must be between 1 and 4")
58     max_operands = max_operands if num_qubits > max_operands else num_qubits
59 
60     gates_1q = [
61         # (Gate class, number of qubits, number of parameters)
62         (standard_gates.IGate, 1, 0),
63         (standard_gates.SXGate, 1, 0),
64         (standard_gates.XGate, 1, 0),
65         (standard_gates.RZGate, 1, 1),
66         (standard_gates.RGate, 1, 2),
67         (standard_gates.HGate, 1, 0),
68         (standard_gates.PhaseGate, 1, 1),
69         (standard_gates.RXGate, 1, 1),
70         (standard_gates.RYGate, 1, 1),
71         (standard_gates.SGate, 1, 0),
72         (standard_gates.SdgGate, 1, 0),
73         (standard_gates.SXdgGate, 1, 0),
74         (standard_gates.TGate, 1, 0),
75         (standard_gates.TdgGate, 1, 0),
76         (standard_gates.UGate, 1, 3),
77         (standard_gates.U1Gate, 1, 1),
78         (standard_gates.U2Gate, 1, 2),
79         (standard_gates.U3Gate, 1, 3),
80         (standard_gates.YGate, 1, 0),
81         (standard_gates.ZGate, 1, 0),
82     ]
83     if reset:
84         gates_1q.append((Reset, 1, 0))
85     gates_2q = [
86         (standard_gates.CXGate, 2, 0),
87         (standard_gates.DCXGate, 2, 0),
88         (standard_gates.CHGate, 2, 0),
89         (standard_gates.CPhaseGate, 2, 1),
90         (standard_gates.CRXGate, 2, 1),
91         (standard_gates.CRYGate, 2, 1),
92         (standard_gates.CRZGate, 2, 1),
93         (standard_gates.CSXGate, 2, 0),
94         (standard_gates.CUGate, 2, 4),
95         (standard_gates.CU1Gate, 2, 1),
96         (standard_gates.CU3Gate, 2, 3),
97         (standard_gates.CYGate, 2, 0),
98         (standard_gates.CZGate, 2, 0),
99         (standard_gates.RXXGate, 2, 1),
100         (standard_gates.RYYGate, 2, 1),
101         (standard_gates.RZZGate, 2, 1),
102         (standard_gates.RZXGate, 2, 1),
103         (standard_gates.XXMinusYYGate, 2, 2),
104         (standard_gates.XXPlusYYGate, 2, 2),
105         (standard_gates.ECRGate, 2, 0),
106         (standard_gates.CSGate, 2, 0),
107         (standard_gates.CSdgGate, 2, 0),
108         (standard_gates.SwapGate, 2, 0),
109         (standard_gates.iSwapGate, 2, 0),
110     ]
111     gates_3q = [
112         (standard_gates.CCXGate, 3, 0),
113         (standard_gates.CSwapGate, 3, 0),
114         (standard_gates.CCZGate, 3, 0),
115         (standard_gates.RCCXGate, 3, 0),
116     ]
117     gates_4q = [
118         (standard_gates.C3SXGate, 4, 0),
119         (standard_gates.RC3XGate, 4, 0),
120     ]
121 
122     gates = gates_1q.copy()
123     if max_operands >= 2:
124         gates.extend(gates_2q)
125     if max_operands >= 3:
126         gates.extend(gates_3q)
127     if max_operands >= 4:
128         gates.extend(gates_4q)
129     gates = np.array(
130         gates, dtype=[("class", object), ("num_qubits", np.int64), ("num_params", np.int64)]
131     )
132     gates_1q = np.array(gates_1q, dtype=gates.dtype)
133 
134     qc = QuantumCircuit(num_qubits)
135 
136     if measure or conditional:
137         cr = ClassicalRegister(num_qubits, "c")
138         qc.add_register(cr)
139 
140     if seed is None:
141         seed = np.random.randint(0, np.iinfo(np.int32).max)
142     rng = np.random.default_rng(seed)
143 
144     qubits = np.array(qc.qubits, dtype=object, copy=True)
145 
146     # Apply arbitrary random operations in layers across all qubits.
147     for _ in range(depth):
148         # We generate all the randomness for the layer in one go, to avoid many separate calls to
149         # the randomisation routines, which can be fairly slow.
150 
151         # This reliably draws too much randomness, but it's less expensive than looping over more
152         # calls to the rng. After, trim it down by finding the point when we've used all the qubits.
153         gate_specs = rng.choice(gates, size=len(qubits))
154         cumulative_qubits = np.cumsum(gate_specs["num_qubits"], dtype=np.int64)
155         # Efficiently find the point in the list where the total gates would use as many as
156         # possible of, but not more than, the number of qubits in the layer.  If there's slack, fill
157         # it with 1q gates.
158         max_index = np.searchsorted(cumulative_qubits, num_qubits, side="right")
159         gate_specs = gate_specs[:max_index]
160         slack = num_qubits - cumulative_qubits[max_index - 1]
161         if slack:
162             gate_specs = np.hstack((gate_specs, rng.choice(gates_1q, size=slack)))
163 
164         # For efficiency in the Python loop, this uses Numpy vectorisation to pre-calculate the
165         # indices into the lists of qubits and parameters for every gate, and then suitably
166         # randomises those lists.
167         q_indices = np.empty(len(gate_specs) + 1, dtype=np.int64)
168         p_indices = np.empty(len(gate_specs) + 1, dtype=np.int64)
169         q_indices[0] = p_indices[0] = 0
170         np.cumsum(gate_specs["num_qubits"], out=q_indices[1:])
171         np.cumsum(gate_specs["num_params"], out=p_indices[1:])
172         parameters = rng.uniform(0, 2 * np.pi, size=p_indices[-1])
173         rng.shuffle(qubits)
174 
175         # We've now generated everything we're going to need.  Now just to add everything.  The
176         # conditional check is outside the two loops to make the more common case of no conditionals
177         # faster, since in Python we don't have a compiler to do this for us.
178         if conditional:
179             is_conditional = rng.random(size=len(gate_specs)) < 0.1
180             condition_values = rng.integers(
181                 0, 1 << min(num_qubits, 63), size=np.count_nonzero(is_conditional)
182             )
183             c_ptr = 0
184             for gate, q_start, q_end, p_start, p_end, is_cond in zip(
185                 gate_specs["class"],
186                 q_indices[:-1],
187                 q_indices[1:],
188                 p_indices[:-1],
189                 p_indices[1:],
190                 is_conditional,
191             ):
192                 operation = gate(*parameters[p_start:p_end])
193                 if is_cond:
194                     # The condition values are required to be bigints, not Numpy's fixed-width type.
195                     operation.condition = (cr, int(condition_values[c_ptr]))
196                     c_ptr += 1
197                 qc._append(CircuitInstruction(operation=operation, qubits=qubits[q_start:q_end]))
198         else:
199             for gate, q_start, q_end, p_start, p_end in zip(
200                 gate_specs["class"], q_indices[:-1], q_indices[1:], p_indices[:-1], p_indices[1:]
201             ):
202                 operation = gate(*parameters[p_start:p_end])
203                 qc._append(CircuitInstruction(operation=operation, qubits=qubits[q_start:q_end]))
204 
205     if measure:
206         qc.measure(qc.qubits, cr)
207 
208     return qc
209
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

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
@@ -144,7 +144,7 @@
     qubits = np.array(qc.qubits, dtype=object, copy=True)
 
     # Apply arbitrary random operations in layers across all qubits.
-    for _ in range(depth):
+    for layer_number in range(depth):
         # We generate all the randomness for the layer in one go, to avoid many separate calls to
         # the randomisation routines, which can be fairly slow.
 
@@ -175,7 +175,7 @@
         # We've now generated everything we're going to need.  Now just to add everything.  The
         # conditional check is outside the two loops to make the more common case of no conditionals
         # faster, since in Python we don't have a compiler to do this for us.
-        if conditional:
+        if conditional and layer_number != 0:
             is_conditional = rng.random(size=len(gate_specs)) < 0.1
             condition_values = rng.integers(
                 0, 1 << min(num_qubits, 63), size=np.count_nonzero(is_conditional)
@@ -191,6 +191,7 @@
             ):
                 operation = gate(*parameters[p_start:p_end])
                 if is_cond:
+                    qc.measure(qc.qubits, cr)
                     # 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

{"golden_diff": "diff --git a/qiskit/circuit/random/utils.py b/qiskit/circuit/random/utils.py\n--- a/qiskit/circuit/random/utils.py\n+++ b/qiskit/circuit/random/utils.py\n@@ -144,7 +144,7 @@\n     qubits = np.array(qc.qubits, dtype=object, copy=True)\n \n     # Apply arbitrary random operations in layers across all qubits.\n-    for _ in range(depth):\n+    for layer_number in range(depth):\n         # We generate all the randomness for the layer in one go, to avoid many separate calls to\n         # the randomisation routines, which can be fairly slow.\n \n@@ -175,7 +175,7 @@\n         # We've now generated everything we're going to need.  Now just to add everything.  The\n         # conditional check is outside the two loops to make the more common case of no conditionals\n         # faster, since in Python we don't have a compiler to do this for us.\n-        if conditional:\n+        if conditional and layer_number != 0:\n             is_conditional = rng.random(size=len(gate_specs)) < 0.1\n             condition_values = rng.integers(\n                 0, 1 << min(num_qubits, 63), size=np.count_nonzero(is_conditional)\n@@ -191,6 +191,7 @@\n             ):\n                 operation = gate(*parameters[p_start:p_end])\n                 if is_cond:\n+                    qc.measure(qc.qubits, cr)\n                     # The condition values are required to be bigints, not Numpy's fixed-width type.\n                     operation.condition = (cr, int(condition_values[c_ptr]))\n                     c_ptr += 1\n", "issue": "`random_circuit` does not include mid-circuit measurements\n### What should we add?\n\n`qiskit.circuit.utils.random_circuit` has a keyword argument `measure=False` that allows opt-in inclusion of an end-of-circuit measurement of all qubits: https://github.com/Qiskit/qiskit-terra/blob/ad7e609d10b02fd98090b0fac132113f329825b6/qiskit/circuit/random/utils.py#L50\r\n\r\nIt would be good to also be able to generalize this to be able to generate circuits which can additionally (and optionally) make of use mid-circuit measurement.\n", "before_files": [{"content": "# This code is part of Qiskit.\n#\n# (C) Copyright IBM 2017.\n#\n# This code is licensed under the Apache License, Version 2.0. You may\n# obtain a copy of this license in the LICENSE.txt file in the root directory\n# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.\n#\n# Any modifications or derivative works of this code must retain this\n# copyright notice, and modified files need to carry a notice indicating\n# that they have been altered from the originals.\n\n\"\"\"Utility functions for generating random circuits.\"\"\"\n\nimport numpy as np\n\nfrom qiskit.circuit import ClassicalRegister, QuantumCircuit, CircuitInstruction\nfrom qiskit.circuit import Reset\nfrom qiskit.circuit.library import standard_gates\nfrom qiskit.circuit.exceptions import CircuitError\n\n\ndef random_circuit(\n    num_qubits, depth, max_operands=4, measure=False, conditional=False, reset=False, seed=None\n):\n    \"\"\"Generate random circuit of arbitrary size and form.\n\n    This function will generate a random circuit by randomly selecting gates\n    from the set of standard gates in :mod:`qiskit.extensions`. For example:\n\n    .. plot::\n       :include-source:\n\n       from qiskit.circuit.random import random_circuit\n\n       circ = random_circuit(2, 2, measure=True)\n       circ.draw(output='mpl')\n\n    Args:\n        num_qubits (int): number of quantum wires\n        depth (int): layers of operations (i.e. critical path length)\n        max_operands (int): maximum qubit operands of each gate (between 1 and 4)\n        measure (bool): if True, measure all qubits at the end\n        conditional (bool): if True, insert middle measurements and conditionals\n        reset (bool): if True, insert middle resets\n        seed (int): sets random seed (optional)\n\n    Returns:\n        QuantumCircuit: constructed circuit\n\n    Raises:\n        CircuitError: when invalid options given\n    \"\"\"\n    if num_qubits == 0:\n        return QuantumCircuit()\n    if max_operands < 1 or max_operands > 4:\n        raise CircuitError(\"max_operands must be between 1 and 4\")\n    max_operands = max_operands if num_qubits > max_operands else num_qubits\n\n    gates_1q = [\n        # (Gate class, number of qubits, number of parameters)\n        (standard_gates.IGate, 1, 0),\n        (standard_gates.SXGate, 1, 0),\n        (standard_gates.XGate, 1, 0),\n        (standard_gates.RZGate, 1, 1),\n        (standard_gates.RGate, 1, 2),\n        (standard_gates.HGate, 1, 0),\n        (standard_gates.PhaseGate, 1, 1),\n        (standard_gates.RXGate, 1, 1),\n        (standard_gates.RYGate, 1, 1),\n        (standard_gates.SGate, 1, 0),\n        (standard_gates.SdgGate, 1, 0),\n        (standard_gates.SXdgGate, 1, 0),\n        (standard_gates.TGate, 1, 0),\n        (standard_gates.TdgGate, 1, 0),\n        (standard_gates.UGate, 1, 3),\n        (standard_gates.U1Gate, 1, 1),\n        (standard_gates.U2Gate, 1, 2),\n        (standard_gates.U3Gate, 1, 3),\n        (standard_gates.YGate, 1, 0),\n        (standard_gates.ZGate, 1, 0),\n    ]\n    if reset:\n        gates_1q.append((Reset, 1, 0))\n    gates_2q = [\n        (standard_gates.CXGate, 2, 0),\n        (standard_gates.DCXGate, 2, 0),\n        (standard_gates.CHGate, 2, 0),\n        (standard_gates.CPhaseGate, 2, 1),\n        (standard_gates.CRXGate, 2, 1),\n        (standard_gates.CRYGate, 2, 1),\n        (standard_gates.CRZGate, 2, 1),\n        (standard_gates.CSXGate, 2, 0),\n        (standard_gates.CUGate, 2, 4),\n        (standard_gates.CU1Gate, 2, 1),\n        (standard_gates.CU3Gate, 2, 3),\n        (standard_gates.CYGate, 2, 0),\n        (standard_gates.CZGate, 2, 0),\n        (standard_gates.RXXGate, 2, 1),\n        (standard_gates.RYYGate, 2, 1),\n        (standard_gates.RZZGate, 2, 1),\n        (standard_gates.RZXGate, 2, 1),\n        (standard_gates.XXMinusYYGate, 2, 2),\n        (standard_gates.XXPlusYYGate, 2, 2),\n        (standard_gates.ECRGate, 2, 0),\n        (standard_gates.CSGate, 2, 0),\n        (standard_gates.CSdgGate, 2, 0),\n        (standard_gates.SwapGate, 2, 0),\n        (standard_gates.iSwapGate, 2, 0),\n    ]\n    gates_3q = [\n        (standard_gates.CCXGate, 3, 0),\n        (standard_gates.CSwapGate, 3, 0),\n        (standard_gates.CCZGate, 3, 0),\n        (standard_gates.RCCXGate, 3, 0),\n    ]\n    gates_4q = [\n        (standard_gates.C3SXGate, 4, 0),\n        (standard_gates.RC3XGate, 4, 0),\n    ]\n\n    gates = gates_1q.copy()\n    if max_operands >= 2:\n        gates.extend(gates_2q)\n    if max_operands >= 3:\n        gates.extend(gates_3q)\n    if max_operands >= 4:\n        gates.extend(gates_4q)\n    gates = np.array(\n        gates, dtype=[(\"class\", object), (\"num_qubits\", np.int64), (\"num_params\", np.int64)]\n    )\n    gates_1q = np.array(gates_1q, dtype=gates.dtype)\n\n    qc = QuantumCircuit(num_qubits)\n\n    if measure or conditional:\n        cr = ClassicalRegister(num_qubits, \"c\")\n        qc.add_register(cr)\n\n    if seed is None:\n        seed = np.random.randint(0, np.iinfo(np.int32).max)\n    rng = np.random.default_rng(seed)\n\n    qubits = np.array(qc.qubits, dtype=object, copy=True)\n\n    # Apply arbitrary random operations in layers across all qubits.\n    for _ in range(depth):\n        # We generate all the randomness for the layer in one go, to avoid many separate calls to\n        # the randomisation routines, which can be fairly slow.\n\n        # This reliably draws too much randomness, but it's less expensive than looping over more\n        # calls to the rng. After, trim it down by finding the point when we've used all the qubits.\n        gate_specs = rng.choice(gates, size=len(qubits))\n        cumulative_qubits = np.cumsum(gate_specs[\"num_qubits\"], dtype=np.int64)\n        # Efficiently find the point in the list where the total gates would use as many as\n        # possible of, but not more than, the number of qubits in the layer.  If there's slack, fill\n        # it with 1q gates.\n        max_index = np.searchsorted(cumulative_qubits, num_qubits, side=\"right\")\n        gate_specs = gate_specs[:max_index]\n        slack = num_qubits - cumulative_qubits[max_index - 1]\n        if slack:\n            gate_specs = np.hstack((gate_specs, rng.choice(gates_1q, size=slack)))\n\n        # For efficiency in the Python loop, this uses Numpy vectorisation to pre-calculate the\n        # indices into the lists of qubits and parameters for every gate, and then suitably\n        # randomises those lists.\n        q_indices = np.empty(len(gate_specs) + 1, dtype=np.int64)\n        p_indices = np.empty(len(gate_specs) + 1, dtype=np.int64)\n        q_indices[0] = p_indices[0] = 0\n        np.cumsum(gate_specs[\"num_qubits\"], out=q_indices[1:])\n        np.cumsum(gate_specs[\"num_params\"], out=p_indices[1:])\n        parameters = rng.uniform(0, 2 * np.pi, size=p_indices[-1])\n        rng.shuffle(qubits)\n\n        # We've now generated everything we're going to need.  Now just to add everything.  The\n        # conditional check is outside the two loops to make the more common case of no conditionals\n        # faster, since in Python we don't have a compiler to do this for us.\n        if conditional:\n            is_conditional = rng.random(size=len(gate_specs)) < 0.1\n            condition_values = rng.integers(\n                0, 1 << min(num_qubits, 63), size=np.count_nonzero(is_conditional)\n            )\n            c_ptr = 0\n            for gate, q_start, q_end, p_start, p_end, is_cond in zip(\n                gate_specs[\"class\"],\n                q_indices[:-1],\n                q_indices[1:],\n                p_indices[:-1],\n                p_indices[1:],\n                is_conditional,\n            ):\n                operation = gate(*parameters[p_start:p_end])\n                if is_cond:\n                    # The condition values are required to be bigints, not Numpy's fixed-width type.\n                    operation.condition = (cr, int(condition_values[c_ptr]))\n                    c_ptr += 1\n                qc._append(CircuitInstruction(operation=operation, qubits=qubits[q_start:q_end]))\n        else:\n            for gate, q_start, q_end, p_start, p_end in zip(\n                gate_specs[\"class\"], q_indices[:-1], q_indices[1:], p_indices[:-1], p_indices[1:]\n            ):\n                operation = gate(*parameters[p_start:p_end])\n                qc._append(CircuitInstruction(operation=operation, qubits=qubits[q_start:q_end]))\n\n    if measure:\n        qc.measure(qc.qubits, cr)\n\n    return qc\n", "path": "qiskit/circuit/random/utils.py"}], "after_files": [{"content": "# This code is part of Qiskit.\n#\n# (C) Copyright IBM 2017.\n#\n# This code is licensed under the Apache License, Version 2.0. You may\n# obtain a copy of this license in the LICENSE.txt file in the root directory\n# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.\n#\n# Any modifications or derivative works of this code must retain this\n# copyright notice, and modified files need to carry a notice indicating\n# that they have been altered from the originals.\n\n\"\"\"Utility functions for generating random circuits.\"\"\"\n\nimport numpy as np\n\nfrom qiskit.circuit import ClassicalRegister, QuantumCircuit, CircuitInstruction\nfrom qiskit.circuit import Reset\nfrom qiskit.circuit.library import standard_gates\nfrom qiskit.circuit.exceptions import CircuitError\n\n\ndef random_circuit(\n    num_qubits, depth, max_operands=4, measure=False, conditional=False, reset=False, seed=None\n):\n    \"\"\"Generate random circuit of arbitrary size and form.\n\n    This function will generate a random circuit by randomly selecting gates\n    from the set of standard gates in :mod:`qiskit.extensions`. For example:\n\n    .. plot::\n       :include-source:\n\n       from qiskit.circuit.random import random_circuit\n\n       circ = random_circuit(2, 2, measure=True)\n       circ.draw(output='mpl')\n\n    Args:\n        num_qubits (int): number of quantum wires\n        depth (int): layers of operations (i.e. critical path length)\n        max_operands (int): maximum qubit operands of each gate (between 1 and 4)\n        measure (bool): if True, measure all qubits at the end\n        conditional (bool): if True, insert middle measurements and conditionals\n        reset (bool): if True, insert middle resets\n        seed (int): sets random seed (optional)\n\n    Returns:\n        QuantumCircuit: constructed circuit\n\n    Raises:\n        CircuitError: when invalid options given\n    \"\"\"\n    if num_qubits == 0:\n        return QuantumCircuit()\n    if max_operands < 1 or max_operands > 4:\n        raise CircuitError(\"max_operands must be between 1 and 4\")\n    max_operands = max_operands if num_qubits > max_operands else num_qubits\n\n    gates_1q = [\n        # (Gate class, number of qubits, number of parameters)\n        (standard_gates.IGate, 1, 0),\n        (standard_gates.SXGate, 1, 0),\n        (standard_gates.XGate, 1, 0),\n        (standard_gates.RZGate, 1, 1),\n        (standard_gates.RGate, 1, 2),\n        (standard_gates.HGate, 1, 0),\n        (standard_gates.PhaseGate, 1, 1),\n        (standard_gates.RXGate, 1, 1),\n        (standard_gates.RYGate, 1, 1),\n        (standard_gates.SGate, 1, 0),\n        (standard_gates.SdgGate, 1, 0),\n        (standard_gates.SXdgGate, 1, 0),\n        (standard_gates.TGate, 1, 0),\n        (standard_gates.TdgGate, 1, 0),\n        (standard_gates.UGate, 1, 3),\n        (standard_gates.U1Gate, 1, 1),\n        (standard_gates.U2Gate, 1, 2),\n        (standard_gates.U3Gate, 1, 3),\n        (standard_gates.YGate, 1, 0),\n        (standard_gates.ZGate, 1, 0),\n    ]\n    if reset:\n        gates_1q.append((Reset, 1, 0))\n    gates_2q = [\n        (standard_gates.CXGate, 2, 0),\n        (standard_gates.DCXGate, 2, 0),\n        (standard_gates.CHGate, 2, 0),\n        (standard_gates.CPhaseGate, 2, 1),\n        (standard_gates.CRXGate, 2, 1),\n        (standard_gates.CRYGate, 2, 1),\n        (standard_gates.CRZGate, 2, 1),\n        (standard_gates.CSXGate, 2, 0),\n        (standard_gates.CUGate, 2, 4),\n        (standard_gates.CU1Gate, 2, 1),\n        (standard_gates.CU3Gate, 2, 3),\n        (standard_gates.CYGate, 2, 0),\n        (standard_gates.CZGate, 2, 0),\n        (standard_gates.RXXGate, 2, 1),\n        (standard_gates.RYYGate, 2, 1),\n        (standard_gates.RZZGate, 2, 1),\n        (standard_gates.RZXGate, 2, 1),\n        (standard_gates.XXMinusYYGate, 2, 2),\n        (standard_gates.XXPlusYYGate, 2, 2),\n        (standard_gates.ECRGate, 2, 0),\n        (standard_gates.CSGate, 2, 0),\n        (standard_gates.CSdgGate, 2, 0),\n        (standard_gates.SwapGate, 2, 0),\n        (standard_gates.iSwapGate, 2, 0),\n    ]\n    gates_3q = [\n        (standard_gates.CCXGate, 3, 0),\n        (standard_gates.CSwapGate, 3, 0),\n        (standard_gates.CCZGate, 3, 0),\n        (standard_gates.RCCXGate, 3, 0),\n    ]\n    gates_4q = [\n        (standard_gates.C3SXGate, 4, 0),\n        (standard_gates.RC3XGate, 4, 0),\n    ]\n\n    gates = gates_1q.copy()\n    if max_operands >= 2:\n        gates.extend(gates_2q)\n    if max_operands >= 3:\n        gates.extend(gates_3q)\n    if max_operands >= 4:\n        gates.extend(gates_4q)\n    gates = np.array(\n        gates, dtype=[(\"class\", object), (\"num_qubits\", np.int64), (\"num_params\", np.int64)]\n    )\n    gates_1q = np.array(gates_1q, dtype=gates.dtype)\n\n    qc = QuantumCircuit(num_qubits)\n\n    if measure or conditional:\n        cr = ClassicalRegister(num_qubits, \"c\")\n        qc.add_register(cr)\n\n    if seed is None:\n        seed = np.random.randint(0, np.iinfo(np.int32).max)\n    rng = np.random.default_rng(seed)\n\n    qubits = np.array(qc.qubits, dtype=object, copy=True)\n\n    # Apply arbitrary random operations in layers across all qubits.\n    for layer_number in range(depth):\n        # We generate all the randomness for the layer in one go, to avoid many separate calls to\n        # the randomisation routines, which can be fairly slow.\n\n        # This reliably draws too much randomness, but it's less expensive than looping over more\n        # calls to the rng. After, trim it down by finding the point when we've used all the qubits.\n        gate_specs = rng.choice(gates, size=len(qubits))\n        cumulative_qubits = np.cumsum(gate_specs[\"num_qubits\"], dtype=np.int64)\n        # Efficiently find the point in the list where the total gates would use as many as\n        # possible of, but not more than, the number of qubits in the layer.  If there's slack, fill\n        # it with 1q gates.\n        max_index = np.searchsorted(cumulative_qubits, num_qubits, side=\"right\")\n        gate_specs = gate_specs[:max_index]\n        slack = num_qubits - cumulative_qubits[max_index - 1]\n        if slack:\n            gate_specs = np.hstack((gate_specs, rng.choice(gates_1q, size=slack)))\n\n        # For efficiency in the Python loop, this uses Numpy vectorisation to pre-calculate the\n        # indices into the lists of qubits and parameters for every gate, and then suitably\n        # randomises those lists.\n        q_indices = np.empty(len(gate_specs) + 1, dtype=np.int64)\n        p_indices = np.empty(len(gate_specs) + 1, dtype=np.int64)\n        q_indices[0] = p_indices[0] = 0\n        np.cumsum(gate_specs[\"num_qubits\"], out=q_indices[1:])\n        np.cumsum(gate_specs[\"num_params\"], out=p_indices[1:])\n        parameters = rng.uniform(0, 2 * np.pi, size=p_indices[-1])\n        rng.shuffle(qubits)\n\n        # We've now generated everything we're going to need.  Now just to add everything.  The\n        # conditional check is outside the two loops to make the more common case of no conditionals\n        # faster, since in Python we don't have a compiler to do this for us.\n        if conditional and layer_number != 0:\n            is_conditional = rng.random(size=len(gate_specs)) < 0.1\n            condition_values = rng.integers(\n                0, 1 << min(num_qubits, 63), size=np.count_nonzero(is_conditional)\n            )\n            c_ptr = 0\n            for gate, q_start, q_end, p_start, p_end, is_cond in zip(\n                gate_specs[\"class\"],\n                q_indices[:-1],\n                q_indices[1:],\n                p_indices[:-1],\n                p_indices[1:],\n                is_conditional,\n            ):\n                operation = gate(*parameters[p_start:p_end])\n                if is_cond:\n                    qc.measure(qc.qubits, cr)\n                    # The condition values are required to be bigints, not Numpy's fixed-width type.\n                    operation.condition = (cr, int(condition_values[c_ptr]))\n                    c_ptr += 1\n                qc._append(CircuitInstruction(operation=operation, qubits=qubits[q_start:q_end]))\n        else:\n            for gate, q_start, q_end, p_start, p_end in zip(\n                gate_specs[\"class\"], q_indices[:-1], q_indices[1:], p_indices[:-1], p_indices[1:]\n            ):\n                operation = gate(*parameters[p_start:p_end])\n                qc._append(CircuitInstruction(operation=operation, qubits=qubits[q_start:q_end]))\n\n    if measure:\n        qc.measure(qc.qubits, cr)\n\n    return qc\n", "path": "qiskit/circuit/random/utils.py"}]}