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
cirq/circuits/circuit_test.py
CHANGED
|
@@ -11,20 +11,20 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
import itertools
|
|
15
16
|
import os
|
|
16
17
|
import time
|
|
17
18
|
from collections import defaultdict
|
|
18
|
-
from random import randint, random,
|
|
19
|
-
from typing import Iterator, Optional, Tuple
|
|
19
|
+
from random import randint, random, randrange, sample
|
|
20
|
+
from typing import Iterator, Optional, Tuple
|
|
20
21
|
|
|
21
22
|
import numpy as np
|
|
22
23
|
import pytest
|
|
23
24
|
import sympy
|
|
24
25
|
|
|
25
26
|
import cirq
|
|
26
|
-
from cirq import circuits
|
|
27
|
-
from cirq import ops
|
|
27
|
+
from cirq import circuits, ops
|
|
28
28
|
from cirq.testing.devices import ValidatingTestDevice
|
|
29
29
|
|
|
30
30
|
|
|
@@ -50,25 +50,9 @@ BCONE = ValidatingTestDevice(
|
|
|
50
50
|
)
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
if TYPE_CHECKING:
|
|
54
|
-
import cirq
|
|
55
|
-
|
|
56
53
|
q0, q1, q2, q3 = cirq.LineQubit.range(4)
|
|
57
54
|
|
|
58
55
|
|
|
59
|
-
class _MomentAndOpTypeValidatingDeviceType(cirq.Device):
|
|
60
|
-
def validate_operation(self, operation):
|
|
61
|
-
if not isinstance(operation, cirq.Operation):
|
|
62
|
-
raise ValueError(f'not isinstance({operation!r}, {cirq.Operation!r})')
|
|
63
|
-
|
|
64
|
-
def validate_moment(self, moment):
|
|
65
|
-
if not isinstance(moment, cirq.Moment):
|
|
66
|
-
raise ValueError(f'not isinstance({moment!r}, {cirq.Moment!r})')
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
moment_and_op_type_validating_device = _MomentAndOpTypeValidatingDeviceType()
|
|
70
|
-
|
|
71
|
-
|
|
72
56
|
def test_from_moments():
|
|
73
57
|
a, b, c, d = cirq.LineQubit.range(4)
|
|
74
58
|
moment = cirq.Moment(cirq.Z(a), cirq.Z(b))
|
|
@@ -80,6 +64,7 @@ def test_from_moments():
|
|
|
80
64
|
[cirq.X(c)],
|
|
81
65
|
[],
|
|
82
66
|
cirq.Z(d),
|
|
67
|
+
None,
|
|
83
68
|
[cirq.measure(a, b, key='ab'), cirq.measure(c, d, key='cd')],
|
|
84
69
|
)
|
|
85
70
|
assert circuit == cirq.Circuit(
|
|
@@ -906,8 +891,8 @@ def test_insert_at_frontier():
|
|
|
906
891
|
self.replacer = replacer
|
|
907
892
|
|
|
908
893
|
def optimization_at(
|
|
909
|
-
self, circuit:
|
|
910
|
-
) -> Optional[
|
|
894
|
+
self, circuit: cirq.Circuit, index: int, op: cirq.Operation
|
|
895
|
+
) -> Optional[cirq.PointOptimizationSummary]:
|
|
911
896
|
new_ops = self.replacer(op)
|
|
912
897
|
return cirq.PointOptimizationSummary(
|
|
913
898
|
clear_span=1, clear_qubits=op.qubits, new_operations=new_ops
|
|
@@ -3554,6 +3539,52 @@ def test_insert_operations_random_circuits(circuit):
|
|
|
3554
3539
|
assert circuit == other_circuit
|
|
3555
3540
|
|
|
3556
3541
|
|
|
3542
|
+
def test_insert_zero_index():
|
|
3543
|
+
# Should always go to moment[0], independent of qubit order or earliest/inline strategy.
|
|
3544
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
3545
|
+
c0 = cirq.Circuit(cirq.X(q0))
|
|
3546
|
+
c0.insert(0, cirq.Y.on_each(q0, q1), strategy=cirq.InsertStrategy.EARLIEST)
|
|
3547
|
+
c1 = cirq.Circuit(cirq.X(q0))
|
|
3548
|
+
c1.insert(0, cirq.Y.on_each(q1, q0), strategy=cirq.InsertStrategy.EARLIEST)
|
|
3549
|
+
c2 = cirq.Circuit(cirq.X(q0))
|
|
3550
|
+
c2.insert(0, cirq.Y.on_each(q0, q1), strategy=cirq.InsertStrategy.INLINE)
|
|
3551
|
+
c3 = cirq.Circuit(cirq.X(q0))
|
|
3552
|
+
c3.insert(0, cirq.Y.on_each(q1, q0), strategy=cirq.InsertStrategy.INLINE)
|
|
3553
|
+
expected = cirq.Circuit(cirq.Moment(cirq.Y(q0), cirq.Y(q1)), cirq.Moment(cirq.X(q0)))
|
|
3554
|
+
assert c0 == expected
|
|
3555
|
+
assert c1 == expected
|
|
3556
|
+
assert c2 == expected
|
|
3557
|
+
assert c3 == expected
|
|
3558
|
+
|
|
3559
|
+
|
|
3560
|
+
def test_insert_earliest_on_previous_moment():
|
|
3561
|
+
q = cirq.LineQubit(0)
|
|
3562
|
+
c = cirq.Circuit(cirq.Moment(cirq.X(q)), cirq.Moment(), cirq.Moment(), cirq.Moment(cirq.Z(q)))
|
|
3563
|
+
c.insert(3, cirq.Y(q), strategy=cirq.InsertStrategy.EARLIEST)
|
|
3564
|
+
# Should fall back to moment[1] since EARLIEST
|
|
3565
|
+
assert c == cirq.Circuit(
|
|
3566
|
+
cirq.Moment(cirq.X(q)), cirq.Moment(cirq.Y(q)), cirq.Moment(), cirq.Moment(cirq.Z(q))
|
|
3567
|
+
)
|
|
3568
|
+
|
|
3569
|
+
|
|
3570
|
+
def test_insert_inline_end_of_circuit():
|
|
3571
|
+
# If end index is specified, INLINE should place all ops there independent of qubit order.
|
|
3572
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
3573
|
+
c0 = cirq.Circuit(cirq.X(q0))
|
|
3574
|
+
c0.insert(1, cirq.Y.on_each(q0, q1), strategy=cirq.InsertStrategy.INLINE)
|
|
3575
|
+
c1 = cirq.Circuit(cirq.X(q0))
|
|
3576
|
+
c1.insert(1, cirq.Y.on_each(q1, q0), strategy=cirq.InsertStrategy.INLINE)
|
|
3577
|
+
c2 = cirq.Circuit(cirq.X(q0))
|
|
3578
|
+
c2.insert(5, cirq.Y.on_each(q0, q1), strategy=cirq.InsertStrategy.INLINE)
|
|
3579
|
+
c3 = cirq.Circuit(cirq.X(q0))
|
|
3580
|
+
c3.insert(5, cirq.Y.on_each(q1, q0), strategy=cirq.InsertStrategy.INLINE)
|
|
3581
|
+
expected = cirq.Circuit(cirq.Moment(cirq.X(q0)), cirq.Moment(cirq.Y(q0), cirq.Y(q1)))
|
|
3582
|
+
assert c0 == expected
|
|
3583
|
+
assert c1 == expected
|
|
3584
|
+
assert c2 == expected
|
|
3585
|
+
assert c3 == expected
|
|
3586
|
+
|
|
3587
|
+
|
|
3557
3588
|
def test_insert_operations_errors():
|
|
3558
3589
|
a, b, c = (cirq.NamedQubit(s) for s in 'abc')
|
|
3559
3590
|
with pytest.raises(ValueError):
|
|
@@ -3578,7 +3609,7 @@ def test_insert_operations_errors():
|
|
|
3578
3609
|
@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit])
|
|
3579
3610
|
def test_to_qasm(circuit_cls):
|
|
3580
3611
|
q0 = cirq.NamedQubit('q0')
|
|
3581
|
-
circuit = circuit_cls(cirq.X(q0))
|
|
3612
|
+
circuit = circuit_cls(cirq.X(q0), cirq.measure(q0, key='mmm'))
|
|
3582
3613
|
assert circuit.to_qasm() == cirq.qasm(circuit)
|
|
3583
3614
|
assert (
|
|
3584
3615
|
circuit.to_qasm()
|
|
@@ -3590,9 +3621,29 @@ include "qelib1.inc";
|
|
|
3590
3621
|
|
|
3591
3622
|
// Qubits: [q0]
|
|
3592
3623
|
qreg q[1];
|
|
3624
|
+
creg m_mmm[1];
|
|
3625
|
+
|
|
3626
|
+
|
|
3627
|
+
x q[0];
|
|
3628
|
+
measure q[0] -> m_mmm[0];
|
|
3629
|
+
"""
|
|
3630
|
+
)
|
|
3631
|
+
assert circuit.to_qasm(version="3.0") == cirq.qasm(circuit, args=cirq.QasmArgs(version="3.0"))
|
|
3632
|
+
assert (
|
|
3633
|
+
circuit.to_qasm(version="3.0")
|
|
3634
|
+
== f"""// Generated from Cirq v{cirq.__version__}
|
|
3635
|
+
|
|
3636
|
+
OPENQASM 3.0;
|
|
3637
|
+
include "stdgates.inc";
|
|
3638
|
+
|
|
3639
|
+
|
|
3640
|
+
// Qubits: [q0]
|
|
3641
|
+
qubit[1] q;
|
|
3642
|
+
bit[1] m_mmm;
|
|
3593
3643
|
|
|
3594
3644
|
|
|
3595
3645
|
x q[0];
|
|
3646
|
+
m_mmm[0] = measure q[0];
|
|
3596
3647
|
"""
|
|
3597
3648
|
)
|
|
3598
3649
|
|
|
@@ -4824,18 +4875,36 @@ global phase: 0.5π
|
|
|
4824
4875
|
def test_create_speed():
|
|
4825
4876
|
# Added in https://github.com/quantumlib/Cirq/pull/5332
|
|
4826
4877
|
# Previously this took ~30s to run. Now it should take ~150ms. However the coverage test can
|
|
4827
|
-
# run this slowly, so allowing
|
|
4878
|
+
# run this slowly, so allowing 4 sec to account for things like that. Feel free to increase the
|
|
4828
4879
|
# buffer time or delete the test entirely if it ends up causing flakes.
|
|
4829
|
-
#
|
|
4830
|
-
# Updated in https://github.com/quantumlib/Cirq/pull/5756
|
|
4831
|
-
# After several tiny overtime failures of the GitHub CI Pytest MacOS (3.7)
|
|
4832
|
-
# the timeout was increased to 4 sec. A more thorough investigation or test
|
|
4833
|
-
# removal should be considered if this continues to time out.
|
|
4834
4880
|
qs = 100
|
|
4835
4881
|
moments = 500
|
|
4836
4882
|
xs = [cirq.X(cirq.LineQubit(i)) for i in range(qs)]
|
|
4837
|
-
|
|
4883
|
+
ops = [xs[i] for i in range(qs) for _ in range(moments)]
|
|
4884
|
+
t = time.perf_counter()
|
|
4885
|
+
c = cirq.Circuit(ops)
|
|
4886
|
+
duration = time.perf_counter() - t
|
|
4887
|
+
assert len(c) == moments
|
|
4888
|
+
assert duration < 4
|
|
4889
|
+
|
|
4890
|
+
|
|
4891
|
+
def test_append_speed():
|
|
4892
|
+
# Previously this took ~17s to run. Now it should take ~150ms. However the coverage test can
|
|
4893
|
+
# run this slowly, so allowing 5 sec to account for things like that. Feel free to increase the
|
|
4894
|
+
# buffer time or delete the test entirely if it ends up causing flakes.
|
|
4895
|
+
#
|
|
4896
|
+
# The `append` improvement mainly helps for deep circuits. It is less useful for wide circuits
|
|
4897
|
+
# because the Moment (immutable) needs verified and reconstructed each time an op is added.
|
|
4898
|
+
qs = 2
|
|
4899
|
+
moments = 10000
|
|
4900
|
+
xs = [cirq.X(cirq.LineQubit(i)) for i in range(qs)]
|
|
4901
|
+
c = cirq.Circuit()
|
|
4838
4902
|
t = time.perf_counter()
|
|
4839
|
-
|
|
4903
|
+
# Iterating with the moments in the inner loop highlights the improvement: when filling in the
|
|
4904
|
+
# second qubit, we no longer have to search backwards from moment 10000 for a placement index.
|
|
4905
|
+
for q in range(qs):
|
|
4906
|
+
for _ in range(moments):
|
|
4907
|
+
c.append(xs[q])
|
|
4908
|
+
duration = time.perf_counter() - t
|
|
4840
4909
|
assert len(c) == moments
|
|
4841
|
-
assert
|
|
4910
|
+
assert duration < 5
|
cirq/circuits/frozen_circuit.py
CHANGED
|
@@ -11,8 +11,13 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
"""An immutable version of the Circuit data structure."""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
15
19
|
from functools import cached_property
|
|
20
|
+
from types import NotImplementedType
|
|
16
21
|
from typing import (
|
|
17
22
|
AbstractSet,
|
|
18
23
|
FrozenSet,
|
|
@@ -27,10 +32,9 @@ from typing import (
|
|
|
27
32
|
|
|
28
33
|
import numpy as np
|
|
29
34
|
|
|
30
|
-
from cirq import
|
|
35
|
+
from cirq import _compat, protocols
|
|
31
36
|
from cirq.circuits import AbstractCircuit, Alignment, Circuit
|
|
32
37
|
from cirq.circuits.insert_strategy import InsertStrategy
|
|
33
|
-
from cirq.type_workarounds import NotImplementedType
|
|
34
38
|
|
|
35
39
|
if TYPE_CHECKING:
|
|
36
40
|
import cirq
|
|
@@ -46,8 +50,8 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
46
50
|
|
|
47
51
|
def __init__(
|
|
48
52
|
self,
|
|
49
|
-
*contents:
|
|
50
|
-
strategy:
|
|
53
|
+
*contents: cirq.OP_TREE,
|
|
54
|
+
strategy: cirq.InsertStrategy = InsertStrategy.EARLIEST,
|
|
51
55
|
tags: Sequence[Hashable] = (),
|
|
52
56
|
) -> None:
|
|
53
57
|
"""Initializes a frozen circuit.
|
|
@@ -71,20 +75,20 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
71
75
|
self._tags = tuple(tags)
|
|
72
76
|
|
|
73
77
|
@classmethod
|
|
74
|
-
def _from_moments(cls, moments: Iterable[
|
|
78
|
+
def _from_moments(cls, moments: Iterable[cirq.Moment]) -> FrozenCircuit:
|
|
75
79
|
new_circuit = FrozenCircuit()
|
|
76
80
|
new_circuit._moments = tuple(moments)
|
|
77
81
|
return new_circuit
|
|
78
82
|
|
|
79
83
|
@property
|
|
80
|
-
def moments(self) -> Sequence[
|
|
84
|
+
def moments(self) -> Sequence[cirq.Moment]:
|
|
81
85
|
return self._moments
|
|
82
86
|
|
|
83
|
-
def freeze(self) ->
|
|
87
|
+
def freeze(self) -> cirq.FrozenCircuit:
|
|
84
88
|
return self
|
|
85
89
|
|
|
86
|
-
def unfreeze(self, copy: bool = True) ->
|
|
87
|
-
return Circuit.
|
|
90
|
+
def unfreeze(self, copy: bool = True) -> cirq.Circuit:
|
|
91
|
+
return Circuit._from_moments(self._moments)
|
|
88
92
|
|
|
89
93
|
@property
|
|
90
94
|
def tags(self) -> Tuple[Hashable, ...]:
|
|
@@ -92,11 +96,11 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
92
96
|
return self._tags
|
|
93
97
|
|
|
94
98
|
@cached_property
|
|
95
|
-
def untagged(self) ->
|
|
99
|
+
def untagged(self) -> cirq.FrozenCircuit:
|
|
96
100
|
"""Returns the underlying FrozenCircuit without any tags."""
|
|
97
101
|
return self._from_moments(self._moments) if self.tags else self
|
|
98
102
|
|
|
99
|
-
def with_tags(self, *new_tags: Hashable) ->
|
|
103
|
+
def with_tags(self, *new_tags: Hashable) -> cirq.FrozenCircuit:
|
|
100
104
|
"""Creates a new tagged `FrozenCircuit` with `self.tags` and `new_tags` combined."""
|
|
101
105
|
if not new_tags:
|
|
102
106
|
return self
|
|
@@ -119,10 +123,10 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
119
123
|
def __getstate__(self):
|
|
120
124
|
# Don't save hash when pickling; see #3777.
|
|
121
125
|
state = self.__dict__
|
|
122
|
-
|
|
123
|
-
if
|
|
126
|
+
hash_attr = _compat._method_cache_name(self.__hash__)
|
|
127
|
+
if hash_attr in state:
|
|
124
128
|
state = state.copy()
|
|
125
|
-
del state[
|
|
129
|
+
del state[hash_attr]
|
|
126
130
|
return state
|
|
127
131
|
|
|
128
132
|
@_compat.cached_method
|
|
@@ -146,28 +150,28 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
146
150
|
return protocols.is_measurement(self.unfreeze())
|
|
147
151
|
|
|
148
152
|
@_compat.cached_method
|
|
149
|
-
def all_qubits(self) -> FrozenSet[
|
|
153
|
+
def all_qubits(self) -> FrozenSet[cirq.Qid]:
|
|
150
154
|
return super().all_qubits()
|
|
151
155
|
|
|
152
156
|
@cached_property
|
|
153
|
-
def _all_operations(self) -> Tuple[
|
|
157
|
+
def _all_operations(self) -> Tuple[cirq.Operation, ...]:
|
|
154
158
|
return tuple(super().all_operations())
|
|
155
159
|
|
|
156
|
-
def all_operations(self) -> Iterator[
|
|
160
|
+
def all_operations(self) -> Iterator[cirq.Operation]:
|
|
157
161
|
return iter(self._all_operations)
|
|
158
162
|
|
|
159
163
|
def has_measurements(self) -> bool:
|
|
160
164
|
return self._is_measurement_()
|
|
161
165
|
|
|
162
166
|
@_compat.cached_method
|
|
163
|
-
def all_measurement_key_objs(self) -> FrozenSet[
|
|
167
|
+
def all_measurement_key_objs(self) -> FrozenSet[cirq.MeasurementKey]:
|
|
164
168
|
return super().all_measurement_key_objs()
|
|
165
169
|
|
|
166
|
-
def _measurement_key_objs_(self) -> FrozenSet[
|
|
170
|
+
def _measurement_key_objs_(self) -> FrozenSet[cirq.MeasurementKey]:
|
|
167
171
|
return self.all_measurement_key_objs()
|
|
168
172
|
|
|
169
173
|
@_compat.cached_method
|
|
170
|
-
def _control_keys_(self) -> FrozenSet[
|
|
174
|
+
def _control_keys_(self) -> FrozenSet[cirq.MeasurementKey]:
|
|
171
175
|
return super()._control_keys_()
|
|
172
176
|
|
|
173
177
|
@_compat.cached_method
|
|
@@ -190,8 +194,8 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
190
194
|
return super()._parameter_names_() | tag_params
|
|
191
195
|
|
|
192
196
|
def _resolve_parameters_(
|
|
193
|
-
self, resolver:
|
|
194
|
-
) ->
|
|
197
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
198
|
+
) -> cirq.FrozenCircuit:
|
|
195
199
|
resolved_circuit = super()._resolve_parameters_(resolver, recursive)
|
|
196
200
|
resolved_tags = [
|
|
197
201
|
protocols.resolve_parameters(tag, resolver, recursive) for tag in self.tags
|
|
@@ -201,23 +205,23 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
201
205
|
def _measurement_key_names_(self) -> FrozenSet[str]:
|
|
202
206
|
return self.all_measurement_key_names()
|
|
203
207
|
|
|
204
|
-
def __add__(self, other) ->
|
|
208
|
+
def __add__(self, other) -> cirq.FrozenCircuit:
|
|
205
209
|
return (self.unfreeze() + other).freeze()
|
|
206
210
|
|
|
207
|
-
def __radd__(self, other) ->
|
|
211
|
+
def __radd__(self, other) -> cirq.FrozenCircuit:
|
|
208
212
|
return (other + self.unfreeze()).freeze()
|
|
209
213
|
|
|
210
214
|
# Needed for numpy to handle multiplication by np.int64 correctly.
|
|
211
215
|
__array_priority__ = 10000
|
|
212
216
|
|
|
213
217
|
# TODO: handle multiplication / powers differently?
|
|
214
|
-
def __mul__(self, other) ->
|
|
218
|
+
def __mul__(self, other) -> cirq.FrozenCircuit:
|
|
215
219
|
return (self.unfreeze() * other).freeze()
|
|
216
220
|
|
|
217
|
-
def __rmul__(self, other) ->
|
|
221
|
+
def __rmul__(self, other) -> cirq.FrozenCircuit:
|
|
218
222
|
return (other * self.unfreeze()).freeze()
|
|
219
223
|
|
|
220
|
-
def __pow__(self, other) ->
|
|
224
|
+
def __pow__(self, other) -> cirq.FrozenCircuit:
|
|
221
225
|
try:
|
|
222
226
|
return (self.unfreeze() ** other).freeze()
|
|
223
227
|
except:
|
|
@@ -238,20 +242,20 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
238
242
|
return cls(moments, strategy=InsertStrategy.EARLIEST, tags=tags)
|
|
239
243
|
|
|
240
244
|
def concat_ragged(
|
|
241
|
-
*circuits:
|
|
242
|
-
) ->
|
|
245
|
+
*circuits: cirq.AbstractCircuit, align: Union[cirq.Alignment, str] = Alignment.LEFT
|
|
246
|
+
) -> cirq.FrozenCircuit:
|
|
243
247
|
return AbstractCircuit.concat_ragged(*circuits, align=align).freeze()
|
|
244
248
|
|
|
245
249
|
concat_ragged.__doc__ = AbstractCircuit.concat_ragged.__doc__
|
|
246
250
|
|
|
247
251
|
def zip(
|
|
248
|
-
*circuits:
|
|
249
|
-
) ->
|
|
252
|
+
*circuits: cirq.AbstractCircuit, align: Union[cirq.Alignment, str] = Alignment.LEFT
|
|
253
|
+
) -> cirq.FrozenCircuit:
|
|
250
254
|
return AbstractCircuit.zip(*circuits, align=align).freeze()
|
|
251
255
|
|
|
252
256
|
zip.__doc__ = AbstractCircuit.zip.__doc__
|
|
253
257
|
|
|
254
|
-
def to_op(self) ->
|
|
258
|
+
def to_op(self) -> cirq.CircuitOperation:
|
|
255
259
|
"""Creates a CircuitOperation wrapping this circuit."""
|
|
256
260
|
from cirq.circuits import CircuitOperation
|
|
257
261
|
|
cirq/circuits/insert_strategy.py
CHANGED
|
@@ -23,6 +23,16 @@ class InsertStrategy:
|
|
|
23
23
|
INLINE: 'InsertStrategy'
|
|
24
24
|
EARLIEST: 'InsertStrategy'
|
|
25
25
|
|
|
26
|
+
def __new__(cls, name: str, doc: str) -> 'InsertStrategy':
|
|
27
|
+
inst = getattr(cls, name, None)
|
|
28
|
+
if not inst or not isinstance(inst, cls):
|
|
29
|
+
inst = super().__new__(cls)
|
|
30
|
+
return inst
|
|
31
|
+
|
|
32
|
+
def __getnewargs__(self):
|
|
33
|
+
"""Returns a tuple of args to pass to __new__ when unpickling."""
|
|
34
|
+
return (self.name, self.__doc__)
|
|
35
|
+
|
|
26
36
|
def __init__(self, name: str, doc: str):
|
|
27
37
|
self.name = name
|
|
28
38
|
self.__doc__ = doc
|
|
@@ -12,8 +12,28 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
import pickle
|
|
16
|
+
|
|
17
|
+
import pytest
|
|
18
|
+
|
|
15
19
|
import cirq
|
|
16
20
|
|
|
17
21
|
|
|
18
22
|
def test_repr():
|
|
19
23
|
assert repr(cirq.InsertStrategy.NEW) == 'cirq.InsertStrategy.NEW'
|
|
24
|
+
assert str(cirq.InsertStrategy.NEW) == 'NEW'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@pytest.mark.parametrize(
|
|
28
|
+
'strategy',
|
|
29
|
+
[
|
|
30
|
+
cirq.InsertStrategy.NEW,
|
|
31
|
+
cirq.InsertStrategy.NEW_THEN_INLINE,
|
|
32
|
+
cirq.InsertStrategy.INLINE,
|
|
33
|
+
cirq.InsertStrategy.EARLIEST,
|
|
34
|
+
],
|
|
35
|
+
ids=lambda strategy: strategy.name,
|
|
36
|
+
)
|
|
37
|
+
def test_identity_after_pickling(strategy: cirq.InsertStrategy):
|
|
38
|
+
unpickled_strategy = pickle.loads(pickle.dumps(strategy))
|
|
39
|
+
assert unpickled_strategy is strategy
|