From da3c4fa328469511f6093bae3e48ec78a58faf8e Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Tue, 6 Jun 2023 12:51:41 -0400 Subject: [PATCH 1/4] utilities: Handle numpy 1.24 rugged arrays Numpy 1.24 removed the deprecated feature of creating dtype=object arrays in: 189eb6e38e78a06d86292b5d503de12fe2bebe38 ("DEP: Finalize ragged array creation deprecation") Signed-off-by: Jan Vesely --- psyneulink/core/globals/utilities.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/psyneulink/core/globals/utilities.py b/psyneulink/core/globals/utilities.py index ea8e1340e14..3261fd26c2e 100644 --- a/psyneulink/core/globals/utilities.py +++ b/psyneulink/core/globals/utilities.py @@ -1022,6 +1022,14 @@ def safe_create_np_array(value): return np.asarray(value) except np.VisibleDeprecationWarning: return np.asarray(value, dtype=object) + except ValueError as e: + # numpy 1.24 removed the above deprecation and raises + # ValueError instead. Note that the below call can still + # raise other ValueErrors + if 'The requested array has an inhomogeneous shape' in str(e): + return np.asarray(value, dtype=object) + raise + except ValueError as e: msg = str(e) if 'cannot guess the desired dtype from the input' in msg: From 51ff0686f96b462dd9f6f7fd93dc961635d4144d Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Tue, 6 Jun 2023 16:27:01 -0400 Subject: [PATCH 2/4] tests/save_state_before_simulations: Extract mechanism values to form homogeneous array Mechanism values are 2D so we need to index all three results to avoid rugged array. Signed-off-by: Jan Vesely --- tests/composition/test_composition.py | 29 +++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/tests/composition/test_composition.py b/tests/composition/test_composition.py index 4171655c2e2..ffdfb49d01a 100644 --- a/tests/composition/test_composition.py +++ b/tests/composition/test_composition.py @@ -6773,10 +6773,12 @@ def test_save_state_before_simulations(self): comp.run(inputs={A: [[1.0], [1.0]]}) + # All mechanism values are 2D but B has two elements, + # extract element 0 out of each. run_1_values = [ - A.parameters.value.get(comp), + A.parameters.value.get(comp)[0], B.parameters.value.get(comp)[0], - C.parameters.value.get(comp) + C.parameters.value.get(comp)[0] ] # "Save state" code from EVCaux @@ -6802,25 +6804,26 @@ def test_save_state_before_simulations(self): # Allow values to continue accumulating so that we can set them back to the saved state comp.run(inputs={A: [[1.0], [1.0]]}) - run_2_values = [A.parameters.value.get(comp), + # All mechanism values are 2D but B has two elements, + # extract element 0 out of each. + run_2_values = [A.parameters.value.get(comp)[0], B.parameters.value.get(comp)[0], - C.parameters.value.get(comp)] + C.parameters.value.get(comp)[0]] comp.run( inputs={A: [[1.0], [1.0]]}, reset_stateful_functions_to=reinitialization_values ) - run_3_values = [A.parameters.value.get(comp), + # All mechanism values are 2D but B has two elements, + # extract element 0 out of each. + run_3_values = [A.parameters.value.get(comp)[0], B.parameters.value.get(comp)[0], - C.parameters.value.get(comp)] - - np.testing.assert_allclose(np.asfarray(run_2_values), - np.asfarray(run_3_values)) - np.testing.assert_allclose(np.asfarray(run_1_values), - [np.array([0.36]), np.array([0.056]), np.array([0.056])]) - np.testing.assert_allclose(np.asfarray(run_2_values), - [np.array([0.5904]), np.array([0.16384]), np.array([0.16384])]) + C.parameters.value.get(comp)[0]] + + np.testing.assert_allclose(run_2_values, run_3_values) + np.testing.assert_allclose(np.asfarray(run_1_values), [[0.36], [0.056], [0.056]]) + np.testing.assert_allclose(np.asfarray(run_2_values), [[0.5904], [0.16384], [0.16384]]) class TestNodeRoles: From f4d1bddd21c05a28492bb5bb08675abedd0a406f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 02:57:01 +0000 Subject: [PATCH 3/4] requirements: update numpy requirement Updates the requirements on [numpy](https://github.com/numpy/numpy) to permit the latest version. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](https://github.com/numpy/numpy/compare/v1.19.0...v1.24.3) --- updated-dependencies: - dependency-name: numpy dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 47c9c2033c6..0212f37f1d8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ llvmlite<0.41 matplotlib<3.7.2 modeci_mdf<0.5, >=0.3.4; (platform_machine == 'AMD64' or platform_machine == 'x86_64') and platform_python_implementation == 'CPython' and implementation_name == 'cpython' networkx<3.2 -numpy>=1.19.0, <1.23.6 +numpy>=1.19.0, <1.24.4 optuna<3.2.0 packaging<24.0 pandas<2.0.3 From 50fc46fbc99e6b01c71c87997659db52aa10bc62 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Tue, 6 Jun 2023 22:30:11 -0400 Subject: [PATCH 4/4] llvm: Represent integer types as unsigned in ctype numpy >=1.24 is more sensitive to casting Python integers to numpy ints with restricted range (e.g. signed vs. unsigned). Most of our uses expect unsigned integers so switch to respective ctypes types. Signed-off-by: Jan Vesely --- psyneulink/core/llvm/builder_context.py | 8 ++++---- tests/llvm/test_builtins_mt_random.py | 4 ++-- tests/llvm/test_builtins_philox_random.py | 8 ++++---- tests/llvm/test_custom_func.py | 8 ++++---- tests/llvm/test_helpers.py | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/psyneulink/core/llvm/builder_context.py b/psyneulink/core/llvm/builder_context.py index cfb999d183c..9f831b75360 100644 --- a/psyneulink/core/llvm/builder_context.py +++ b/psyneulink/core/llvm/builder_context.py @@ -636,13 +636,13 @@ def _convert_llvm_ir_to_ctype(t: ir.Type): if t.width == 1: return ctypes.c_bool elif t.width == 8: - return ctypes.c_int8 + return ctypes.c_uint8 elif t.width == 16: - return ctypes.c_int16 + return ctypes.c_uint16 elif t.width == 32: - return ctypes.c_int32 + return ctypes.c_uint32 elif t.width == 64: - return ctypes.c_int64 + return ctypes.c_uint64 else: assert False, "Unknown integer type: {}".format(type_t) elif type_t is ir.DoubleType: diff --git a/tests/llvm/test_builtins_mt_random.py b/tests/llvm/test_builtins_mt_random.py index ff3711746e6..4d25e53c8cd 100644 --- a/tests/llvm/test_builtins_mt_random.py +++ b/tests/llvm/test_builtins_mt_random.py @@ -28,7 +28,7 @@ def f(): init_fun(state, SEED) gen_fun = pnlvm.LLVMBinaryFunction.get('__pnl_builtin_mt_rand_int32') - out = ctypes.c_longlong() + out = ctypes.c_ulonglong() def f(): gen_fun(state, out) return out.value @@ -39,7 +39,7 @@ def f(): init_fun.cuda_call(gpu_state, np.int32(SEED)) gen_fun = pnlvm.LLVMBinaryFunction.get('__pnl_builtin_mt_rand_int32') - out = np.asarray([0], dtype=np.int64) + out = np.asarray([0], dtype=np.uint64) gpu_out = pnlvm.jit_engine.pycuda.driver.Out(out) def f(): gen_fun.cuda_call(gpu_state, gpu_out) diff --git a/tests/llvm/test_builtins_philox_random.py b/tests/llvm/test_builtins_philox_random.py index fa921ef95ac..40fc1abc09a 100644 --- a/tests/llvm/test_builtins_philox_random.py +++ b/tests/llvm/test_builtins_philox_random.py @@ -19,7 +19,7 @@ def test_random_int64(benchmark, mode, seed, expected): res = [] if mode == 'numpy': - state = np.random.Philox([np.uint64(seed)]) + state = np.random.Philox([np.int64(seed).astype(np.uint64)]) prng = np.random.Generator(state) def f(): # Get uint range [0, MAX] to avoid any intermediate caching of random bits @@ -31,7 +31,7 @@ def f(): init_fun(state, seed) gen_fun = pnlvm.LLVMBinaryFunction.get('__pnl_builtin_philox_rand_int64') - out = ctypes.c_longlong() + out = ctypes.c_ulonglong() def f(): gen_fun(state, out) return np.uint64(out.value) @@ -75,10 +75,10 @@ def f(): init_fun(state, SEED) gen_fun = pnlvm.LLVMBinaryFunction.get('__pnl_builtin_philox_rand_int32') - out = ctypes.c_int() + out = ctypes.c_uint() def f(): gen_fun(state, out) - return np.uint32(out.value) + return out.value elif mode == 'PTX': init_fun = pnlvm.LLVMBinaryFunction.get('__pnl_builtin_philox_rand_init') state_size = ctypes.sizeof(init_fun.byref_arg_types[0]) diff --git a/tests/llvm/test_custom_func.py b/tests/llvm/test_custom_func.py index 406beb937c3..d15e65146ce 100644 --- a/tests/llvm/test_custom_func.py +++ b/tests/llvm/test_custom_func.py @@ -8,10 +8,10 @@ @pytest.mark.llvm @pytest.mark.parametrize('mode', ['CPU', pytest.param('PTX', marks=pytest.mark.cuda)]) -@pytest.mark.parametrize('val', [np.int8(0x7e), - np.int16(0x7eec), - np.int32(0x7eedbeee), - np.int64(0x7eedcafedeadbeee) +@pytest.mark.parametrize('val', [np.uint8(0x7e), + np.uint16(0x7eec), + np.uint32(0x7eedbeee), + np.uint64(0x7eedcafedeadbeee) ], ids=lambda x: str(x.dtype)) def test_integer_broadcast(mode, val): custom_name = None diff --git a/tests/llvm/test_helpers.py b/tests/llvm/test_helpers.py index ff8f9254ac6..0f7110ccf43 100644 --- a/tests/llvm/test_helpers.py +++ b/tests/llvm/test_helpers.py @@ -212,11 +212,11 @@ def test_helper_all_close(mode, var1, var2, atol, rtol): ct_ty = ctypes.POINTER(bin_f.byref_arg_types[0]) ct_vec1 = vec1.ctypes.data_as(ct_ty) ct_vec2 = vec2.ctypes.data_as(ct_ty) - res = ctypes.c_int32() + res = ctypes.c_uint32() bin_f(ct_vec1, ct_vec2, ctypes.byref(res)) else: - res = np.array([5], dtype=np.int32) + res = np.array([5], dtype=np.uint32) bin_f.cuda_wrap_call(vec1, vec2, res) res = res[0]