cirq-core 1.3.0.dev20231201141002__py3-none-any.whl → 1.4.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 +4 -0
- cirq/_compat.py +9 -11
- cirq/_compat_test.py +45 -56
- cirq/_version.py +31 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/circuit.py +13 -8
- cirq/circuits/circuit_operation.py +2 -1
- cirq/circuits/circuit_test.py +2 -2
- cirq/circuits/frozen_circuit.py +3 -2
- cirq/circuits/moment.py +12 -10
- cirq/circuits/qasm_output.py +5 -1
- cirq/circuits/qasm_output_test.py +25 -10
- cirq/contrib/qcircuit/qcircuit_diagram_info.py +9 -7
- cirq/contrib/quimb/mps_simulator_test.py +1 -1
- cirq/contrib/quimb/state_vector.py +9 -2
- cirq/contrib/svg/svg.py +2 -1
- cirq/contrib/svg/svg_test.py +1 -0
- cirq/devices/grid_qubit.py +85 -32
- cirq/devices/grid_qubit_test.py +22 -4
- cirq/devices/line_qubit.py +74 -26
- cirq/devices/line_qubit_test.py +19 -0
- cirq/devices/noise_utils.py +33 -31
- cirq/devices/noise_utils_test.py +1 -84
- cirq/devices/superconducting_qubits_noise_properties.py +7 -6
- cirq/experiments/__init__.py +8 -0
- cirq/experiments/qubit_characterizations.py +288 -44
- cirq/experiments/qubit_characterizations_test.py +61 -7
- cirq/experiments/random_quantum_circuit_generation.py +1 -1
- cirq/experiments/single_qubit_readout_calibration.py +132 -6
- cirq/experiments/single_qubit_readout_calibration_test.py +3 -1
- cirq/experiments/t1_decay_experiment.py +14 -7
- cirq/experiments/t1_decay_experiment_test.py +14 -26
- cirq/experiments/two_qubit_xeb.py +483 -0
- cirq/experiments/two_qubit_xeb_test.py +304 -0
- cirq/json_resolver_cache.py +2 -0
- cirq/linalg/decompositions.py +11 -13
- cirq/linalg/decompositions_test.py +1 -3
- cirq/linalg/diagonalize.py +5 -4
- cirq/linalg/predicates.py +8 -6
- cirq/linalg/transformations.py +2 -1
- cirq/linalg/transformations_test.py +1 -1
- cirq/ops/__init__.py +2 -0
- cirq/ops/clifford_gate.py +59 -16
- cirq/ops/common_gates_test.py +1 -2
- cirq/ops/control_values.py +4 -3
- cirq/ops/controlled_gate_test.py +1 -3
- cirq/ops/gate_operation.py +10 -1
- cirq/ops/named_qubit.py +74 -28
- cirq/ops/named_qubit_test.py +19 -0
- cirq/ops/parity_gates.py +5 -0
- cirq/ops/parity_gates_test.py +2 -10
- cirq/ops/pauli_gates.py +5 -2
- cirq/ops/pauli_string.py +2 -2
- cirq/ops/permutation_gate.py +16 -18
- cirq/ops/phased_iswap_gate_test.py +1 -3
- cirq/ops/phased_x_gate.py +1 -1
- cirq/ops/phased_x_z_gate.py +17 -1
- cirq/ops/phased_x_z_gate_test.py +24 -0
- cirq/ops/qid_util.py +4 -8
- cirq/ops/qubit_manager.py +7 -4
- cirq/ops/qubit_manager_test.py +20 -0
- cirq/ops/raw_types.py +5 -2
- cirq/ops/raw_types_test.py +14 -15
- cirq/ops/uniform_superposition_gate.py +123 -0
- cirq/ops/uniform_superposition_gate_test.py +94 -0
- cirq/protocols/approximate_equality_protocol_test.py +2 -2
- cirq/protocols/circuit_diagram_info_protocol.py +6 -4
- cirq/protocols/commutes_protocol.py +2 -4
- cirq/protocols/decompose_protocol.py +7 -12
- cirq/protocols/decompose_protocol_test.py +7 -3
- cirq/protocols/has_stabilizer_effect_protocol.py +1 -5
- cirq/protocols/has_stabilizer_effect_protocol_test.py +13 -4
- cirq/protocols/json_serialization.py +51 -181
- cirq/protocols/json_serialization_test.py +13 -47
- cirq/protocols/json_test_data/CircuitOperation.json +131 -148
- cirq/protocols/json_test_data/CircuitOperation.json_inward +55 -0
- cirq/protocols/json_test_data/CircuitOperation.repr_inward +6 -0
- cirq/protocols/json_test_data/FrozenCircuit.json +196 -210
- cirq/protocols/json_test_data/FrozenCircuit.json_inward +35 -0
- cirq/protocols/json_test_data/FrozenCircuit.repr_inward +4 -0
- cirq/protocols/json_test_data/UniformSuperpositionGate.json +5 -0
- cirq/protocols/json_test_data/UniformSuperpositionGate.repr +1 -0
- cirq/protocols/json_test_data/cirq.MSGate.json +4 -0
- cirq/protocols/json_test_data/cirq.MSGate.repr +1 -0
- cirq/protocols/json_test_data/spec.py +2 -0
- cirq/protocols/pow_protocol_test.py +1 -3
- cirq/protocols/resolve_parameters.py +4 -2
- cirq/qis/__init__.py +10 -0
- cirq/qis/clifford_tableau.py +8 -2
- cirq/qis/noise_utils.py +123 -0
- cirq/qis/noise_utils_test.py +97 -0
- cirq/sim/classical_simulator.py +227 -87
- cirq/sim/classical_simulator_test.py +135 -0
- cirq/sim/clifford/clifford_simulator_test.py +4 -2
- cirq/sim/mux.py +5 -3
- cirq/sim/simulation_product_state.py +15 -10
- cirq/sim/simulation_state.py +1 -1
- cirq/sim/simulation_state_test.py +2 -2
- cirq/sim/simulator_base.py +3 -3
- cirq/sim/state_vector_simulation_state.py +4 -4
- cirq/sim/state_vector_simulator.py +17 -2
- cirq/study/__init__.py +1 -0
- cirq/study/result.py +14 -0
- cirq/study/result_test.py +6 -0
- cirq/study/sweeps.py +4 -2
- cirq/study/sweeps_test.py +8 -0
- cirq/testing/__init__.py +6 -1
- cirq/testing/_compat_test_data/__init__.py +3 -3
- cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
- cirq/testing/circuit_compare.py +1 -1
- cirq/testing/consistent_qasm.py +6 -0
- cirq/testing/gate_features.py +10 -0
- cirq/testing/lin_alg_utils.py +5 -3
- cirq/transformers/__init__.py +15 -0
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +3 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +24 -0
- cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +17 -0
- cirq/transformers/dynamical_decoupling.py +122 -0
- cirq/transformers/dynamical_decoupling_test.py +123 -0
- cirq/transformers/gauge_compiling/__init__.py +26 -0
- cirq/transformers/gauge_compiling/cz_gauge.py +46 -0
- cirq/transformers/gauge_compiling/cz_gauge_test.py +23 -0
- cirq/transformers/gauge_compiling/gauge_compiling.py +214 -0
- cirq/transformers/gauge_compiling/gauge_compiling_test.py +41 -0
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +83 -0
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +52 -0
- cirq/transformers/gauge_compiling/iswap_gauge.py +105 -0
- cirq/transformers/gauge_compiling/iswap_gauge_test.py +23 -0
- cirq/transformers/gauge_compiling/spin_inversion_gauge.py +33 -0
- cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py +37 -0
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +64 -0
- cirq/transformers/gauge_compiling/sqrt_cz_gauge_test.py +27 -0
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +94 -0
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py +22 -0
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +1 -0
- cirq/transformers/merge_k_qubit_gates_test.py +23 -23
- cirq/transformers/merge_single_qubit_gates_test.py +14 -14
- cirq/transformers/optimize_for_target_gateset.py +39 -17
- cirq/transformers/optimize_for_target_gateset_test.py +189 -39
- cirq/transformers/qubit_management_transformers.py +1 -1
- cirq/transformers/routing/visualize_routed_circuit_test.py +17 -17
- cirq/transformers/stratify_test.py +13 -13
- cirq/transformers/target_gatesets/compilation_target_gateset.py +26 -2
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +16 -16
- cirq/transformers/target_gatesets/cz_gateset.py +4 -0
- cirq/transformers/transformer_api.py +1 -2
- cirq/transformers/transformer_primitives.py +15 -14
- cirq/transformers/transformer_primitives_test.py +99 -72
- cirq/value/classical_data.py +6 -6
- cirq/value/value_equality_attr.py +4 -0
- cirq/work/sampler.py +3 -4
- cirq/work/sampler_test.py +25 -0
- {cirq_core-1.3.0.dev20231201141002.dist-info → cirq_core-1.4.0.dist-info}/METADATA +10 -19
- {cirq_core-1.3.0.dev20231201141002.dist-info → cirq_core-1.4.0.dist-info}/RECORD +157 -130
- {cirq_core-1.3.0.dev20231201141002.dist-info → cirq_core-1.4.0.dist-info}/WHEEL +1 -1
- {cirq_core-1.3.0.dev20231201141002.dist-info → cirq_core-1.4.0.dist-info}/LICENSE +0 -0
- {cirq_core-1.3.0.dev20231201141002.dist-info → cirq_core-1.4.0.dist-info}/top_level.txt +0 -0
cirq/__init__.py
CHANGED
|
@@ -240,6 +240,7 @@ from cirq.ops import (
|
|
|
240
240
|
MatrixGate,
|
|
241
241
|
MixedUnitaryChannel,
|
|
242
242
|
M,
|
|
243
|
+
MSGate,
|
|
243
244
|
measure,
|
|
244
245
|
measure_each,
|
|
245
246
|
measure_paulistring_terms,
|
|
@@ -331,10 +332,12 @@ from cirq.ops import (
|
|
|
331
332
|
ZPowGate,
|
|
332
333
|
ZZ,
|
|
333
334
|
ZZPowGate,
|
|
335
|
+
UniformSuperpositionGate,
|
|
334
336
|
)
|
|
335
337
|
|
|
336
338
|
from cirq.transformers import (
|
|
337
339
|
AbstractInitialMapper,
|
|
340
|
+
add_dynamical_decoupling,
|
|
338
341
|
align_left,
|
|
339
342
|
align_right,
|
|
340
343
|
CompilationTargetGateset,
|
|
@@ -508,6 +511,7 @@ from cirq.study import (
|
|
|
508
511
|
to_sweeps,
|
|
509
512
|
Result,
|
|
510
513
|
UnitSweep,
|
|
514
|
+
UNIT_SWEEP,
|
|
511
515
|
Zip,
|
|
512
516
|
ZipLongest,
|
|
513
517
|
)
|
cirq/_compat.py
CHANGED
|
@@ -61,23 +61,19 @@ def with_debug(value: bool) -> Iterator[None]:
|
|
|
61
61
|
__cirq_debug__.reset(token)
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
except ImportError:
|
|
67
|
-
from backports.cached_property import cached_property # type: ignore[no-redef]
|
|
64
|
+
# Sentinel used by wrapped_no_args below when method has not yet been cached.
|
|
65
|
+
_NOT_FOUND = object()
|
|
68
66
|
|
|
69
67
|
|
|
70
68
|
TFunc = TypeVar('TFunc', bound=Callable)
|
|
71
69
|
|
|
72
70
|
|
|
73
71
|
@overload
|
|
74
|
-
def cached_method(__func: TFunc) -> TFunc:
|
|
75
|
-
...
|
|
72
|
+
def cached_method(__func: TFunc) -> TFunc: ...
|
|
76
73
|
|
|
77
74
|
|
|
78
75
|
@overload
|
|
79
|
-
def cached_method(*, maxsize: int = 128) -> Callable[[TFunc], TFunc]:
|
|
80
|
-
...
|
|
76
|
+
def cached_method(*, maxsize: int = 128) -> Callable[[TFunc], TFunc]: ...
|
|
81
77
|
|
|
82
78
|
|
|
83
79
|
def cached_method(method: Optional[TFunc] = None, *, maxsize: int = 128) -> Any:
|
|
@@ -103,9 +99,11 @@ def cached_method(method: Optional[TFunc] = None, *, maxsize: int = 128) -> Any:
|
|
|
103
99
|
|
|
104
100
|
@functools.wraps(func)
|
|
105
101
|
def wrapped_no_args(self):
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
result = getattr(self, cache_name, _NOT_FOUND)
|
|
103
|
+
if result is _NOT_FOUND:
|
|
104
|
+
result = func(self)
|
|
105
|
+
object.__setattr__(self, cache_name, result)
|
|
106
|
+
return result
|
|
109
107
|
|
|
110
108
|
return wrapped_no_args
|
|
111
109
|
|
cirq/_compat_test.py
CHANGED
|
@@ -38,7 +38,6 @@ import cirq.testing
|
|
|
38
38
|
from cirq._compat import (
|
|
39
39
|
block_overlapping_deprecation,
|
|
40
40
|
cached_method,
|
|
41
|
-
cached_property,
|
|
42
41
|
proper_repr,
|
|
43
42
|
dataclass_repr,
|
|
44
43
|
deprecated,
|
|
@@ -346,7 +345,7 @@ def test_wrap_module():
|
|
|
346
345
|
|
|
347
346
|
|
|
348
347
|
def test_deprecate_attributes_assert_attributes_in_sys_modules():
|
|
349
|
-
|
|
348
|
+
run_in_subprocess(_test_deprecate_attributes_assert_attributes_in_sys_modules)
|
|
350
349
|
|
|
351
350
|
|
|
352
351
|
def _test_deprecate_attributes_assert_attributes_in_sys_modules():
|
|
@@ -635,42 +634,49 @@ _repeated_child_deprecation_msg = [
|
|
|
635
634
|
] + _deprecation_origin
|
|
636
635
|
|
|
637
636
|
|
|
638
|
-
def _trace_unhandled_exceptions(*args, queue: 'multiprocessing.Queue', func: Callable
|
|
637
|
+
def _trace_unhandled_exceptions(*args, queue: 'multiprocessing.Queue', func: Callable):
|
|
639
638
|
try:
|
|
640
|
-
func(*args
|
|
639
|
+
func(*args)
|
|
641
640
|
queue.put(None)
|
|
642
641
|
except BaseException as ex:
|
|
643
642
|
msg = str(ex)
|
|
644
643
|
queue.put((type(ex).__name__, msg, traceback.format_exc()))
|
|
645
644
|
|
|
646
645
|
|
|
647
|
-
def
|
|
648
|
-
"""
|
|
646
|
+
def run_in_subprocess(test_func, *args):
|
|
647
|
+
"""Run a function in a subprocess.
|
|
648
|
+
|
|
649
|
+
This ensures that sys.modules changes in subprocesses won't impact the parent process.
|
|
650
|
+
|
|
651
|
+
Args:
|
|
652
|
+
test_func: The function to be run in a subprocess.
|
|
653
|
+
*args: Positional args to pass to the function.
|
|
654
|
+
"""
|
|
655
|
+
|
|
649
656
|
assert callable(test_func), (
|
|
650
|
-
"
|
|
657
|
+
"run_in_subprocess expects a function. Did you call the function instead of passing "
|
|
651
658
|
"it to this method?"
|
|
652
659
|
)
|
|
653
660
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
661
|
+
# Use spawn to ensure subprocesses are isolated.
|
|
662
|
+
# See https://github.com/quantumlib/Cirq/issues/6373
|
|
663
|
+
ctx = multiprocessing.get_context('spawn')
|
|
657
664
|
|
|
658
|
-
|
|
659
|
-
kwargs['queue'] = exception
|
|
660
|
-
kwargs['func'] = test_func
|
|
661
|
-
p = ctx.Process(target=_trace_unhandled_exceptions, args=args, kwargs=kwargs)
|
|
662
|
-
p.start()
|
|
663
|
-
p.join()
|
|
664
|
-
result = exception.get()
|
|
665
|
-
if result: # pragma: no cover
|
|
666
|
-
ex_type, msg, ex_trace = result
|
|
667
|
-
if ex_type == "Skipped":
|
|
668
|
-
warnings.warn(f"Skipping: {ex_type}: {msg}\n{ex_trace}")
|
|
669
|
-
pytest.skip(f'{ex_type}: {msg}\n{ex_trace}')
|
|
670
|
-
else:
|
|
671
|
-
pytest.fail(f'{ex_type}: {msg}\n{ex_trace}')
|
|
665
|
+
queue = ctx.Queue()
|
|
672
666
|
|
|
673
|
-
|
|
667
|
+
p = ctx.Process(
|
|
668
|
+
target=_trace_unhandled_exceptions, args=args, kwargs={'queue': queue, 'func': test_func}
|
|
669
|
+
)
|
|
670
|
+
p.start()
|
|
671
|
+
p.join()
|
|
672
|
+
result = queue.get()
|
|
673
|
+
if result: # pragma: no cover
|
|
674
|
+
ex_type, msg, ex_trace = result
|
|
675
|
+
if ex_type == "Skipped":
|
|
676
|
+
warnings.warn(f"Skipping: {ex_type}: {msg}\n{ex_trace}")
|
|
677
|
+
pytest.skip(f'{ex_type}: {msg}\n{ex_trace}')
|
|
678
|
+
else:
|
|
679
|
+
pytest.fail(f'{ex_type}: {msg}\n{ex_trace}')
|
|
674
680
|
|
|
675
681
|
|
|
676
682
|
@mock.patch.dict(os.environ, {"CIRQ_FORCE_DEDUPE_MODULE_DEPRECATION": "1"})
|
|
@@ -698,7 +704,7 @@ def subprocess_context(test_func):
|
|
|
698
704
|
],
|
|
699
705
|
)
|
|
700
706
|
def test_deprecated_module(outdated_method, deprecation_messages):
|
|
701
|
-
|
|
707
|
+
run_in_subprocess(_test_deprecated_module_inner, outdated_method, deprecation_messages)
|
|
702
708
|
|
|
703
709
|
|
|
704
710
|
def _test_deprecated_module_inner(outdated_method, deprecation_messages):
|
|
@@ -736,7 +742,7 @@ def test_same_name_submodule_earlier_in_subtree():
|
|
|
736
742
|
cirq.ops.engine.calibration packages. The wrong resolution resulted in false circular
|
|
737
743
|
imports!
|
|
738
744
|
"""
|
|
739
|
-
|
|
745
|
+
run_in_subprocess(_test_same_name_submodule_earlier_in_subtree_inner)
|
|
740
746
|
|
|
741
747
|
|
|
742
748
|
def _test_same_name_submodule_earlier_in_subtree_inner():
|
|
@@ -748,7 +754,7 @@ def _test_same_name_submodule_earlier_in_subtree_inner():
|
|
|
748
754
|
def test_metadata_search_path():
|
|
749
755
|
# to cater for metadata path finders
|
|
750
756
|
# https://docs.python.org/3/library/importlib.metadata.html#extending-the-search-algorithm
|
|
751
|
-
|
|
757
|
+
run_in_subprocess(_test_metadata_search_path_inner)
|
|
752
758
|
|
|
753
759
|
|
|
754
760
|
def _test_metadata_search_path_inner(): # pragma: no cover
|
|
@@ -760,7 +766,7 @@ def _test_metadata_search_path_inner(): # pragma: no cover
|
|
|
760
766
|
|
|
761
767
|
|
|
762
768
|
def test_metadata_distributions_after_deprecated_submodule():
|
|
763
|
-
|
|
769
|
+
run_in_subprocess(_test_metadata_distributions_after_deprecated_submodule)
|
|
764
770
|
|
|
765
771
|
|
|
766
772
|
def _test_metadata_distributions_after_deprecated_submodule():
|
|
@@ -779,7 +785,7 @@ def _test_metadata_distributions_after_deprecated_submodule():
|
|
|
779
785
|
|
|
780
786
|
|
|
781
787
|
def test_parent_spec_after_deprecated_submodule():
|
|
782
|
-
|
|
788
|
+
run_in_subprocess(_test_parent_spec_after_deprecated_submodule)
|
|
783
789
|
|
|
784
790
|
|
|
785
791
|
def _test_parent_spec_after_deprecated_submodule():
|
|
@@ -791,7 +797,7 @@ def _test_parent_spec_after_deprecated_submodule():
|
|
|
791
797
|
def test_type_repr_in_new_module():
|
|
792
798
|
# to cater for metadata path finders
|
|
793
799
|
# https://docs.python.org/3/library/importlib.metadata.html#extending-the-search-algorithm
|
|
794
|
-
|
|
800
|
+
run_in_subprocess(_test_type_repr_in_new_module_inner)
|
|
795
801
|
|
|
796
802
|
|
|
797
803
|
def _test_type_repr_in_new_module_inner():
|
|
@@ -849,19 +855,19 @@ def _test_broken_module_3_inner():
|
|
|
849
855
|
|
|
850
856
|
|
|
851
857
|
def test_deprecated_module_error_handling_1():
|
|
852
|
-
|
|
858
|
+
run_in_subprocess(_test_broken_module_1_inner)
|
|
853
859
|
|
|
854
860
|
|
|
855
861
|
def test_deprecated_module_error_handling_2():
|
|
856
|
-
|
|
862
|
+
run_in_subprocess(_test_broken_module_2_inner)
|
|
857
863
|
|
|
858
864
|
|
|
859
865
|
def test_deprecated_module_error_handling_3():
|
|
860
|
-
|
|
866
|
+
run_in_subprocess(_test_broken_module_3_inner)
|
|
861
867
|
|
|
862
868
|
|
|
863
869
|
def test_new_module_is_top_level():
|
|
864
|
-
|
|
870
|
+
run_in_subprocess(_test_new_module_is_top_level_inner)
|
|
865
871
|
|
|
866
872
|
|
|
867
873
|
def _test_new_module_is_top_level_inner():
|
|
@@ -877,7 +883,7 @@ def _test_new_module_is_top_level_inner():
|
|
|
877
883
|
|
|
878
884
|
|
|
879
885
|
def test_import_deprecated_with_no_attribute():
|
|
880
|
-
|
|
886
|
+
run_in_subprocess(_test_import_deprecated_with_no_attribute_inner)
|
|
881
887
|
|
|
882
888
|
|
|
883
889
|
def _test_import_deprecated_with_no_attribute_inner():
|
|
@@ -970,7 +976,7 @@ def test_deprecated_module_loader_repr():
|
|
|
970
976
|
|
|
971
977
|
def test_subprocess_test_failure():
|
|
972
978
|
with pytest.raises(Failed, match='ValueError.*this fails'):
|
|
973
|
-
|
|
979
|
+
run_in_subprocess(_test_subprocess_test_failure_inner)
|
|
974
980
|
|
|
975
981
|
|
|
976
982
|
def _test_subprocess_test_failure_inner():
|
|
@@ -978,7 +984,7 @@ def _test_subprocess_test_failure_inner():
|
|
|
978
984
|
|
|
979
985
|
|
|
980
986
|
def test_dir_is_still_valid():
|
|
981
|
-
|
|
987
|
+
run_in_subprocess(_dir_is_still_valid_inner)
|
|
982
988
|
|
|
983
989
|
|
|
984
990
|
def _dir_is_still_valid_inner():
|
|
@@ -986,7 +992,7 @@ def _dir_is_still_valid_inner():
|
|
|
986
992
|
|
|
987
993
|
import cirq.testing._compat_test_data as mod
|
|
988
994
|
|
|
989
|
-
for m in ['fake_a', '
|
|
995
|
+
for m in ['fake_a', 'logging', 'module_a']:
|
|
990
996
|
assert m in dir(mod)
|
|
991
997
|
|
|
992
998
|
|
|
@@ -1004,23 +1010,6 @@ def test_block_overlapping_deprecation():
|
|
|
1004
1010
|
f(5)
|
|
1005
1011
|
|
|
1006
1012
|
|
|
1007
|
-
def test_cached_property():
|
|
1008
|
-
class Foo:
|
|
1009
|
-
def __init__(self):
|
|
1010
|
-
self.bar_calls = 0
|
|
1011
|
-
|
|
1012
|
-
@cached_property
|
|
1013
|
-
def bar(self):
|
|
1014
|
-
self.bar_calls += 1
|
|
1015
|
-
return []
|
|
1016
|
-
|
|
1017
|
-
foo = Foo()
|
|
1018
|
-
bar = foo.bar
|
|
1019
|
-
bar2 = foo.bar
|
|
1020
|
-
assert bar2 is bar
|
|
1021
|
-
assert foo.bar_calls == 1
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
1013
|
class Bar:
|
|
1025
1014
|
def __init__(self) -> None:
|
|
1026
1015
|
self.foo_calls: Dict[int, int] = collections.Counter()
|
cirq/_version.py
CHANGED
|
@@ -1 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
# Copyright 2018 The Cirq Developers
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Define version number here, read it from setup.py automatically,
|
|
16
|
+
and warn users that the latest version of cirq uses python 3.10+"""
|
|
17
|
+
|
|
18
|
+
import sys
|
|
19
|
+
|
|
20
|
+
if sys.version_info < (3, 10, 0): # pragma: no cover
|
|
21
|
+
raise SystemError(
|
|
22
|
+
"You installed the latest version of cirq but aren't on python 3.10+.\n"
|
|
23
|
+
'To fix this error, you need to either:\n'
|
|
24
|
+
'\n'
|
|
25
|
+
'A) Update to python 3.10 or later.\n'
|
|
26
|
+
'- OR -\n'
|
|
27
|
+
'B) Explicitly install an older deprecated-but-compatible version '
|
|
28
|
+
'of cirq (e.g. "python -m pip install cirq==1.1.*")'
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
__version__ = "1.4.0"
|
cirq/_version_test.py
CHANGED
cirq/circuits/circuit.py
CHANGED
|
@@ -29,14 +29,14 @@ from typing import (
|
|
|
29
29
|
AbstractSet,
|
|
30
30
|
Any,
|
|
31
31
|
Callable,
|
|
32
|
-
Mapping,
|
|
33
|
-
MutableSequence,
|
|
34
32
|
cast,
|
|
35
33
|
Dict,
|
|
36
34
|
FrozenSet,
|
|
37
35
|
Iterable,
|
|
38
36
|
Iterator,
|
|
39
37
|
List,
|
|
38
|
+
Mapping,
|
|
39
|
+
MutableSequence,
|
|
40
40
|
Optional,
|
|
41
41
|
overload,
|
|
42
42
|
Sequence,
|
|
@@ -58,9 +58,9 @@ from cirq._doc import document
|
|
|
58
58
|
from cirq.circuits._bucket_priority_queue import BucketPriorityQueue
|
|
59
59
|
from cirq.circuits.circuit_operation import CircuitOperation
|
|
60
60
|
from cirq.circuits.insert_strategy import InsertStrategy
|
|
61
|
+
from cirq.circuits.moment import Moment
|
|
61
62
|
from cirq.circuits.qasm_output import QasmOutput
|
|
62
63
|
from cirq.circuits.text_diagram_drawer import TextDiagramDrawer
|
|
63
|
-
from cirq.circuits.moment import Moment
|
|
64
64
|
from cirq.protocols import circuit_diagram_info_protocol
|
|
65
65
|
from cirq.type_workarounds import NotImplementedType
|
|
66
66
|
|
|
@@ -203,19 +203,24 @@ class AbstractCircuit(abc.ABC):
|
|
|
203
203
|
copy: If True and 'self' is a Circuit, returns a copy that circuit.
|
|
204
204
|
"""
|
|
205
205
|
|
|
206
|
-
def __bool__(self):
|
|
206
|
+
def __bool__(self) -> bool:
|
|
207
207
|
return bool(self.moments)
|
|
208
208
|
|
|
209
|
-
def __eq__(self, other):
|
|
209
|
+
def __eq__(self, other) -> bool:
|
|
210
210
|
if not isinstance(other, AbstractCircuit):
|
|
211
211
|
return NotImplemented
|
|
212
|
-
return
|
|
212
|
+
return other is self or (
|
|
213
|
+
len(self.moments) == len(other.moments)
|
|
214
|
+
and all(m0 == m1 for m0, m1 in zip(self.moments, other.moments))
|
|
215
|
+
)
|
|
213
216
|
|
|
214
217
|
def _approx_eq_(self, other: Any, atol: Union[int, float]) -> bool:
|
|
215
218
|
"""See `cirq.protocols.SupportsApproximateEquality`."""
|
|
216
219
|
if not isinstance(other, AbstractCircuit):
|
|
217
220
|
return NotImplemented
|
|
218
|
-
return cirq.protocols.approx_eq(
|
|
221
|
+
return other is self or cirq.protocols.approx_eq(
|
|
222
|
+
tuple(self.moments), tuple(other.moments), atol=atol
|
|
223
|
+
)
|
|
219
224
|
|
|
220
225
|
def __ne__(self, other) -> bool:
|
|
221
226
|
return not self == other
|
|
@@ -2625,7 +2630,7 @@ def _draw_moment_in_diagram(
|
|
|
2625
2630
|
if desc:
|
|
2626
2631
|
y = max(label_map.values(), default=0) + 1
|
|
2627
2632
|
if tags and include_tags:
|
|
2628
|
-
desc = desc + str
|
|
2633
|
+
desc = desc + f"[{', '.join(map(str, tags))}]"
|
|
2629
2634
|
out_diagram.write(x0, y, desc)
|
|
2630
2635
|
|
|
2631
2636
|
if not non_global_ops:
|
|
@@ -19,6 +19,7 @@ applied as part of a larger circuit, a CircuitOperation will execute all
|
|
|
19
19
|
component operations in order, including any nested CircuitOperations.
|
|
20
20
|
"""
|
|
21
21
|
import math
|
|
22
|
+
from functools import cached_property
|
|
22
23
|
from typing import (
|
|
23
24
|
Callable,
|
|
24
25
|
cast,
|
|
@@ -38,7 +39,7 @@ import numpy as np
|
|
|
38
39
|
import sympy
|
|
39
40
|
|
|
40
41
|
from cirq import circuits, ops, protocols, value, study
|
|
41
|
-
from cirq._compat import
|
|
42
|
+
from cirq._compat import proper_repr
|
|
42
43
|
|
|
43
44
|
if TYPE_CHECKING:
|
|
44
45
|
import cirq
|
cirq/circuits/circuit_test.py
CHANGED
cirq/circuits/frozen_circuit.py
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""An immutable version of the Circuit data structure."""
|
|
15
|
+
from functools import cached_property
|
|
15
16
|
from typing import (
|
|
16
17
|
AbstractSet,
|
|
17
18
|
FrozenSet,
|
|
@@ -90,7 +91,7 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
90
91
|
"""Returns a tuple of the Circuit's tags."""
|
|
91
92
|
return self._tags
|
|
92
93
|
|
|
93
|
-
@
|
|
94
|
+
@cached_property
|
|
94
95
|
def untagged(self) -> 'cirq.FrozenCircuit':
|
|
95
96
|
"""Returns the underlying FrozenCircuit without any tags."""
|
|
96
97
|
return self._from_moments(self._moments) if self.tags else self
|
|
@@ -148,7 +149,7 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
148
149
|
def all_qubits(self) -> FrozenSet['cirq.Qid']:
|
|
149
150
|
return super().all_qubits()
|
|
150
151
|
|
|
151
|
-
@
|
|
152
|
+
@cached_property
|
|
152
153
|
def _all_operations(self) -> Tuple['cirq.Operation', ...]:
|
|
153
154
|
return tuple(super().all_operations())
|
|
154
155
|
|
cirq/circuits/moment.py
CHANGED
|
@@ -283,9 +283,11 @@ class Moment:
|
|
|
283
283
|
|
|
284
284
|
def _with_measurement_key_mapping_(self, key_map: Mapping[str, str]):
|
|
285
285
|
return Moment(
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
286
|
+
(
|
|
287
|
+
protocols.with_measurement_key_mapping(op, key_map)
|
|
288
|
+
if protocols.measurement_keys_touched(op)
|
|
289
|
+
else op
|
|
290
|
+
)
|
|
289
291
|
for op in self.operations
|
|
290
292
|
)
|
|
291
293
|
|
|
@@ -320,9 +322,11 @@ class Moment:
|
|
|
320
322
|
|
|
321
323
|
def _with_key_path_prefix_(self, prefix: Tuple[str, ...]):
|
|
322
324
|
return Moment(
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
325
|
+
(
|
|
326
|
+
protocols.with_key_path_prefix(op, prefix)
|
|
327
|
+
if protocols.measurement_keys_touched(op)
|
|
328
|
+
else op
|
|
329
|
+
)
|
|
326
330
|
for op in self.operations
|
|
327
331
|
)
|
|
328
332
|
|
|
@@ -343,14 +347,14 @@ class Moment:
|
|
|
343
347
|
if not isinstance(other, type(self)):
|
|
344
348
|
return NotImplemented
|
|
345
349
|
|
|
346
|
-
return self._sorted_operations_() == other._sorted_operations_()
|
|
350
|
+
return self is other or self._sorted_operations_() == other._sorted_operations_()
|
|
347
351
|
|
|
348
352
|
def _approx_eq_(self, other: Any, atol: Union[int, float]) -> bool:
|
|
349
353
|
"""See `cirq.protocols.SupportsApproximateEquality`."""
|
|
350
354
|
if not isinstance(other, type(self)):
|
|
351
355
|
return NotImplemented
|
|
352
356
|
|
|
353
|
-
return protocols.approx_eq(
|
|
357
|
+
return self is other or protocols.approx_eq(
|
|
354
358
|
self._sorted_operations_(), other._sorted_operations_(), atol=atol
|
|
355
359
|
)
|
|
356
360
|
|
|
@@ -510,13 +514,11 @@ class Moment:
|
|
|
510
514
|
return cls.from_ops(*operations)
|
|
511
515
|
|
|
512
516
|
def __add__(self, other: 'cirq.OP_TREE') -> 'cirq.Moment':
|
|
513
|
-
|
|
514
517
|
if isinstance(other, circuits.AbstractCircuit):
|
|
515
518
|
return NotImplemented # Delegate to Circuit.__radd__.
|
|
516
519
|
return self.with_operations(other)
|
|
517
520
|
|
|
518
521
|
def __sub__(self, other: 'cirq.OP_TREE') -> 'cirq.Moment':
|
|
519
|
-
|
|
520
522
|
must_remove = set(op_tree.flatten_to_ops(other))
|
|
521
523
|
new_ops = []
|
|
522
524
|
for op in self.operations:
|
cirq/circuits/qasm_output.py
CHANGED
|
@@ -293,7 +293,11 @@ class QasmOutput:
|
|
|
293
293
|
output(f'creg {meas_id}[{len(meas.qubits)}];\n')
|
|
294
294
|
else:
|
|
295
295
|
output(f'creg {meas_id}[{len(meas.qubits)}]; // Measurement: {comment}\n')
|
|
296
|
-
|
|
296
|
+
# In OpenQASM 2.0, the transformation of global phase gates is ignored.
|
|
297
|
+
# Therefore, no newline is created when the operations contained in
|
|
298
|
+
# a circuit consist only of global phase gates.
|
|
299
|
+
if any(not isinstance(op.gate, ops.GlobalPhaseGate) for op in self.operations):
|
|
300
|
+
output_line_gap(2)
|
|
297
301
|
|
|
298
302
|
# Operations
|
|
299
303
|
self._write_operations(self.operations, output, output_line_gap)
|
|
@@ -191,6 +191,19 @@ ry(pi*-0.25) q[0];
|
|
|
191
191
|
)
|
|
192
192
|
|
|
193
193
|
|
|
194
|
+
def test_qasm_global_pahse():
|
|
195
|
+
output = cirq.QasmOutput((cirq.global_phase_operation(np.exp(1j * 5))), ())
|
|
196
|
+
assert (
|
|
197
|
+
str(output)
|
|
198
|
+
== """OPENQASM 2.0;
|
|
199
|
+
include "qelib1.inc";
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
// Qubits: []
|
|
203
|
+
"""
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
|
|
194
207
|
def test_precision():
|
|
195
208
|
(q0,) = _make_qubits(1)
|
|
196
209
|
output = cirq.QasmOutput((cirq.X(q0) ** 0.1234567,), (q0,), precision=3)
|
|
@@ -318,16 +331,18 @@ def _all_operations(q0, q1, q2, q3, q4, include_measurements=True):
|
|
|
318
331
|
cirq.PhasedXPowGate(phase_exponent=0.333, exponent=0.5).on(q1),
|
|
319
332
|
cirq.PhasedXPowGate(phase_exponent=0.777, exponent=-0.5).on(q1),
|
|
320
333
|
(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
334
|
+
(
|
|
335
|
+
cirq.measure(q0, key='xX'),
|
|
336
|
+
cirq.measure(q2, key='x_a'),
|
|
337
|
+
cirq.measure(q1, key='x?'),
|
|
338
|
+
cirq.measure(q3, key='X'),
|
|
339
|
+
cirq.measure(q4, key='_x'),
|
|
340
|
+
cirq.measure(q2, key='x_a'),
|
|
341
|
+
cirq.measure(q1, q2, q3, key='multi', invert_mask=(False, True)),
|
|
342
|
+
)
|
|
343
|
+
if include_measurements
|
|
344
|
+
else ()
|
|
345
|
+
),
|
|
331
346
|
ExampleOperation(),
|
|
332
347
|
ExampleCompositeOperation(),
|
|
333
348
|
)
|
|
@@ -51,13 +51,15 @@ def hardcoded_qcircuit_diagram_info(op: ops.Operation) -> Optional[protocols.Cir
|
|
|
51
51
|
symbols = (
|
|
52
52
|
(r'\targ',)
|
|
53
53
|
if op.gate == ops.X
|
|
54
|
-
else (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
else (
|
|
55
|
+
(r'\control', r'\control')
|
|
56
|
+
if op.gate == ops.CZ
|
|
57
|
+
else (
|
|
58
|
+
(r'\control', r'\targ')
|
|
59
|
+
if op.gate == ops.CNOT
|
|
60
|
+
else (r'\meter',) if isinstance(op.gate, ops.MeasurementGate) else ()
|
|
61
|
+
)
|
|
62
|
+
)
|
|
61
63
|
)
|
|
62
64
|
return protocols.CircuitDiagramInfo(symbols) if symbols else None
|
|
63
65
|
|
|
@@ -335,7 +335,7 @@ def test_random_circuits_equal_more_rows():
|
|
|
335
335
|
assert_same_output_as_dense(circuit, qubits)
|
|
336
336
|
|
|
337
337
|
|
|
338
|
-
def
|
|
338
|
+
def test_random_circuits_equal_more_cols():
|
|
339
339
|
circuit = cirq.testing.random_circuit(
|
|
340
340
|
qubits=cirq.GridQubit.rect(2, 3), n_moments=6, op_density=1.0
|
|
341
341
|
)
|
|
@@ -170,8 +170,15 @@ def tensor_expectation_value(
|
|
|
170
170
|
)
|
|
171
171
|
else:
|
|
172
172
|
tn.rank_simplify(inplace=True)
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
# TODO(#6586): revert when our minimum quimb version has bugfix for quimb#231
|
|
174
|
+
# Skip path-info evaluation when TensorNetwork consists of scalar Tensors.
|
|
175
|
+
# Avoid bug in quimb-1.8.0.
|
|
176
|
+
# Ref: https://github.com/jcmgray/quimb/issues/231
|
|
177
|
+
if tn.ind_map:
|
|
178
|
+
path_info = tn.contract(get='path-info')
|
|
179
|
+
ram_gb = path_info.largest_intermediate * 128 / 8 / 1024 / 1024 / 1024
|
|
180
|
+
else:
|
|
181
|
+
ram_gb = 0
|
|
175
182
|
if ram_gb > max_ram_gb:
|
|
176
183
|
raise MemoryError(f"We estimate that this contraction will take too much RAM! {ram_gb} GB")
|
|
177
184
|
e_val = tn.contract(inplace=True)
|
cirq/contrib/svg/svg.py
CHANGED
|
@@ -9,7 +9,7 @@ if TYPE_CHECKING:
|
|
|
9
9
|
import cirq
|
|
10
10
|
|
|
11
11
|
QBLUE = '#1967d2'
|
|
12
|
-
FONT = matplotlib.font_manager.FontProperties(
|
|
12
|
+
FONT = matplotlib.font_manager.FontProperties()
|
|
13
13
|
EMPTY_MOMENT_COLWIDTH = float(21) # assumed default column width
|
|
14
14
|
|
|
15
15
|
|
|
@@ -21,6 +21,7 @@ def fixup_text(text: str):
|
|
|
21
21
|
# https://github.com/quantumlib/Cirq/issues/2905
|
|
22
22
|
text = text.replace('[<virtual>]', '')
|
|
23
23
|
text = text.replace('[cirq.VirtualTag()]', '')
|
|
24
|
+
text = text.replace('&', '&')
|
|
24
25
|
text = text.replace('<', '<').replace('>', '>')
|
|
25
26
|
return text
|
|
26
27
|
|