|
15 | 15 | """Heuristic qubit routing algorithm based on arxiv:1902.08091."""
|
16 | 16 |
|
17 | 17 | from typing import Any, Dict, List, Optional, Set, Sequence, Tuple, TYPE_CHECKING
|
18 |
| -from itertools import combinations |
| 18 | +import itertools |
19 | 19 | import networkx as nx
|
20 | 20 |
|
21 | 21 | from cirq import circuits, ops, protocols
|
@@ -48,7 +48,9 @@ def _disjoint_nc2_combinations(
|
48 | 48 | Returns:
|
49 | 49 | All 2-combinations between qubit pairs that are disjoint.
|
50 | 50 | """
|
51 |
| - return [pair for pair in combinations(qubit_pairs, 2) if set(pair[0]).isdisjoint(pair[1])] |
| 51 | + return [ |
| 52 | + pair for pair in itertools.combinations(qubit_pairs, 2) if set(pair[0]).isdisjoint(pair[1]) |
| 53 | + ] |
52 | 54 |
|
53 | 55 |
|
54 | 56 | @transformer_api.transformer
|
@@ -245,17 +247,28 @@ def _get_one_and_two_qubit_ops_as_timesteps(
|
245 | 247 | The i'th entry in the nested two-qubit and single-qubit ops correspond to the two-qubit
|
246 | 248 | gates and single-qubit gates of the i'th timesteps respectively. When constructing the
|
247 | 249 | output routed circuit, single-qubit operations are inserted before two-qubit operations.
|
| 250 | +
|
| 251 | + Raises: |
| 252 | + ValueError: if circuit has intermediate measurement op's that act on 3 or more qubits. |
248 | 253 | """
|
249 | 254 | two_qubit_circuit = circuits.Circuit()
|
250 | 255 | single_qubit_ops: List[List[cirq.Operation]] = []
|
| 256 | + |
| 257 | + if any( |
| 258 | + protocols.num_qubits(op) > 2 and protocols.is_measurement(op) |
| 259 | + for op in itertools.chain(*circuit.moments[:-1]) |
| 260 | + ): |
| 261 | + # There is at least one non-terminal measurement on 3+ qubits |
| 262 | + raise ValueError('Non-terminal measurements on three or more qubits are not supported') |
| 263 | + |
251 | 264 | for moment in circuit:
|
252 | 265 | for op in moment:
|
253 | 266 | timestep = two_qubit_circuit.earliest_available_moment(op)
|
254 | 267 | single_qubit_ops.extend([] for _ in range(timestep + 1 - len(single_qubit_ops)))
|
255 | 268 | two_qubit_circuit.append(
|
256 | 269 | circuits.Moment() for _ in range(timestep + 1 - len(two_qubit_circuit))
|
257 | 270 | )
|
258 |
| - if protocols.num_qubits(op) == 2 and not protocols.is_measurement(op): |
| 271 | + if protocols.num_qubits(op) == 2: |
259 | 272 | two_qubit_circuit[timestep] = two_qubit_circuit[timestep].with_operation(op)
|
260 | 273 | else:
|
261 | 274 | single_qubit_ops[timestep].append(op)
|
|
0 commit comments