cirq-core 1.5.0.dev20250409225226__py3-none-any.whl → 1.6.0__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/__init__.py +16 -17
- cirq/_compat.py +21 -20
- cirq/_compat_test.py +14 -34
- cirq/_doc.py +4 -2
- cirq/_import.py +8 -6
- cirq/_import_test.py +4 -2
- cirq/_version.py +6 -6
- cirq/_version_test.py +2 -2
- cirq/circuits/_block_diagram_drawer.py +11 -10
- cirq/circuits/_block_diagram_drawer_test.py +8 -6
- cirq/circuits/_box_drawing_character_data.py +8 -8
- cirq/circuits/_box_drawing_character_data_test.py +3 -1
- cirq/circuits/_bucket_priority_queue.py +9 -7
- cirq/circuits/_bucket_priority_queue_test.py +22 -20
- cirq/circuits/circuit.py +248 -172
- cirq/circuits/circuit_operation.py +73 -83
- cirq/circuits/circuit_operation_test.py +128 -90
- cirq/circuits/circuit_test.py +211 -151
- cirq/circuits/frozen_circuit.py +23 -60
- cirq/circuits/frozen_circuit_test.py +31 -8
- cirq/circuits/insert_strategy.py +7 -5
- cirq/circuits/insert_strategy_test.py +4 -2
- cirq/circuits/moment.py +88 -40
- cirq/circuits/moment_test.py +128 -51
- cirq/circuits/optimization_pass.py +5 -5
- cirq/circuits/optimization_pass_test.py +10 -10
- cirq/circuits/qasm_output.py +11 -11
- cirq/circuits/qasm_output_test.py +25 -22
- cirq/circuits/text_diagram_drawer.py +23 -38
- cirq/circuits/text_diagram_drawer_test.py +19 -17
- cirq/conftest.py +4 -3
- cirq/contrib/__init__.py +4 -4
- cirq/contrib/acquaintance/__init__.py +1 -1
- cirq/contrib/acquaintance/bipartite.py +5 -8
- cirq/contrib/acquaintance/bipartite_test.py +18 -13
- cirq/contrib/acquaintance/devices.py +2 -2
- cirq/contrib/acquaintance/devices_test.py +5 -3
- cirq/contrib/acquaintance/executor.py +5 -5
- cirq/contrib/acquaintance/executor_test.py +13 -9
- cirq/contrib/acquaintance/gates.py +18 -28
- cirq/contrib/acquaintance/gates_test.py +24 -20
- cirq/contrib/acquaintance/inspection_utils.py +8 -4
- cirq/contrib/acquaintance/inspection_utils_test.py +4 -2
- cirq/contrib/acquaintance/mutation_utils.py +4 -4
- cirq/contrib/acquaintance/mutation_utils_test.py +4 -2
- cirq/contrib/acquaintance/optimizers.py +4 -4
- cirq/contrib/acquaintance/optimizers_test.py +4 -1
- cirq/contrib/acquaintance/permutation.py +15 -27
- cirq/contrib/acquaintance/permutation_test.py +26 -17
- cirq/contrib/acquaintance/shift.py +4 -4
- cirq/contrib/acquaintance/shift_swap_network.py +4 -4
- cirq/contrib/acquaintance/shift_swap_network_test.py +9 -6
- cirq/contrib/acquaintance/shift_test.py +8 -6
- cirq/contrib/acquaintance/strategies/cubic.py +2 -2
- cirq/contrib/acquaintance/strategies/cubic_test.py +4 -2
- cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
- cirq/contrib/acquaintance/strategies/quartic_paired_test.py +10 -6
- cirq/contrib/acquaintance/testing.py +2 -0
- cirq/contrib/acquaintance/topological_sort.py +2 -2
- cirq/contrib/acquaintance/topological_sort_test.py +3 -1
- cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
- cirq/contrib/bayesian_network/bayesian_network_gate_test.py +14 -9
- cirq/contrib/circuitdag/circuit_dag.py +4 -4
- cirq/contrib/circuitdag/circuit_dag_test.py +17 -15
- cirq/contrib/custom_simulators/custom_state_simulator.py +5 -5
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +22 -17
- cirq/contrib/graph_device/graph_device.py +12 -11
- cirq/contrib/graph_device/graph_device_test.py +18 -14
- cirq/contrib/graph_device/hypergraph.py +16 -14
- cirq/contrib/graph_device/hypergraph_test.py +13 -11
- cirq/contrib/graph_device/uniform_graph_device.py +6 -4
- cirq/contrib/graph_device/uniform_graph_device_test.py +11 -3
- cirq/contrib/hacks/disable_validation.py +6 -1
- cirq/contrib/hacks/disable_validation_test.py +3 -1
- cirq/contrib/json.py +31 -5
- cirq/contrib/json_test.py +6 -3
- cirq/contrib/json_test_data/DampedReadoutNoiseModel.json +12 -0
- cirq/contrib/json_test_data/DampedReadoutNoiseModel.repr +4 -0
- cirq/contrib/json_test_data/DepolarizingNoiseModel.json +12 -0
- cirq/contrib/json_test_data/DepolarizingNoiseModel.repr +4 -0
- cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.json +6 -0
- cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.repr +1 -0
- cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.json +5 -0
- cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.repr +1 -0
- cirq/contrib/json_test_data/ReadoutNoiseModel.json +12 -0
- cirq/contrib/json_test_data/ReadoutNoiseModel.repr +4 -0
- cirq/contrib/json_test_data/__init__.py +17 -0
- cirq/contrib/json_test_data/spec.py +32 -0
- cirq/contrib/noise_models/noise_models.py +119 -5
- cirq/contrib/noise_models/noise_models_test.py +37 -9
- cirq/contrib/paulistring/clifford_optimize.py +6 -4
- cirq/contrib/paulistring/clifford_optimize_test.py +6 -5
- cirq/contrib/paulistring/clifford_target_gateset.py +10 -10
- cirq/contrib/paulistring/clifford_target_gateset_test.py +13 -11
- cirq/contrib/paulistring/optimize.py +2 -0
- cirq/contrib/paulistring/optimize_test.py +4 -3
- cirq/contrib/paulistring/pauli_string_dag.py +2 -0
- cirq/contrib/paulistring/pauli_string_dag_test.py +3 -1
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +255 -120
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +398 -19
- cirq/contrib/paulistring/pauli_string_optimize.py +7 -1
- cirq/contrib/paulistring/pauli_string_optimize_test.py +5 -3
- cirq/contrib/paulistring/recombine.py +6 -4
- cirq/contrib/paulistring/recombine_test.py +3 -1
- cirq/contrib/paulistring/separate.py +9 -6
- cirq/contrib/paulistring/separate_test.py +3 -1
- cirq/contrib/qasm_import/_lexer.py +3 -2
- cirq/contrib/qasm_import/_lexer_test.py +49 -13
- cirq/contrib/qasm_import/_parser.py +547 -83
- cirq/contrib/qasm_import/_parser_test.py +988 -97
- cirq/contrib/qasm_import/exception.py +2 -0
- cirq/contrib/qasm_import/qasm.py +8 -2
- cirq/contrib/qasm_import/qasm_test.py +7 -4
- cirq/contrib/qcircuit/qcircuit_diagram_info.py +5 -5
- cirq/contrib/qcircuit/qcircuit_diagram_info_test.py +4 -1
- cirq/contrib/qcircuit/qcircuit_pdf.py +7 -3
- cirq/contrib/qcircuit/qcircuit_pdf_test.py +3 -1
- cirq/contrib/qcircuit/qcircuit_test.py +10 -8
- cirq/contrib/quantum_volume/quantum_volume.py +31 -27
- cirq/contrib/quantum_volume/quantum_volume_test.py +19 -16
- cirq/contrib/quimb/density_matrix.py +15 -14
- cirq/contrib/quimb/density_matrix_test.py +10 -7
- cirq/contrib/quimb/grid_circuits.py +5 -2
- cirq/contrib/quimb/grid_circuits_test.py +3 -0
- cirq/contrib/quimb/mps_simulator.py +20 -20
- cirq/contrib/quimb/mps_simulator_test.py +3 -0
- cirq/contrib/quimb/state_vector.py +12 -11
- cirq/contrib/quimb/state_vector_test.py +3 -0
- cirq/contrib/quirk/export_to_quirk.py +5 -3
- cirq/contrib/quirk/export_to_quirk_test.py +18 -16
- cirq/contrib/quirk/linearize_circuit.py +2 -0
- cirq/contrib/quirk/quirk_gate.py +18 -17
- cirq/contrib/routing/device.py +5 -3
- cirq/contrib/routing/device_test.py +2 -0
- cirq/contrib/routing/greedy.py +10 -21
- cirq/contrib/routing/greedy_test.py +4 -2
- cirq/contrib/routing/initialization.py +2 -2
- cirq/contrib/routing/initialization_test.py +5 -3
- cirq/contrib/routing/router.py +9 -5
- cirq/contrib/routing/router_test.py +2 -0
- cirq/contrib/routing/swap_network.py +3 -3
- cirq/contrib/routing/swap_network_test.py +3 -1
- cirq/contrib/routing/utils.py +2 -2
- cirq/contrib/routing/utils_test.py +3 -0
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +15 -9
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +3 -0
- cirq/contrib/svg/svg.py +3 -3
- cirq/contrib/svg/svg_test.py +8 -5
- cirq/devices/device.py +4 -4
- cirq/devices/device_test.py +7 -4
- cirq/devices/grid_device_metadata.py +10 -10
- cirq/devices/grid_device_metadata_test.py +3 -0
- cirq/devices/grid_qubit.py +29 -21
- cirq/devices/grid_qubit_test.py +3 -0
- cirq/devices/insertion_noise_model.py +7 -7
- cirq/devices/insertion_noise_model_test.py +7 -5
- cirq/devices/line_qubit.py +13 -13
- cirq/devices/line_qubit_test.py +2 -0
- cirq/devices/named_topologies.py +18 -29
- cirq/devices/named_topologies_test.py +13 -10
- cirq/devices/noise_model.py +3 -3
- cirq/devices/noise_model_test.py +19 -15
- cirq/devices/noise_properties.py +15 -6
- cirq/devices/noise_properties_test.py +34 -3
- cirq/devices/noise_utils.py +11 -9
- cirq/devices/noise_utils_test.py +2 -0
- cirq/devices/superconducting_qubits_noise_properties.py +23 -22
- cirq/devices/superconducting_qubits_noise_properties_test.py +6 -6
- cirq/devices/thermal_noise_model.py +107 -37
- cirq/devices/thermal_noise_model_test.py +21 -0
- cirq/devices/unconstrained_device.py +5 -3
- cirq/devices/unconstrained_device_test.py +2 -0
- cirq/experiments/__init__.py +4 -2
- cirq/experiments/benchmarking/__init__.py +17 -0
- cirq/experiments/benchmarking/parallel_xeb.py +677 -0
- cirq/experiments/benchmarking/parallel_xeb_test.py +447 -0
- cirq/experiments/fidelity_estimation.py +14 -8
- cirq/experiments/fidelity_estimation_test.py +3 -0
- cirq/experiments/n_qubit_tomography.py +17 -16
- cirq/experiments/n_qubit_tomography_test.py +8 -5
- cirq/experiments/purity_estimation.py +2 -0
- cirq/experiments/purity_estimation_test.py +2 -0
- cirq/experiments/qubit_characterizations.py +207 -103
- cirq/experiments/qubit_characterizations_test.py +40 -12
- cirq/experiments/random_quantum_circuit_generation.py +56 -70
- cirq/experiments/random_quantum_circuit_generation_test.py +11 -8
- cirq/experiments/readout_confusion_matrix.py +24 -22
- cirq/experiments/readout_confusion_matrix_test.py +2 -0
- cirq/experiments/single_qubit_readout_calibration.py +30 -15
- cirq/experiments/single_qubit_readout_calibration_test.py +5 -2
- cirq/experiments/t1_decay_experiment.py +9 -7
- cirq/experiments/t1_decay_experiment_test.py +13 -11
- cirq/experiments/t2_decay_experiment.py +16 -13
- cirq/experiments/t2_decay_experiment_test.py +2 -0
- cirq/experiments/two_qubit_xeb.py +64 -57
- cirq/experiments/two_qubit_xeb_test.py +10 -6
- cirq/experiments/xeb_fitting.py +39 -35
- cirq/experiments/xeb_sampling.py +37 -44
- cirq/experiments/xeb_sampling_test.py +3 -0
- cirq/experiments/xeb_simulation.py +14 -10
- cirq/experiments/xeb_simulation_test.py +5 -5
- cirq/experiments/z_phase_calibration.py +32 -29
- cirq/experiments/z_phase_calibration_test.py +3 -4
- cirq/interop/quirk/cells/__init__.py +1 -1
- cirq/interop/quirk/cells/all_cells.py +7 -2
- cirq/interop/quirk/cells/arithmetic_cells.py +29 -41
- cirq/interop/quirk/cells/arithmetic_cells_test.py +17 -14
- cirq/interop/quirk/cells/cell.py +19 -28
- cirq/interop/quirk/cells/cell_test.py +3 -0
- cirq/interop/quirk/cells/composite_cell.py +13 -28
- cirq/interop/quirk/cells/composite_cell_test.py +2 -0
- cirq/interop/quirk/cells/control_cells.py +15 -15
- cirq/interop/quirk/cells/control_cells_test.py +7 -5
- cirq/interop/quirk/cells/frequency_space_cells.py +4 -3
- cirq/interop/quirk/cells/frequency_space_cells_test.py +3 -1
- cirq/interop/quirk/cells/ignored_cells.py +3 -0
- cirq/interop/quirk/cells/ignored_cells_test.py +3 -1
- cirq/interop/quirk/cells/input_cells.py +7 -5
- cirq/interop/quirk/cells/input_cells_test.py +7 -5
- cirq/interop/quirk/cells/input_rotation_cells.py +15 -13
- cirq/interop/quirk/cells/input_rotation_cells_test.py +9 -7
- cirq/interop/quirk/cells/measurement_cells.py +5 -2
- cirq/interop/quirk/cells/measurement_cells_test.py +3 -1
- cirq/interop/quirk/cells/parse.py +22 -23
- cirq/interop/quirk/cells/parse_test.py +12 -10
- cirq/interop/quirk/cells/qubit_permutation_cells.py +5 -3
- cirq/interop/quirk/cells/qubit_permutation_cells_test.py +9 -7
- cirq/interop/quirk/cells/scalar_cells.py +4 -1
- cirq/interop/quirk/cells/scalar_cells_test.py +3 -1
- cirq/interop/quirk/cells/single_qubit_rotation_cells.py +5 -2
- cirq/interop/quirk/cells/single_qubit_rotation_cells_test.py +5 -3
- cirq/interop/quirk/cells/swap_cell.py +8 -6
- cirq/interop/quirk/cells/swap_cell_test.py +6 -4
- cirq/interop/quirk/cells/testing.py +6 -6
- cirq/interop/quirk/cells/testing_test.py +8 -6
- cirq/interop/quirk/cells/unsupported_cells.py +3 -0
- cirq/interop/quirk/cells/unsupported_cells_test.py +4 -2
- cirq/interop/quirk/url_to_circuit.py +23 -36
- cirq/interop/quirk/url_to_circuit_test.py +4 -1
- cirq/json_resolver_cache.py +14 -12
- cirq/linalg/__init__.py +4 -6
- cirq/linalg/combinators.py +7 -5
- cirq/linalg/combinators_test.py +10 -7
- cirq/linalg/decompositions.py +24 -35
- cirq/linalg/decompositions_test.py +3 -1
- cirq/linalg/diagonalize.py +6 -4
- cirq/linalg/diagonalize_test.py +15 -14
- cirq/linalg/operator_spaces.py +14 -14
- cirq/linalg/operator_spaces_test.py +13 -11
- cirq/linalg/predicates.py +18 -9
- cirq/linalg/predicates_test.py +5 -0
- cirq/linalg/tolerance.py +6 -3
- cirq/linalg/tolerance_test.py +6 -4
- cirq/linalg/transformations.py +23 -20
- cirq/linalg/transformations_test.py +73 -43
- cirq/neutral_atoms/convert_to_neutral_atom_gates.py +9 -3
- cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +3 -1
- cirq/neutral_atoms/neutral_atom_devices.py +2 -0
- cirq/ops/__init__.py +2 -0
- cirq/ops/arithmetic_operation.py +21 -21
- cirq/ops/arithmetic_operation_test.py +7 -8
- cirq/ops/boolean_hamiltonian.py +23 -22
- cirq/ops/boolean_hamiltonian_test.py +12 -9
- cirq/ops/classically_controlled_operation.py +31 -36
- cirq/ops/classically_controlled_operation_test.py +121 -117
- cirq/ops/clifford_gate.py +98 -81
- cirq/ops/clifford_gate_test.py +72 -57
- cirq/ops/common_channels.py +44 -44
- cirq/ops/common_channels_test.py +83 -81
- cirq/ops/common_gate_families.py +9 -7
- cirq/ops/common_gate_families_test.py +11 -7
- cirq/ops/common_gates.py +164 -183
- cirq/ops/common_gates_test.py +135 -95
- cirq/ops/control_values.py +23 -26
- cirq/ops/control_values_test.py +22 -20
- cirq/ops/controlled_gate.py +64 -112
- cirq/ops/controlled_gate_test.py +130 -35
- cirq/ops/controlled_operation.py +24 -35
- cirq/ops/controlled_operation_test.py +8 -6
- cirq/ops/dense_pauli_string.py +38 -49
- cirq/ops/dense_pauli_string_test.py +4 -2
- cirq/ops/diagonal_gate.py +18 -31
- cirq/ops/diagonal_gate_test.py +13 -13
- cirq/ops/eigen_gate.py +29 -29
- cirq/ops/eigen_gate_test.py +45 -28
- cirq/ops/fourier_transform.py +14 -20
- cirq/ops/fourier_transform_test.py +15 -12
- cirq/ops/fsim_gate.py +43 -42
- cirq/ops/fsim_gate_test.py +29 -29
- cirq/ops/gate_features.py +2 -0
- cirq/ops/gate_features_test.py +5 -3
- cirq/ops/gate_operation.py +43 -65
- cirq/ops/gate_operation_test.py +46 -42
- cirq/ops/gateset.py +28 -40
- cirq/ops/gateset_test.py +4 -2
- cirq/ops/global_phase_op.py +45 -20
- cirq/ops/global_phase_op_test.py +44 -20
- cirq/ops/greedy_qubit_manager.py +10 -8
- cirq/ops/greedy_qubit_manager_test.py +5 -3
- cirq/ops/identity.py +14 -12
- cirq/ops/identity_test.py +24 -20
- cirq/ops/kraus_channel.py +11 -8
- cirq/ops/kraus_channel_test.py +14 -11
- cirq/ops/linear_combinations.py +65 -77
- cirq/ops/linear_combinations_test.py +14 -9
- cirq/ops/matrix_gates.py +21 -18
- cirq/ops/matrix_gates_test.py +16 -0
- cirq/ops/measure_util.py +15 -20
- cirq/ops/measure_util_test.py +2 -0
- cirq/ops/measurement_gate.py +26 -37
- cirq/ops/measurement_gate_test.py +2 -0
- cirq/ops/mixed_unitary_channel.py +12 -9
- cirq/ops/mixed_unitary_channel_test.py +14 -11
- cirq/ops/named_qubit.py +16 -13
- cirq/ops/named_qubit_test.py +15 -13
- cirq/ops/op_tree.py +9 -7
- cirq/ops/op_tree_test.py +22 -19
- cirq/ops/parallel_gate.py +15 -17
- cirq/ops/parallel_gate_test.py +18 -16
- cirq/ops/parity_gates.py +23 -25
- cirq/ops/parity_gates_test.py +36 -32
- cirq/ops/pauli_gates.py +22 -21
- cirq/ops/pauli_gates_test.py +29 -20
- cirq/ops/pauli_interaction_gate.py +15 -19
- cirq/ops/pauli_interaction_gate_test.py +10 -8
- cirq/ops/pauli_measurement_gate.py +23 -35
- cirq/ops/pauli_measurement_gate_test.py +2 -0
- cirq/ops/pauli_string.py +92 -120
- cirq/ops/pauli_string_phasor.py +52 -45
- cirq/ops/pauli_string_phasor_test.py +4 -5
- cirq/ops/pauli_string_raw_types.py +9 -7
- cirq/ops/pauli_string_raw_types_test.py +2 -0
- cirq/ops/pauli_string_test.py +31 -154
- cirq/ops/pauli_sum_exponential.py +12 -12
- cirq/ops/pauli_sum_exponential_test.py +12 -10
- cirq/ops/permutation_gate.py +8 -6
- cirq/ops/permutation_gate_test.py +10 -8
- cirq/ops/phased_iswap_gate.py +16 -16
- cirq/ops/phased_iswap_gate_test.py +17 -15
- cirq/ops/phased_x_gate.py +16 -17
- cirq/ops/phased_x_gate_test.py +18 -16
- cirq/ops/phased_x_z_gate.py +24 -22
- cirq/ops/phased_x_z_gate_test.py +17 -11
- cirq/ops/projector.py +16 -11
- cirq/ops/projector_test.py +19 -16
- cirq/ops/qid_util.py +7 -5
- cirq/ops/qid_util_test.py +2 -0
- cirq/ops/qubit_manager.py +11 -9
- cirq/ops/qubit_manager_test.py +6 -4
- cirq/ops/qubit_order.py +11 -14
- cirq/ops/qubit_order_or_list.py +4 -2
- cirq/ops/qubit_order_test.py +12 -10
- cirq/ops/random_gate_channel.py +12 -10
- cirq/ops/random_gate_channel_test.py +14 -11
- cirq/ops/raw_types.py +109 -129
- cirq/ops/raw_types_test.py +63 -57
- cirq/ops/state_preparation_channel.py +7 -7
- cirq/ops/state_preparation_channel_test.py +11 -9
- cirq/ops/swap_gates.py +13 -15
- cirq/ops/swap_gates_test.py +19 -17
- cirq/ops/tags.py +5 -3
- cirq/ops/tags_test.py +4 -2
- cirq/ops/three_qubit_gates.py +43 -76
- cirq/ops/three_qubit_gates_test.py +19 -17
- cirq/ops/two_qubit_diagonal_gate.py +13 -13
- cirq/ops/two_qubit_diagonal_gate_test.py +10 -8
- cirq/ops/uniform_superposition_gate.py +5 -3
- cirq/ops/uniform_superposition_gate_test.py +5 -3
- cirq/ops/wait_gate.py +17 -14
- cirq/ops/wait_gate_test.py +9 -6
- cirq/protocols/__init__.py +0 -3
- cirq/protocols/act_on_protocol.py +8 -6
- cirq/protocols/act_on_protocol_test.py +15 -12
- cirq/protocols/apply_channel_protocol.py +10 -14
- cirq/protocols/apply_channel_protocol_test.py +2 -0
- cirq/protocols/apply_mixture_protocol.py +13 -42
- cirq/protocols/apply_mixture_protocol_test.py +7 -5
- cirq/protocols/apply_unitary_protocol.py +39 -34
- cirq/protocols/apply_unitary_protocol_test.py +4 -1
- cirq/protocols/approximate_equality_protocol.py +2 -0
- cirq/protocols/approximate_equality_protocol_test.py +2 -0
- cirq/protocols/circuit_diagram_info_protocol.py +58 -42
- cirq/protocols/circuit_diagram_info_protocol_test.py +70 -12
- cirq/protocols/commutes_protocol.py +8 -7
- cirq/protocols/commutes_protocol_test.py +2 -0
- cirq/protocols/control_key_protocol.py +6 -4
- cirq/protocols/control_key_protocol_test.py +3 -1
- cirq/protocols/decompose_protocol.py +49 -48
- cirq/protocols/decompose_protocol_test.py +27 -16
- cirq/protocols/equal_up_to_global_phase_protocol.py +2 -0
- cirq/protocols/equal_up_to_global_phase_protocol_test.py +9 -6
- cirq/protocols/has_stabilizer_effect_protocol.py +7 -5
- cirq/protocols/has_stabilizer_effect_protocol_test.py +7 -5
- cirq/protocols/has_unitary_protocol.py +10 -6
- cirq/protocols/has_unitary_protocol_test.py +13 -8
- cirq/protocols/hash_from_pickle_test.py +2 -11
- cirq/protocols/inverse_protocol.py +13 -16
- cirq/protocols/inverse_protocol_test.py +5 -3
- cirq/protocols/json_serialization.py +35 -54
- cirq/protocols/json_serialization_test.py +14 -21
- cirq/protocols/json_test_data/CXSWAP.json +46 -0
- cirq/protocols/json_test_data/CXSWAP.repr +13 -0
- cirq/protocols/json_test_data/CZSWAP.json +46 -0
- cirq/protocols/json_test_data/CZSWAP.repr +13 -0
- cirq/protocols/json_test_data/CircuitOperation.json +6 -3
- cirq/protocols/json_test_data/CircuitOperation.repr_inward +4 -2
- cirq/protocols/json_test_data/Moment.json +24 -1
- cirq/protocols/json_test_data/Moment.repr +6 -1
- cirq/protocols/json_test_data/ThermalNoiseModel.json +32 -0
- cirq/protocols/json_test_data/ThermalNoiseModel.repr +1 -0
- cirq/protocols/json_test_data/spec.py +6 -2
- cirq/protocols/kraus_protocol.py +47 -7
- cirq/protocols/kraus_protocol_test.py +86 -12
- cirq/protocols/measurement_key_protocol.py +15 -16
- cirq/protocols/measurement_key_protocol_test.py +13 -11
- cirq/protocols/mixture_protocol.py +7 -5
- cirq/protocols/mixture_protocol_test.py +4 -2
- cirq/protocols/mul_protocol.py +2 -3
- cirq/protocols/mul_protocol_test.py +2 -0
- cirq/protocols/pauli_expansion_protocol.py +6 -3
- cirq/protocols/pauli_expansion_protocol_test.py +5 -3
- cirq/protocols/phase_protocol.py +2 -0
- cirq/protocols/phase_protocol_test.py +3 -1
- cirq/protocols/pow_protocol.py +11 -16
- cirq/protocols/pow_protocol_test.py +2 -0
- cirq/protocols/qasm.py +14 -20
- cirq/protocols/qasm_test.py +6 -3
- cirq/protocols/qid_shape_protocol.py +8 -8
- cirq/protocols/qid_shape_protocol_test.py +3 -1
- cirq/protocols/resolve_parameters.py +5 -3
- cirq/protocols/resolve_parameters_test.py +8 -7
- cirq/protocols/trace_distance_bound.py +6 -4
- cirq/protocols/trace_distance_bound_test.py +3 -1
- cirq/protocols/unitary_protocol.py +17 -7
- cirq/protocols/unitary_protocol_test.py +12 -2
- cirq/qis/channels.py +6 -2
- cirq/qis/channels_test.py +20 -16
- cirq/qis/clifford_tableau.py +21 -19
- cirq/qis/clifford_tableau_test.py +2 -2
- cirq/qis/entropy.py +14 -3
- cirq/qis/entropy_test.py +3 -1
- cirq/qis/measures.py +13 -13
- cirq/qis/measures_test.py +20 -14
- cirq/qis/noise_utils.py +2 -0
- cirq/qis/noise_utils_test.py +9 -7
- cirq/qis/quantum_state_representation.py +7 -8
- cirq/qis/states.py +58 -56
- cirq/qis/states_test.py +2 -0
- cirq/sim/classical_simulator.py +23 -22
- cirq/sim/classical_simulator_test.py +2 -0
- cirq/sim/clifford/clifford_simulator.py +23 -21
- cirq/sim/clifford/clifford_simulator_test.py +7 -4
- cirq/sim/clifford/clifford_tableau_simulation_state.py +10 -7
- cirq/sim/clifford/clifford_tableau_simulation_state_test.py +5 -5
- cirq/sim/clifford/stabilizer_ch_form_simulation_state.py +8 -6
- cirq/sim/clifford/stabilizer_ch_form_simulation_state_test.py +8 -6
- cirq/sim/clifford/stabilizer_sampler.py +9 -7
- cirq/sim/clifford/stabilizer_sampler_test.py +4 -2
- cirq/sim/clifford/stabilizer_simulation_state.py +14 -13
- cirq/sim/clifford/stabilizer_simulation_state_test.py +6 -4
- cirq/sim/clifford/stabilizer_state_ch_form.py +13 -11
- cirq/sim/clifford/stabilizer_state_ch_form_test.py +4 -2
- cirq/sim/density_matrix_simulation_state.py +26 -27
- cirq/sim/density_matrix_simulation_state_test.py +10 -8
- cirq/sim/density_matrix_simulator.py +30 -28
- cirq/sim/density_matrix_simulator_test.py +48 -48
- cirq/sim/density_matrix_utils.py +13 -11
- cirq/sim/density_matrix_utils_test.py +38 -36
- cirq/sim/mux.py +33 -31
- cirq/sim/mux_test.py +3 -0
- cirq/sim/simulation_product_state.py +15 -15
- cirq/sim/simulation_product_state_test.py +29 -26
- cirq/sim/simulation_state.py +29 -38
- cirq/sim/simulation_state_base.py +21 -32
- cirq/sim/simulation_state_test.py +15 -13
- cirq/sim/simulation_utils.py +5 -2
- cirq/sim/simulation_utils_test.py +5 -2
- cirq/sim/simulator.py +90 -106
- cirq/sim/simulator_base.py +33 -45
- cirq/sim/simulator_base_test.py +20 -15
- cirq/sim/simulator_test.py +23 -14
- cirq/sim/sparse_simulator.py +19 -17
- cirq/sim/sparse_simulator_test.py +41 -40
- cirq/sim/state_vector.py +15 -12
- cirq/sim/state_vector_simulation_state.py +31 -31
- cirq/sim/state_vector_simulation_state_test.py +16 -14
- cirq/sim/state_vector_simulator.py +17 -14
- cirq/sim/state_vector_simulator_test.py +2 -0
- cirq/sim/state_vector_test.py +6 -3
- cirq/study/flatten_expressions.py +16 -15
- cirq/study/flatten_expressions_test.py +13 -11
- cirq/study/resolver.py +18 -17
- cirq/study/resolver_test.py +22 -20
- cirq/study/result.py +17 -27
- cirq/study/result_test.py +2 -0
- cirq/study/sweepable.py +12 -10
- cirq/study/sweepable_test.py +3 -0
- cirq/study/sweeps.py +42 -61
- cirq/study/sweeps_test.py +33 -0
- cirq/testing/__init__.py +7 -11
- cirq/testing/_compat_test_data/module_a/__init__.py +1 -0
- cirq/testing/_compat_test_data/module_a/module_b/__init__.py +1 -0
- cirq/testing/_compat_test_data/module_a/sub/__init__.py +1 -0
- cirq/testing/circuit_compare.py +8 -17
- cirq/testing/circuit_compare_test.py +2 -0
- cirq/testing/consistent_act_on.py +13 -11
- cirq/testing/consistent_act_on_test.py +5 -3
- cirq/testing/consistent_channels.py +2 -0
- cirq/testing/consistent_channels_test.py +10 -8
- cirq/testing/consistent_controlled_gate_op.py +5 -5
- cirq/testing/consistent_controlled_gate_op_test.py +18 -18
- cirq/testing/consistent_decomposition.py +2 -2
- cirq/testing/consistent_decomposition_test.py +4 -2
- cirq/testing/consistent_pauli_expansion.py +2 -0
- cirq/testing/consistent_pauli_expansion_test.py +3 -1
- cirq/testing/consistent_phase_by.py +2 -0
- cirq/testing/consistent_phase_by_test.py +3 -1
- cirq/testing/consistent_protocols.py +14 -20
- cirq/testing/consistent_protocols_test.py +13 -11
- cirq/testing/consistent_qasm.py +6 -4
- cirq/testing/consistent_qasm_test.py +7 -7
- cirq/testing/consistent_resolve_parameters.py +2 -0
- cirq/testing/consistent_specified_has_unitary.py +2 -2
- cirq/testing/consistent_specified_has_unitary_test.py +6 -4
- cirq/testing/consistent_unitary.py +1 -0
- cirq/testing/consistent_unitary_test.py +4 -2
- cirq/testing/deprecation.py +5 -2
- cirq/testing/deprecation_test.py +5 -2
- cirq/testing/devices.py +7 -4
- cirq/testing/devices_test.py +7 -4
- cirq/testing/equals_tester.py +4 -2
- cirq/testing/equals_tester_test.py +21 -17
- cirq/testing/equivalent_basis_map.py +6 -4
- cirq/testing/equivalent_basis_map_test.py +6 -4
- cirq/testing/equivalent_repr_eval.py +6 -4
- cirq/testing/equivalent_repr_eval_test.py +5 -3
- cirq/testing/gate_features.py +2 -0
- cirq/testing/gate_features_test.py +7 -5
- cirq/testing/json.py +19 -15
- cirq/testing/json_test.py +5 -3
- cirq/testing/lin_alg_utils.py +10 -11
- cirq/testing/lin_alg_utils_test.py +14 -12
- cirq/testing/logs.py +7 -6
- cirq/testing/logs_test.py +9 -7
- cirq/testing/no_identifier_qubit.py +4 -2
- cirq/testing/no_identifier_qubit_test.py +5 -3
- cirq/testing/op_tree.py +2 -0
- cirq/testing/op_tree_test.py +4 -1
- cirq/testing/order_tester.py +2 -0
- cirq/testing/order_tester_test.py +8 -6
- cirq/testing/pytest_utils.py +2 -0
- cirq/testing/pytest_utils_test.py +4 -2
- cirq/testing/random_circuit.py +21 -20
- cirq/testing/random_circuit_test.py +12 -9
- cirq/testing/repr_pretty_tester.py +1 -0
- cirq/testing/repr_pretty_tester_test.py +5 -3
- cirq/testing/routing_devices.py +4 -1
- cirq/testing/routing_devices_test.py +9 -6
- cirq/testing/sample_circuits.py +4 -1
- cirq/testing/sample_circuits_test.py +3 -1
- cirq/testing/sample_gates.py +3 -0
- cirq/testing/sample_gates_test.py +5 -2
- cirq/transformers/__init__.py +11 -4
- cirq/transformers/align.py +9 -7
- cirq/transformers/align_test.py +2 -0
- cirq/transformers/analytical_decompositions/__init__.py +3 -6
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +18 -16
- cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +2 -0
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +19 -16
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +11 -9
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +5 -3
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +5 -3
- cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +5 -3
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +141 -44
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +35 -1
- cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +8 -7
- cirq/transformers/analytical_decompositions/single_qubit_decompositions_test.py +2 -0
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +7 -4
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +3 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +11 -19
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +8 -33
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +9 -11
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -0
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +91 -27
- cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +36 -7
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +20 -21
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +8 -6
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +13 -15
- cirq/transformers/analytical_decompositions/two_qubit_to_ms_test.py +3 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +39 -41
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -0
- cirq/transformers/drop_empty_moments.py +5 -3
- cirq/transformers/drop_empty_moments_test.py +4 -2
- cirq/transformers/drop_negligible_operations.py +7 -5
- cirq/transformers/drop_negligible_operations_test.py +2 -0
- cirq/transformers/dynamical_decoupling.py +49 -42
- cirq/transformers/dynamical_decoupling_test.py +223 -205
- cirq/transformers/eject_phased_paulis.py +28 -26
- cirq/transformers/eject_phased_paulis_test.py +12 -9
- cirq/transformers/eject_z.py +12 -12
- cirq/transformers/eject_z_test.py +2 -2
- cirq/transformers/expand_composite.py +6 -4
- cirq/transformers/expand_composite_test.py +3 -1
- cirq/transformers/gauge_compiling/__init__.py +3 -1
- cirq/transformers/gauge_compiling/cphase_gauge.py +2 -0
- cirq/transformers/gauge_compiling/cphase_gauge_test.py +2 -0
- cirq/transformers/gauge_compiling/cz_gauge.py +2 -0
- cirq/transformers/gauge_compiling/cz_gauge_test.py +1 -0
- cirq/transformers/gauge_compiling/gauge_compiling.py +45 -41
- cirq/transformers/gauge_compiling/gauge_compiling_test.py +2 -0
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +1 -0
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +5 -1
- cirq/transformers/gauge_compiling/iswap_gauge.py +2 -0
- cirq/transformers/gauge_compiling/iswap_gauge_test.py +1 -0
- cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -0
- cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py +2 -0
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +7 -6
- cirq/transformers/gauge_compiling/sqrt_cz_gauge_test.py +2 -0
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +2 -0
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py +2 -0
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +6 -3
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +3 -0
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +12 -9
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +9 -7
- cirq/transformers/insertion_sort.py +8 -6
- cirq/transformers/insertion_sort_test.py +3 -1
- cirq/transformers/measurement_transformers.py +29 -29
- cirq/transformers/measurement_transformers_test.py +2 -0
- cirq/transformers/merge_k_qubit_gates.py +12 -10
- cirq/transformers/merge_k_qubit_gates_test.py +18 -18
- cirq/transformers/merge_single_qubit_gates.py +197 -20
- cirq/transformers/merge_single_qubit_gates_test.py +177 -5
- cirq/transformers/noise_adding.py +5 -3
- cirq/transformers/noise_adding_test.py +2 -0
- cirq/transformers/optimize_for_target_gateset.py +19 -17
- cirq/transformers/optimize_for_target_gateset_test.py +11 -8
- cirq/transformers/qubit_management_transformers.py +13 -11
- cirq/transformers/qubit_management_transformers_test.py +5 -3
- cirq/transformers/randomized_measurements.py +16 -14
- cirq/transformers/randomized_measurements_test.py +10 -4
- cirq/transformers/routing/initial_mapper.py +6 -4
- cirq/transformers/routing/initial_mapper_test.py +2 -0
- cirq/transformers/routing/line_initial_mapper.py +16 -14
- cirq/transformers/routing/line_initial_mapper_test.py +9 -7
- cirq/transformers/routing/mapping_manager.py +10 -10
- cirq/transformers/routing/mapping_manager_test.py +2 -0
- cirq/transformers/routing/route_circuit_cqc.py +33 -31
- cirq/transformers/routing/route_circuit_cqc_test.py +15 -13
- cirq/transformers/routing/visualize_routed_circuit.py +8 -7
- cirq/transformers/routing/visualize_routed_circuit_test.py +4 -2
- cirq/transformers/stratify.py +17 -15
- cirq/transformers/stratify_test.py +3 -0
- cirq/transformers/symbolize.py +103 -0
- cirq/transformers/symbolize_test.py +62 -0
- cirq/transformers/synchronize_terminal_measurements.py +10 -10
- cirq/transformers/synchronize_terminal_measurements_test.py +12 -10
- cirq/transformers/tag_transformers.py +97 -0
- cirq/transformers/tag_transformers_test.py +103 -0
- cirq/transformers/target_gatesets/compilation_target_gateset.py +21 -19
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +20 -16
- cirq/transformers/target_gatesets/cz_gateset.py +7 -5
- cirq/transformers/target_gatesets/cz_gateset_test.py +21 -19
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +9 -7
- cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +25 -25
- cirq/transformers/transformer_api.py +34 -47
- cirq/transformers/transformer_api_test.py +9 -8
- cirq/transformers/transformer_primitives.py +39 -49
- cirq/transformers/transformer_primitives_test.py +10 -17
- cirq/value/abc_alt.py +6 -4
- cirq/value/abc_alt_test.py +5 -3
- cirq/value/angle.py +11 -12
- cirq/value/angle_test.py +5 -3
- cirq/value/classical_data.py +27 -27
- cirq/value/classical_data_test.py +11 -8
- cirq/value/condition.py +26 -24
- cirq/value/condition_test.py +2 -0
- cirq/value/digits.py +14 -11
- cirq/value/digits_test.py +2 -0
- cirq/value/duration.py +23 -20
- cirq/value/duration_test.py +2 -0
- cirq/value/linear_dict.py +25 -30
- cirq/value/linear_dict_test.py +10 -8
- cirq/value/measurement_key.py +12 -12
- cirq/value/measurement_key_test.py +2 -0
- cirq/value/periodic_value.py +4 -4
- cirq/value/periodic_value_test.py +11 -7
- cirq/value/probability.py +3 -1
- cirq/value/probability_test.py +4 -2
- cirq/value/product_state.py +15 -13
- cirq/value/product_state_test.py +4 -1
- cirq/value/random_state.py +2 -0
- cirq/value/random_state_test.py +5 -3
- cirq/value/timestamp.py +11 -7
- cirq/value/timestamp_test.py +14 -12
- cirq/value/type_alias.py +4 -4
- cirq/value/value_equality_attr.py +8 -9
- cirq/value/value_equality_attr_test.py +14 -11
- cirq/vis/density_matrix.py +3 -3
- cirq/vis/density_matrix_test.py +20 -17
- cirq/vis/heatmap.py +24 -37
- cirq/vis/heatmap_test.py +3 -0
- cirq/vis/histogram.py +9 -6
- cirq/vis/histogram_test.py +5 -2
- cirq/vis/state_histogram.py +10 -8
- cirq/vis/state_histogram_test.py +7 -5
- cirq/vis/vis_utils.py +4 -1
- cirq/vis/vis_utils_test.py +4 -1
- cirq/work/collector.py +12 -18
- cirq/work/collector_test.py +15 -10
- cirq/work/observable_grouping.py +6 -7
- cirq/work/observable_grouping_test.py +10 -9
- cirq/work/observable_measurement.py +47 -45
- cirq/work/observable_measurement_data.py +22 -17
- cirq/work/observable_measurement_data_test.py +4 -1
- cirq/work/observable_measurement_test.py +48 -29
- cirq/work/observable_readout_calibration.py +5 -2
- cirq/work/observable_readout_calibration_test.py +5 -2
- cirq/work/observable_settings.py +13 -22
- cirq/work/observable_settings_test.py +9 -7
- cirq/work/pauli_sum_collector.py +12 -10
- cirq/work/pauli_sum_collector_test.py +9 -9
- cirq/work/sampler.py +42 -43
- cirq/work/sampler_test.py +31 -24
- cirq/work/zeros_sampler.py +6 -4
- cirq/work/zeros_sampler_test.py +7 -5
- {cirq_core-1.5.0.dev20250409225226.dist-info → cirq_core-1.6.0.dist-info}/METADATA +7 -8
- cirq_core-1.6.0.dist-info/RECORD +1241 -0
- {cirq_core-1.5.0.dev20250409225226.dist-info → cirq_core-1.6.0.dist-info}/WHEEL +1 -1
- cirq_core-1.5.0.dev20250409225226.dist-info/RECORD +0 -1216
- {cirq_core-1.5.0.dev20250409225226.dist-info → cirq_core-1.6.0.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.5.0.dev20250409225226.dist-info → cirq_core-1.6.0.dist-info}/top_level.txt +0 -0
|
@@ -12,8 +12,10 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import abc
|
|
16
|
-
from typing import
|
|
18
|
+
from typing import TYPE_CHECKING
|
|
17
19
|
|
|
18
20
|
from cirq import value
|
|
19
21
|
|
|
@@ -37,7 +39,7 @@ class AbstractInitialMapper(metaclass=abc.ABCMeta):
|
|
|
37
39
|
"""
|
|
38
40
|
|
|
39
41
|
@abc.abstractmethod
|
|
40
|
-
def initial_mapping(self, circuit:
|
|
42
|
+
def initial_mapping(self, circuit: cirq.AbstractCircuit) -> dict[cirq.Qid, cirq.Qid]:
|
|
41
43
|
"""Maps the logical qubits of a circuit onto physical qubits on a device.
|
|
42
44
|
|
|
43
45
|
Args:
|
|
@@ -52,10 +54,10 @@ class AbstractInitialMapper(metaclass=abc.ABCMeta):
|
|
|
52
54
|
class HardCodedInitialMapper(AbstractInitialMapper):
|
|
53
55
|
"""Initial Mapper class takes a hard-coded mapping and returns it."""
|
|
54
56
|
|
|
55
|
-
def __init__(self, _map:
|
|
57
|
+
def __init__(self, _map: dict[cirq.Qid, cirq.Qid]) -> None:
|
|
56
58
|
self._map = _map
|
|
57
59
|
|
|
58
|
-
def initial_mapping(self, circuit:
|
|
60
|
+
def initial_mapping(self, circuit: cirq.AbstractCircuit) -> dict[cirq.Qid, cirq.Qid]:
|
|
59
61
|
"""Returns the hard-coded initial mapping.
|
|
60
62
|
|
|
61
63
|
Args:
|
|
@@ -30,8 +30,10 @@ If some logical qubits are unampped after this first procedure then there are tw
|
|
|
30
30
|
the nearest available neighbor to the center of the device.
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
+
from __future__ import annotations
|
|
34
|
+
|
|
33
35
|
from collections import deque
|
|
34
|
-
from typing import
|
|
36
|
+
from typing import TYPE_CHECKING
|
|
35
37
|
|
|
36
38
|
import networkx as nx
|
|
37
39
|
|
|
@@ -82,8 +84,8 @@ class LineInitialMapper(initial_mapper.AbstractInitialMapper):
|
|
|
82
84
|
self.center = nx.center(self.device_graph)[0]
|
|
83
85
|
|
|
84
86
|
def _make_circuit_graph(
|
|
85
|
-
self, circuit:
|
|
86
|
-
) ->
|
|
87
|
+
self, circuit: cirq.AbstractCircuit
|
|
88
|
+
) -> tuple[list[deque[cirq.Qid]], dict[cirq.Qid, cirq.Qid]]:
|
|
87
89
|
"""Creates a (potentially incomplete) qubit connectivity graph of the circuit.
|
|
88
90
|
|
|
89
91
|
Iterates over moments in the circuit from left to right and adds edges between logical
|
|
@@ -99,11 +101,11 @@ class LineInitialMapper(initial_mapper.AbstractInitialMapper):
|
|
|
99
101
|
The (potentially incomplete) qubit connectivity graph of the circuit, which is
|
|
100
102
|
guaranteed to be a forest of line graphs.
|
|
101
103
|
"""
|
|
102
|
-
circuit_graph:
|
|
103
|
-
component_id:
|
|
104
|
-
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] = {}
|
|
105
107
|
|
|
106
|
-
def degree_lt_two(q:
|
|
108
|
+
def degree_lt_two(q: cirq.Qid):
|
|
107
109
|
return any(circuit_graph[component_id[q]][i] == q for i in [-1, 0])
|
|
108
110
|
|
|
109
111
|
for op in circuit.all_operations():
|
|
@@ -141,7 +143,7 @@ class LineInitialMapper(initial_mapper.AbstractInitialMapper):
|
|
|
141
143
|
)
|
|
142
144
|
return graph, partners
|
|
143
145
|
|
|
144
|
-
def initial_mapping(self, circuit:
|
|
146
|
+
def initial_mapping(self, circuit: cirq.AbstractCircuit) -> dict[cirq.Qid, cirq.Qid]:
|
|
145
147
|
"""Maps disjoint lines of logical qubits onto lines of physical qubits.
|
|
146
148
|
|
|
147
149
|
Args:
|
|
@@ -151,13 +153,13 @@ class LineInitialMapper(initial_mapper.AbstractInitialMapper):
|
|
|
151
153
|
a dictionary that maps logical qubits in the circuit (keys) to physical qubits on the
|
|
152
154
|
device (values).
|
|
153
155
|
"""
|
|
154
|
-
mapped_physicals:
|
|
155
|
-
qubit_map:
|
|
156
|
+
mapped_physicals: set[cirq.Qid] = set()
|
|
157
|
+
qubit_map: dict[cirq.Qid, cirq.Qid] = {}
|
|
156
158
|
circuit_graph, partners = self._make_circuit_graph(circuit)
|
|
157
159
|
|
|
158
160
|
def next_physical(
|
|
159
|
-
current_physical:
|
|
160
|
-
) ->
|
|
161
|
+
current_physical: cirq.Qid, partner: cirq.Qid, isolated: bool = False
|
|
162
|
+
) -> cirq.Qid:
|
|
161
163
|
# Handle the first physical qubit getting mapped.
|
|
162
164
|
if current_physical not in mapped_physicals:
|
|
163
165
|
return current_physical
|
|
@@ -189,8 +191,8 @@ class LineInitialMapper(initial_mapper.AbstractInitialMapper):
|
|
|
189
191
|
return qubit_map
|
|
190
192
|
|
|
191
193
|
def _closest_unmapped_qubit(
|
|
192
|
-
self, source:
|
|
193
|
-
) ->
|
|
194
|
+
self, source: cirq.Qid, mapped_physicals: set[cirq.Qid]
|
|
195
|
+
) -> cirq.Qid:
|
|
194
196
|
"""Finds the closest available neighbor to a physical qubit 'source' on the device.
|
|
195
197
|
|
|
196
198
|
Args:
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import networkx as nx
|
|
16
18
|
import pytest
|
|
17
19
|
|
|
@@ -66,7 +68,7 @@ def construct_valid_circuit():
|
|
|
66
68
|
)
|
|
67
69
|
|
|
68
70
|
|
|
69
|
-
def test_valid_circuit():
|
|
71
|
+
def test_valid_circuit() -> None:
|
|
70
72
|
# Any circuit with a (full connectivity) graph of disjoint lines should be directly
|
|
71
73
|
# executable after mapping a a supporting device topology without the need for inserting
|
|
72
74
|
# any swaps.
|
|
@@ -79,7 +81,7 @@ def test_valid_circuit():
|
|
|
79
81
|
device.validate_circuit(mapped_circuit)
|
|
80
82
|
|
|
81
83
|
|
|
82
|
-
def test_long_line_on_grid_device():
|
|
84
|
+
def test_long_line_on_grid_device() -> None:
|
|
83
85
|
# tests
|
|
84
86
|
# -if strategy is able to map a single long line onto the device whenever the device topology
|
|
85
87
|
# supports it (i.e. is Hamiltonian)
|
|
@@ -106,7 +108,7 @@ def test_long_line_on_grid_device():
|
|
|
106
108
|
mapper.initial_mapping(step_circuit)
|
|
107
109
|
|
|
108
110
|
|
|
109
|
-
def test_small_circuit_on_grid_device():
|
|
111
|
+
def test_small_circuit_on_grid_device() -> None:
|
|
110
112
|
circuit = construct_small_circuit()
|
|
111
113
|
device_graph = cirq.testing.construct_grid_device(7, 7).metadata.nx_graph
|
|
112
114
|
mapper = cirq.LineInitialMapper(device_graph)
|
|
@@ -126,7 +128,7 @@ def test_small_circuit_on_grid_device():
|
|
|
126
128
|
cirq.testing.assert_same_circuits(circuit.transform_qubits(mapping), expected_circuit)
|
|
127
129
|
|
|
128
130
|
|
|
129
|
-
def test_small_circuit_on_ring_device():
|
|
131
|
+
def test_small_circuit_on_ring_device() -> None:
|
|
130
132
|
circuit = construct_small_circuit()
|
|
131
133
|
device_graph = cirq.testing.construct_ring_device(10, directed=True).metadata.nx_graph
|
|
132
134
|
|
|
@@ -159,7 +161,7 @@ glob_mapper = cirq.LineInitialMapper(glob_device_graph)
|
|
|
159
161
|
)
|
|
160
162
|
def test_random_circuits_grid_device(
|
|
161
163
|
qubits: int, n_moments: int, op_density: float, random_state: int
|
|
162
|
-
):
|
|
164
|
+
) -> None:
|
|
163
165
|
c_orig = cirq.testing.random_circuit(
|
|
164
166
|
qubits=qubits, n_moments=n_moments, op_density=op_density, random_state=random_state
|
|
165
167
|
)
|
|
@@ -176,7 +178,7 @@ def test_random_circuits_grid_device(
|
|
|
176
178
|
)
|
|
177
179
|
def test_large_random_circuits_grid_device(
|
|
178
180
|
qubits: int, n_moments: int, op_density: float, random_state: int
|
|
179
|
-
):
|
|
181
|
+
) -> None:
|
|
180
182
|
c_orig = cirq.testing.random_circuit(
|
|
181
183
|
qubits=qubits, n_moments=n_moments, op_density=op_density, random_state=random_state
|
|
182
184
|
)
|
|
@@ -187,7 +189,7 @@ def test_large_random_circuits_grid_device(
|
|
|
187
189
|
assert nx.is_connected(nx.induced_subgraph(glob_device_graph, mapping.values()))
|
|
188
190
|
|
|
189
191
|
|
|
190
|
-
def test_repr():
|
|
192
|
+
def test_repr() -> None:
|
|
191
193
|
device_graph = cirq.testing.construct_grid_device(7, 7).metadata.nx_graph
|
|
192
194
|
mapper = cirq.LineInitialMapper(device_graph)
|
|
193
195
|
cirq.testing.assert_equivalent_repr(mapper, setup_code='import cirq\nimport networkx as nx')
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
"""Manages the mapping from logical to physical qubits during a routing procedure."""
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import Sequence, TYPE_CHECKING
|
|
18
20
|
|
|
19
21
|
import networkx as nx
|
|
20
22
|
import numpy as np
|
|
@@ -35,9 +37,7 @@ class MappingManager:
|
|
|
35
37
|
logical qubits are mapped to, via `self.logical_qid_to_int` map).
|
|
36
38
|
"""
|
|
37
39
|
|
|
38
|
-
def __init__(
|
|
39
|
-
self, device_graph: nx.Graph, initial_mapping: Dict['cirq.Qid', 'cirq.Qid']
|
|
40
|
-
) -> None:
|
|
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.
|
|
@@ -178,7 +178,7 @@ class MappingManager:
|
|
|
178
178
|
self._logical_to_physical[[lq1, lq2]] = self._logical_to_physical[[lq2, lq1]]
|
|
179
179
|
self._physical_to_logical[[pq1, pq2]] = self._physical_to_logical[[pq2, pq1]]
|
|
180
180
|
|
|
181
|
-
def mapped_op(self, op:
|
|
181
|
+
def mapped_op(self, op: cirq.Operation) -> cirq.Operation:
|
|
182
182
|
"""Transforms the given logical operation to act on corresponding physical qubits.
|
|
183
183
|
|
|
184
184
|
Args:
|
|
@@ -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)
|
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
"""Heuristic qubit routing algorithm based on arxiv:1902.08091."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
import itertools
|
|
18
|
-
from typing import Any,
|
|
20
|
+
from typing import Any, Sequence, TYPE_CHECKING
|
|
19
21
|
|
|
20
22
|
import networkx as nx
|
|
21
23
|
|
|
@@ -26,12 +28,12 @@ from cirq.transformers.routing import line_initial_mapper, mapping_manager
|
|
|
26
28
|
if TYPE_CHECKING:
|
|
27
29
|
import cirq
|
|
28
30
|
|
|
29
|
-
QidIntPair =
|
|
31
|
+
QidIntPair = tuple[int, int]
|
|
30
32
|
|
|
31
33
|
|
|
32
34
|
def _disjoint_nc2_combinations(
|
|
33
35
|
qubit_pairs: Sequence[QidIntPair],
|
|
34
|
-
) ->
|
|
36
|
+
) -> list[tuple[QidIntPair, QidIntPair]]:
|
|
35
37
|
"""Gets disjoint pair combinations of qubits pairs.
|
|
36
38
|
|
|
37
39
|
For example:
|
|
@@ -108,13 +110,13 @@ class RouteCQC:
|
|
|
108
110
|
|
|
109
111
|
def __call__(
|
|
110
112
|
self,
|
|
111
|
-
circuit:
|
|
113
|
+
circuit: cirq.AbstractCircuit,
|
|
112
114
|
*,
|
|
113
115
|
lookahead_radius: int = 8,
|
|
114
116
|
tag_inserted_swaps: bool = False,
|
|
115
|
-
initial_mapper:
|
|
116
|
-
context:
|
|
117
|
-
) ->
|
|
117
|
+
initial_mapper: cirq.AbstractInitialMapper | None = None,
|
|
118
|
+
context: cirq.TransformerContext | None = None,
|
|
119
|
+
) -> cirq.AbstractCircuit:
|
|
118
120
|
"""Transforms the given circuit to make it executable on the device.
|
|
119
121
|
|
|
120
122
|
This method calls self.route_circuit and returns the routed circuit. See docstring of
|
|
@@ -150,13 +152,13 @@ class RouteCQC:
|
|
|
150
152
|
|
|
151
153
|
def route_circuit(
|
|
152
154
|
self,
|
|
153
|
-
circuit:
|
|
155
|
+
circuit: cirq.AbstractCircuit,
|
|
154
156
|
*,
|
|
155
157
|
lookahead_radius: int = 8,
|
|
156
158
|
tag_inserted_swaps: bool = False,
|
|
157
|
-
initial_mapper:
|
|
158
|
-
context:
|
|
159
|
-
) ->
|
|
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]]:
|
|
160
162
|
"""Transforms the given circuit to make it executable on the device.
|
|
161
163
|
|
|
162
164
|
This transformer assumes that all multi-qubit operations have been decomposed into 2-qubit
|
|
@@ -241,8 +243,8 @@ class RouteCQC:
|
|
|
241
243
|
|
|
242
244
|
@classmethod
|
|
243
245
|
def _get_one_and_two_qubit_ops_as_timesteps(
|
|
244
|
-
cls, circuit:
|
|
245
|
-
) ->
|
|
246
|
+
cls, circuit: cirq.AbstractCircuit
|
|
247
|
+
) -> tuple[list[list[cirq.Operation]], list[list[cirq.Operation]]]:
|
|
246
248
|
"""Gets the single and two qubit operations of the circuit factored into timesteps.
|
|
247
249
|
|
|
248
250
|
The i'th entry in the nested two-qubit and single-qubit ops correspond to the two-qubit
|
|
@@ -254,7 +256,7 @@ class RouteCQC:
|
|
|
254
256
|
qubits with a custom key.
|
|
255
257
|
"""
|
|
256
258
|
two_qubit_circuit = circuits.Circuit()
|
|
257
|
-
single_qubit_ops:
|
|
259
|
+
single_qubit_ops: list[list[cirq.Operation]] = []
|
|
258
260
|
|
|
259
261
|
for i, moment in enumerate(circuit):
|
|
260
262
|
for op in moment:
|
|
@@ -286,11 +288,11 @@ class RouteCQC:
|
|
|
286
288
|
def _route(
|
|
287
289
|
cls,
|
|
288
290
|
mm: mapping_manager.MappingManager,
|
|
289
|
-
two_qubit_ops:
|
|
290
|
-
single_qubit_ops:
|
|
291
|
+
two_qubit_ops: list[list[cirq.Operation]],
|
|
292
|
+
single_qubit_ops: list[list[cirq.Operation]],
|
|
291
293
|
lookahead_radius: int,
|
|
292
294
|
tag_inserted_swaps: bool = False,
|
|
293
|
-
) ->
|
|
295
|
+
) -> list[list[cirq.Operation]]:
|
|
294
296
|
"""Main routing procedure that inserts necessary swaps on the given timesteps.
|
|
295
297
|
|
|
296
298
|
The i'th element of the returned list corresponds to the routed operatiosn in the i'th
|
|
@@ -309,18 +311,18 @@ class RouteCQC:
|
|
|
309
311
|
Returns:
|
|
310
312
|
a list of lists corresponding to timesteps of the routed circuit.
|
|
311
313
|
"""
|
|
312
|
-
two_qubit_ops_ints:
|
|
314
|
+
two_qubit_ops_ints: list[list[QidIntPair]] = [
|
|
313
315
|
[
|
|
314
316
|
(mm.logical_qid_to_int[op.qubits[0]], mm.logical_qid_to_int[op.qubits[1]])
|
|
315
317
|
for op in timestep_ops
|
|
316
318
|
]
|
|
317
319
|
for timestep_ops in two_qubit_ops
|
|
318
320
|
]
|
|
319
|
-
routed_ops:
|
|
321
|
+
routed_ops: list[list[cirq.Operation]] = []
|
|
320
322
|
|
|
321
323
|
def process_executable_two_qubit_ops(timestep: int) -> int:
|
|
322
|
-
unexecutable_ops:
|
|
323
|
-
unexecutable_ops_ints:
|
|
324
|
+
unexecutable_ops: list[cirq.Operation] = []
|
|
325
|
+
unexecutable_ops_ints: list[QidIntPair] = []
|
|
324
326
|
for op, op_ints in zip(two_qubit_ops[timestep], two_qubit_ops_ints[timestep]):
|
|
325
327
|
if mm.is_adjacent(*op_ints):
|
|
326
328
|
routed_ops[timestep].append(mm.mapped_op(op))
|
|
@@ -339,10 +341,10 @@ class RouteCQC:
|
|
|
339
341
|
|
|
340
342
|
# swaps applied in the current timestep thus far. This ensures the same swaps
|
|
341
343
|
# don't get executed twice in the same timestep.
|
|
342
|
-
seen:
|
|
344
|
+
seen: set[tuple[QidIntPair, ...]] = set()
|
|
343
345
|
|
|
344
346
|
while process_executable_two_qubit_ops(timestep):
|
|
345
|
-
chosen_swaps:
|
|
347
|
+
chosen_swaps: tuple[QidIntPair, ...] | None = None
|
|
346
348
|
for strat in strats:
|
|
347
349
|
chosen_swaps = strat(mm, two_qubit_ops_ints, timestep, lookahead_radius)
|
|
348
350
|
if chosen_swaps is not None:
|
|
@@ -370,7 +372,7 @@ class RouteCQC:
|
|
|
370
372
|
mm: mapping_manager.MappingManager,
|
|
371
373
|
two_qubit_ops_ints: Sequence[Sequence[QidIntPair]],
|
|
372
374
|
timestep: int,
|
|
373
|
-
) ->
|
|
375
|
+
) -> tuple[QidIntPair, ...]:
|
|
374
376
|
"""Inserts SWAPS along the shortest path of the qubits that are the farthest.
|
|
375
377
|
|
|
376
378
|
Since swaps along the shortest path are being executed one after the other, in order
|
|
@@ -388,7 +390,7 @@ class RouteCQC:
|
|
|
388
390
|
two_qubit_ops_ints: Sequence[Sequence[QidIntPair]],
|
|
389
391
|
timestep: int,
|
|
390
392
|
lookahead_radius: int,
|
|
391
|
-
) ->
|
|
393
|
+
) -> tuple[QidIntPair, ...] | None:
|
|
392
394
|
"""Computes cost function with pairs of candidate swaps that act on disjoint qubits."""
|
|
393
395
|
pair_sigma = _disjoint_nc2_combinations(
|
|
394
396
|
cls._initial_candidate_swaps(mm, two_qubit_ops_ints[timestep])
|
|
@@ -404,9 +406,9 @@ class RouteCQC:
|
|
|
404
406
|
two_qubit_ops_ints: Sequence[Sequence[QidIntPair]],
|
|
405
407
|
timestep: int,
|
|
406
408
|
lookahead_radius: int,
|
|
407
|
-
) ->
|
|
409
|
+
) -> tuple[QidIntPair, ...] | None:
|
|
408
410
|
"""Computes cost function with list of single candidate swaps."""
|
|
409
|
-
sigma:
|
|
411
|
+
sigma: list[tuple[QidIntPair, ...]] = [
|
|
410
412
|
(swap,) for swap in cls._initial_candidate_swaps(mm, two_qubit_ops_ints[timestep])
|
|
411
413
|
]
|
|
412
414
|
return cls._choose_optimal_swap(mm, two_qubit_ops_ints, timestep, lookahead_radius, sigma)
|
|
@@ -418,8 +420,8 @@ class RouteCQC:
|
|
|
418
420
|
two_qubit_ops_ints: Sequence[Sequence[QidIntPair]],
|
|
419
421
|
timestep: int,
|
|
420
422
|
lookahead_radius: int,
|
|
421
|
-
sigma: Sequence[
|
|
422
|
-
) ->
|
|
423
|
+
sigma: Sequence[tuple[QidIntPair, ...]],
|
|
424
|
+
) -> tuple[QidIntPair, ...] | None:
|
|
423
425
|
"""Optionally returns the swap with minimum cost from a list of n-tuple candidate swaps.
|
|
424
426
|
|
|
425
427
|
Computes a cost (as defined by the overridable function `_cost`) for each candidate swap
|
|
@@ -447,7 +449,7 @@ class RouteCQC:
|
|
|
447
449
|
@classmethod
|
|
448
450
|
def _initial_candidate_swaps(
|
|
449
451
|
cls, mm: mapping_manager.MappingManager, two_qubit_ops: Sequence[QidIntPair]
|
|
450
|
-
) ->
|
|
452
|
+
) -> list[QidIntPair]:
|
|
451
453
|
"""Finds all feasible SWAPs between qubits involved in 2-qubit operations."""
|
|
452
454
|
physical_qubits = (mm.logical_to_physical[lq[i]] for lq in two_qubit_ops for i in range(2))
|
|
453
455
|
physical_swaps = mm.induced_subgraph_int.edges(nbunch=physical_qubits)
|
|
@@ -459,7 +461,7 @@ class RouteCQC:
|
|
|
459
461
|
def _cost(
|
|
460
462
|
cls,
|
|
461
463
|
mm: mapping_manager.MappingManager,
|
|
462
|
-
swaps:
|
|
464
|
+
swaps: tuple[QidIntPair, ...],
|
|
463
465
|
two_qubit_ops: Sequence[QidIntPair],
|
|
464
466
|
) -> Any:
|
|
465
467
|
"""Computes the cost function for the given list of swaps over the current timestep ops.
|
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import pytest
|
|
16
18
|
|
|
17
19
|
import cirq
|
|
18
20
|
|
|
19
21
|
|
|
20
|
-
def test_directed_device():
|
|
22
|
+
def test_directed_device() -> None:
|
|
21
23
|
device = cirq.testing.construct_ring_device(10, directed=True)
|
|
22
24
|
device_graph = device.metadata.nx_graph
|
|
23
25
|
with pytest.raises(ValueError, match="Device graph must be undirected."):
|
|
@@ -33,7 +35,7 @@ def test_directed_device():
|
|
|
33
35
|
for op_density in [0.3, 0.5, 0.7]
|
|
34
36
|
],
|
|
35
37
|
)
|
|
36
|
-
def test_route_small_circuit_random(n_qubits, n_moments, op_density, seed):
|
|
38
|
+
def test_route_small_circuit_random(n_qubits, n_moments, op_density, seed) -> None:
|
|
37
39
|
c_orig = cirq.testing.random_circuit(
|
|
38
40
|
qubits=n_qubits, n_moments=n_moments, op_density=op_density, random_state=seed
|
|
39
41
|
)
|
|
@@ -47,7 +49,7 @@ def test_route_small_circuit_random(n_qubits, n_moments, op_density, seed):
|
|
|
47
49
|
)
|
|
48
50
|
|
|
49
51
|
|
|
50
|
-
def test_high_qubit_count():
|
|
52
|
+
def test_high_qubit_count() -> None:
|
|
51
53
|
c_orig = cirq.testing.random_circuit(qubits=40, n_moments=350, op_density=0.4, random_state=0)
|
|
52
54
|
device = cirq.testing.construct_grid_device(7, 7)
|
|
53
55
|
device_graph = device.metadata.nx_graph
|
|
@@ -56,7 +58,7 @@ def test_high_qubit_count():
|
|
|
56
58
|
device.validate_circuit(c_routed)
|
|
57
59
|
|
|
58
60
|
|
|
59
|
-
def test_multi_qubit_gate_inputs():
|
|
61
|
+
def test_multi_qubit_gate_inputs() -> None:
|
|
60
62
|
device = cirq.testing.construct_grid_device(4, 4)
|
|
61
63
|
device_graph = device.metadata.nx_graph
|
|
62
64
|
router = cirq.RouteCQC(device_graph)
|
|
@@ -97,7 +99,7 @@ def test_multi_qubit_gate_inputs():
|
|
|
97
99
|
device.validate_circuit(c_routed)
|
|
98
100
|
|
|
99
101
|
|
|
100
|
-
def test_circuit_with_measurement_gates():
|
|
102
|
+
def test_circuit_with_measurement_gates() -> None:
|
|
101
103
|
device = cirq.testing.construct_ring_device(3)
|
|
102
104
|
device_graph = device.metadata.nx_graph
|
|
103
105
|
q = cirq.LineQubit.range(3)
|
|
@@ -108,7 +110,7 @@ def test_circuit_with_measurement_gates():
|
|
|
108
110
|
cirq.testing.assert_same_circuits(routed_circuit, circuit)
|
|
109
111
|
|
|
110
112
|
|
|
111
|
-
def test_circuit_with_two_qubit_intermediate_measurement_gate():
|
|
113
|
+
def test_circuit_with_two_qubit_intermediate_measurement_gate() -> None:
|
|
112
114
|
device = cirq.testing.construct_ring_device(2)
|
|
113
115
|
device_graph = device.metadata.nx_graph
|
|
114
116
|
router = cirq.RouteCQC(device_graph)
|
|
@@ -121,7 +123,7 @@ def test_circuit_with_two_qubit_intermediate_measurement_gate():
|
|
|
121
123
|
device.validate_circuit(routed_circuit)
|
|
122
124
|
|
|
123
125
|
|
|
124
|
-
def test_circuit_with_multi_qubit_intermediate_measurement_gate_and_with_default_key():
|
|
126
|
+
def test_circuit_with_multi_qubit_intermediate_measurement_gate_and_with_default_key() -> None:
|
|
125
127
|
device = cirq.testing.construct_ring_device(3)
|
|
126
128
|
device_graph = device.metadata.nx_graph
|
|
127
129
|
router = cirq.RouteCQC(device_graph)
|
|
@@ -135,7 +137,7 @@ def test_circuit_with_multi_qubit_intermediate_measurement_gate_and_with_default
|
|
|
135
137
|
cirq.testing.assert_same_circuits(routed_circuit, expected)
|
|
136
138
|
|
|
137
139
|
|
|
138
|
-
def test_circuit_with_multi_qubit_intermediate_measurement_gate_with_custom_key():
|
|
140
|
+
def test_circuit_with_multi_qubit_intermediate_measurement_gate_with_custom_key() -> None:
|
|
139
141
|
device = cirq.testing.construct_ring_device(3)
|
|
140
142
|
device_graph = device.metadata.nx_graph
|
|
141
143
|
router = cirq.RouteCQC(device_graph)
|
|
@@ -150,7 +152,7 @@ def test_circuit_with_multi_qubit_intermediate_measurement_gate_with_custom_key(
|
|
|
150
152
|
)
|
|
151
153
|
|
|
152
154
|
|
|
153
|
-
def test_circuit_with_non_unitary_and_global_phase():
|
|
155
|
+
def test_circuit_with_non_unitary_and_global_phase() -> None:
|
|
154
156
|
device = cirq.testing.construct_ring_device(4)
|
|
155
157
|
device_graph = device.metadata.nx_graph
|
|
156
158
|
q = cirq.LineQubit.range(3)
|
|
@@ -176,7 +178,7 @@ def test_circuit_with_non_unitary_and_global_phase():
|
|
|
176
178
|
cirq.testing.assert_same_circuits(routed_circuit, expected)
|
|
177
179
|
|
|
178
180
|
|
|
179
|
-
def test_circuit_with_tagged_ops():
|
|
181
|
+
def test_circuit_with_tagged_ops() -> None:
|
|
180
182
|
device = cirq.testing.construct_ring_device(4)
|
|
181
183
|
device_graph = device.metadata.nx_graph
|
|
182
184
|
q = cirq.LineQubit.range(3)
|
|
@@ -205,7 +207,7 @@ def test_circuit_with_tagged_ops():
|
|
|
205
207
|
cirq.testing.assert_same_circuits(routed_circuit, expected)
|
|
206
208
|
|
|
207
209
|
|
|
208
|
-
def test_already_valid_circuit():
|
|
210
|
+
def test_already_valid_circuit() -> None:
|
|
209
211
|
device = cirq.testing.construct_ring_device(10)
|
|
210
212
|
device_graph = device.metadata.nx_graph
|
|
211
213
|
circuit = cirq.Circuit(
|
|
@@ -222,7 +224,7 @@ def test_already_valid_circuit():
|
|
|
222
224
|
cirq.testing.assert_same_circuits(routed_circuit, circuit)
|
|
223
225
|
|
|
224
226
|
|
|
225
|
-
def test_empty_circuit():
|
|
227
|
+
def test_empty_circuit() -> None:
|
|
226
228
|
device = cirq.testing.construct_grid_device(5, 5)
|
|
227
229
|
device_graph = device.metadata.nx_graph
|
|
228
230
|
empty_circuit = cirq.Circuit()
|
|
@@ -235,7 +237,7 @@ def test_empty_circuit():
|
|
|
235
237
|
)
|
|
236
238
|
|
|
237
239
|
|
|
238
|
-
def test_repr():
|
|
240
|
+
def test_repr() -> None:
|
|
239
241
|
device = cirq.testing.construct_ring_device(10)
|
|
240
242
|
device_graph = device.metadata.nx_graph
|
|
241
243
|
router = cirq.RouteCQC(device_graph)
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
from
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
16
18
|
|
|
17
19
|
from cirq import circuits, ops
|
|
18
20
|
|
|
@@ -23,20 +25,19 @@ if TYPE_CHECKING:
|
|
|
23
25
|
class _SwapPrintGate(ops.Gate):
|
|
24
26
|
"""A gate that displays the string representation of each qubits on the circuit."""
|
|
25
27
|
|
|
26
|
-
def __init__(self, qubits:
|
|
28
|
+
def __init__(self, qubits: tuple[tuple[cirq.Qid, cirq.Qid], ...]) -> None:
|
|
27
29
|
self.qubits = qubits
|
|
28
30
|
|
|
29
31
|
def num_qubits(self):
|
|
30
32
|
return len(self.qubits)
|
|
31
33
|
|
|
32
|
-
def _circuit_diagram_info_(self, args:
|
|
34
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> tuple[str, ...]:
|
|
33
35
|
return tuple(f'{str(q[1])}' for q in self.qubits)
|
|
34
36
|
|
|
35
37
|
|
|
36
38
|
def routed_circuit_with_mapping(
|
|
37
|
-
routed_circuit:
|
|
38
|
-
|
|
39
|
-
) -> 'cirq.AbstractCircuit':
|
|
39
|
+
routed_circuit: cirq.AbstractCircuit, initial_map: dict[cirq.Qid, cirq.Qid] | None = None
|
|
40
|
+
) -> cirq.AbstractCircuit:
|
|
40
41
|
"""Returns the same circuits with information about the permutation of qubits after each swap.
|
|
41
42
|
|
|
42
43
|
Args:
|
|
@@ -54,7 +55,7 @@ def routed_circuit_with_mapping(
|
|
|
54
55
|
initial_map = qdict.copy()
|
|
55
56
|
inverse_map = {v: k for k, v in initial_map.items()}
|
|
56
57
|
|
|
57
|
-
def swap_print_moment() ->
|
|
58
|
+
def swap_print_moment() -> cirq.Operation:
|
|
58
59
|
return _SwapPrintGate(
|
|
59
60
|
tuple(zip(qdict.values(), [inverse_map[x] for x in qdict.values()]))
|
|
60
61
|
).on(*all_qubits)
|
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import pytest
|
|
16
18
|
|
|
17
19
|
import cirq
|
|
18
20
|
|
|
19
21
|
|
|
20
|
-
def test_routed_circuit_with_mapping_simple():
|
|
22
|
+
def test_routed_circuit_with_mapping_simple() -> None:
|
|
21
23
|
q = cirq.LineQubit.range(2)
|
|
22
24
|
circuit = cirq.Circuit([cirq.Moment(cirq.SWAP(q[0], q[1]).with_tags(cirq.RoutingSwapTag()))])
|
|
23
25
|
expected_diagram = """
|
|
@@ -57,7 +59,7 @@ def test_routed_circuit_with_mapping_simple():
|
|
|
57
59
|
cirq.routed_circuit_with_mapping(circuit)
|
|
58
60
|
|
|
59
61
|
|
|
60
|
-
def test_routed_circuit_with_mapping_multi_swaps():
|
|
62
|
+
def test_routed_circuit_with_mapping_multi_swaps() -> None:
|
|
61
63
|
q = cirq.LineQubit.range(6)
|
|
62
64
|
circuit = cirq.Circuit(
|
|
63
65
|
[
|