Skip to content

Commit

Permalink
treewide: Don't use numpy asfarray (#3158)
Browse files Browse the repository at this point in the history
Drop redundant uses.
Switch to 'asarray' for cases that provide explicit type.
Switch to 'asarray(..., dtype=float)' for all other cases.

Avoid type overflow in seed calculation.
  • Loading branch information
jvesely authored Jan 10, 2025
2 parents 047401e + c8eb799 commit 4a5472c
Show file tree
Hide file tree
Showing 17 changed files with 71 additions and 69 deletions.
4 changes: 2 additions & 2 deletions psyneulink/core/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -1425,7 +1425,7 @@ def _get_state_initializer(self, context):
def _convert(p):
x = p.get(context)
if p.name == 'matrix': # Flatten matrix
val = tuple(np.asfarray(x).flatten())
val = tuple(np.asarray(x, dtype=float).ravel())
elif isinstance(x, np.random.RandomState):
state = x.get_state(legacy=False)

Expand Down Expand Up @@ -1626,7 +1626,7 @@ def _get_values(p):
elif p.name == 'num_trials_per_estimate': # Should always be int
return 0 if param is None else int(param)
elif p.name == 'matrix': # Flatten matrix
return tuple(np.asfarray(param).flatten())
return tuple(np.asarray(param, dtype=float).ravel())
return _convert(param)

return tuple(map(_get_values, self._get_compilation_params()))
Expand Down
2 changes: 1 addition & 1 deletion psyneulink/core/components/functions/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ def convert_output_type(self, value, output_type=None):
# Note: if 2D or 1D array has more than two items, generate exception
elif output_type is FunctionOutputType.NP_0D_ARRAY:
if object_has_single_value(value):
value = np.asfarray(value)
value = np.asarray(value, dtype=float)
else:
raise FunctionError(f"Can't convert value ({value}) with more than a single number to a raw number.")

