cirq-core 1.6.0.dev20250520054601__py3-none-any.whl → 1.6.0.dev20250520183459__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cirq-core might be problematic. Click here for more details.
- cirq/_compat.py +15 -17
- cirq/_compat_test.py +6 -9
- cirq/_doc.py +2 -2
- cirq/_import.py +6 -6
- cirq/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/_block_diagram_drawer.py +9 -10
- cirq/circuits/_box_drawing_character_data.py +6 -8
- cirq/circuits/_bucket_priority_queue.py +7 -7
- cirq/circuits/circuit.py +118 -125
- cirq/circuits/circuit_operation.py +38 -52
- cirq/circuits/circuit_test.py +4 -4
- cirq/circuits/frozen_circuit.py +13 -23
- cirq/circuits/moment.py +23 -29
- cirq/circuits/optimization_pass.py +4 -4
- cirq/circuits/optimization_pass_test.py +4 -6
- cirq/circuits/qasm_output.py +11 -11
- cirq/circuits/text_diagram_drawer.py +21 -36
- cirq/contrib/acquaintance/bipartite.py +5 -8
- cirq/contrib/acquaintance/executor.py +5 -5
- cirq/contrib/acquaintance/executor_test.py +3 -3
- cirq/contrib/acquaintance/gates.py +16 -26
- cirq/contrib/acquaintance/gates_test.py +3 -3
- cirq/contrib/acquaintance/mutation_utils.py +4 -4
- cirq/contrib/acquaintance/optimizers.py +4 -4
- cirq/contrib/acquaintance/permutation.py +15 -27
- cirq/contrib/acquaintance/shift.py +3 -3
- cirq/contrib/acquaintance/shift_swap_network.py +4 -4
- cirq/contrib/acquaintance/strategies/cubic.py +2 -2
- cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
- cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
- cirq/contrib/circuitdag/circuit_dag.py +2 -2
- cirq/contrib/custom_simulators/custom_state_simulator.py +3 -3
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +4 -4
- cirq/contrib/graph_device/graph_device.py +5 -5
- cirq/contrib/graph_device/hypergraph.py +12 -12
- cirq/contrib/graph_device/uniform_graph_device.py +4 -4
- cirq/contrib/paulistring/clifford_optimize.py +2 -2
- cirq/contrib/paulistring/clifford_target_gateset.py +7 -7
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +31 -31
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +23 -23
- cirq/contrib/paulistring/recombine.py +3 -3
- cirq/contrib/paulistring/separate.py +2 -2
- cirq/contrib/qasm_import/_parser.py +20 -32
- cirq/contrib/qcircuit/qcircuit_diagram_info.py +3 -5
- cirq/contrib/quantum_volume/quantum_volume.py +24 -24
- cirq/contrib/quimb/density_matrix.py +12 -14
- cirq/contrib/quimb/mps_simulator.py +20 -20
- cirq/contrib/quimb/state_vector.py +6 -10
- cirq/contrib/quirk/export_to_quirk.py +3 -3
- cirq/contrib/quirk/quirk_gate.py +15 -15
- cirq/contrib/routing/device.py +3 -3
- cirq/contrib/routing/greedy.py +10 -21
- cirq/contrib/routing/initialization.py +2 -2
- cirq/contrib/routing/swap_network.py +3 -3
- cirq/contrib/routing/utils.py +2 -2
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +8 -8
- cirq/contrib/svg/svg.py +3 -3
- cirq/devices/grid_device_metadata.py +10 -10
- cirq/devices/grid_qubit.py +20 -20
- cirq/devices/insertion_noise_model.py +5 -5
- cirq/devices/line_qubit.py +13 -13
- cirq/devices/named_topologies.py +18 -29
- cirq/devices/noise_model.py +3 -3
- cirq/devices/noise_properties.py +2 -2
- cirq/devices/noise_properties_test.py +1 -3
- cirq/devices/noise_utils.py +7 -7
- cirq/devices/superconducting_qubits_noise_properties.py +21 -21
- cirq/devices/superconducting_qubits_noise_properties_test.py +5 -7
- cirq/devices/thermal_noise_model.py +14 -14
- cirq/devices/unconstrained_device.py +2 -2
- cirq/experiments/benchmarking/parallel_xeb.py +29 -31
- cirq/experiments/n_qubit_tomography.py +5 -7
- cirq/experiments/qubit_characterizations.py +29 -40
- cirq/experiments/qubit_characterizations_test.py +1 -1
- cirq/experiments/random_quantum_circuit_generation.py +19 -33
- cirq/experiments/random_quantum_circuit_generation_test.py +6 -6
- cirq/experiments/readout_confusion_matrix.py +14 -14
- cirq/experiments/single_qubit_readout_calibration.py +12 -12
- cirq/experiments/t2_decay_experiment.py +7 -7
- cirq/experiments/two_qubit_xeb.py +32 -32
- cirq/experiments/two_qubit_xeb_test.py +5 -5
- cirq/experiments/xeb_fitting.py +25 -25
- cirq/experiments/xeb_sampling.py +22 -33
- cirq/experiments/xeb_simulation.py +5 -5
- cirq/experiments/xeb_simulation_test.py +3 -3
- cirq/experiments/z_phase_calibration.py +19 -19
- cirq/interop/quirk/cells/arithmetic_cells.py +23 -36
- cirq/interop/quirk/cells/cell.py +9 -21
- cirq/interop/quirk/cells/composite_cell.py +7 -22
- cirq/interop/quirk/cells/control_cells.py +8 -8
- cirq/interop/quirk/cells/input_cells.py +4 -4
- cirq/interop/quirk/cells/input_rotation_cells.py +5 -5
- cirq/interop/quirk/cells/parse.py +20 -23
- cirq/interop/quirk/cells/qubit_permutation_cells.py +3 -3
- cirq/interop/quirk/cells/swap_cell.py +3 -3
- cirq/interop/quirk/cells/testing.py +5 -7
- cirq/interop/quirk/url_to_circuit.py +17 -33
- cirq/json_resolver_cache.py +6 -6
- cirq/linalg/decompositions.py +20 -31
- cirq/linalg/diagonalize.py +4 -4
- cirq/linalg/diagonalize_test.py +3 -4
- cirq/linalg/operator_spaces.py +5 -5
- cirq/linalg/predicates.py +7 -7
- cirq/linalg/transformations.py +20 -20
- cirq/ops/arithmetic_operation.py +13 -15
- cirq/ops/boolean_hamiltonian.py +17 -17
- cirq/ops/classically_controlled_operation.py +13 -25
- cirq/ops/clifford_gate.py +31 -35
- cirq/ops/clifford_gate_test.py +2 -3
- cirq/ops/common_channels.py +30 -32
- cirq/ops/common_gates.py +64 -74
- cirq/ops/control_values.py +12 -12
- cirq/ops/controlled_gate.py +15 -30
- cirq/ops/controlled_gate_test.py +5 -5
- cirq/ops/controlled_operation.py +12 -25
- cirq/ops/controlled_operation_test.py +5 -5
- cirq/ops/dense_pauli_string.py +23 -34
- cirq/ops/dense_pauli_string_test.py +1 -2
- cirq/ops/diagonal_gate.py +9 -20
- cirq/ops/diagonal_gate_test.py +1 -3
- cirq/ops/eigen_gate.py +11 -23
- cirq/ops/eigen_gate_test.py +6 -8
- cirq/ops/fourier_transform.py +5 -5
- cirq/ops/fsim_gate.py +14 -14
- cirq/ops/gate_operation.py +23 -44
- cirq/ops/gateset.py +23 -37
- cirq/ops/gateset_test.py +2 -2
- cirq/ops/global_phase_op.py +8 -10
- cirq/ops/greedy_qubit_manager.py +6 -6
- cirq/ops/identity.py +9 -9
- cirq/ops/kraus_channel.py +7 -7
- cirq/ops/linear_combinations.py +29 -48
- cirq/ops/matrix_gates.py +8 -8
- cirq/ops/measure_util.py +13 -14
- cirq/ops/measurement_gate.py +18 -29
- cirq/ops/mixed_unitary_channel.py +8 -8
- cirq/ops/named_qubit.py +10 -10
- cirq/ops/op_tree.py +7 -7
- cirq/ops/parallel_gate.py +5 -5
- cirq/ops/parity_gates.py +14 -14
- cirq/ops/pauli_gates.py +8 -10
- cirq/ops/pauli_interaction_gate.py +6 -6
- cirq/ops/pauli_measurement_gate.py +11 -23
- cirq/ops/pauli_string.py +35 -52
- cirq/ops/pauli_string_phasor.py +4 -14
- cirq/ops/pauli_string_raw_types.py +3 -3
- cirq/ops/pauli_sum_exponential.py +2 -2
- cirq/ops/permutation_gate.py +4 -4
- cirq/ops/phased_iswap_gate.py +9 -9
- cirq/ops/phased_x_gate.py +10 -10
- cirq/ops/phased_x_z_gate.py +11 -11
- cirq/ops/projector.py +6 -6
- cirq/ops/qubit_manager.py +6 -6
- cirq/ops/qubit_order.py +3 -3
- cirq/ops/random_gate_channel.py +4 -4
- cirq/ops/raw_types.py +48 -70
- cirq/ops/state_preparation_channel.py +3 -3
- cirq/ops/swap_gates.py +9 -9
- cirq/ops/tags.py +2 -4
- cirq/ops/three_qubit_gates.py +20 -38
- cirq/ops/two_qubit_diagonal_gate.py +5 -5
- cirq/ops/uniform_superposition_gate.py +2 -2
- cirq/ops/wait_gate.py +5 -5
- cirq/protocols/act_on_protocol_test.py +3 -3
- cirq/protocols/apply_channel_protocol.py +8 -14
- cirq/protocols/apply_mixture_protocol.py +14 -16
- cirq/protocols/apply_mixture_protocol_test.py +5 -6
- cirq/protocols/apply_unitary_protocol.py +17 -19
- cirq/protocols/circuit_diagram_info_protocol.py +19 -30
- cirq/protocols/decompose_protocol.py +30 -34
- cirq/protocols/inverse_protocol.py +7 -7
- cirq/protocols/json_serialization.py +32 -51
- cirq/protocols/json_serialization_test.py +9 -10
- cirq/protocols/kraus_protocol.py +4 -4
- cirq/protocols/kraus_protocol_test.py +3 -3
- cirq/protocols/measurement_key_protocol.py +11 -13
- cirq/protocols/mixture_protocol.py +4 -4
- cirq/protocols/qasm.py +11 -13
- cirq/protocols/qid_shape_protocol.py +6 -8
- cirq/qis/clifford_tableau.py +12 -12
- cirq/qis/measures.py +7 -7
- cirq/qis/quantum_state_representation.py +3 -3
- cirq/qis/states.py +51 -51
- cirq/sim/classical_simulator.py +10 -10
- cirq/sim/clifford/clifford_simulator.py +6 -6
- cirq/sim/clifford/clifford_tableau_simulation_state_test.py +1 -3
- cirq/sim/clifford/stabilizer_sampler.py +4 -4
- cirq/sim/clifford/stabilizer_state_ch_form.py +3 -3
- cirq/sim/density_matrix_simulation_state.py +15 -15
- cirq/sim/density_matrix_simulator.py +11 -11
- cirq/sim/density_matrix_utils.py +9 -9
- cirq/sim/mux.py +9 -9
- cirq/sim/simulation_product_state.py +9 -9
- cirq/sim/simulation_product_state_test.py +2 -2
- cirq/sim/simulation_state.py +14 -27
- cirq/sim/simulation_state_base.py +8 -24
- cirq/sim/simulation_utils.py +3 -4
- cirq/sim/simulator.py +28 -43
- cirq/sim/simulator_base.py +12 -25
- cirq/sim/simulator_base_test.py +6 -6
- cirq/sim/simulator_test.py +7 -7
- cirq/sim/sparse_simulator.py +8 -8
- cirq/sim/state_vector.py +8 -8
- cirq/sim/state_vector_simulation_state.py +17 -17
- cirq/sim/state_vector_simulator.py +4 -4
- cirq/study/flatten_expressions.py +12 -14
- cirq/study/resolver.py +9 -11
- cirq/study/result.py +11 -24
- cirq/study/sweepable.py +5 -5
- cirq/study/sweeps.py +27 -40
- cirq/testing/circuit_compare.py +5 -5
- cirq/testing/consistent_controlled_gate_op_test.py +7 -11
- cirq/testing/consistent_protocols.py +10 -10
- cirq/testing/consistent_protocols_test.py +7 -7
- cirq/testing/consistent_qasm.py +4 -4
- cirq/testing/consistent_qasm_test.py +2 -3
- cirq/testing/devices.py +4 -5
- cirq/testing/equals_tester.py +2 -2
- cirq/testing/equivalent_basis_map.py +4 -4
- cirq/testing/equivalent_repr_eval.py +3 -3
- cirq/testing/json.py +14 -14
- cirq/testing/logs.py +3 -3
- cirq/testing/no_identifier_qubit.py +2 -3
- cirq/testing/random_circuit.py +7 -7
- cirq/testing/random_circuit_test.py +3 -3
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +16 -16
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +13 -13
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +5 -5
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +3 -3
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +3 -3
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +4 -4
- cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +6 -7
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +2 -2
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +7 -7
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +4 -4
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +7 -7
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +11 -11
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +5 -5
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +14 -14
- cirq/transformers/dynamical_decoupling.py +13 -13
- cirq/transformers/dynamical_decoupling_test.py +4 -4
- cirq/transformers/eject_phased_paulis.py +16 -16
- cirq/transformers/eject_z.py +5 -7
- cirq/transformers/gauge_compiling/gauge_compiling.py +38 -38
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +2 -2
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +8 -8
- cirq/transformers/insertion_sort.py +5 -5
- cirq/transformers/measurement_transformers.py +14 -14
- cirq/transformers/merge_k_qubit_gates_test.py +1 -3
- cirq/transformers/merge_single_qubit_gates_test.py +1 -3
- cirq/transformers/qubit_management_transformers.py +5 -5
- cirq/transformers/routing/initial_mapper.py +4 -4
- cirq/transformers/routing/line_initial_mapper.py +9 -9
- cirq/transformers/routing/mapping_manager.py +7 -7
- cirq/transformers/routing/route_circuit_cqc.py +27 -27
- cirq/transformers/routing/visualize_routed_circuit.py +4 -4
- cirq/transformers/stratify.py +8 -8
- cirq/transformers/synchronize_terminal_measurements.py +6 -6
- cirq/transformers/target_gatesets/compilation_target_gateset.py +8 -8
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -2
- cirq/transformers/target_gatesets/cz_gateset.py +4 -4
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +5 -5
- cirq/transformers/transformer_api.py +11 -26
- cirq/transformers/transformer_primitives.py +24 -36
- cirq/transformers/transformer_primitives_test.py +3 -3
- cirq/value/classical_data.py +18 -18
- cirq/value/condition.py +8 -8
- cirq/value/digits.py +7 -7
- cirq/value/duration.py +12 -12
- cirq/value/linear_dict.py +8 -12
- cirq/value/linear_dict_test.py +2 -2
- cirq/value/measurement_key.py +8 -8
- cirq/value/product_state.py +9 -9
- cirq/value/value_equality_attr.py +4 -4
- cirq/vis/heatmap.py +23 -35
- cirq/work/collector.py +9 -17
- cirq/work/observable_grouping.py +4 -7
- cirq/work/observable_measurement.py +29 -41
- cirq/work/observable_measurement_data.py +14 -14
- cirq/work/observable_measurement_test.py +2 -2
- cirq/work/observable_settings.py +9 -10
- cirq/work/pauli_sum_collector.py +5 -5
- cirq/work/sampler.py +17 -17
- cirq/work/zeros_sampler.py +3 -3
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/RECORD +290 -290
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/WHEEL +1 -1
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/top_level.txt +0 -0
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
from cirq import circuits, ops
|
|
20
20
|
|
|
@@ -24,7 +24,7 @@ if TYPE_CHECKING:
|
|
|
24
24
|
|
|
25
25
|
def _get_qubit_mapping_first_and_last_moment(
|
|
26
26
|
circuit: cirq.AbstractCircuit,
|
|
27
|
-
) ->
|
|
27
|
+
) -> dict[cirq.Qid, tuple[int, int]]:
|
|
28
28
|
"""Computes `(first_moment_idx, last_moment_idx)` tuple for each qubit in the input circuit.
|
|
29
29
|
|
|
30
30
|
Args:
|
|
@@ -48,7 +48,7 @@ def _is_temp(q: cirq.Qid) -> bool:
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
def map_clean_and_borrowable_qubits(
|
|
51
|
-
circuit: cirq.AbstractCircuit, *, qm:
|
|
51
|
+
circuit: cirq.AbstractCircuit, *, qm: cirq.QubitManager | None = None
|
|
52
52
|
) -> cirq.Circuit:
|
|
53
53
|
"""Uses `qm: QubitManager` to map all `CleanQubit`/`BorrowableQubit`s to system qubits.
|
|
54
54
|
|
|
@@ -99,8 +99,8 @@ def map_clean_and_borrowable_qubits(
|
|
|
99
99
|
trivial_map = {q: q for q in all_qubits}
|
|
100
100
|
# `allocated_map` maintains the mapping of all temporary qubits seen so far, mapping each of
|
|
101
101
|
# them to either a newly allocated managed ancilla or an existing borrowed system qubit.
|
|
102
|
-
allocated_map:
|
|
103
|
-
to_free:
|
|
102
|
+
allocated_map: dict[cirq.Qid, cirq.Qid] = {}
|
|
103
|
+
to_free: set[cirq.Qid] = set()
|
|
104
104
|
last_op_idx = -1
|
|
105
105
|
|
|
106
106
|
def map_func(op: cirq.Operation, idx: int) -> cirq.OP_TREE:
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import abc
|
|
18
|
-
from typing import
|
|
18
|
+
from typing import TYPE_CHECKING
|
|
19
19
|
|
|
20
20
|
from cirq import value
|
|
21
21
|
|
|
@@ -39,7 +39,7 @@ class AbstractInitialMapper(metaclass=abc.ABCMeta):
|
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
41
|
@abc.abstractmethod
|
|
42
|
-
def initial_mapping(self, circuit: cirq.AbstractCircuit) ->
|
|
42
|
+
def initial_mapping(self, circuit: cirq.AbstractCircuit) -> dict[cirq.Qid, cirq.Qid]:
|
|
43
43
|
"""Maps the logical qubits of a circuit onto physical qubits on a device.
|
|
44
44
|
|
|
45
45
|
Args:
|
|
@@ -54,10 +54,10 @@ class AbstractInitialMapper(metaclass=abc.ABCMeta):
|
|
|
54
54
|
class HardCodedInitialMapper(AbstractInitialMapper):
|
|
55
55
|
"""Initial Mapper class takes a hard-coded mapping and returns it."""
|
|
56
56
|
|
|
57
|
-
def __init__(self, _map:
|
|
57
|
+
def __init__(self, _map: dict[cirq.Qid, cirq.Qid]) -> None:
|
|
58
58
|
self._map = _map
|
|
59
59
|
|
|
60
|
-
def initial_mapping(self, circuit: cirq.AbstractCircuit) ->
|
|
60
|
+
def initial_mapping(self, circuit: cirq.AbstractCircuit) -> dict[cirq.Qid, cirq.Qid]:
|
|
61
61
|
"""Returns the hard-coded initial mapping.
|
|
62
62
|
|
|
63
63
|
Args:
|
|
@@ -33,7 +33,7 @@ If some logical qubits are unampped after this first procedure then there are tw
|
|
|
33
33
|
from __future__ import annotations
|
|
34
34
|
|
|
35
35
|
from collections import deque
|
|
36
|
-
from typing import
|
|
36
|
+
from typing import TYPE_CHECKING
|
|
37
37
|
|
|
38
38
|
import networkx as nx
|
|
39
39
|
|
|
@@ -85,7 +85,7 @@ class LineInitialMapper(initial_mapper.AbstractInitialMapper):
|
|
|
85
85
|
|
|
86
86
|
def _make_circuit_graph(
|
|
87
87
|
self, circuit: cirq.AbstractCircuit
|
|
88
|
-
) ->
|
|
88
|
+
) -> tuple[list[deque[cirq.Qid]], dict[cirq.Qid, cirq.Qid]]:
|
|
89
89
|
"""Creates a (potentially incomplete) qubit connectivity graph of the circuit.
|
|
90
90
|
|
|
91
91
|
Iterates over moments in the circuit from left to right and adds edges between logical
|
|
@@ -101,9 +101,9 @@ class LineInitialMapper(initial_mapper.AbstractInitialMapper):
|
|
|
101
101
|
The (potentially incomplete) qubit connectivity graph of the circuit, which is
|
|
102
102
|
guaranteed to be a forest of line graphs.
|
|
103
103
|
"""
|
|
104
|
-
circuit_graph:
|
|
105
|
-
component_id:
|
|
106
|
-
partners:
|
|
104
|
+
circuit_graph: list[deque[cirq.Qid]] = [deque([q]) for q in sorted(circuit.all_qubits())]
|
|
105
|
+
component_id: dict[cirq.Qid, int] = {q[0]: i for i, q in enumerate(circuit_graph)}
|
|
106
|
+
partners: dict[cirq.Qid, cirq.Qid] = {}
|
|
107
107
|
|
|
108
108
|
def degree_lt_two(q: cirq.Qid):
|
|
109
109
|
return any(circuit_graph[component_id[q]][i] == q for i in [-1, 0])
|
|
@@ -143,7 +143,7 @@ class LineInitialMapper(initial_mapper.AbstractInitialMapper):
|
|
|
143
143
|
)
|
|
144
144
|
return graph, partners
|
|
145
145
|
|
|
146
|
-
def initial_mapping(self, circuit: cirq.AbstractCircuit) ->
|
|
146
|
+
def initial_mapping(self, circuit: cirq.AbstractCircuit) -> dict[cirq.Qid, cirq.Qid]:
|
|
147
147
|
"""Maps disjoint lines of logical qubits onto lines of physical qubits.
|
|
148
148
|
|
|
149
149
|
Args:
|
|
@@ -153,8 +153,8 @@ class LineInitialMapper(initial_mapper.AbstractInitialMapper):
|
|
|
153
153
|
a dictionary that maps logical qubits in the circuit (keys) to physical qubits on the
|
|
154
154
|
device (values).
|
|
155
155
|
"""
|
|
156
|
-
mapped_physicals:
|
|
157
|
-
qubit_map:
|
|
156
|
+
mapped_physicals: set[cirq.Qid] = set()
|
|
157
|
+
qubit_map: dict[cirq.Qid, cirq.Qid] = {}
|
|
158
158
|
circuit_graph, partners = self._make_circuit_graph(circuit)
|
|
159
159
|
|
|
160
160
|
def next_physical(
|
|
@@ -191,7 +191,7 @@ class LineInitialMapper(initial_mapper.AbstractInitialMapper):
|
|
|
191
191
|
return qubit_map
|
|
192
192
|
|
|
193
193
|
def _closest_unmapped_qubit(
|
|
194
|
-
self, source: cirq.Qid, mapped_physicals:
|
|
194
|
+
self, source: cirq.Qid, mapped_physicals: set[cirq.Qid]
|
|
195
195
|
) -> cirq.Qid:
|
|
196
196
|
"""Finds the closest available neighbor to a physical qubit 'source' on the device.
|
|
197
197
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
-
from typing import
|
|
19
|
+
from typing import Sequence, TYPE_CHECKING
|
|
20
20
|
|
|
21
21
|
import networkx as nx
|
|
22
22
|
import numpy as np
|
|
@@ -37,7 +37,7 @@ class MappingManager:
|
|
|
37
37
|
logical qubits are mapped to, via `self.logical_qid_to_int` map).
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
|
-
def __init__(self, device_graph: nx.Graph, initial_mapping:
|
|
40
|
+
def __init__(self, device_graph: nx.Graph, initial_mapping: dict[cirq.Qid, cirq.Qid]) -> None:
|
|
41
41
|
"""Initializes MappingManager.
|
|
42
42
|
|
|
43
43
|
Args:
|
|
@@ -84,12 +84,12 @@ class MappingManager:
|
|
|
84
84
|
)
|
|
85
85
|
|
|
86
86
|
@property
|
|
87
|
-
def physical_qid_to_int(self) ->
|
|
87
|
+
def physical_qid_to_int(self) -> dict[cirq.Qid, int]:
|
|
88
88
|
"""Mapping of physical qubits, that were part of the initial mapping, to unique integers."""
|
|
89
89
|
return self._physical_qid_to_int
|
|
90
90
|
|
|
91
91
|
@property
|
|
92
|
-
def int_to_physical_qid(self) ->
|
|
92
|
+
def int_to_physical_qid(self) -> list[cirq.Qid]:
|
|
93
93
|
"""Inverse mapping of unique integers to corresponding physical qubits.
|
|
94
94
|
|
|
95
95
|
`self.physical_qid_to_int[self.int_to_physical_qid[i]] == i` for each i.
|
|
@@ -97,12 +97,12 @@ class MappingManager:
|
|
|
97
97
|
return self._int_to_physical_qid
|
|
98
98
|
|
|
99
99
|
@property
|
|
100
|
-
def logical_qid_to_int(self) ->
|
|
100
|
+
def logical_qid_to_int(self) -> dict[cirq.Qid, int]:
|
|
101
101
|
"""Mapping of logical qubits, that were part of the initial mapping, to unique integers."""
|
|
102
102
|
return self._logical_qid_to_int
|
|
103
103
|
|
|
104
104
|
@property
|
|
105
|
-
def int_to_logical_qid(self) ->
|
|
105
|
+
def int_to_logical_qid(self) -> list[cirq.Qid]:
|
|
106
106
|
"""Inverse mapping of unique integers to corresponding physical qubits.
|
|
107
107
|
|
|
108
108
|
`self.logical_qid_to_int[self.int_to_logical_qid[i]] == i` for each i.
|
|
@@ -189,7 +189,7 @@ class MappingManager:
|
|
|
189
189
|
"""
|
|
190
190
|
logical_ints = [self._logical_qid_to_int[q] for q in op.qubits]
|
|
191
191
|
physical_ints = self.logical_to_physical[logical_ints]
|
|
192
|
-
qubit_map:
|
|
192
|
+
qubit_map: dict[cirq.Qid, cirq.Qid] = {
|
|
193
193
|
q: self._int_to_physical_qid[physical_ints[i]] for i, q in enumerate(op.qubits)
|
|
194
194
|
}
|
|
195
195
|
return op.transform_qubits(qubit_map)
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
import itertools
|
|
20
|
-
from typing import Any,
|
|
20
|
+
from typing import Any, Sequence, TYPE_CHECKING
|
|
21
21
|
|
|
22
22
|
import networkx as nx
|
|
23
23
|
|
|
@@ -28,12 +28,12 @@ from cirq.transformers.routing import line_initial_mapper, mapping_manager
|
|
|
28
28
|
if TYPE_CHECKING:
|
|
29
29
|
import cirq
|
|
30
30
|
|
|
31
|
-
QidIntPair =
|
|
31
|
+
QidIntPair = tuple[int, int]
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def _disjoint_nc2_combinations(
|
|
35
35
|
qubit_pairs: Sequence[QidIntPair],
|
|
36
|
-
) ->
|
|
36
|
+
) -> list[tuple[QidIntPair, QidIntPair]]:
|
|
37
37
|
"""Gets disjoint pair combinations of qubits pairs.
|
|
38
38
|
|
|
39
39
|
For example:
|
|
@@ -114,8 +114,8 @@ class RouteCQC:
|
|
|
114
114
|
*,
|
|
115
115
|
lookahead_radius: int = 8,
|
|
116
116
|
tag_inserted_swaps: bool = False,
|
|
117
|
-
initial_mapper:
|
|
118
|
-
context:
|
|
117
|
+
initial_mapper: cirq.AbstractInitialMapper | None = None,
|
|
118
|
+
context: cirq.TransformerContext | None = None,
|
|
119
119
|
) -> cirq.AbstractCircuit:
|
|
120
120
|
"""Transforms the given circuit to make it executable on the device.
|
|
121
121
|
|
|
@@ -156,9 +156,9 @@ class RouteCQC:
|
|
|
156
156
|
*,
|
|
157
157
|
lookahead_radius: int = 8,
|
|
158
158
|
tag_inserted_swaps: bool = False,
|
|
159
|
-
initial_mapper:
|
|
160
|
-
context:
|
|
161
|
-
) ->
|
|
159
|
+
initial_mapper: cirq.AbstractInitialMapper | None = None,
|
|
160
|
+
context: cirq.TransformerContext | None = None,
|
|
161
|
+
) -> tuple[cirq.AbstractCircuit, dict[cirq.Qid, cirq.Qid], dict[cirq.Qid, cirq.Qid]]:
|
|
162
162
|
"""Transforms the given circuit to make it executable on the device.
|
|
163
163
|
|
|
164
164
|
This transformer assumes that all multi-qubit operations have been decomposed into 2-qubit
|
|
@@ -244,7 +244,7 @@ class RouteCQC:
|
|
|
244
244
|
@classmethod
|
|
245
245
|
def _get_one_and_two_qubit_ops_as_timesteps(
|
|
246
246
|
cls, circuit: cirq.AbstractCircuit
|
|
247
|
-
) ->
|
|
247
|
+
) -> tuple[list[list[cirq.Operation]], list[list[cirq.Operation]]]:
|
|
248
248
|
"""Gets the single and two qubit operations of the circuit factored into timesteps.
|
|
249
249
|
|
|
250
250
|
The i'th entry in the nested two-qubit and single-qubit ops correspond to the two-qubit
|
|
@@ -256,7 +256,7 @@ class RouteCQC:
|
|
|
256
256
|
qubits with a custom key.
|
|
257
257
|
"""
|
|
258
258
|
two_qubit_circuit = circuits.Circuit()
|
|
259
|
-
single_qubit_ops:
|
|
259
|
+
single_qubit_ops: list[list[cirq.Operation]] = []
|
|
260
260
|
|
|
261
261
|
for i, moment in enumerate(circuit):
|
|
262
262
|
for op in moment:
|
|
@@ -288,11 +288,11 @@ class RouteCQC:
|
|
|
288
288
|
def _route(
|
|
289
289
|
cls,
|
|
290
290
|
mm: mapping_manager.MappingManager,
|
|
291
|
-
two_qubit_ops:
|
|
292
|
-
single_qubit_ops:
|
|
291
|
+
two_qubit_ops: list[list[cirq.Operation]],
|
|
292
|
+
single_qubit_ops: list[list[cirq.Operation]],
|
|
293
293
|
lookahead_radius: int,
|
|
294
294
|
tag_inserted_swaps: bool = False,
|
|
295
|
-
) ->
|
|
295
|
+
) -> list[list[cirq.Operation]]:
|
|
296
296
|
"""Main routing procedure that inserts necessary swaps on the given timesteps.
|
|
297
297
|
|
|
298
298
|
The i'th element of the returned list corresponds to the routed operatiosn in the i'th
|
|
@@ -311,18 +311,18 @@ class RouteCQC:
|
|
|
311
311
|
Returns:
|
|
312
312
|
a list of lists corresponding to timesteps of the routed circuit.
|
|
313
313
|
"""
|
|
314
|
-
two_qubit_ops_ints:
|
|
314
|
+
two_qubit_ops_ints: list[list[QidIntPair]] = [
|
|
315
315
|
[
|
|
316
316
|
(mm.logical_qid_to_int[op.qubits[0]], mm.logical_qid_to_int[op.qubits[1]])
|
|
317
317
|
for op in timestep_ops
|
|
318
318
|
]
|
|
319
319
|
for timestep_ops in two_qubit_ops
|
|
320
320
|
]
|
|
321
|
-
routed_ops:
|
|
321
|
+
routed_ops: list[list[cirq.Operation]] = []
|
|
322
322
|
|
|
323
323
|
def process_executable_two_qubit_ops(timestep: int) -> int:
|
|
324
|
-
unexecutable_ops:
|
|
325
|
-
unexecutable_ops_ints:
|
|
324
|
+
unexecutable_ops: list[cirq.Operation] = []
|
|
325
|
+
unexecutable_ops_ints: list[QidIntPair] = []
|
|
326
326
|
for op, op_ints in zip(two_qubit_ops[timestep], two_qubit_ops_ints[timestep]):
|
|
327
327
|
if mm.is_adjacent(*op_ints):
|
|
328
328
|
routed_ops[timestep].append(mm.mapped_op(op))
|
|
@@ -341,10 +341,10 @@ class RouteCQC:
|
|
|
341
341
|
|
|
342
342
|
# swaps applied in the current timestep thus far. This ensures the same swaps
|
|
343
343
|
# don't get executed twice in the same timestep.
|
|
344
|
-
seen:
|
|
344
|
+
seen: set[tuple[QidIntPair, ...]] = set()
|
|
345
345
|
|
|
346
346
|
while process_executable_two_qubit_ops(timestep):
|
|
347
|
-
chosen_swaps:
|
|
347
|
+
chosen_swaps: tuple[QidIntPair, ...] | None = None
|
|
348
348
|
for strat in strats:
|
|
349
349
|
chosen_swaps = strat(mm, two_qubit_ops_ints, timestep, lookahead_radius)
|
|
350
350
|
if chosen_swaps is not None:
|
|
@@ -372,7 +372,7 @@ class RouteCQC:
|
|
|
372
372
|
mm: mapping_manager.MappingManager,
|
|
373
373
|
two_qubit_ops_ints: Sequence[Sequence[QidIntPair]],
|
|
374
374
|
timestep: int,
|
|
375
|
-
) ->
|
|
375
|
+
) -> tuple[QidIntPair, ...]:
|
|
376
376
|
"""Inserts SWAPS along the shortest path of the qubits that are the farthest.
|
|
377
377
|
|
|
378
378
|
Since swaps along the shortest path are being executed one after the other, in order
|
|
@@ -390,7 +390,7 @@ class RouteCQC:
|
|
|
390
390
|
two_qubit_ops_ints: Sequence[Sequence[QidIntPair]],
|
|
391
391
|
timestep: int,
|
|
392
392
|
lookahead_radius: int,
|
|
393
|
-
) ->
|
|
393
|
+
) -> tuple[QidIntPair, ...] | None:
|
|
394
394
|
"""Computes cost function with pairs of candidate swaps that act on disjoint qubits."""
|
|
395
395
|
pair_sigma = _disjoint_nc2_combinations(
|
|
396
396
|
cls._initial_candidate_swaps(mm, two_qubit_ops_ints[timestep])
|
|
@@ -406,9 +406,9 @@ class RouteCQC:
|
|
|
406
406
|
two_qubit_ops_ints: Sequence[Sequence[QidIntPair]],
|
|
407
407
|
timestep: int,
|
|
408
408
|
lookahead_radius: int,
|
|
409
|
-
) ->
|
|
409
|
+
) -> tuple[QidIntPair, ...] | None:
|
|
410
410
|
"""Computes cost function with list of single candidate swaps."""
|
|
411
|
-
sigma:
|
|
411
|
+
sigma: list[tuple[QidIntPair, ...]] = [
|
|
412
412
|
(swap,) for swap in cls._initial_candidate_swaps(mm, two_qubit_ops_ints[timestep])
|
|
413
413
|
]
|
|
414
414
|
return cls._choose_optimal_swap(mm, two_qubit_ops_ints, timestep, lookahead_radius, sigma)
|
|
@@ -420,8 +420,8 @@ class RouteCQC:
|
|
|
420
420
|
two_qubit_ops_ints: Sequence[Sequence[QidIntPair]],
|
|
421
421
|
timestep: int,
|
|
422
422
|
lookahead_radius: int,
|
|
423
|
-
sigma: Sequence[
|
|
424
|
-
) ->
|
|
423
|
+
sigma: Sequence[tuple[QidIntPair, ...]],
|
|
424
|
+
) -> tuple[QidIntPair, ...] | None:
|
|
425
425
|
"""Optionally returns the swap with minimum cost from a list of n-tuple candidate swaps.
|
|
426
426
|
|
|
427
427
|
Computes a cost (as defined by the overridable function `_cost`) for each candidate swap
|
|
@@ -449,7 +449,7 @@ class RouteCQC:
|
|
|
449
449
|
@classmethod
|
|
450
450
|
def _initial_candidate_swaps(
|
|
451
451
|
cls, mm: mapping_manager.MappingManager, two_qubit_ops: Sequence[QidIntPair]
|
|
452
|
-
) ->
|
|
452
|
+
) -> list[QidIntPair]:
|
|
453
453
|
"""Finds all feasible SWAPs between qubits involved in 2-qubit operations."""
|
|
454
454
|
physical_qubits = (mm.logical_to_physical[lq[i]] for lq in two_qubit_ops for i in range(2))
|
|
455
455
|
physical_swaps = mm.induced_subgraph_int.edges(nbunch=physical_qubits)
|
|
@@ -461,7 +461,7 @@ class RouteCQC:
|
|
|
461
461
|
def _cost(
|
|
462
462
|
cls,
|
|
463
463
|
mm: mapping_manager.MappingManager,
|
|
464
|
-
swaps:
|
|
464
|
+
swaps: tuple[QidIntPair, ...],
|
|
465
465
|
two_qubit_ops: Sequence[QidIntPair],
|
|
466
466
|
) -> Any:
|
|
467
467
|
"""Computes the cost function for the given list of swaps over the current timestep ops.
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
from cirq import circuits, ops
|
|
20
20
|
|
|
@@ -25,18 +25,18 @@ if TYPE_CHECKING:
|
|
|
25
25
|
class _SwapPrintGate(ops.Gate):
|
|
26
26
|
"""A gate that displays the string representation of each qubits on the circuit."""
|
|
27
27
|
|
|
28
|
-
def __init__(self, qubits:
|
|
28
|
+
def __init__(self, qubits: tuple[tuple[cirq.Qid, cirq.Qid], ...]) -> None:
|
|
29
29
|
self.qubits = qubits
|
|
30
30
|
|
|
31
31
|
def num_qubits(self):
|
|
32
32
|
return len(self.qubits)
|
|
33
33
|
|
|
34
|
-
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) ->
|
|
34
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> tuple[str, ...]:
|
|
35
35
|
return tuple(f'{str(q[1])}' for q in self.qubits)
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def routed_circuit_with_mapping(
|
|
39
|
-
routed_circuit: cirq.AbstractCircuit, initial_map:
|
|
39
|
+
routed_circuit: cirq.AbstractCircuit, initial_map: dict[cirq.Qid, cirq.Qid] | None = None
|
|
40
40
|
) -> cirq.AbstractCircuit:
|
|
41
41
|
"""Returns the same circuits with information about the permutation of qubits after each swap.
|
|
42
42
|
|
cirq/transformers/stratify.py
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
import itertools
|
|
20
|
-
from typing import Callable,
|
|
20
|
+
from typing import Callable, Iterable, Sequence, TYPE_CHECKING, Union
|
|
21
21
|
|
|
22
22
|
from cirq import _import, circuits, ops, protocols
|
|
23
23
|
from cirq.transformers import transformer_api
|
|
@@ -33,7 +33,7 @@ Classifier = Callable[['cirq.Operation'], bool]
|
|
|
33
33
|
|
|
34
34
|
# Any of the possible operation categories that we can stratify on.
|
|
35
35
|
Category = Union[
|
|
36
|
-
'cirq.Gate', 'cirq.Operation',
|
|
36
|
+
'cirq.Gate', 'cirq.Operation', type['cirq.Gate'], type['cirq.Operation'], Classifier
|
|
37
37
|
]
|
|
38
38
|
|
|
39
39
|
|
|
@@ -41,7 +41,7 @@ Category = Union[
|
|
|
41
41
|
def stratified_circuit(
|
|
42
42
|
circuit: cirq.AbstractCircuit,
|
|
43
43
|
*,
|
|
44
|
-
context:
|
|
44
|
+
context: cirq.TransformerContext | None = None,
|
|
45
45
|
categories: Iterable[Category] = (),
|
|
46
46
|
) -> cirq.Circuit:
|
|
47
47
|
"""Repacks avoiding simultaneous operations with different classes.
|
|
@@ -117,12 +117,12 @@ def _stratify_circuit(
|
|
|
117
117
|
The stratified circuit.
|
|
118
118
|
"""
|
|
119
119
|
num_classes = len(classifiers) + 1 # include one "extra" category for ignored operations
|
|
120
|
-
new_moments:
|
|
120
|
+
new_moments: list[list[cirq.Operation]] = []
|
|
121
121
|
|
|
122
122
|
# Keep track of the latest time index for each qubit, measurement key, and control key.
|
|
123
|
-
qubit_time_index:
|
|
124
|
-
measurement_time_index:
|
|
125
|
-
control_time_index:
|
|
123
|
+
qubit_time_index: dict[cirq.Qid, int] = {}
|
|
124
|
+
measurement_time_index: dict[cirq.MeasurementKey, int] = {}
|
|
125
|
+
control_time_index: dict[cirq.MeasurementKey, int] = {}
|
|
126
126
|
|
|
127
127
|
# The minimum time index for operations with a tag in context.tags_to_ignore.
|
|
128
128
|
last_ignored_ops_time_index = 0
|
|
@@ -177,7 +177,7 @@ def _stratify_circuit(
|
|
|
177
177
|
|
|
178
178
|
def _get_classifiers(
|
|
179
179
|
circuit: circuits.AbstractCircuit, categories: Iterable[Category]
|
|
180
|
-
) ->
|
|
180
|
+
) -> list[Classifier]:
|
|
181
181
|
"""Convert a collection of categories into a list of classifiers.
|
|
182
182
|
|
|
183
183
|
The returned list of classifiers is:
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
-
from typing import
|
|
19
|
+
from typing import TYPE_CHECKING
|
|
20
20
|
|
|
21
21
|
from cirq import circuits, protocols
|
|
22
22
|
from cirq.transformers import transformer_api
|
|
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
|
|
25
25
|
import cirq
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def find_terminal_measurements(circuit: cirq.AbstractCircuit) ->
|
|
28
|
+
def find_terminal_measurements(circuit: cirq.AbstractCircuit) -> list[tuple[int, cirq.Operation]]:
|
|
29
29
|
"""Finds all terminal measurements in the given circuit.
|
|
30
30
|
|
|
31
31
|
A measurement is terminal if there are no other operations acting on the measured qubits
|
|
@@ -39,9 +39,9 @@ def find_terminal_measurements(circuit: cirq.AbstractCircuit) -> List[Tuple[int,
|
|
|
39
39
|
(moment_index, measurement_operation).
|
|
40
40
|
"""
|
|
41
41
|
|
|
42
|
-
open_qubits:
|
|
43
|
-
seen_control_keys:
|
|
44
|
-
terminal_measurements:
|
|
42
|
+
open_qubits: set[cirq.Qid] = set(circuit.all_qubits())
|
|
43
|
+
seen_control_keys: set[cirq.MeasurementKey] = set()
|
|
44
|
+
terminal_measurements: set[tuple[int, cirq.Operation]] = set()
|
|
45
45
|
for i in range(len(circuit) - 1, -1, -1):
|
|
46
46
|
moment = circuit[i]
|
|
47
47
|
for q in open_qubits:
|
|
@@ -64,7 +64,7 @@ def find_terminal_measurements(circuit: cirq.AbstractCircuit) -> List[Tuple[int,
|
|
|
64
64
|
def synchronize_terminal_measurements(
|
|
65
65
|
circuit: cirq.AbstractCircuit,
|
|
66
66
|
*,
|
|
67
|
-
context:
|
|
67
|
+
context: cirq.TransformerContext | None = None,
|
|
68
68
|
after_other_operations: bool = True,
|
|
69
69
|
) -> cirq.Circuit:
|
|
70
70
|
"""Move measurements to the end of the circuit.
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
import abc
|
|
20
|
-
from typing import Hashable,
|
|
20
|
+
from typing import Hashable, TYPE_CHECKING
|
|
21
21
|
|
|
22
22
|
from cirq import circuits, ops, protocols, transformers
|
|
23
23
|
from cirq.transformers import merge_k_qubit_gates, merge_single_qubit_gates
|
|
@@ -67,7 +67,7 @@ def create_transformer_with_kwargs(transformer: cirq.TRANSFORMER, **kwargs) -> c
|
|
|
67
67
|
raise SyntaxError('**kwargs to be captured must not contain `context`.')
|
|
68
68
|
|
|
69
69
|
def transformer_with_kwargs(
|
|
70
|
-
circuit: cirq.AbstractCircuit, *, context:
|
|
70
|
+
circuit: cirq.AbstractCircuit, *, context: cirq.TransformerContext | None = None
|
|
71
71
|
) -> cirq.AbstractCircuit:
|
|
72
72
|
return transformer(circuit, context=context, **kwargs)
|
|
73
73
|
|
|
@@ -83,8 +83,8 @@ class CompilationTargetGateset(ops.Gateset, metaclass=abc.ABCMeta):
|
|
|
83
83
|
|
|
84
84
|
def __init__(
|
|
85
85
|
self,
|
|
86
|
-
*gates:
|
|
87
|
-
name:
|
|
86
|
+
*gates: type[cirq.Gate] | cirq.Gate | cirq.GateFamily,
|
|
87
|
+
name: str | None = None,
|
|
88
88
|
unroll_circuit_op: bool = True,
|
|
89
89
|
preserve_moment_structure: bool = True,
|
|
90
90
|
reorder_operations: bool = False,
|
|
@@ -155,7 +155,7 @@ class CompilationTargetGateset(ops.Gateset, metaclass=abc.ABCMeta):
|
|
|
155
155
|
return "_default_merged_k_qubit_unitaries"
|
|
156
156
|
|
|
157
157
|
@property
|
|
158
|
-
def preprocess_transformers(self) ->
|
|
158
|
+
def preprocess_transformers(self) -> list[cirq.TRANSFORMER]:
|
|
159
159
|
"""List of transformers which should be run before decomposing individual operations."""
|
|
160
160
|
reorder_transfomers = (
|
|
161
161
|
[transformers.insertion_sort_transformer] if self._reorder_operations else []
|
|
@@ -174,9 +174,9 @@ class CompilationTargetGateset(ops.Gateset, metaclass=abc.ABCMeta):
|
|
|
174
174
|
]
|
|
175
175
|
|
|
176
176
|
@property
|
|
177
|
-
def postprocess_transformers(self) ->
|
|
177
|
+
def postprocess_transformers(self) -> list[cirq.TRANSFORMER]:
|
|
178
178
|
"""List of transformers which should be run after decomposing individual operations."""
|
|
179
|
-
processors:
|
|
179
|
+
processors: list[cirq.TRANSFORMER] = [
|
|
180
180
|
merge_single_qubit_gates.merge_single_qubit_moments_to_phxz,
|
|
181
181
|
transformers.drop_negligible_operations,
|
|
182
182
|
transformers.drop_empty_moments,
|
|
@@ -250,7 +250,7 @@ class TwoQubitCompilationTargetGateset(CompilationTargetGateset):
|
|
|
250
250
|
)
|
|
251
251
|
if switch_to_new:
|
|
252
252
|
return new_optree
|
|
253
|
-
mapped_old_optree:
|
|
253
|
+
mapped_old_optree: list[cirq.OP_TREE] = []
|
|
254
254
|
for old_op in ops.flatten_to_ops(old_optree):
|
|
255
255
|
if old_op in self:
|
|
256
256
|
mapped_old_optree.append(old_op)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
import pytest
|
|
20
20
|
|
|
@@ -37,7 +37,7 @@ def test_compilation_target_gateset() -> None:
|
|
|
37
37
|
return op if cirq.num_qubits(op) == 2 and cirq.has_unitary(op) else NotImplemented
|
|
38
38
|
|
|
39
39
|
@property
|
|
40
|
-
def preprocess_transformers(self) ->
|
|
40
|
+
def preprocess_transformers(self) -> list[cirq.TRANSFORMER]:
|
|
41
41
|
return []
|
|
42
42
|
|
|
43
43
|
gateset = ExampleTargetGateset()
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
-
from typing import Any,
|
|
19
|
+
from typing import Any, Sequence, TYPE_CHECKING
|
|
20
20
|
|
|
21
21
|
from cirq import ops, protocols
|
|
22
22
|
from cirq.transformers.analytical_decompositions import two_qubit_to_cz
|
|
@@ -49,7 +49,7 @@ class CZTargetGateset(compilation_target_gateset.TwoQubitCompilationTargetGatese
|
|
|
49
49
|
*,
|
|
50
50
|
atol: float = 1e-8,
|
|
51
51
|
allow_partial_czs: bool = False,
|
|
52
|
-
additional_gates: Sequence[
|
|
52
|
+
additional_gates: Sequence[type[cirq.Gate] | cirq.Gate | cirq.GateFamily] = (),
|
|
53
53
|
preserve_moment_structure: bool = True,
|
|
54
54
|
reorder_operations: bool = False,
|
|
55
55
|
) -> None:
|
|
@@ -108,8 +108,8 @@ class CZTargetGateset(compilation_target_gateset.TwoQubitCompilationTargetGatese
|
|
|
108
108
|
def _value_equality_values_(self) -> Any:
|
|
109
109
|
return self.atol, self.allow_partial_czs, frozenset(self.additional_gates)
|
|
110
110
|
|
|
111
|
-
def _json_dict_(self) ->
|
|
112
|
-
d:
|
|
111
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
112
|
+
d: dict[str, Any] = {'atol': self.atol, 'allow_partial_czs': self.allow_partial_czs}
|
|
113
113
|
if self.additional_gates:
|
|
114
114
|
d['additional_gates'] = list(self.additional_gates)
|
|
115
115
|
return d
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
-
from typing import Any,
|
|
19
|
+
from typing import Any, Sequence, TYPE_CHECKING
|
|
20
20
|
|
|
21
21
|
from cirq import ops, protocols
|
|
22
22
|
from cirq.transformers.analytical_decompositions import two_qubit_to_sqrt_iswap
|
|
@@ -49,9 +49,9 @@ class SqrtIswapTargetGateset(compilation_target_gateset.TwoQubitCompilationTarge
|
|
|
49
49
|
self,
|
|
50
50
|
*,
|
|
51
51
|
atol: float = 1e-8,
|
|
52
|
-
required_sqrt_iswap_count:
|
|
52
|
+
required_sqrt_iswap_count: int | None = None,
|
|
53
53
|
use_sqrt_iswap_inv: bool = False,
|
|
54
|
-
additional_gates: Sequence[
|
|
54
|
+
additional_gates: Sequence[type[cirq.Gate] | cirq.Gate | cirq.GateFamily] = (),
|
|
55
55
|
):
|
|
56
56
|
"""Initializes `cirq.SqrtIswapTargetGateset`
|
|
57
57
|
|
|
@@ -125,8 +125,8 @@ class SqrtIswapTargetGateset(compilation_target_gateset.TwoQubitCompilationTarge
|
|
|
125
125
|
frozenset(self.additional_gates),
|
|
126
126
|
)
|
|
127
127
|
|
|
128
|
-
def _json_dict_(self) ->
|
|
129
|
-
d:
|
|
128
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
129
|
+
d: dict[str, Any] = {
|
|
130
130
|
'atol': self.atol,
|
|
131
131
|
'required_sqrt_iswap_count': self.required_sqrt_iswap_count,
|
|
132
132
|
'use_sqrt_iswap_inv': self.use_sqrt_iswap_inv,
|