diff --git a/cirq-core/cirq/_compat.py b/cirq-core/cirq/_compat.py index 3cc1cdb1e5e..ea4030025f9 100644 --- a/cirq-core/cirq/_compat.py +++ b/cirq-core/cirq/_compat.py @@ -192,6 +192,9 @@ def _print(self, expr, **kwargs): if hasattr(value, "__qualname__"): return f"{value.__module__}.{value.__qualname__}" + if isinstance(value, np.number): + return str(value) + return repr(value) diff --git a/cirq-core/cirq/contrib/requirements.txt b/cirq-core/cirq/contrib/requirements.txt index 9bb5ef009e8..89faa2ab4c6 100644 --- a/cirq-core/cirq/contrib/requirements.txt +++ b/cirq-core/cirq/contrib/requirements.txt @@ -4,5 +4,5 @@ ply>=3.6 pylatex~=1.4 # quimb -quimb~=1.7 +quimb>=1.8 opt_einsum diff --git a/cirq-core/cirq/protocols/circuit_diagram_info_protocol.py b/cirq-core/cirq/protocols/circuit_diagram_info_protocol.py index 3b6b3445912..03ccf171ac0 100644 --- a/cirq-core/cirq/protocols/circuit_diagram_info_protocol.py +++ b/cirq-core/cirq/protocols/circuit_diagram_info_protocol.py @@ -277,6 +277,8 @@ def format_radians(self, radians: Union[sympy.Basic, int, float]) -> str: if self.precision is not None and not isinstance(radians, sympy.Basic): quantity = self.format_real(radians / np.pi) return quantity + unit + if isinstance(radians, np.number): + return str(radians) return repr(radians) def copy(self): diff --git a/cirq-core/cirq/protocols/circuit_diagram_info_protocol_test.py b/cirq-core/cirq/protocols/circuit_diagram_info_protocol_test.py index a1a5baca530..23198efea01 100644 --- a/cirq-core/cirq/protocols/circuit_diagram_info_protocol_test.py +++ b/cirq-core/cirq/protocols/circuit_diagram_info_protocol_test.py @@ -208,6 +208,9 @@ def test_format_real(): assert args.format_real(sympy.Symbol('t')) == 't' assert args.format_real(sympy.Symbol('t') * 2 + 1) == '2*t + 1' + assert args.format_real(np.float64(1.1)) == '1.1' + assert args.format_real(np.int32(1)) == '1' + args.precision = None assert args.format_real(1) == '1' assert args.format_real(1.1) == '1.1' @@ -252,6 +255,7 @@ def test_format_radians_without_precision(): assert args.format_radians(-np.pi) == '-pi' assert args.format_radians(1.1) == '1.1' assert args.format_radians(1.234567) == '1.234567' + assert args.format_radians(np.float32(1.234567)) == '1.234567' assert args.format_radians(1 / 7) == repr(1 / 7) assert args.format_radians(sympy.Symbol('t')) == 't' assert args.format_radians(sympy.Symbol('t') * 2 + 1) == '2*t + 1' @@ -261,6 +265,7 @@ def test_format_radians_without_precision(): assert args.format_radians(-np.pi) == '-π' assert args.format_radians(1.1) == '1.1' assert args.format_radians(1.234567) == '1.234567' + assert args.format_radians(np.float32(1.234567)) == '1.234567' assert args.format_radians(1 / 7) == repr(1 / 7) assert args.format_radians(sympy.Symbol('t')) == 't' assert args.format_radians(sympy.Symbol('t') * 2 + 1) == '2*t + 1' diff --git a/cirq-core/cirq/protocols/json_serialization_test.py b/cirq-core/cirq/protocols/json_serialization_test.py index 82ac67b6278..15334d31f5c 100644 --- a/cirq-core/cirq/protocols/json_serialization_test.py +++ b/cirq-core/cirq/protocols/json_serialization_test.py @@ -55,6 +55,13 @@ class _ModuleDeprecation: 'non_existent_should_be_fine': None, } +# TODO(#6706) remove after cirq_rigetti supports NumPy 2.0 +if np.__version__.startswith("2."): # pragma: no cover + warnings.warn( + "json_serialization_test - ignoring cirq_rigetti due to incompatibility with NumPy 2.0" + ) + del TESTED_MODULES["cirq_rigetti"] + def _get_testspecs_for_modules() -> List[ModuleJsonTestSpec]: modules = [] diff --git a/cirq-core/cirq/qis/states.py b/cirq-core/cirq/qis/states.py index f38ec81d010..5d3803fe8f7 100644 --- a/cirq-core/cirq/qis/states.py +++ b/cirq-core/cirq/qis/states.py @@ -264,7 +264,7 @@ def quantum_state( dtype = DEFAULT_COMPLEX_DTYPE data = one_hot(index=state, shape=(dim,), dtype=dtype) else: - data = np.array(state, copy=False) + data = np.asarray(state) if qid_shape is None: qid_shape = infer_qid_shape(state) if data.ndim == 1 and data.dtype.kind != 'c': diff --git a/cirq-core/cirq/sim/simulator.py b/cirq-core/cirq/sim/simulator.py index 2608482b6a0..66104a43f5e 100644 --- a/cirq-core/cirq/sim/simulator.py +++ b/cirq-core/cirq/sim/simulator.py @@ -912,7 +912,7 @@ def __repr__(self) -> str: def __str__(self) -> str: def bitstring(vals): separator = ' ' if np.max(vals) >= 10 else '' - return separator.join(str(int(v)) for v in vals) + return separator.join(str(v.item()) for v in vals) results = sorted([(key, bitstring(val)) for key, val in self.measurements.items()]) if not results: diff --git a/cirq-core/cirq/sim/sparse_simulator_test.py b/cirq-core/cirq/sim/sparse_simulator_test.py index d07e95ecd86..b4445026e6d 100644 --- a/cirq-core/cirq/sim/sparse_simulator_test.py +++ b/cirq-core/cirq/sim/sparse_simulator_test.py @@ -115,7 +115,7 @@ def test_run_repetitions_terminal_measurement_stochastic(): q = cirq.LineQubit(0) c = cirq.Circuit(cirq.H(q), cirq.measure(q, key='q')) results = cirq.Simulator().run(c, repetitions=10000) - assert 1000 <= sum(v[0] for v in results.measurements['q']) < 9000 + assert 1000 <= np.count_nonzero(results.measurements['q']) < 9000 @pytest.mark.parametrize('dtype', [np.complex64, np.complex128]) @@ -255,7 +255,7 @@ def test_run_mixture(dtype: Type[np.complexfloating], split: bool): simulator = cirq.Simulator(dtype=dtype, split_untangled_states=split) circuit = cirq.Circuit(cirq.bit_flip(0.5)(q0), cirq.measure(q0)) result = simulator.run(circuit, repetitions=100) - assert 20 < sum(result.measurements['q(0)'])[0] < 80 + assert 20 < np.count_nonzero(result.measurements['q(0)']) < 80 @pytest.mark.parametrize('dtype', [np.complex64, np.complex128]) @@ -265,8 +265,8 @@ def test_run_mixture_with_gates(dtype: Type[np.complexfloating], split: bool): simulator = cirq.Simulator(dtype=dtype, split_untangled_states=split, seed=23) circuit = cirq.Circuit(cirq.H(q0), cirq.phase_flip(0.5)(q0), cirq.H(q0), cirq.measure(q0)) result = simulator.run(circuit, repetitions=100) - assert sum(result.measurements['q(0)'])[0] < 80 - assert sum(result.measurements['q(0)'])[0] > 20 + assert np.count_nonzero(result.measurements['q(0)']) < 80 + assert np.count_nonzero(result.measurements['q(0)']) > 20 @pytest.mark.parametrize('dtype', [np.complex64, np.complex128]) diff --git a/cirq-core/requirements.txt b/cirq-core/requirements.txt index b526c835455..fc39ec8c005 100644 --- a/cirq-core/requirements.txt +++ b/cirq-core/requirements.txt @@ -4,10 +4,10 @@ attrs>=21.3.0 duet>=0.2.8 matplotlib~=3.0 networkx>=2.4 -numpy~=1.22 +numpy>=1.24 pandas sortedcontainers~=2.0 -scipy~=1.0 +scipy~=1.8 sympy typing_extensions>=4.2 tqdm diff --git a/cirq-google/cirq_google/serialization/arg_func_langs.py b/cirq-google/cirq_google/serialization/arg_func_langs.py index b725f0b84e3..82104ad5a19 100644 --- a/cirq-google/cirq_google/serialization/arg_func_langs.py +++ b/cirq-google/cirq_google/serialization/arg_func_langs.py @@ -474,9 +474,9 @@ def clifford_tableau_arg_to_proto( msg = v2.program_pb2.CliffordTableau() if out is None else out msg.num_qubits = value.n msg.initial_state = value.initial_state - msg.xs.extend(value.xs.flatten()) - msg.rs.extend(value.rs.flatten()) - msg.zs.extend(value.zs.flatten()) + msg.xs.extend(map(bool, value.xs.flatten())) + msg.rs.extend(map(bool, value.rs.flatten())) + msg.zs.extend(map(bool, value.zs.flatten())) return msg diff --git a/conftest.py b/conftest.py index d61f5277b2b..668abd5efea 100644 --- a/conftest.py +++ b/conftest.py @@ -13,6 +13,7 @@ # limitations under the License. import pytest +import numpy as np def pytest_addoption(parser): @@ -25,6 +26,19 @@ def pytest_addoption(parser): parser.addoption( "--enable-slow-tests", action="store_true", default=False, help="run slow tests" ) + parser.addoption( + "--warn-numpy-data-promotion", + action="store_true", + default=False, + help="enable NumPy 2 data type promotion warnings", + ) + + +def pytest_configure(config): + # If requested, globally enable verbose NumPy 2 warnings about data type + # promotion. See https://numpy.org/doc/2.0/numpy_2_0_migration_guide.html. + if config.option.warn_numpy_data_promotion: + np._set_promotion_state("weak_and_warn") def pytest_collection_modifyitems(config, items): diff --git a/dev_tools/requirements/dev-np2.env.txt b/dev_tools/requirements/dev-np2.env.txt new file mode 100644 index 00000000000..6c86721cebe --- /dev/null +++ b/dev_tools/requirements/dev-np2.env.txt @@ -0,0 +1,17 @@ +# This file describes a development environment for cirq with NumPy-2 +# It skips cirq_rigetti which has dependencies incompatible with NumPy-2. +# +# TODO(#6706) remove this file after cirq_rigetti supports NumPy 2.0 + +# dev.env.txt expanded without cirq-rigetti ---------------------------------- + +-r ../../cirq-aqt/requirements.txt +-r ../../cirq-core/requirements.txt +-r ../../cirq-google/requirements.txt +-r ../../cirq-core/cirq/contrib/requirements.txt + +-r deps/dev-tools.txt + +# own rules ------------------------------------------------------------------ + +numpy>=2 diff --git a/examples/bb84.py b/examples/bb84.py index ffe5adcb584..dcaf1c82b58 100644 --- a/examples/bb84.py +++ b/examples/bb84.py @@ -128,7 +128,7 @@ def main(num_qubits=8): repetitions = 1 result = cirq.Simulator().run(program=circuit, repetitions=repetitions) - result_bitstring = bitstring([int(result.measurements[str(q)]) for q in qubits]) + result_bitstring = bitstring([result.measurements[str(q)].item() for q in qubits]) # Take only qubits where bases match obtained_key = ''.join( @@ -158,14 +158,14 @@ def main(num_qubits=8): # Run simulations. repetitions = 1 result = cirq.Simulator().run(program=alice_eve_circuit, repetitions=repetitions) - eve_state = [int(result.measurements[str(q)]) for q in qubits] + eve_state = [result.measurements[str(q)].item() for q in qubits] eve_bob_circuit = make_bb84_circ(num_qubits, eve_basis, bob_basis, eve_state) # Run simulations. repetitions = 1 result = cirq.Simulator().run(program=eve_bob_circuit, repetitions=repetitions) - result_bitstring = bitstring([int(result.measurements[str(q)]) for q in qubits]) + result_bitstring = bitstring([result.measurements[str(q)].item() for q in qubits]) # Take only qubits where bases match obtained_key = ''.join(