Expand Down
23 changes: 12 additions & 11 deletions psyneulink/core/components/functions/stateful/memoryfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1289,10 +1289,10 @@ def _parse_selection_function_variable(self, variable, context=None, distance_re
distance_result = self.distance_function(self._parse_distance_function_variable(variable), context=context)
# TEST PRINT:
# print(distance_result, self.distance_function.defaults.value)
return np.asfarray([
return np.asarray([
distance_result if i == 0 else np.zeros_like(distance_result)
for i in range(self.defaults.max_entries)
])
], dtype=float)

def _validate(self, context=None):
"""Validate distance_function, selection_function and memory store"""
Expand Down Expand Up @@ -1328,10 +1328,10 @@ def _validate(self, context=None):

# Default to full memory
selection_function = self.selection_function
test_var = np.asfarray([
test_var = np.asarray([
distance_result if i == 0 else np.zeros_like(distance_result)
for i in range(self._get_current_parameter_value('max_entries', context))
])
], dtype=float)
try:
result = np.asarray(selection_function(test_var, context=context))
except Exception as e:
Expand Down Expand Up @@ -2313,10 +2313,10 @@ def _parse_selection_function_variable(self, variable, context=None):
distance_result = self.distance_function.parameters.value._get(context)
# TEST PRINT:
# print(distance_result, self.distance_function.defaults.value)
return np.asfarray([
return np.asarray([
distance_result if i == 0 else np.zeros_like(distance_result)
for i in range(self.defaults.max_entries)
])
], dtype=float)

def _get_state_ids(self):
return super()._get_state_ids() + ["ring_memory"]
Expand Down Expand Up @@ -2553,9 +2553,10 @@ def _validate(self, context=None):

# Default to full memory
selection_function = self.selection_function
test_var = np.asfarray([distance_result if i==0
else np.zeros_like(distance_result)
for i in range(self._get_current_parameter_value('max_entries', context))])
test_var = np.asarray([distance_result if i==0 else np.zeros_like(distance_result)
for i in range(self._get_current_parameter_value('max_entries', context))],
dtype=float)

if isinstance(selection_function, type):
selection_function = selection_function(default_variable=test_var, context=context)
fct_string = 'Function type'
Expand Down Expand Up @@ -2709,12 +2710,12 @@ def _function(self,
# Store variable to dict:
rate = self._get_current_parameter_value(RATE, context)
if rate is not None:
key = np.asfarray(key) * np.asfarray(rate)
key = np.asarray(key, dtype=float) * np.asarray(rate, dtype=float)
assert len(key) == len(variable[KEYS]), "{} vs. {}".format(key, variable[KEYS])

if noise is not None:
# TODO: does val need noise?
key = np.asfarray(key) + np.asfarray(noise)[KEYS]
key = np.asarray(key, dtype=float) + np.asarray(noise, dtype=float)[KEYS]
assert len(key) == len(variable[KEYS]), "{} vs. {}".format(key, variable[KEYS])

if storage_prob == 1.0 or (storage_prob > 0.0 and storage_prob > random_state.uniform()):
Expand Down
8 changes: 4 additions & 4 deletions psyneulink/core/globals/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -1707,12 +1707,12 @@ def seed(self, seed):
assert False, "Use 'seed' parameter instead of seeding the random state directly"


_seed = np.int32((time.time() * 1000) % 2**31)
_seed = np.uint32((time.time() * 1000) % 2**31)
def get_global_seed(offset=1):
global _seed
_seed += offset
_seed %= 2**31
return _seed - offset
old_seed = _seed
_seed = (_seed + offset) % 2**31
return old_seed


def set_global_seed(new_seed):
Expand Down
4 changes: 2 additions & 2 deletions psyneulink/core/llvm/builder_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ def _param_struct(p):
if isinstance(val, ContentAddressableList):
return ir.LiteralStructType(self.get_param_struct_type(x) for x in val)
elif p.name == 'matrix': # Flatten matrix
val = np.asfarray(val).flatten()
val = np.asarray(val, dtype=float).ravel()
elif p.name == 'num_trials_per_estimate': # Should always be int
val = np.int32(0) if val is None else np.int32(val)
elif np.ndim(val) == 0 and component._is_param_modulated(p):
Expand All @@ -508,7 +508,7 @@ def _state_struct(p):
if isinstance(val, ContentAddressableList):
return ir.LiteralStructType(self.get_state_struct_type(x) for x in val)
if p.name == 'matrix': # Flatten matrix
val = np.asfarray(val).flatten()
val = np.asarray(val, dtype=float).ravel()
struct = self.convert_python_struct_to_llvm_ir(val)
return ir.ArrayType(struct, p.history_min_length + 1)

Expand Down
4 changes: 2 additions & 2 deletions psyneulink/core/llvm/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def _state_struct(self):
return self._get_compilation_param('_state', '_get_state_initializer', 1)

def execute(self, variable):
new_variable = np.asfarray(variable, dtype=self._bin_func.np_arg_dtypes[2].base)
new_variable = np.asarray(variable, dtype=self._bin_func.np_arg_dtypes[2].base)
data_in = new_variable.reshape(self._bin_func.np_arg_dtypes[2].shape)

data_out = self._bin_func.np_buffer_for_arg(3)
Expand All @@ -273,7 +273,7 @@ def execute(self, variable):

def cuda_execute(self, variable):
# Create input argument, PyCUDA doesn't care about shape
data_in = np.asfarray(variable, dtype=self._bin_func.np_arg_dtypes[2].base)
data_in = np.asarray(variable, dtype=self._bin_func.np_arg_dtypes[2].base)
data_out = self._bin_func.np_buffer_for_arg(3)

self._bin_func.cuda_call(self._cuda_param_struct,
Expand Down
2 changes: 2 additions & 0 deletions tests/composition/pec/test_stab_flex_pec_fit.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import psyneulink as pnl
import pytest

import optuna

Expand Down Expand Up @@ -384,6 +385,7 @@ def run_stab_flex_cond(

return comp, df

@pytest.mark.llvm
def test_stab_flex_cond_fit():
from psyneulink.core.globals.utilities import set_global_seed

Expand Down
4 changes: 2 additions & 2 deletions tests/composition/test_composition.py
Original file line number Diff line number Diff line change
Expand Up @@ -7267,8 +7267,8 @@ def test_save_state_before_simulations(self):
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]])
np.testing.assert_allclose(run_1_values, [[0.36], [0.056], [0.056]])
np.testing.assert_allclose(run_2_values, [[0.5904], [0.16384], [0.16384]])

def test_reset_clear_results(self):
mech = ProcessingMechanism(name='mech')
Expand Down
2 changes: 1 addition & 1 deletion tests/composition/test_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -3354,7 +3354,7 @@ def test_model_based_ocm(self, benchmark, controller_mode, result, mode, ocm_mod

def comp_run(inputs, execution_mode):
comp.run(inputs=inputs, execution_mode=execution_mode)
return comp.results.copy(), np.asfarray(ocm.function.saved_values)
return comp.results.copy(), np.asarray(ocm.function.saved_values)

results, saved_values = benchmark(comp_run, inputs, mode)

Expand Down
23 changes: 11 additions & 12 deletions tests/functions/test_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ def test_buffer_initializer_len_3(self, benchmark):
history=3)
np.testing.assert_allclose(B.execute(3.0), [[1.0], [2.0], np.array([3.])])
np.testing.assert_allclose(B.execute(4.0), [[2.0], np.array([3.]), np.array([4.])])

val = benchmark(B.execute, 5.0)
np.testing.assert_allclose(val, [np.array([3.]), np.array([4.]), np.array([5.])])
np.testing.assert_array_equal(val, [[3.], [4.], [5.]])

@pytest.mark.benchmark(group="BufferFunction")
def test_buffer_as_function_of_processing_mech(self, benchmark):
Expand All @@ -100,7 +101,7 @@ def test_buffer_as_function_of_processing_mech(self, benchmark):
val = benchmark(P.execute, 1.0)

# NOTE: actual output is [0, [[1]]]
np.testing.assert_allclose(np.asfarray(val, dtype=object), [[0., 1.]])
np.testing.assert_allclose(val, [[0., 1.]])

# fails due to value and variable problems when Buffer is the function of a mechanism
# P = ProcessingMechanism(function=Buffer(default_variable=[[0.0], [1.0], [2.0]],
Expand All @@ -121,17 +122,15 @@ def test_buffer_as_function_of_origin_mech_in_composition(self):
def assemble_full_result():
full_result.append(P.parameters.value.get(C))

C.run(inputs={P: [[1.0], [2.0], [3.0], [4.0], [5.0]]},
call_after_trial=assemble_full_result)
C.run(inputs={P: [[1.0], [2.0], [3.0], [4.0], [5.0]]}, call_after_trial=assemble_full_result)
# only returns index 0 item of the deque on each trial (OutputPort value)
np.testing.assert_allclose(np.asfarray(C.results), [[[0.0]], [[0.0]], [[1.0]], [[2.0]], [[3.0]]])
np.testing.assert_allclose(C.results, [[[0.0]], [[0.0]], [[1.0]], [[2.0]], [[3.0]]])

# stores full mechanism value (full deque) on each trial
expected_full_result = [np.array([[0.], [1.]]),
np.array([[0.], [1.], [2.]]),
np.array([[1.], [2.], [3.]]), # Shape change
np.array([[2.], [3.], [4.]]),
np.array([[3.], [4.], [5.]])]
expected_full_result = [[[0.], [1.]],
[[0.], [1.], [2.]],
[[1.], [2.], [3.]], # Shape change
[[2.], [3.], [4.]],
[[3.], [4.], [5.]]]
for i in range(5):
np.testing.assert_allclose(expected_full_result[i],
np.asfarray(full_result[i]))
np.testing.assert_array_equal(expected_full_result[i], full_result[i])
29 changes: 16 additions & 13 deletions tests/llvm/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ def test_helper_fclamp(mode):

builder.ret_void()

ref = np.clip(VECTOR, TST_MIN, TST_MAX)
bounds = np.asfarray([TST_MIN, TST_MAX])

bin_f = pnlvm.LLVMBinaryFunction.get(custom_name, ctype_ptr_args=(0, 2))
local_vec = VECTOR.copy()

ref = np.clip(VECTOR, TST_MIN, TST_MAX)
bounds = np.asarray([TST_MIN, TST_MAX], dtype=bin_f.np_arg_dtypes[2].base)

if mode == 'CPU':
ct_vec = local_vec.ctypes.data_as(bin_f.c_func.argtypes[0])
ct_bounds = bounds.ctypes.data_as(bin_f.c_func.argtypes[2])
Expand Down Expand Up @@ -141,8 +141,8 @@ def test_helper_is_close(mode, var1, var2, rtol, atol, fp_type):

bin_f = pnlvm.LLVMBinaryFunction.get(custom_name, ctype_ptr_args=(0, 1, 2))

vec1 = np.atleast_1d(np.asfarray(var1, dtype=bin_f.np_arg_dtypes[0].base))
vec2 = np.atleast_1d(np.asfarray(var2, dtype=bin_f.np_arg_dtypes[1].base))
vec1 = np.atleast_1d(np.asarray(var1, dtype=bin_f.np_arg_dtypes[0].base))
vec2 = np.atleast_1d(np.asarray(var2, dtype=bin_f.np_arg_dtypes[1].base))
assert len(vec1) == len(vec2)
res = np.empty_like(vec2)

Expand All @@ -163,8 +163,8 @@ def test_helper_is_close(mode, var1, var2, rtol, atol, fp_type):
@pytest.mark.parametrize('mode', ['CPU', pytest.helpers.cuda_param('PTX')])
@pytest.mark.parametrize('rtol,atol', [[0, 0], [None, None], [None, 100], [2, None]])
@pytest.mark.parametrize('var1,var2',
[[1, 1], [1, 100], [1,2], [-4,5], [0, -100], [-1,-2],
[[1,1,1,-4,0,-1], [1,100,2,5,-100,-2]]
[[1, 1], [1, 100], [1, 2], [-4, 5], [0, -100], [-1, -2],
[[1, 1, 1, -4, 0, -1], [1, 100, 2, 5, -100, -2]]
])
def test_helper_all_close(mode, var1, var2, atol, rtol):

Expand All @@ -174,8 +174,8 @@ def test_helper_all_close(mode, var1, var2, atol, rtol):
if atol is not None:
tolerance['atol'] = atol

vec1 = np.atleast_1d(np.asfarray(var1))
vec2 = np.atleast_1d(np.asfarray(var2))
vec1 = np.atleast_1d(var1)
vec2 = np.atleast_1d(var2)
assert len(vec1) == len(vec2)

with pnlvm.LLVMBuilderContext.get_current() as ctx:
Expand All @@ -194,6 +194,9 @@ def test_helper_all_close(mode, var1, var2, atol, rtol):
builder.ret_void()

bin_f = pnlvm.LLVMBinaryFunction.get(custom_name)
vec1 = np.atleast_1d(np.asarray(var1, dtype=bin_f.np_arg_dtypes[0].base))
vec2 = np.atleast_1d(np.asarray(var2, dtype=bin_f.np_arg_dtypes[1].base))
assert len(vec1) == len(vec2)
res = bin_f.np_buffer_for_arg(2)

ref = np.allclose(vec1, vec2, **tolerance)
Expand Down Expand Up @@ -438,7 +441,7 @@ def test_helper_numerical(mode, op, var, expected, fp_type):

bin_f = pnlvm.LLVMBinaryFunction.get(custom_name)

res = np.asfarray(var, dtype=bin_f.np_arg_dtypes[0])
res = np.asarray(var, dtype=bin_f.np_arg_dtypes[0])

if mode == 'CPU':
bin_f(res)
Expand Down Expand Up @@ -478,8 +481,8 @@ def test_helper_recursive_iterate_arrays(mode, var1, var2, expected):

bin_f = pnlvm.LLVMBinaryFunction.get(custom_name)

vec1 = np.asfarray(var1, dtype=bin_f.np_arg_dtypes[0].base)
vec2 = np.asfarray(var2, dtype=bin_f.np_arg_dtypes[1].base)
vec1 = np.asarray(var1, dtype=bin_f.np_arg_dtypes[0].base)
vec2 = np.asarray(var2, dtype=bin_f.np_arg_dtypes[1].base)
res = bin_f.np_buffer_for_arg(2)

if mode == 'CPU':
Expand Down Expand Up @@ -518,7 +521,7 @@ def test_helper_convert_fp_type(t1, t2, mode, val):
np_dt1, np_dt2 = (np.dtype(bin_f.np_arg_dtypes[i]) for i in (0, 1))

# instantiate value, result and reference
x = np.asfarray(val, dtype=np_dt1)
x = np.asarray(val, dtype=np_dt1)
y = bin_f.np_buffer_for_arg(1)
ref = x.astype(np_dt2)

Expand Down
2 changes: 1 addition & 1 deletion tests/mechanisms/test_control_mechanism.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def test_identicalness_of_control_and_gating(self):
# c.add_linear_processing_pathway(pathway=z)
comp.add_node(Control_Mechanism)

np.testing.assert_allclose(np.asfarray(Control_Mechanism.parameters.control_allocation.get()), [[0], [0], [0]])
np.testing.assert_allclose(Control_Mechanism.parameters.control_allocation.get(), [[0], [0], [0]])

stim_list = {
Input_Layer: [[-1, 30]],
Expand Down
25 changes: 11 additions & 14 deletions tests/mechanisms/test_ddm_mechanism.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_valid(self):
# returns previous_value + rate * variable * time_step_size + noise
# 0.0 + 1.0 * 1.0 * 1.0 + 0.0
D.execute(1.0)
np.testing.assert_allclose(np.asfarray(D.value), [[1.0], [1.0]])
np.testing.assert_array_equal(D.value, [[1.0], [1.0]])
np.testing.assert_allclose(D.output_ports[0].value[0], 1.0)
np.testing.assert_allclose(D.output_ports[1].value[0], 1.0)

Expand All @@ -38,7 +38,7 @@ def test_valid(self):
np.testing.assert_allclose(D.function.value[0], 2.0)
np.testing.assert_allclose(D.function.parameters.previous_value.get(), 2.0)
np.testing.assert_allclose(D.function.previous_time, 0.1)
np.testing.assert_allclose(np.asfarray(D.value), [[1.0], [1.0]])
np.testing.assert_array_equal(D.value, [[1.0], [1.0]])
np.testing.assert_allclose(D.output_ports[0].value[0], 1.0)
np.testing.assert_allclose(D.output_ports[1].value[0], 1.0)

Expand All @@ -47,7 +47,7 @@ def test_valid(self):
np.testing.assert_allclose(D.function.value[0], 0.0)
np.testing.assert_allclose(D.function.parameters.previous_value.get(), 0.0)
np.testing.assert_allclose(D.function.previous_time, 0.0)
np.testing.assert_allclose(np.asfarray(D.value), [[1.0], [1.0]])
np.testing.assert_array_equal(D.value, [[1.0], [1.0]])
np.testing.assert_allclose(D.output_ports[0].value[0], 1.0)
np.testing.assert_allclose(D.output_ports[1].value[0], 1.0)

Expand All @@ -56,13 +56,13 @@ def test_valid(self):
np.testing.assert_allclose(D.function.value[0], 2.0)
np.testing.assert_allclose(D.function.parameters.previous_value.get(), 2.0)
np.testing.assert_allclose(D.function.previous_time, 0.1)
np.testing.assert_allclose(np.asfarray(D.value), [[2.0], [0.1]])
np.testing.assert_array_equal(D.value, [[2.0], [0.1]])
np.testing.assert_allclose(D.output_ports[0].value, 2.0)
np.testing.assert_allclose(D.output_ports[1].value, 0.1)

D.execute(1.0)
# 2.0 + 1.0 = 3.0 ; 0.1 + 1.0 = 1.1
np.testing.assert_allclose(np.asfarray(D.value), [[3.0], [1.1]])
np.testing.assert_array_equal(D.value, [[3.0], [1.1]])
np.testing.assert_allclose(D.output_ports[0].value[0], 3.0)
np.testing.assert_allclose(D.output_ports[1].value[0], 1.1)

Expand Down Expand Up @@ -639,10 +639,7 @@ def test_DDM_in_composition(benchmark, comp_mode):
inputs = {M: [10]}
val = benchmark(C.run, inputs, num_trials=2, execution_mode=comp_mode)

# FIXME: Python version returns dtype=object
val = np.asfarray(val)
np.testing.assert_allclose(val[0], [2.0])
np.testing.assert_allclose(val[1], [0.2])
np.testing.assert_allclose(val, [[2.0], [0.2]])


@pytest.mark.composition
Expand Down Expand Up @@ -812,8 +809,8 @@ def test_DDMMechanism_LCA_equivalent(comp_mode):
ddm = DDM(default_variable=[0],
function=DriftDiffusionIntegrator(rate=1, time_step_size=0.1),
execute_until_finished=False)
comp2 = Composition()
comp2.add_node(ddm)
result2 = comp2.run(inputs={ddm:[1]}, execution_mode=comp_mode)
np.testing.assert_allclose(np.asfarray(result2[0]), [0.1])
np.testing.assert_allclose(np.asfarray(result2[1]), [0.1])
comp = Composition()
comp.add_node(ddm)
result = comp.run(inputs={ddm:[1]}, execution_mode=comp_mode)

np.testing.assert_allclose(result, [[0.1], [0.1]])
Loading

0 comments on commit 4a5472c

Please sign in to comment.