From 8eedec0a1e686403b608d2536c1ba01bedb33723 Mon Sep 17 00:00:00 2001 From: Katherine Mantel Date: Fri, 26 Feb 2021 20:44:31 -0500 Subject: [PATCH] Component: set _needs_recompile flag for execution_id on parameter shape change --- psyneulink/core/components/component.py | 15 +++++++++++++ psyneulink/core/compositions/composition.py | 3 +++ psyneulink/core/globals/parameters.py | 25 ++++++++++++++++++++- psyneulink/core/llvm/execution.py | 2 ++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/psyneulink/core/components/component.py b/psyneulink/core/components/component.py index ab866f21576..1fa6a446eaf 100644 --- a/psyneulink/core/components/component.py +++ b/psyneulink/core/components/component.py @@ -2616,6 +2616,21 @@ def _set_multiple_parameter_values(self, context, **kwargs): for (k, v) in kwargs.items(): getattr(self.parameters, k)._set(v, context) + def _record_parameter_shapes(self, context, visited=None): + if visited is None: + visited = set([self]) + + if context is None: + context = self.most_recent_context + + for p in self.parameters: + p._record_shape(context) + + for obj in self._dependent_components: + if obj not in visited: + visited.add(obj) + obj._record_parameter_shapes(context, visited=visited) + # ------------------------------------------------------------------------------------------------------------------ # Parsing methods # ------------------------------------------------------------------------------------------------------------------ diff --git a/psyneulink/core/compositions/composition.py b/psyneulink/core/compositions/composition.py index e39375391d1..b9481a95db2 100644 --- a/psyneulink/core/compositions/composition.py +++ b/psyneulink/core/compositions/composition.py @@ -13156,6 +13156,9 @@ def _gen_llvm_function(self, *, ctx:pnlvm.LLVMBuilderContext, tags:frozenset): else: return pnlvm.codegen.gen_composition_exec(ctx, self, tags=tags) + def _delete_compilation_data(self, context): + self._compilation_data.execution.delete(context) + def enable_logging(self): for item in self.nodes + self.projections: if isinstance(item, Composition): diff --git a/psyneulink/core/globals/parameters.py b/psyneulink/core/globals/parameters.py index d9045cfb3c0..2873297dd9c 100644 --- a/psyneulink/core/globals/parameters.py +++ b/psyneulink/core/globals/parameters.py @@ -321,7 +321,7 @@ def _recurrent_transfer_mechanism_matrix_setter(value, owning_component=None, co from psyneulink.core.globals.context import Context, ContextError, ContextFlags, _get_time, handle_external_context from psyneulink.core.globals.context import time as time_object from psyneulink.core.globals.log import LogCondition, LogEntry, LogError -from psyneulink.core.globals.utilities import call_with_pruned_args, convert_all_elements_to_np_array, copy_iterable_with_shared, \ +from psyneulink.core.globals.utilities import call_with_pruned_args, convert_all_elements_to_np_array, copy_iterable_with_shared, extended_shape, \ get_alias_property_getter, get_alias_property_setter, get_deepcopy_with_shared, is_numeric, unproxy_weakproxy, create_union_set, safe_equals, get_function_sig_default_value, try_extract_0d_array_item from psyneulink.core.rpc.graph_pb2 import Entry, ndArray @@ -1003,6 +1003,7 @@ def __init__( _inherited_source=None, _user_specified=False, _scalar_converted=False, + _shape=None, **kwargs ): if isinstance(aliases, str): @@ -1065,6 +1066,7 @@ def __init__( _user_specified=_user_specified, _temp_uninherited=set(), _scalar_converted=_scalar_converted, + _shape=_shape, **kwargs ) @@ -1537,6 +1539,10 @@ def _set(self, value, context, skip_history=False, skip_log=False, **kwargs): return value def _set_value(self, value, execution_id=None, context=None, skip_history=False, skip_log=False, skip_delivery=False): + # before compilation has happened, we don't need to track shape changes + if self._shape is not None: + self._record_shape(context, value) + # store history if not skip_history: if execution_id in self.values: @@ -1765,6 +1771,23 @@ def _initialize_from_context(self, context=None, base_context=Context(execution_ except ParameterError as e: raise ParameterError('Error when attempting to initialize from {0}: {1}'.format(base_context.execution_id, e)) + def _record_shape(self, context, value=NotImplemented): + if value is NotImplemented: + value = self._get(context) + + try: + new_shape = extended_shape(value) + except TypeError: + new_shape = type(value) + + if self._shape is not None and new_shape != self._shape: + self._shape = new_shape + try: + for comp in self._owner._owner.compositions: + comp._delete_compilation_data(context) + except AttributeError: + pass + # KDM 7/30/18: the below is weird like this in order to use this like a property, but also include it # in the interface for user simplicity: that is, inheritable (by this Parameter's children or from its parent), # visible in a Parameter's repr, and easily settable by the user diff --git a/psyneulink/core/llvm/execution.py b/psyneulink/core/llvm/execution.py index e50967d32cb..2981f4ac980 100644 --- a/psyneulink/core/llvm/execution.py +++ b/psyneulink/core/llvm/execution.py @@ -399,6 +399,8 @@ def __init__(self, composition, execution_ids=[None], *, additional_tags=frozens @staticmethod def get(composition, context, additional_tags=frozenset()): + composition._record_parameter_shapes(context) + executions = composition._compilation_data.execution._get(context) if executions is None: executions = dict()