cirq-core 1.4.1__py3-none-any.whl → 1.5.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 +587 -569
- cirq/_compat.py +9 -0
- cirq/_compat_test.py +11 -9
- cirq/_import.py +7 -8
- cirq/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/__init__.py +15 -9
- cirq/circuits/_block_diagram_drawer.py +1 -2
- cirq/circuits/_block_diagram_drawer_test.py +3 -3
- cirq/circuits/_box_drawing_character_data.py +0 -1
- cirq/circuits/_box_drawing_character_data_test.py +2 -2
- cirq/circuits/_bucket_priority_queue.py +0 -1
- cirq/circuits/_bucket_priority_queue_test.py +1 -1
- cirq/circuits/circuit.py +336 -234
- cirq/circuits/circuit_operation.py +102 -52
- cirq/circuits/circuit_operation_test.py +85 -4
- cirq/circuits/circuit_test.py +101 -32
- cirq/circuits/frozen_circuit.py +36 -32
- cirq/circuits/insert_strategy.py +10 -0
- cirq/circuits/insert_strategy_test.py +20 -0
- cirq/circuits/moment.py +79 -80
- cirq/circuits/moment_test.py +105 -2
- cirq/circuits/optimization_pass.py +15 -15
- cirq/circuits/optimization_pass_test.py +8 -9
- cirq/circuits/qasm_output.py +64 -33
- cirq/circuits/qasm_output_test.py +63 -2
- cirq/circuits/text_diagram_drawer.py +26 -56
- cirq/circuits/text_diagram_drawer_test.py +5 -4
- cirq/contrib/__init__.py +2 -2
- cirq/contrib/acquaintance/__init__.py +44 -29
- cirq/contrib/acquaintance/bipartite.py +8 -7
- cirq/contrib/acquaintance/bipartite_test.py +11 -1
- cirq/contrib/acquaintance/devices.py +5 -4
- cirq/contrib/acquaintance/devices_test.py +5 -1
- cirq/contrib/acquaintance/executor.py +18 -21
- cirq/contrib/acquaintance/executor_test.py +3 -2
- cirq/contrib/acquaintance/gates.py +36 -27
- cirq/contrib/acquaintance/gates_test.py +1 -1
- cirq/contrib/acquaintance/inspection_utils.py +10 -9
- cirq/contrib/acquaintance/inspection_utils_test.py +6 -1
- cirq/contrib/acquaintance/mutation_utils.py +10 -10
- cirq/contrib/acquaintance/optimizers.py +7 -6
- cirq/contrib/acquaintance/optimizers_test.py +1 -1
- cirq/contrib/acquaintance/permutation.py +22 -21
- cirq/contrib/acquaintance/permutation_test.py +1 -1
- cirq/contrib/acquaintance/shift.py +8 -6
- cirq/contrib/acquaintance/shift_swap_network.py +6 -4
- cirq/contrib/acquaintance/strategies/__init__.py +9 -3
- cirq/contrib/acquaintance/strategies/complete.py +4 -3
- cirq/contrib/acquaintance/strategies/cubic.py +5 -3
- cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
- cirq/contrib/acquaintance/topological_sort.py +4 -2
- cirq/contrib/bayesian_network/__init__.py +3 -1
- cirq/contrib/bayesian_network/bayesian_network_gate.py +5 -3
- cirq/contrib/circuitdag/__init__.py +1 -1
- cirq/contrib/circuitdag/circuit_dag.py +24 -24
- cirq/contrib/circuitdag/circuit_dag_test.py +1 -1
- cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +15 -11
- cirq/contrib/graph_device/__init__.py +8 -8
- cirq/contrib/graph_device/graph_device.py +8 -8
- cirq/contrib/graph_device/graph_device_test.py +0 -1
- cirq/contrib/graph_device/hypergraph_test.py +1 -0
- cirq/contrib/json.py +1 -2
- cirq/contrib/json_test.py +2 -2
- cirq/contrib/noise_models/__init__.py +5 -6
- cirq/contrib/noise_models/noise_models.py +8 -6
- cirq/contrib/paulistring/__init__.py +22 -10
- cirq/contrib/paulistring/clifford_optimize.py +1 -1
- cirq/contrib/paulistring/clifford_optimize_test.py +0 -1
- cirq/contrib/paulistring/clifford_target_gateset.py +15 -12
- cirq/contrib/paulistring/optimize.py +2 -2
- cirq/contrib/paulistring/optimize_test.py +0 -1
- cirq/contrib/paulistring/pauli_string_dag_test.py +0 -1
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +379 -0
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +523 -0
- cirq/contrib/paulistring/pauli_string_optimize.py +3 -1
- cirq/contrib/paulistring/pauli_string_optimize_test.py +1 -3
- cirq/contrib/paulistring/recombine.py +2 -2
- cirq/contrib/paulistring/recombine_test.py +2 -2
- cirq/contrib/paulistring/separate.py +3 -4
- cirq/contrib/qasm_import/__init__.py +2 -2
- cirq/contrib/qasm_import/_lexer.py +21 -26
- cirq/contrib/qasm_import/_lexer_test.py +90 -6
- cirq/contrib/qasm_import/_parser.py +238 -47
- cirq/contrib/qasm_import/_parser_test.py +514 -59
- cirq/contrib/qasm_import/qasm_test.py +1 -1
- cirq/contrib/qcircuit/__init__.py +6 -4
- cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
- cirq/contrib/qcircuit/qcircuit_pdf.py +1 -2
- cirq/{experiments/grid_parallel_two_qubit_xeb_test.py → contrib/qcircuit/qcircuit_pdf_test.py} +13 -12
- cirq/contrib/qcircuit/qcircuit_test.py +1 -1
- cirq/contrib/quantum_volume/__init__.py +7 -7
- cirq/contrib/quantum_volume/quantum_volume.py +6 -11
- cirq/contrib/quantum_volume/quantum_volume_test.py +3 -1
- cirq/contrib/quimb/__init__.py +16 -13
- cirq/contrib/quimb/density_matrix.py +1 -1
- cirq/contrib/quimb/mps_simulator.py +27 -28
- cirq/contrib/quimb/mps_simulator_test.py +5 -0
- cirq/contrib/quimb/state_vector.py +3 -10
- cirq/contrib/quirk/__init__.py +1 -1
- cirq/contrib/quirk/export_to_quirk.py +3 -3
- cirq/contrib/routing/__init__.py +12 -9
- cirq/contrib/routing/device.py +1 -1
- cirq/contrib/routing/device_test.py +1 -2
- cirq/contrib/routing/greedy.py +7 -5
- cirq/contrib/routing/greedy_test.py +5 -3
- cirq/contrib/routing/initialization.py +3 -1
- cirq/contrib/routing/initialization_test.py +1 -1
- cirq/contrib/routing/swap_network.py +6 -6
- cirq/contrib/routing/utils.py +6 -4
- cirq/contrib/routing/utils_test.py +1 -2
- cirq/{type_workarounds.py → contrib/shuffle_circuits/__init__.py} +5 -10
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +250 -0
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +363 -0
- cirq/contrib/svg/__init__.py +1 -1
- cirq/contrib/svg/svg.py +12 -10
- cirq/contrib/svg/svg_test.py +3 -2
- cirq/devices/__init__.py +34 -25
- cirq/devices/device.py +16 -12
- cirq/devices/device_test.py +1 -0
- cirq/devices/grid_device_metadata.py +16 -12
- cirq/devices/grid_device_metadata_test.py +2 -1
- cirq/devices/grid_qubit.py +31 -26
- cirq/devices/grid_qubit_test.py +30 -1
- cirq/devices/insertion_noise_model.py +6 -6
- cirq/devices/insertion_noise_model_test.py +1 -1
- cirq/devices/line_qubit.py +28 -20
- cirq/devices/line_qubit_test.py +26 -0
- cirq/devices/named_topologies.py +12 -10
- cirq/devices/named_topologies_test.py +5 -4
- cirq/devices/noise_model.py +29 -33
- cirq/devices/noise_properties.py +2 -2
- cirq/devices/noise_properties_test.py +2 -2
- cirq/devices/noise_utils.py +3 -3
- cirq/devices/superconducting_qubits_noise_properties.py +2 -2
- cirq/devices/superconducting_qubits_noise_properties_test.py +3 -3
- cirq/devices/thermal_noise_model.py +2 -1
- cirq/devices/unconstrained_device.py +1 -1
- cirq/devices/unconstrained_device_test.py +6 -0
- cirq/experiments/__init__.py +51 -34
- cirq/experiments/qubit_characterizations.py +17 -15
- cirq/experiments/qubit_characterizations_test.py +4 -6
- cirq/experiments/random_quantum_circuit_generation.py +10 -9
- cirq/experiments/random_quantum_circuit_generation_test.py +21 -4
- cirq/experiments/readout_confusion_matrix.py +73 -8
- cirq/experiments/readout_confusion_matrix_test.py +104 -1
- cirq/experiments/single_qubit_readout_calibration.py +8 -6
- cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
- cirq/experiments/t1_decay_experiment.py +4 -5
- cirq/experiments/t1_decay_experiment_test.py +1 -2
- cirq/experiments/t2_decay_experiment.py +0 -1
- cirq/experiments/t2_decay_experiment_test.py +1 -2
- cirq/experiments/two_qubit_xeb.py +157 -33
- cirq/experiments/two_qubit_xeb_test.py +38 -22
- cirq/experiments/xeb_fitting.py +99 -19
- cirq/experiments/xeb_fitting_test.py +64 -25
- cirq/experiments/xeb_sampling.py +14 -18
- cirq/experiments/xeb_simulation.py +4 -3
- cirq/experiments/xeb_simulation_test.py +20 -14
- cirq/experiments/z_phase_calibration.py +368 -0
- cirq/experiments/z_phase_calibration_test.py +241 -0
- cirq/interop/__init__.py +4 -1
- cirq/interop/quirk/__init__.py +7 -4
- cirq/interop/quirk/cells/__init__.py +17 -6
- cirq/interop/quirk/cells/arithmetic_cells.py +8 -8
- cirq/interop/quirk/cells/arithmetic_cells_test.py +1 -1
- cirq/interop/quirk/cells/cell.py +6 -6
- cirq/interop/quirk/cells/composite_cell.py +5 -5
- cirq/interop/quirk/cells/composite_cell_test.py +1 -1
- cirq/interop/quirk/cells/control_cells.py +1 -1
- cirq/interop/quirk/cells/frequency_space_cells.py +2 -2
- cirq/interop/quirk/cells/ignored_cells.py +1 -1
- cirq/interop/quirk/cells/input_cells.py +1 -1
- cirq/interop/quirk/cells/input_cells_test.py +1 -1
- cirq/interop/quirk/cells/input_rotation_cells.py +1 -1
- cirq/interop/quirk/cells/input_rotation_cells_test.py +1 -1
- cirq/interop/quirk/cells/measurement_cells.py +1 -1
- cirq/interop/quirk/cells/parse.py +8 -7
- cirq/interop/quirk/cells/parse_test.py +2 -2
- cirq/interop/quirk/cells/single_qubit_rotation_cells.py +1 -1
- cirq/interop/quirk/cells/swap_cell_test.py +1 -1
- cirq/interop/quirk/cells/unsupported_cells.py +1 -1
- cirq/interop/quirk/url_to_circuit.py +7 -7
- cirq/interop/quirk/url_to_circuit_test.py +1 -1
- cirq/ion/__init__.py +4 -2
- cirq/json_resolver_cache.py +15 -7
- cirq/linalg/__init__.py +62 -51
- cirq/linalg/combinators.py +4 -4
- cirq/linalg/combinators_test.py +4 -1
- cirq/linalg/decompositions.py +15 -40
- cirq/linalg/decompositions_test.py +16 -22
- cirq/linalg/diagonalize.py +1 -1
- cirq/linalg/diagonalize_test.py +1 -1
- cirq/linalg/operator_spaces.py +20 -4
- cirq/linalg/operator_spaces_test.py +15 -2
- cirq/linalg/predicates.py +3 -3
- cirq/linalg/predicates_test.py +1 -0
- cirq/linalg/tolerance.py +2 -2
- cirq/linalg/transformations.py +30 -12
- cirq/linalg/transformations_test.py +13 -0
- cirq/neutral_atoms/__init__.py +2 -2
- cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +0 -1
- cirq/ops/__init__.py +172 -132
- cirq/ops/arithmetic_operation.py +2 -2
- cirq/ops/arithmetic_operation_test.py +2 -2
- cirq/ops/boolean_hamiltonian.py +3 -2
- cirq/ops/classically_controlled_operation.py +39 -12
- cirq/ops/classically_controlled_operation_test.py +147 -1
- cirq/ops/clifford_gate.py +38 -36
- cirq/ops/clifford_gate_test.py +75 -1
- cirq/ops/common_channels.py +16 -45
- cirq/ops/common_channels_test.py +10 -0
- cirq/ops/common_gate_families.py +1 -1
- cirq/ops/common_gate_families_test.py +1 -0
- cirq/ops/common_gates.py +48 -49
- cirq/ops/common_gates_test.py +18 -2
- cirq/ops/control_values.py +3 -3
- cirq/ops/control_values_test.py +2 -1
- cirq/ops/controlled_gate.py +36 -23
- cirq/ops/controlled_gate_test.py +70 -3
- cirq/ops/controlled_operation.py +6 -5
- cirq/ops/controlled_operation_test.py +7 -3
- cirq/ops/dense_pauli_string.py +11 -11
- cirq/ops/diagonal_gate.py +2 -2
- cirq/ops/diagonal_gate_test.py +1 -0
- cirq/ops/eigen_gate.py +16 -36
- cirq/ops/eigen_gate_test.py +60 -10
- cirq/ops/fourier_transform.py +1 -3
- cirq/ops/fourier_transform_test.py +2 -1
- cirq/ops/fsim_gate.py +42 -3
- cirq/ops/fsim_gate_test.py +21 -0
- cirq/ops/gate_operation.py +8 -8
- cirq/ops/gate_operation_test.py +4 -2
- cirq/ops/gateset_test.py +11 -2
- cirq/ops/global_phase_op.py +8 -7
- cirq/ops/global_phase_op_test.py +1 -1
- cirq/ops/greedy_qubit_manager_test.py +5 -0
- cirq/ops/identity.py +14 -4
- cirq/ops/identity_test.py +24 -0
- cirq/ops/kraus_channel.py +1 -0
- cirq/ops/kraus_channel_test.py +3 -1
- cirq/ops/linear_combinations.py +27 -21
- cirq/ops/linear_combinations_test.py +23 -4
- cirq/ops/matrix_gates.py +24 -8
- cirq/ops/measure_util.py +2 -2
- cirq/ops/measurement_gate.py +7 -4
- cirq/ops/measurement_gate_test.py +2 -1
- cirq/ops/mixed_unitary_channel.py +1 -0
- cirq/ops/mixed_unitary_channel_test.py +3 -1
- cirq/ops/named_qubit.py +8 -1
- cirq/ops/op_tree.py +3 -30
- cirq/ops/op_tree_test.py +4 -0
- cirq/ops/parallel_gate.py +2 -3
- cirq/ops/parallel_gate_test.py +2 -1
- cirq/ops/parity_gates.py +7 -8
- cirq/ops/parity_gates_test.py +1 -0
- cirq/ops/pauli_gates.py +5 -11
- cirq/ops/pauli_gates_test.py +1 -0
- cirq/ops/pauli_interaction_gate.py +11 -5
- cirq/ops/pauli_interaction_gate_test.py +2 -3
- cirq/ops/pauli_measurement_gate.py +6 -5
- cirq/ops/pauli_measurement_gate_test.py +1 -0
- cirq/ops/pauli_string.py +115 -130
- cirq/ops/pauli_string_phasor.py +21 -20
- cirq/ops/pauli_string_phasor_test.py +13 -3
- cirq/ops/pauli_string_raw_types.py +1 -0
- cirq/ops/pauli_string_test.py +192 -55
- cirq/ops/pauli_sum_exponential.py +3 -4
- cirq/ops/pauli_sum_exponential_test.py +0 -1
- cirq/ops/permutation_gate.py +2 -2
- cirq/ops/permutation_gate_test.py +1 -1
- cirq/ops/phased_iswap_gate.py +6 -7
- cirq/ops/phased_iswap_gate_test.py +21 -5
- cirq/ops/phased_x_gate.py +11 -25
- cirq/ops/phased_x_gate_test.py +19 -3
- cirq/ops/phased_x_z_gate.py +12 -11
- cirq/ops/projector.py +4 -5
- cirq/ops/qubit_manager.py +2 -1
- cirq/ops/qubit_manager_test.py +2 -1
- cirq/ops/qubit_order.py +1 -1
- cirq/ops/random_gate_channel.py +1 -1
- cirq/ops/random_gate_channel_test.py +0 -6
- cirq/ops/raw_types.py +146 -50
- cirq/ops/raw_types_test.py +37 -3
- cirq/ops/state_preparation_channel.py +2 -2
- cirq/ops/state_preparation_channel_test.py +2 -1
- cirq/ops/swap_gates.py +9 -4
- cirq/ops/three_qubit_gates.py +8 -8
- cirq/ops/three_qubit_gates_test.py +1 -0
- cirq/ops/two_qubit_diagonal_gate.py +4 -3
- cirq/ops/uniform_superposition_gate.py +4 -4
- cirq/ops/uniform_superposition_gate_test.py +1 -0
- cirq/ops/wait_gate.py +6 -8
- cirq/protocols/__init__.py +135 -83
- cirq/protocols/act_on_protocol.py +1 -1
- cirq/protocols/act_on_protocol_test.py +1 -1
- cirq/protocols/apply_channel_protocol.py +3 -3
- cirq/protocols/apply_mixture_protocol.py +15 -9
- cirq/protocols/apply_mixture_protocol_test.py +11 -0
- cirq/protocols/apply_unitary_protocol.py +2 -2
- cirq/protocols/apply_unitary_protocol_test.py +2 -1
- cirq/protocols/approximate_equality_protocol.py +7 -8
- cirq/protocols/approximate_equality_protocol_test.py +3 -1
- cirq/protocols/circuit_diagram_info_protocol.py +8 -6
- cirq/protocols/circuit_diagram_info_protocol_test.py +5 -0
- cirq/protocols/commutes_protocol.py +6 -6
- cirq/protocols/control_key_protocol.py +1 -1
- cirq/protocols/decompose_protocol.py +4 -5
- cirq/protocols/decompose_protocol_test.py +2 -1
- cirq/protocols/equal_up_to_global_phase_protocol.py +3 -3
- cirq/protocols/equal_up_to_global_phase_protocol_test.py +7 -0
- cirq/protocols/has_stabilizer_effect_protocol.py +5 -5
- cirq/protocols/has_unitary_protocol.py +1 -1
- cirq/protocols/has_unitary_protocol_test.py +8 -7
- cirq/protocols/hash_from_pickle_test.py +120 -0
- cirq/protocols/inverse_protocol.py +1 -1
- cirq/protocols/json_serialization.py +14 -1
- cirq/protocols/json_serialization_test.py +28 -7
- cirq/protocols/json_test_data/BitMaskKeyCondition.json +86 -0
- cirq/protocols/json_test_data/BitMaskKeyCondition.repr +7 -0
- cirq/protocols/json_test_data/Concat.json +19 -0
- cirq/protocols/json_test_data/Concat.repr +1 -0
- cirq/protocols/json_test_data/README.md +4 -2
- cirq/protocols/json_test_data/SympyCondition.json +60 -15
- cirq/protocols/json_test_data/SympyCondition.repr +4 -1
- cirq/protocols/json_test_data/_InverseCompositeGate.json +10 -0
- cirq/protocols/json_test_data/_InverseCompositeGate.repr +1 -0
- cirq/protocols/json_test_data/__init__.py +1 -1
- cirq/protocols/json_test_data/sympy.And.json +13 -0
- cirq/protocols/json_test_data/sympy.And.repr +1 -0
- cirq/protocols/json_test_data/sympy.Indexed.json +18 -0
- cirq/protocols/json_test_data/sympy.Indexed.repr +1 -0
- cirq/protocols/json_test_data/sympy.IndexedBase.json +9 -0
- cirq/protocols/json_test_data/sympy.IndexedBase.repr +1 -0
- cirq/protocols/json_test_data/sympy.Not.json +9 -0
- cirq/protocols/json_test_data/sympy.Not.repr +1 -0
- cirq/protocols/json_test_data/sympy.Or.json +13 -0
- cirq/protocols/json_test_data/sympy.Or.repr +1 -0
- cirq/protocols/json_test_data/sympy.Xor.json +13 -0
- cirq/protocols/json_test_data/sympy.Xor.repr +1 -0
- cirq/protocols/kraus_protocol.py +8 -8
- cirq/protocols/kraus_protocol_test.py +0 -1
- cirq/protocols/measurement_key_protocol.py +1 -1
- cirq/protocols/measurement_key_protocol_test.py +7 -7
- cirq/protocols/mixture_protocol.py +6 -4
- cirq/protocols/mixture_protocol_test.py +21 -13
- cirq/protocols/pauli_expansion_protocol.py +1 -0
- cirq/protocols/pow_protocol.py +1 -1
- cirq/protocols/qasm.py +25 -6
- cirq/protocols/qasm_test.py +17 -0
- cirq/protocols/qid_shape_protocol.py +2 -2
- cirq/protocols/resolve_parameters.py +2 -3
- cirq/protocols/resolve_parameters_test.py +2 -1
- cirq/protocols/trace_distance_bound.py +1 -1
- cirq/protocols/trace_distance_bound_test.py +1 -0
- cirq/protocols/unitary_protocol.py +3 -3
- cirq/protocols/unitary_protocol_test.py +1 -1
- cirq/qis/__init__.py +48 -35
- cirq/qis/channels_test.py +0 -9
- cirq/qis/clifford_tableau.py +46 -26
- cirq/qis/clifford_tableau_test.py +2 -1
- cirq/qis/entropy.py +115 -0
- cirq/qis/entropy_test.py +43 -0
- cirq/qis/measures.py +5 -4
- cirq/qis/measures_test.py +7 -0
- cirq/qis/noise_utils_test.py +4 -4
- cirq/qis/quantum_state_representation.py +1 -1
- cirq/qis/states.py +7 -7
- cirq/sim/__init__.py +55 -37
- cirq/sim/classical_simulator.py +7 -6
- cirq/sim/classical_simulator_test.py +3 -1
- cirq/sim/clifford/__init__.py +17 -9
- cirq/sim/clifford/clifford_simulator.py +5 -4
- cirq/sim/clifford/clifford_simulator_test.py +32 -9
- cirq/sim/clifford/clifford_tableau_simulation_state.py +1 -1
- cirq/sim/clifford/stabilizer_simulation_state.py +1 -1
- cirq/sim/clifford/stabilizer_state_ch_form.py +4 -3
- cirq/sim/density_matrix_simulator.py +3 -2
- cirq/sim/density_matrix_simulator_test.py +12 -4
- cirq/sim/density_matrix_utils.py +1 -1
- cirq/sim/mux.py +2 -2
- cirq/sim/simulation_state.py +4 -5
- cirq/sim/simulation_state_base.py +2 -2
- cirq/sim/simulation_state_test.py +1 -1
- cirq/sim/simulation_utils.py +3 -1
- cirq/sim/simulation_utils_test.py +2 -3
- cirq/sim/simulator.py +7 -6
- cirq/sim/simulator_base.py +5 -5
- cirq/sim/simulator_test.py +14 -3
- cirq/sim/sparse_simulator.py +4 -3
- cirq/sim/sparse_simulator_test.py +17 -9
- cirq/sim/state_vector.py +2 -2
- cirq/sim/state_vector_simulation_state_test.py +1 -1
- cirq/sim/state_vector_simulator.py +4 -4
- cirq/sim/state_vector_test.py +27 -32
- cirq/study/__init__.py +27 -21
- cirq/study/flatten_expressions.py +5 -6
- cirq/study/flatten_expressions_test.py +1 -1
- cirq/study/resolver.py +14 -11
- cirq/study/resolver_test.py +10 -1
- cirq/study/result.py +3 -3
- cirq/study/sweepable.py +15 -9
- cirq/study/sweepable_test.py +27 -0
- cirq/study/sweeps.py +65 -10
- cirq/study/sweeps_test.py +123 -0
- cirq/testing/__init__.py +86 -57
- cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
- cirq/testing/_compat_test_data/module_a/sub/subsub/__init__.py +1 -1
- cirq/testing/circuit_compare.py +3 -4
- cirq/testing/circuit_compare_test.py +7 -8
- cirq/testing/consistent_act_on.py +3 -3
- cirq/testing/consistent_channels_test.py +2 -1
- cirq/testing/consistent_controlled_gate_op.py +3 -2
- cirq/testing/consistent_controlled_gate_op_test.py +2 -3
- cirq/testing/consistent_decomposition.py +1 -1
- cirq/testing/consistent_decomposition_test.py +1 -2
- cirq/testing/consistent_pauli_expansion_test.py +1 -1
- cirq/testing/consistent_phase_by.py +1 -1
- cirq/testing/consistent_phase_by_test.py +1 -2
- cirq/testing/consistent_protocols.py +11 -11
- cirq/testing/consistent_protocols_test.py +4 -5
- cirq/testing/consistent_qasm.py +8 -12
- cirq/testing/consistent_qasm_test.py +1 -1
- cirq/testing/consistent_resolve_parameters.py +2 -1
- cirq/testing/consistent_specified_has_unitary_test.py +1 -1
- cirq/testing/consistent_unitary.py +3 -1
- cirq/testing/consistent_unitary_test.py +3 -3
- cirq/testing/devices.py +1 -1
- cirq/testing/devices_test.py +1 -0
- cirq/testing/equals_tester.py +2 -4
- cirq/testing/equals_tester_test.py +6 -5
- cirq/testing/equivalent_basis_map.py +1 -0
- cirq/testing/equivalent_basis_map_test.py +0 -1
- cirq/testing/gate_features_test.py +5 -0
- cirq/testing/json.py +4 -4
- cirq/testing/lin_alg_utils_test.py +1 -1
- cirq/testing/order_tester.py +1 -1
- cirq/testing/order_tester_test.py +1 -1
- cirq/testing/pytest_utils.py +57 -0
- cirq/testing/pytest_utils_test.py +35 -0
- cirq/testing/random_circuit.py +2 -2
- cirq/testing/random_circuit_test.py +2 -2
- cirq/testing/routing_devices_test.py +2 -1
- cirq/testing/sample_circuits.py +1 -1
- cirq/testing/sample_gates.py +5 -4
- cirq/testing/sample_gates_test.py +2 -2
- cirq/transformers/__init__.py +101 -82
- cirq/transformers/align.py +12 -1
- cirq/transformers/align_test.py +13 -0
- cirq/transformers/analytical_decompositions/__init__.py +27 -24
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +2 -1
- cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +1 -1
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +1 -1
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +1 -1
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +1 -1
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +2 -2
- cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +4 -4
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +99 -24
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +105 -14
- cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +1 -1
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +1 -1
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +3 -4
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -1
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -6
- cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +1 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -1
- cirq/transformers/drop_empty_moments.py +1 -0
- cirq/transformers/drop_negligible_operations.py +1 -0
- cirq/transformers/dynamical_decoupling.py +255 -43
- cirq/transformers/dynamical_decoupling_test.py +730 -17
- cirq/transformers/eject_phased_paulis.py +29 -15
- cirq/transformers/eject_phased_paulis_test.py +3 -8
- cirq/transformers/eject_z.py +3 -2
- cirq/transformers/eject_z_test.py +3 -3
- cirq/transformers/gauge_compiling/__init__.py +25 -9
- cirq/transformers/gauge_compiling/cphase_gauge.py +146 -0
- cirq/transformers/gauge_compiling/cphase_gauge_test.py +42 -0
- cirq/transformers/gauge_compiling/cz_gauge.py +4 -4
- cirq/transformers/gauge_compiling/gauge_compiling.py +245 -6
- cirq/transformers/gauge_compiling/gauge_compiling_test.py +107 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +39 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +10 -1
- cirq/transformers/gauge_compiling/iswap_gauge.py +2 -2
- cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -2
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +23 -5
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +3 -2
- cirq/transformers/heuristic_decompositions/__init__.py +3 -3
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +2 -1
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +1 -1
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -4
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +4 -4
- cirq/transformers/insertion_sort.py +64 -0
- cirq/transformers/insertion_sort_test.py +34 -0
- cirq/transformers/measurement_transformers.py +14 -1
- cirq/transformers/measurement_transformers_test.py +35 -0
- cirq/transformers/merge_k_qubit_gates.py +2 -2
- cirq/transformers/merge_single_qubit_gates.py +1 -1
- cirq/transformers/merge_single_qubit_gates_test.py +1 -1
- cirq/transformers/noise_adding.py +115 -0
- cirq/transformers/noise_adding_test.py +54 -0
- cirq/transformers/optimize_for_target_gateset.py +1 -1
- cirq/transformers/optimize_for_target_gateset_test.py +3 -2
- cirq/transformers/qubit_management_transformers.py +1 -1
- cirq/transformers/randomized_measurements.py +171 -0
- cirq/transformers/randomized_measurements_test.py +68 -0
- cirq/transformers/routing/__init__.py +14 -5
- cirq/transformers/routing/initial_mapper.py +1 -1
- cirq/transformers/routing/initial_mapper_test.py +1 -0
- cirq/transformers/routing/line_initial_mapper.py +3 -2
- cirq/transformers/routing/mapping_manager.py +2 -2
- cirq/transformers/routing/mapping_manager_test.py +2 -2
- cirq/transformers/routing/route_circuit_cqc.py +3 -2
- cirq/transformers/routing/route_circuit_cqc_test.py +2 -1
- cirq/transformers/routing/visualize_routed_circuit.py +1 -0
- cirq/transformers/routing/visualize_routed_circuit_test.py +1 -0
- cirq/transformers/stratify.py +2 -2
- cirq/transformers/synchronize_terminal_measurements.py +2 -1
- cirq/transformers/target_gatesets/__init__.py +7 -5
- cirq/transformers/target_gatesets/compilation_target_gateset.py +16 -3
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -0
- cirq/transformers/target_gatesets/cz_gateset.py +5 -1
- cirq/transformers/target_gatesets/cz_gateset_test.py +23 -2
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +1 -1
- cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +3 -2
- cirq/transformers/transformer_api.py +5 -4
- cirq/transformers/transformer_api_test.py +11 -3
- cirq/transformers/transformer_primitives.py +9 -31
- cirq/transformers/transformer_primitives_test.py +6 -5
- cirq/value/__init__.py +51 -30
- cirq/value/abc_alt.py +1 -2
- cirq/value/angle.py +2 -0
- cirq/value/classical_data.py +1 -0
- cirq/value/condition.py +149 -3
- cirq/value/condition_test.py +254 -0
- cirq/value/digits.py +1 -1
- cirq/value/duration.py +4 -4
- cirq/value/duration_test.py +2 -1
- cirq/value/linear_dict.py +85 -24
- cirq/value/linear_dict_test.py +94 -3
- cirq/value/measurement_key.py +9 -2
- cirq/value/periodic_value.py +2 -3
- cirq/value/periodic_value_test.py +5 -0
- cirq/value/probability.py +1 -0
- cirq/value/random_state.py +1 -1
- cirq/value/timestamp.py +2 -4
- cirq/value/timestamp_test.py +2 -1
- cirq/value/type_alias.py +2 -2
- cirq/value/value_equality_attr.py +14 -2
- cirq/value/value_equality_attr_test.py +1 -1
- cirq/vis/__init__.py +9 -6
- cirq/vis/density_matrix.py +1 -1
- cirq/vis/density_matrix_test.py +2 -5
- cirq/vis/heatmap.py +49 -12
- cirq/vis/heatmap_test.py +168 -4
- cirq/vis/histogram.py +1 -1
- cirq/vis/histogram_test.py +1 -2
- cirq/vis/state_histogram.py +7 -5
- cirq/vis/state_histogram_test.py +2 -2
- cirq/work/__init__.py +19 -13
- cirq/work/collector.py +2 -2
- cirq/work/observable_grouping.py +2 -2
- cirq/work/observable_measurement.py +3 -3
- cirq/work/observable_measurement_data.py +5 -2
- cirq/work/observable_measurement_test.py +8 -8
- cirq/work/observable_readout_calibration.py +2 -2
- cirq/work/observable_readout_calibration_test.py +2 -1
- cirq/work/observable_settings.py +8 -7
- cirq/work/observable_settings_test.py +3 -2
- cirq/work/pauli_sum_collector.py +1 -1
- cirq/work/sampler.py +8 -20
- cirq/work/sampler_test.py +4 -3
- cirq/work/zeros_sampler.py +1 -1
- cirq_core-1.5.0.dist-info/METADATA +125 -0
- {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
- {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/WHEEL +1 -1
- cirq/experiments/grid_parallel_two_qubit_xeb.py +0 -62
- cirq/protocols/json_test_data/GridParallelXEBMetadata.json +0 -119
- cirq/protocols/json_test_data/GridParallelXEBMetadata.repr +0 -1
- cirq_core-1.4.1.dist-info/METADATA +0 -45
- {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
- {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
|
@@ -13,55 +13,70 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Tools for creating and using acquaintance strategies."""
|
|
16
|
+
from cirq.contrib.acquaintance.bipartite import (
|
|
17
|
+
BipartiteGraphType as BipartiteGraphType,
|
|
18
|
+
BipartiteSwapNetworkGate as BipartiteSwapNetworkGate,
|
|
19
|
+
)
|
|
16
20
|
|
|
17
|
-
from cirq.contrib.acquaintance.
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
from cirq.contrib.acquaintance.devices import (
|
|
22
|
+
get_acquaintance_size as get_acquaintance_size,
|
|
23
|
+
UnconstrainedAcquaintanceDevice as UnconstrainedAcquaintanceDevice,
|
|
24
|
+
)
|
|
20
25
|
|
|
21
26
|
from cirq.contrib.acquaintance.executor import (
|
|
22
|
-
AcquaintanceOperation,
|
|
23
|
-
GreedyExecutionStrategy,
|
|
24
|
-
StrategyExecutorTransformer,
|
|
27
|
+
AcquaintanceOperation as AcquaintanceOperation,
|
|
28
|
+
GreedyExecutionStrategy as GreedyExecutionStrategy,
|
|
29
|
+
StrategyExecutorTransformer as StrategyExecutorTransformer,
|
|
25
30
|
)
|
|
26
31
|
|
|
27
|
-
from cirq.contrib.acquaintance.gates import
|
|
32
|
+
from cirq.contrib.acquaintance.gates import (
|
|
33
|
+
acquaint as acquaint,
|
|
34
|
+
AcquaintanceOpportunityGate as AcquaintanceOpportunityGate,
|
|
35
|
+
SwapNetworkGate as SwapNetworkGate,
|
|
36
|
+
)
|
|
28
37
|
|
|
29
|
-
from cirq.contrib.acquaintance.inspection_utils import
|
|
38
|
+
from cirq.contrib.acquaintance.inspection_utils import (
|
|
39
|
+
get_logical_acquaintance_opportunities as get_logical_acquaintance_opportunities,
|
|
40
|
+
)
|
|
30
41
|
|
|
31
42
|
from cirq.contrib.acquaintance.mutation_utils import (
|
|
32
|
-
expose_acquaintance_gates,
|
|
33
|
-
rectify_acquaintance_strategy,
|
|
34
|
-
replace_acquaintance_with_swap_network,
|
|
43
|
+
expose_acquaintance_gates as expose_acquaintance_gates,
|
|
44
|
+
rectify_acquaintance_strategy as rectify_acquaintance_strategy,
|
|
45
|
+
replace_acquaintance_with_swap_network as replace_acquaintance_with_swap_network,
|
|
35
46
|
)
|
|
36
47
|
|
|
37
|
-
from cirq.contrib.acquaintance.optimizers import
|
|
48
|
+
from cirq.contrib.acquaintance.optimizers import (
|
|
49
|
+
remove_redundant_acquaintance_opportunities as remove_redundant_acquaintance_opportunities,
|
|
50
|
+
)
|
|
38
51
|
|
|
39
52
|
from cirq.contrib.acquaintance.permutation import (
|
|
40
|
-
LinearPermutationGate,
|
|
41
|
-
PermutationGate,
|
|
42
|
-
SwapPermutationGate,
|
|
43
|
-
update_mapping,
|
|
44
|
-
get_logical_operations,
|
|
45
|
-
display_mapping,
|
|
46
|
-
return_to_initial_mapping,
|
|
47
|
-
uses_consistent_swap_gate,
|
|
48
|
-
EXPAND_PERMUTATION_GATES,
|
|
49
|
-
DECOMPOSE_PERMUTATION_GATES,
|
|
53
|
+
LinearPermutationGate as LinearPermutationGate,
|
|
54
|
+
PermutationGate as PermutationGate,
|
|
55
|
+
SwapPermutationGate as SwapPermutationGate,
|
|
56
|
+
update_mapping as update_mapping,
|
|
57
|
+
get_logical_operations as get_logical_operations,
|
|
58
|
+
display_mapping as display_mapping,
|
|
59
|
+
return_to_initial_mapping as return_to_initial_mapping,
|
|
60
|
+
uses_consistent_swap_gate as uses_consistent_swap_gate,
|
|
61
|
+
EXPAND_PERMUTATION_GATES as EXPAND_PERMUTATION_GATES,
|
|
62
|
+
DECOMPOSE_PERMUTATION_GATES as DECOMPOSE_PERMUTATION_GATES,
|
|
50
63
|
)
|
|
51
64
|
|
|
52
|
-
from cirq.contrib.acquaintance.shift import CircularShiftGate
|
|
65
|
+
from cirq.contrib.acquaintance.shift import CircularShiftGate as CircularShiftGate
|
|
53
66
|
|
|
54
|
-
from cirq.contrib.acquaintance.shift_swap_network import
|
|
67
|
+
from cirq.contrib.acquaintance.shift_swap_network import (
|
|
68
|
+
ShiftSwapNetworkGate as ShiftSwapNetworkGate,
|
|
69
|
+
)
|
|
55
70
|
|
|
56
71
|
from cirq.contrib.acquaintance.strategies import (
|
|
57
|
-
complete_acquaintance_strategy,
|
|
58
|
-
cubic_acquaintance_strategy,
|
|
59
|
-
quartic_paired_acquaintance_strategy,
|
|
72
|
+
complete_acquaintance_strategy as complete_acquaintance_strategy,
|
|
73
|
+
cubic_acquaintance_strategy as cubic_acquaintance_strategy,
|
|
74
|
+
quartic_paired_acquaintance_strategy as quartic_paired_acquaintance_strategy,
|
|
60
75
|
)
|
|
61
76
|
|
|
62
77
|
from cirq.contrib.acquaintance.topological_sort import (
|
|
63
|
-
is_topologically_sorted,
|
|
64
|
-
random_topological_sort,
|
|
78
|
+
is_topologically_sorted as is_topologically_sorted,
|
|
79
|
+
random_topological_sort as random_topological_sort,
|
|
65
80
|
)
|
|
66
81
|
|
|
67
82
|
from cirq.contrib.acquaintance import testing
|
|
@@ -12,12 +12,13 @@
|
|
|
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 enum
|
|
16
18
|
import itertools
|
|
17
|
-
from typing import Dict, Sequence, Tuple,
|
|
19
|
+
from typing import Dict, Iterator, Sequence, Tuple, TYPE_CHECKING, Union
|
|
18
20
|
|
|
19
21
|
from cirq import ops
|
|
20
|
-
|
|
21
22
|
from cirq.contrib.acquaintance.gates import acquaint
|
|
22
23
|
from cirq.contrib.acquaintance.permutation import PermutationGate, SwapPermutationGate
|
|
23
24
|
|
|
@@ -63,7 +64,7 @@ class BipartiteSwapNetworkGate(PermutationGate):
|
|
|
63
64
|
self,
|
|
64
65
|
subgraph: Union[str, BipartiteGraphType],
|
|
65
66
|
part_size: int,
|
|
66
|
-
swap_gate:
|
|
67
|
+
swap_gate: cirq.Gate = ops.SWAP,
|
|
67
68
|
) -> None:
|
|
68
69
|
super().__init__(2 * part_size, swap_gate)
|
|
69
70
|
self.part_size = part_size
|
|
@@ -72,7 +73,7 @@ class BipartiteSwapNetworkGate(PermutationGate):
|
|
|
72
73
|
)
|
|
73
74
|
self.swap_gate = swap_gate
|
|
74
75
|
|
|
75
|
-
def decompose_complete(self, qubits: Sequence[
|
|
76
|
+
def decompose_complete(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
76
77
|
swap_gate = SwapPermutationGate(self.swap_gate)
|
|
77
78
|
if self.part_size == 1:
|
|
78
79
|
yield acquaint(*qubits)
|
|
@@ -87,7 +88,7 @@ class BipartiteSwapNetworkGate(PermutationGate):
|
|
|
87
88
|
yield acquaint(*qubits[x : x + 2])
|
|
88
89
|
yield swap_gate(*qubits[x : x + 2])
|
|
89
90
|
|
|
90
|
-
def decompose_matching(self, qubits: Sequence[
|
|
91
|
+
def decompose_matching(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
91
92
|
swap_gate = SwapPermutationGate(self.swap_gate)
|
|
92
93
|
for k in range(-self.part_size + 1, self.part_size):
|
|
93
94
|
for x in range(abs(k), 2 * self.part_size - abs(k), 2):
|
|
@@ -96,7 +97,7 @@ class BipartiteSwapNetworkGate(PermutationGate):
|
|
|
96
97
|
else:
|
|
97
98
|
yield acquaint(*qubits[x : x + 2])
|
|
98
99
|
|
|
99
|
-
def _decompose_(self, qubits: Sequence[
|
|
100
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> cirq.OP_TREE:
|
|
100
101
|
if len(qubits) != 2 * self.part_size:
|
|
101
102
|
raise ValueError('len(qubits) != 2 * self.part_size')
|
|
102
103
|
if self.subgraph == BipartiteGraphType.COMPLETE:
|
|
@@ -123,7 +124,7 @@ class BipartiteSwapNetworkGate(PermutationGate):
|
|
|
123
124
|
return dict(enumerate(range(2 * self.part_size)))
|
|
124
125
|
raise NotImplementedError(str(self.subgraph) + 'not implemented')
|
|
125
126
|
|
|
126
|
-
def _circuit_diagram_info_(self, args:
|
|
127
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> Tuple[str, ...]:
|
|
127
128
|
qubit_count = 2 * self.part_size
|
|
128
129
|
if args.known_qubit_count not in (None, qubit_count):
|
|
129
130
|
raise ValueError('args.known_qubit_count not in (None, 2 * self.part_size)')
|
|
@@ -19,7 +19,6 @@ import pytest
|
|
|
19
19
|
import cirq
|
|
20
20
|
import cirq.contrib.acquaintance as cca
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
circuit_diagrams = {
|
|
24
23
|
(
|
|
25
24
|
'undecomposed',
|
|
@@ -340,3 +339,14 @@ def test_decomposition_permutation_consistency(part_size, subgraph):
|
|
|
340
339
|
cca.update_mapping(mapping, gate._decompose_(qubits))
|
|
341
340
|
permutation = gate.permutation()
|
|
342
341
|
assert {qubits[i]: j for i, j in permutation.items()} == mapping
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def test_bad_number_of_qubits():
|
|
345
|
+
gate = cca.BipartiteSwapNetworkGate(cca.BipartiteGraphType.COMPLETE, 6)
|
|
346
|
+
qubits = cirq.LineQubit.range(6)
|
|
347
|
+
mapping = {q: i for i, q in enumerate(qubits)}
|
|
348
|
+
with pytest.raises(ValueError, match='len'):
|
|
349
|
+
cca.update_mapping(mapping, gate._decompose_(qubits))
|
|
350
|
+
gate.part_size = 5
|
|
351
|
+
with pytest.raises(ValueError, match='qubit_count'):
|
|
352
|
+
gate.permutation()
|
|
@@ -12,15 +12,16 @@
|
|
|
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
16
|
|
|
17
17
|
import abc
|
|
18
|
+
from typing import TYPE_CHECKING, Union
|
|
18
19
|
|
|
19
20
|
from cirq import circuits, devices, ops
|
|
20
|
-
from cirq.contrib.acquaintance.gates import AcquaintanceOpportunityGate, SwapNetworkGate
|
|
21
21
|
from cirq.contrib.acquaintance.bipartite import BipartiteSwapNetworkGate
|
|
22
|
-
from cirq.contrib.acquaintance.
|
|
22
|
+
from cirq.contrib.acquaintance.gates import AcquaintanceOpportunityGate, SwapNetworkGate
|
|
23
23
|
from cirq.contrib.acquaintance.permutation import PermutationGate
|
|
24
|
+
from cirq.contrib.acquaintance.shift_swap_network import ShiftSwapNetworkGate
|
|
24
25
|
|
|
25
26
|
if TYPE_CHECKING:
|
|
26
27
|
import cirq
|
|
@@ -31,7 +32,7 @@ class AcquaintanceDevice(devices.Device, metaclass=abc.ABCMeta):
|
|
|
31
32
|
|
|
32
33
|
gate_types = (AcquaintanceOpportunityGate, PermutationGate)
|
|
33
34
|
|
|
34
|
-
def validate_operation(self, operation:
|
|
35
|
+
def validate_operation(self, operation: cirq.Operation) -> None:
|
|
35
36
|
if not (
|
|
36
37
|
isinstance(operation, ops.GateOperation) and isinstance(operation.gate, self.gate_types)
|
|
37
38
|
):
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
import pytest
|
|
16
16
|
|
|
17
17
|
import cirq
|
|
18
|
-
|
|
19
18
|
import cirq.contrib.acquaintance as cca
|
|
20
19
|
|
|
21
20
|
|
|
@@ -28,3 +27,8 @@ def test_acquaintance_device():
|
|
|
28
27
|
swap_network = cca.SwapNetworkGate((1, 2, 1))
|
|
29
28
|
cca.UnconstrainedAcquaintanceDevice.validate_operation(cca.acquaint(*qubits[:2]))
|
|
30
29
|
cca.UnconstrainedAcquaintanceDevice.validate_operation(swap_network(*qubits))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_not_operation():
|
|
33
|
+
with pytest.raises(TypeError):
|
|
34
|
+
_ = cca.get_acquaintance_size(cirq.LineQubit(1))
|
|
@@ -12,22 +12,22 @@
|
|
|
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
16
|
|
|
17
17
|
import abc
|
|
18
18
|
from collections import defaultdict
|
|
19
|
+
from typing import DefaultDict, Dict, Iterator, Optional, Sequence, TYPE_CHECKING
|
|
19
20
|
|
|
20
21
|
from cirq import circuits, devices, ops, protocols, transformers
|
|
21
|
-
|
|
22
22
|
from cirq.contrib.acquaintance.gates import AcquaintanceOpportunityGate
|
|
23
|
+
from cirq.contrib.acquaintance.mutation_utils import expose_acquaintance_gates
|
|
23
24
|
from cirq.contrib.acquaintance.permutation import (
|
|
24
|
-
|
|
25
|
+
LogicalGates,
|
|
25
26
|
LogicalIndex,
|
|
26
27
|
LogicalIndexSequence,
|
|
27
|
-
LogicalGates,
|
|
28
28
|
LogicalMapping,
|
|
29
|
+
PermutationGate,
|
|
29
30
|
)
|
|
30
|
-
from cirq.contrib.acquaintance.mutation_utils import expose_acquaintance_gates
|
|
31
31
|
|
|
32
32
|
if TYPE_CHECKING:
|
|
33
33
|
import cirq
|
|
@@ -44,7 +44,7 @@ class ExecutionStrategy(metaclass=abc.ABCMeta):
|
|
|
44
44
|
|
|
45
45
|
@property
|
|
46
46
|
@abc.abstractmethod
|
|
47
|
-
def device(self) ->
|
|
47
|
+
def device(self) -> cirq.Device:
|
|
48
48
|
"""The device for which the executed acquaintance strategy should be
|
|
49
49
|
valid.
|
|
50
50
|
"""
|
|
@@ -56,8 +56,8 @@ class ExecutionStrategy(metaclass=abc.ABCMeta):
|
|
|
56
56
|
|
|
57
57
|
@abc.abstractmethod
|
|
58
58
|
def get_operations(
|
|
59
|
-
self, indices: Sequence[LogicalIndex], qubits: Sequence[
|
|
60
|
-
) ->
|
|
59
|
+
self, indices: Sequence[LogicalIndex], qubits: Sequence[cirq.Qid]
|
|
60
|
+
) -> cirq.OP_TREE:
|
|
61
61
|
"""Gets the logical operations to apply to qubits."""
|
|
62
62
|
|
|
63
63
|
def __call__(self, *args, **kwargs):
|
|
@@ -75,6 +75,7 @@ class ExecutionStrategy(metaclass=abc.ABCMeta):
|
|
|
75
75
|
strategy = StrategyExecutorTransformer(self)
|
|
76
76
|
final_circuit = strategy(input_circuit, **kwargs)
|
|
77
77
|
input_circuit._moments = final_circuit._moments
|
|
78
|
+
input_circuit._placement_cache = final_circuit._placement_cache
|
|
78
79
|
return strategy.mapping
|
|
79
80
|
|
|
80
81
|
|
|
@@ -98,13 +99,13 @@ class StrategyExecutorTransformer:
|
|
|
98
99
|
self._mapping = execution_strategy.initial_mapping.copy()
|
|
99
100
|
|
|
100
101
|
def __call__(
|
|
101
|
-
self, circuit: circuits.AbstractCircuit, context: Optional[
|
|
102
|
+
self, circuit: circuits.AbstractCircuit, context: Optional[cirq.TransformerContext] = None
|
|
102
103
|
) -> circuits.Circuit:
|
|
103
104
|
"""Executes an acquaintance strategy using cirq.map_operations_and_unroll and
|
|
104
105
|
mutates initial mapping.
|
|
105
106
|
|
|
106
107
|
Args:
|
|
107
|
-
circuit:
|
|
108
|
+
circuit: `cirq.Circuit` input circuit to transform.
|
|
108
109
|
context: `cirq.TransformerContext` storing common configurable
|
|
109
110
|
options for transformers.
|
|
110
111
|
|
|
@@ -127,7 +128,7 @@ class StrategyExecutorTransformer:
|
|
|
127
128
|
def mapping(self) -> LogicalMapping:
|
|
128
129
|
return self._mapping
|
|
129
130
|
|
|
130
|
-
def _map_func(self, op:
|
|
131
|
+
def _map_func(self, op: cirq.Operation, index) -> cirq.OP_TREE:
|
|
131
132
|
if isinstance(op.gate, AcquaintanceOpportunityGate):
|
|
132
133
|
logical_indices = tuple(self._mapping[q] for q in op.qubits)
|
|
133
134
|
logical_operations = self.execution_strategy.get_operations(logical_indices, op.qubits)
|
|
@@ -151,17 +152,13 @@ class AcquaintanceOperation(ops.GateOperation):
|
|
|
151
152
|
logical indices on a particular set of physical qubits.
|
|
152
153
|
"""
|
|
153
154
|
|
|
154
|
-
def __init__(
|
|
155
|
-
self, qubits: Sequence['cirq.Qid'], logical_indices: Sequence[LogicalIndex]
|
|
156
|
-
) -> None:
|
|
155
|
+
def __init__(self, qubits: Sequence[cirq.Qid], logical_indices: Sequence[LogicalIndex]) -> None:
|
|
157
156
|
if len(logical_indices) != len(qubits):
|
|
158
157
|
raise ValueError('len(logical_indices) != len(qubits)')
|
|
159
158
|
super().__init__(AcquaintanceOpportunityGate(num_qubits=len(qubits)), qubits)
|
|
160
159
|
self.logical_indices: LogicalIndexSequence = logical_indices
|
|
161
160
|
|
|
162
|
-
def _circuit_diagram_info_(
|
|
163
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
164
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
161
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
165
162
|
wire_symbols = tuple(f'({i})' for i in self.logical_indices)
|
|
166
163
|
return protocols.CircuitDiagramInfo(wire_symbols=wire_symbols)
|
|
167
164
|
|
|
@@ -177,7 +174,7 @@ class GreedyExecutionStrategy(ExecutionStrategy):
|
|
|
177
174
|
self,
|
|
178
175
|
gates: LogicalGates,
|
|
179
176
|
initial_mapping: LogicalMapping,
|
|
180
|
-
device: Optional[
|
|
177
|
+
device: Optional[cirq.Device] = None,
|
|
181
178
|
) -> None:
|
|
182
179
|
"""Inits GreedyExecutionStrategy.
|
|
183
180
|
|
|
@@ -203,12 +200,12 @@ class GreedyExecutionStrategy(ExecutionStrategy):
|
|
|
203
200
|
return self._initial_mapping
|
|
204
201
|
|
|
205
202
|
@property
|
|
206
|
-
def device(self) ->
|
|
203
|
+
def device(self) -> cirq.Device:
|
|
207
204
|
return self._device
|
|
208
205
|
|
|
209
206
|
def get_operations(
|
|
210
|
-
self, indices: Sequence[LogicalIndex], qubits: Sequence[
|
|
211
|
-
) ->
|
|
207
|
+
self, indices: Sequence[LogicalIndex], qubits: Sequence[cirq.Qid]
|
|
208
|
+
) -> Iterator[cirq.OP_TREE]:
|
|
212
209
|
index_set = frozenset(indices)
|
|
213
210
|
if index_set in self.index_set_to_gates:
|
|
214
211
|
gates = self.index_set_to_gates.pop(index_set)
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
|
|
15
15
|
from itertools import combinations
|
|
16
16
|
from string import ascii_lowercase
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import Dict, Sequence, Tuple
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
import pytest
|
|
21
21
|
|
|
22
22
|
import cirq
|
|
23
|
-
import cirq.testing as ct
|
|
24
23
|
import cirq.contrib.acquaintance as cca
|
|
24
|
+
import cirq.testing as ct
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class ExampleGate(cirq.Gate):
|
|
@@ -48,6 +48,7 @@ def test_executor_explicit():
|
|
|
48
48
|
}
|
|
49
49
|
initial_mapping = {q: i for i, q in enumerate(sorted(qubits))}
|
|
50
50
|
execution_strategy = cca.GreedyExecutionStrategy(gates, initial_mapping)
|
|
51
|
+
assert execution_strategy.device == cirq.UNCONSTRAINED_DEVICE
|
|
51
52
|
|
|
52
53
|
with pytest.raises(ValueError):
|
|
53
54
|
executor = cca.StrategyExecutorTransformer(None)
|
|
@@ -12,33 +12,42 @@
|
|
|
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 functools
|
|
16
18
|
import itertools
|
|
17
19
|
import math
|
|
18
20
|
import operator
|
|
19
|
-
from typing import
|
|
21
|
+
from typing import (
|
|
22
|
+
Dict,
|
|
23
|
+
Iterable,
|
|
24
|
+
Iterator,
|
|
25
|
+
List,
|
|
26
|
+
NamedTuple,
|
|
27
|
+
Optional,
|
|
28
|
+
Sequence,
|
|
29
|
+
Tuple,
|
|
30
|
+
TYPE_CHECKING,
|
|
31
|
+
)
|
|
20
32
|
|
|
21
33
|
from cirq import ops, protocols, value
|
|
22
|
-
|
|
23
|
-
from cirq.contrib.acquaintance.shift import CircularShiftGate
|
|
24
34
|
from cirq.contrib.acquaintance.permutation import (
|
|
35
|
+
LinearPermutationGate,
|
|
25
36
|
PermutationGate,
|
|
26
37
|
SwapPermutationGate,
|
|
27
|
-
LinearPermutationGate,
|
|
28
38
|
)
|
|
39
|
+
from cirq.contrib.acquaintance.shift import CircularShiftGate
|
|
29
40
|
|
|
30
41
|
if TYPE_CHECKING:
|
|
31
42
|
import cirq
|
|
32
43
|
|
|
33
44
|
|
|
34
45
|
def operations_to_part_lens(
|
|
35
|
-
qubit_order: Sequence[
|
|
46
|
+
qubit_order: Sequence[cirq.Qid], op_tree: cirq.OP_TREE
|
|
36
47
|
) -> Tuple[int, ...]:
|
|
37
48
|
qubit_sort_key = functools.partial(operator.indexOf, qubit_order)
|
|
38
49
|
op_parts = [tuple(sorted(op.qubits, key=qubit_sort_key)) for op in ops.flatten_op_tree(op_tree)]
|
|
39
|
-
singletons: List[Tuple[
|
|
40
|
-
(q,) for q in set(qubit_order).difference(*op_parts)
|
|
41
|
-
]
|
|
50
|
+
singletons: List[Tuple[cirq.Qid, ...]] = [(q,) for q in set(qubit_order).difference(*op_parts)]
|
|
42
51
|
part_sort_key = lambda p: min(qubit_sort_key(q) for q in p)
|
|
43
52
|
parts = tuple(tuple(part) for part in sorted(singletons + op_parts, key=part_sort_key))
|
|
44
53
|
|
|
@@ -62,7 +71,7 @@ class AcquaintanceOpportunityGate(ops.Gate, ops.InterchangeableQubitsGate):
|
|
|
62
71
|
f'num_qubits={self.num_qubits()!r})'
|
|
63
72
|
)
|
|
64
73
|
|
|
65
|
-
def _circuit_diagram_info_(self, args:
|
|
74
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> Iterable[str]:
|
|
66
75
|
wire_symbol = '█' if args.use_unicode_characters else 'Acq'
|
|
67
76
|
wire_symbols = (wire_symbol,) * self.num_qubits()
|
|
68
77
|
return wire_symbols
|
|
@@ -71,7 +80,7 @@ class AcquaintanceOpportunityGate(ops.Gate, ops.InterchangeableQubitsGate):
|
|
|
71
80
|
return self._num_qubits
|
|
72
81
|
|
|
73
82
|
|
|
74
|
-
def acquaint(*qubits) ->
|
|
83
|
+
def acquaint(*qubits) -> cirq.Operation:
|
|
75
84
|
return AcquaintanceOpportunityGate(len(qubits)).on(*qubits)
|
|
76
85
|
|
|
77
86
|
|
|
@@ -87,14 +96,14 @@ Layers = NamedTuple(
|
|
|
87
96
|
)
|
|
88
97
|
|
|
89
98
|
|
|
90
|
-
def new_layers(**kwargs: List[
|
|
99
|
+
def new_layers(**kwargs: List[cirq.Operation]) -> Layers:
|
|
91
100
|
return Layers._make(kwargs.get(field, []) for field in Layers._fields)
|
|
92
101
|
|
|
93
102
|
|
|
94
103
|
def acquaint_insides(
|
|
95
|
-
swap_gate:
|
|
96
|
-
acquaintance_gate:
|
|
97
|
-
qubits: Sequence[
|
|
104
|
+
swap_gate: cirq.Gate,
|
|
105
|
+
acquaintance_gate: cirq.Operation,
|
|
106
|
+
qubits: Sequence[cirq.Qid],
|
|
98
107
|
before: bool,
|
|
99
108
|
layers: Layers,
|
|
100
109
|
mapping: Dict[ops.Qid, int],
|
|
@@ -144,10 +153,10 @@ def _get_max_reach(size: int, round_up: bool = True) -> int:
|
|
|
144
153
|
|
|
145
154
|
|
|
146
155
|
def acquaint_and_shift(
|
|
147
|
-
parts: Tuple[List[
|
|
156
|
+
parts: Tuple[List[cirq.Qid], List[cirq.Qid]],
|
|
148
157
|
layers: Layers,
|
|
149
158
|
acquaintance_size: Optional[int],
|
|
150
|
-
swap_gate:
|
|
159
|
+
swap_gate: cirq.Gate,
|
|
151
160
|
mapping: Dict[ops.Qid, int],
|
|
152
161
|
):
|
|
153
162
|
"""Acquaints and shifts a pair of lists of qubits. The first part is
|
|
@@ -268,7 +277,7 @@ class SwapNetworkGate(PermutationGate):
|
|
|
268
277
|
self,
|
|
269
278
|
part_lens: Sequence[int],
|
|
270
279
|
acquaintance_size: Optional[int] = 0,
|
|
271
|
-
swap_gate:
|
|
280
|
+
swap_gate: cirq.Gate = ops.SWAP,
|
|
272
281
|
) -> None:
|
|
273
282
|
super().__init__(sum(part_lens), swap_gate)
|
|
274
283
|
if len(part_lens) < 2:
|
|
@@ -276,7 +285,7 @@ class SwapNetworkGate(PermutationGate):
|
|
|
276
285
|
self.part_lens = tuple(part_lens)
|
|
277
286
|
self.acquaintance_size = acquaintance_size
|
|
278
287
|
|
|
279
|
-
def _decompose_(self, qubits: Sequence[
|
|
288
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
280
289
|
qubit_to_position = {q: i for i, q in enumerate(qubits)}
|
|
281
290
|
mapping = dict(qubit_to_position)
|
|
282
291
|
parts = []
|
|
@@ -306,10 +315,12 @@ class SwapNetworkGate(PermutationGate):
|
|
|
306
315
|
parts_qubits = list(left_part + right_part)
|
|
307
316
|
parts[i] = parts_qubits[: len(right_part)]
|
|
308
317
|
parts[i + 1] = parts_qubits[len(right_part) :]
|
|
309
|
-
|
|
318
|
+
if op_sort_key is not None:
|
|
319
|
+
layers.prior_interstitial.sort(key=op_sort_key)
|
|
310
320
|
for l in ('prior_interstitial', 'pre', 'intra', 'post'):
|
|
311
321
|
yield getattr(layers, l)
|
|
312
|
-
|
|
322
|
+
if op_sort_key is not None:
|
|
323
|
+
layers.posterior_interstitial.sort(key=op_sort_key)
|
|
313
324
|
yield layers.posterior_interstitial
|
|
314
325
|
|
|
315
326
|
assert list(
|
|
@@ -322,9 +333,7 @@ class SwapNetworkGate(PermutationGate):
|
|
|
322
333
|
if final_gate:
|
|
323
334
|
yield final_gate(*qubits)
|
|
324
335
|
|
|
325
|
-
def _circuit_diagram_info_(
|
|
326
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
327
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
336
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
328
337
|
wire_symbol = '×' if args.use_unicode_characters else 'swap'
|
|
329
338
|
wire_symbols = tuple(
|
|
330
339
|
wire_symbol + f'({part_index},{qubit_index})'
|
|
@@ -335,11 +344,11 @@ class SwapNetworkGate(PermutationGate):
|
|
|
335
344
|
|
|
336
345
|
@staticmethod
|
|
337
346
|
def from_operations(
|
|
338
|
-
qubit_order: Sequence[
|
|
339
|
-
operations: Sequence[
|
|
347
|
+
qubit_order: Sequence[cirq.Qid],
|
|
348
|
+
operations: Sequence[cirq.Operation],
|
|
340
349
|
acquaintance_size: Optional[int] = 0,
|
|
341
|
-
swap_gate:
|
|
342
|
-
) ->
|
|
350
|
+
swap_gate: cirq.Gate = ops.SWAP,
|
|
351
|
+
) -> SwapNetworkGate:
|
|
343
352
|
part_sizes = operations_to_part_lens(qubit_order, operations)
|
|
344
353
|
return SwapNetworkGate(part_sizes, acquaintance_size, swap_gate)
|
|
345
354
|
|
|
@@ -12,17 +12,18 @@
|
|
|
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
16
|
|
|
17
|
-
from
|
|
17
|
+
from typing import FrozenSet, Iterator, Sequence, Set, TYPE_CHECKING
|
|
18
18
|
|
|
19
|
+
from cirq import devices
|
|
20
|
+
from cirq.contrib import circuitdag
|
|
19
21
|
from cirq.contrib.acquaintance.executor import AcquaintanceOperation, ExecutionStrategy
|
|
20
22
|
from cirq.contrib.acquaintance.mutation_utils import expose_acquaintance_gates
|
|
21
|
-
from cirq.contrib.acquaintance.permutation import LogicalIndex, LogicalMapping
|
|
22
|
-
from cirq.contrib import circuitdag
|
|
23
23
|
|
|
24
24
|
if TYPE_CHECKING:
|
|
25
25
|
import cirq
|
|
26
|
+
from cirq.contrib.acquaintance.permutation import LogicalIndex, LogicalMapping
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
class LogicalAnnotator(ExecutionStrategy):
|
|
@@ -41,16 +42,16 @@ class LogicalAnnotator(ExecutionStrategy):
|
|
|
41
42
|
return self._initial_mapping
|
|
42
43
|
|
|
43
44
|
@property
|
|
44
|
-
def device(self) ->
|
|
45
|
+
def device(self) -> cirq.Device:
|
|
45
46
|
return devices.UNCONSTRAINED_DEVICE
|
|
46
47
|
|
|
47
48
|
def get_operations(
|
|
48
|
-
self, indices: Sequence[LogicalIndex], qubits: Sequence[
|
|
49
|
-
) ->
|
|
49
|
+
self, indices: Sequence[LogicalIndex], qubits: Sequence[cirq.Qid]
|
|
50
|
+
) -> Iterator[cirq.OP_TREE]:
|
|
50
51
|
yield AcquaintanceOperation(qubits, indices)
|
|
51
52
|
|
|
52
53
|
|
|
53
|
-
def get_acquaintance_dag(strategy:
|
|
54
|
+
def get_acquaintance_dag(strategy: cirq.Circuit, initial_mapping: LogicalMapping):
|
|
54
55
|
strategy = strategy.copy()
|
|
55
56
|
expose_acquaintance_gates(strategy)
|
|
56
57
|
LogicalAnnotator(initial_mapping)(strategy)
|
|
@@ -64,7 +65,7 @@ def get_acquaintance_dag(strategy: 'cirq.Circuit', initial_mapping: LogicalMappi
|
|
|
64
65
|
|
|
65
66
|
|
|
66
67
|
def get_logical_acquaintance_opportunities(
|
|
67
|
-
strategy:
|
|
68
|
+
strategy: cirq.Circuit, initial_mapping: LogicalMapping
|
|
68
69
|
) -> Set[FrozenSet[LogicalIndex]]:
|
|
69
70
|
acquaintance_dag = get_acquaintance_dag(strategy, initial_mapping)
|
|
70
71
|
logical_acquaintance_opportunities = set()
|
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
from itertools import
|
|
15
|
+
from itertools import combinations, product
|
|
16
16
|
|
|
17
17
|
import pytest
|
|
18
18
|
|
|
19
19
|
import cirq
|
|
20
20
|
import cirq.contrib.acquaintance as cca
|
|
21
|
+
import cirq.contrib.acquaintance.inspection_utils as inspection_utils
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
@pytest.mark.parametrize('n_qubits, acquaintance_size', product(range(2, 6), range(2, 5)))
|
|
@@ -27,3 +28,7 @@ def test_get_logical_acquaintance_opportunities(n_qubits, acquaintance_size):
|
|
|
27
28
|
initial_mapping = {q: i for i, q in enumerate(qubits)}
|
|
28
29
|
opps = cca.get_logical_acquaintance_opportunities(acquaintance_strategy, initial_mapping)
|
|
29
30
|
assert opps == set(frozenset(s) for s in combinations(range(n_qubits), acquaintance_size))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_device():
|
|
34
|
+
assert inspection_utils.LogicalAnnotator({}).device == cirq.UNCONSTRAINED_DEVICE
|