Skip to content

Commit

Permalink
Refactor/context/source (#765)
Browse files Browse the repository at this point in the history
* • Project:
  - implement all assignments to and tests against context regarding
    initialization and execution converted to context attribute

  - still need to implement message passing of context.source in place
    of context string for COMMAND_LINE and other circumstances
    (such as ADD_STATES, SET_ATTRIBUTES, RUN, etc.)

* • Project:
  - implement message passing of context.source in place of context

* - context = ContextFlags.CONSTRUCTOR complete

* -

* -

* - partway through implementing all context arguments as ContextFlags

* - partway through implementing all context arguments as ContextFlags

* - partway through implementing all context arguments as ContextFlags

* - partway through implementing all context arguments as ContextFlags

* cleaning up use of helper methods in FHNIntegratorFunction and updating context check to ContextFlags

* - partway through implementing all context arguments as ContextFlags

* -

* -

* -

* -

* -

* -

* -

* - passes all tests

* Merge branch 'devel' of https://github.com/PrincetonUniversity/PsyNeuLink into refactor/context/source_devel

# Conflicts:
#	psyneulink/components/component.py
#	psyneulink/components/functions/function.py
#	psyneulink/components/mechanisms/adaptive/control/controlmechanism.py
#	psyneulink/components/mechanisms/adaptive/control/defaultcontrolmechanism.py
#	psyneulink/components/mechanisms/adaptive/gating/gatingmechanism.py
#	psyneulink/components/mechanisms/adaptive/learning/learningauxiliary.py
#	psyneulink/components/mechanisms/adaptive/learning/learningmechanism.py
#	psyneulink/components/mechanisms/mechanism.py
#	psyneulink/components/mechanisms/processing/compositioninterfacemechanism.py
#	psyneulink/components/mechanisms/processing/defaultprocessingmechanism.py
#	psyneulink/components/mechanisms/processing/integratormechanism.py
#	psyneulink/components/mechanisms/processing/objectivemechanism.py
#	psyneulink/components/mechanisms/processing/processingmechanism.py
#	psyneulink/components/mechanisms/processing/transfermechanism.py
#	psyneulink/components/projections/modulatory/controlprojection.py
#	psyneulink/components/projections/modulatory/gatingprojection.py
#	psyneulink/components/projections/modulatory/learningprojection.py
#	psyneulink/components/projections/modulatory/modulatoryprojection.py
#	psyneulink/components/projections/pathway/mappingprojection.py
#	psyneulink/components/projections/pathway/pathwayprojection.py
#	psyneulink/components/projections/projection.py
#	psyneulink/components/shellclasses.py
#	psyneulink/components/states/parameterstate.py
#	psyneulink/components/states/state.py
#	psyneulink/globals/context.py
#	psyneulink/globals/environment.py
#	psyneulink/globals/log.py
#	psyneulink/library/mechanisms/adaptive/learning/autoassociativelearningmechanism.py
#	psyneulink/library/mechanisms/processing/integrator/ddm.py
#	psyneulink/library/mechanisms/processing/objective/comparatormechanism.py
#	psyneulink/library/mechanisms/processing/transfer/lca.py
#	psyneulink/library/mechanisms/processing/transfer/recurrenttransfermechanism.py
#	psyneulink/library/projections/pathway/autoassociativeprojection.py

* Merge branch 'devel' of https://github.com/PrincetonUniversity/PsyNeuLink into refactor/context/source_devel

# Conflicts:
#	psyneulink/components/component.py
#	psyneulink/components/functions/function.py
#	psyneulink/components/mechanisms/adaptive/control/controlmechanism.py
#	psyneulink/components/mechanisms/adaptive/control/defaultcontrolmechanism.py
#	psyneulink/components/mechanisms/adaptive/gating/gatingmechanism.py
#	psyneulink/components/mechanisms/adaptive/learning/learningauxiliary.py
#	psyneulink/components/mechanisms/adaptive/learning/learningmechanism.py
#	psyneulink/components/mechanisms/mechanism.py
#	psyneulink/components/mechanisms/processing/compositioninterfacemechanism.py
#	psyneulink/components/mechanisms/processing/defaultprocessingmechanism.py
#	psyneulink/components/mechanisms/processing/integratormechanism.py
#	psyneulink/components/mechanisms/processing/objectivemechanism.py
#	psyneulink/components/mechanisms/processing/processingmechanism.py
#	psyneulink/components/mechanisms/processing/transfermechanism.py
#	psyneulink/components/projections/modulatory/controlprojection.py
#	psyneulink/components/projections/modulatory/gatingprojection.py
#	psyneulink/components/projections/modulatory/learningprojection.py
#	psyneulink/components/projections/modulatory/modulatoryprojection.py
#	psyneulink/components/projections/pathway/mappingprojection.py
#	psyneulink/components/projections/pathway/pathwayprojection.py
#	psyneulink/components/projections/projection.py
#	psyneulink/components/shellclasses.py
#	psyneulink/components/states/parameterstate.py
#	psyneulink/components/states/state.py
#	psyneulink/globals/context.py
#	psyneulink/globals/environment.py
#	psyneulink/globals/log.py
#	psyneulink/library/mechanisms/adaptive/learning/autoassociativelearningmechanism.py
#	psyneulink/library/mechanisms/processing/integrator/ddm.py
#	psyneulink/library/mechanisms/processing/objective/comparatormechanism.py
#	psyneulink/library/mechanisms/processing/transfer/lca.py
#	psyneulink/library/mechanisms/processing/transfer/recurrenttransfermechanism.py
#	psyneulink/library/projections/pathway/autoassociativeprojection.py

* -

* -

* -

* -

* -

* -

* -

* • LCA, DDM:
  - _execute:  self.function -> super._execute()

* • InputState, ParameterState:
  - _execute:  self.function -> super._execute()

* -

* -

* -

* • Context
  context argument of all methods replaced with ContextFlag
  self.context.string used for human-readable descriptive information
  • Loading branch information
jdcpni authored Apr 29, 2018
1 parent bf3d16b commit bd9917b
Show file tree
Hide file tree
Showing 53 changed files with 794 additions and 922 deletions.
9 changes: 5 additions & 4 deletions .idea/runConfigurations/Scratch_Pad.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

92 changes: 57 additions & 35 deletions psyneulink/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ class `UserList <https://docs.python.org/3.6/library/collections.html?highlight=
import typecheck as tc

from psyneulink.globals.context import Context, ContextFlags, _get_time
from psyneulink.globals.keywords import COMMAND_LINE, COMPONENT_INIT, CONTEXT, CONTROL_PROJECTION, DEFERRED_INITIALIZATION, FUNCTION, FUNCTION_CHECK_ARGS, FUNCTION_PARAMS, INITIALIZING, INIT_FULL_EXECUTE_METHOD, INPUT_STATES, LEARNING, LEARNING_PROJECTION, LOG_ENTRIES, MATRIX, MODULATORY_SPEC_KEYWORDS, NAME, OUTPUT_STATES, PARAMS, PARAMS_CURRENT, PREFS_ARG, SEPARATOR_BAR, SET_ATTRIBUTE, SIZE, USER_PARAMS, VALUE, VARIABLE, kwComponentCategory
from psyneulink.globals.keywords import COMPONENT_INIT, CONTEXT, CONTROL_PROJECTION, DEFERRED_INITIALIZATION, FUNCTION, FUNCTION_CHECK_ARGS, FUNCTION_PARAMS, INITIALIZING, INIT_FULL_EXECUTE_METHOD, INPUT_STATES, LEARNING, LEARNING_PROJECTION, LOG_ENTRIES, MATRIX, MODULATORY_SPEC_KEYWORDS, NAME, OUTPUT_STATES, PARAMS, PARAMS_CURRENT, PREFS_ARG, SEPARATOR_BAR, SIZE, USER_PARAMS, VALUE, VARIABLE, kwComponentCategory
from psyneulink.globals.log import LogCondition
from psyneulink.globals.preferences.componentpreferenceset import ComponentPreferenceSet, kpVerbosePref
from psyneulink.globals.preferences.preferenceset import PreferenceEntry, PreferenceLevel, PreferenceSet
Expand Down Expand Up @@ -879,11 +879,9 @@ def __init__(self,
default_variable,
param_defaults,
size=NotImplemented, # 7/5/17 CW: this is a hack to check whether the user has passed in a size arg
name=None,
prefs=None,
context=None,
function=None,
):
name=None,
prefs=None):
"""Assign default preferences; enforce required params; validate and instantiate params and execute method
Initialization arguments:
Expand All @@ -907,16 +905,14 @@ def __init__(self,
# del self.init_args['self']
# # del self.init_args['__class__']
# return

context = context + INITIALIZING + ": " + COMPONENT_INIT # cxt-done
context = ContextFlags.COMPONENT
self.context.initialization_status = ContextFlags.INITIALIZING
self.context.execution_phase = None
if not self.context.source:
self.context.source = ContextFlags.COMPONENT
self.context.string = context + INITIALIZING + ": " + COMPONENT_INIT
self.context.string = "{}: {} {}".format(COMPONENT_INIT, INITIALIZING, self.name)

self.context.initialization_status = ContextFlags.INITIALIZING
# self.context.initialization_status = ContextFlags.UNSET

defaults = self.ClassDefaults.values().copy()
if param_defaults is not None:
Expand Down Expand Up @@ -1663,11 +1659,10 @@ def _check_args(self, variable=None, params=None, target_set=None, context=None)
# Validate variable if parameter_validation is set and the function was called with a variable
# IMPLEMENTATION NOTE: context is used here just for reporting; it is not tested in any of the methods called
if self.prefs.paramValidationPref and variable is not None:
if context:
context = context + SEPARATOR_BAR + FUNCTION_CHECK_ARGS
if self.context.string:
self.context.string = self.context.string + SEPARATOR_BAR + FUNCTION_CHECK_ARGS
else:
context = FUNCTION_CHECK_ARGS
self.context.string = context
self.context.string = FUNCTION_CHECK_ARGS
variable = self._update_variable(self._validate_variable(variable, context=context))

# PARAMS ------------------------------------------------------------
Expand Down Expand Up @@ -1827,7 +1822,7 @@ def _instantiate_defaults(self,

# VALIDATE VARIABLE (if not called from assign_params)

if not any(context_string in context for context_string in {COMMAND_LINE, SET_ATTRIBUTE}): # cxt-test
if not (context & (ContextFlags.COMMAND_LINE | ContextFlags.PROPERTY)):
# if variable has been passed then validate and, if OK, assign as self.instance_defaults.variable
variable = self._update_variable(self._validate_variable(variable, context=context))

Expand All @@ -1844,7 +1839,7 @@ def _instantiate_defaults(self,
raise ComponentError("Altering paramClassDefaults not permitted")

if default_set is None:
if any(context_string in context for context_string in {COMMAND_LINE, SET_ATTRIBUTE}): # cxt-test
if context & (ContextFlags.COMMAND_LINE | ContextFlags.PROPERTY):
default_set = {}
for param_name in request_set:
try:
Expand Down Expand Up @@ -1935,7 +1930,7 @@ def _instantiate_defaults(self,
# FUNCTION class has changed, so replace rather than update FUNCTION_PARAMS
if param_name is FUNCTION:
try:
if function_class != default_function_class and COMMAND_LINE in context: # cxt-test
if function_class != default_function_class and context & ContextFlags.COMMAND_LINE:
from psyneulink.components.functions.function import Function_Base
if isinstance(function, Function_Base):
request_set[FUNCTION] = function.__class__
Expand Down Expand Up @@ -2001,10 +1996,7 @@ def assign_params(self, request_set=None, context=None):
Instantiate any items in request set that require it (i.e., function or states).
"""
if context is None:
self.context.source = ContextFlags.COMMAND_LINE # cxt-push
self.context.string = COMMAND_LINE
context = context or COMMAND_LINE # cxt-done
context = context or ContextFlags.COMMAND_LINE
self._assign_params(request_set=request_set, context=context)

@tc.typecheck
Expand Down Expand Up @@ -2071,34 +2063,38 @@ def _assign_params(self, request_set:tc.optional(dict)=None, context=None):

validated_set_param_names = list(validated_set.keys())

curr_context = self.context.flags # cxt-buffer
curr_context = self.context.flags
curr_context_str = self.context.string

# If an input_state is being added from the command line,
# must _instantiate_attributes_before_function to parse input_states specification
# Otherwise, should not be run,
# as it induces an unecessary call to _instantatiate_parameter_states (during instantiate_input_states),
# that causes name-repetition problems when it is called as part of the standard init procedure
if INPUT_STATES in validated_set_param_names and COMMAND_LINE in context: # cxt-test
self.context.source = ContextFlags.COMMAND_LINE # cxt-push
self._instantiate_attributes_before_function(context=COMMAND_LINE) # cxt-done
if INPUT_STATES in validated_set_param_names and context & ContextFlags.COMMAND_LINE:
self.context.source = ContextFlags.COMMAND_LINE
self._instantiate_attributes_before_function(context=ContextFlags.COMMAND_LINE)
# Give owner a chance to instantiate function and/or function params
# (e.g., wrap in UserDefineFunction, as per EVCControlMechanism)
elif any(isinstance(param_value, (function_type, Function)) or
(inspect.isclass(param_value) and issubclass(param_value, Function))
for param_value in validated_set.values()):
self._instantiate_attributes_before_function()

# If the object's function is being assigned, and it is a class, instantiate it as a Function object
if FUNCTION in validated_set and inspect.isclass(self.function):
self.context.source = ContextFlags.COMMAND_LINE
self._instantiate_function(context=ContextFlags.COMMAND_LINE)
# FIX: WHY SHOULD IT BE CALLED DURING STANDRD INIT PROCEDURE?
# # MODIFIED 5/5/17 OLD:
# if OUTPUT_STATES in validated_set:
# MODIFIED 5/5/17 NEW: [THIS FAILS WITH A SPECIFICATION IN output_states ARG OF CONSTRUCTOR]
if OUTPUT_STATES in validated_set and COMMAND_LINE in context: # cxt-test
if OUTPUT_STATES in validated_set and context & ContextFlags.COMMAND_LINE:
# MODIFIED 5/5/17 END
self.context.source = COMMAND_LINE # cxt-push
self._instantiate_attributes_after_function(context=COMMAND_LINE) # cxt-done
self.context.source = ContextFlags.COMMAND_LINE
self._instantiate_attributes_after_function(context=ContextFlags.COMMAND_LINE)

self.context.flags = curr_context # cxt-pop
self.context.flags = curr_context
self.context.string = curr_context_str

def reset_params(self, mode=ResetMode.INSTANCE_TO_CLASS):
Expand Down Expand Up @@ -2703,18 +2699,47 @@ def execute(self, variable=None, runtime_params=None, context=None):

def _execute(self, variable=None, function_variable=None, runtime_params=None, context=None, **kwargs):

# GET/SET CONTEXT

from psyneulink.components.functions.function import Function
if isinstance(self, Function):
pass # Functions don't have a Logs or maintain execution_counts or time
else:
if self.context.initialization_status & ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING):
self._increment_execution_count()
self._update_current_execution_time(context=context) # cxt-pass
self._update_current_execution_time(context=context)

# If Component has a Function (function_object), assign Component's execution_phase to its context
try:
fct_context_attrib = self.function_object.context
# curr_context = self.context.execution_phase
curr_context = self.context.flags
except AttributeError:
# Otherwise if Component *is* a Function, assign its owner's execution_phase to its context
try:
fct_context_attrib = self.context
# curr_context = self.owner.context.execution_phase
curr_context = self.owner.context.flags
except AttributeError:
# Otherwise assign ContextFlags.PROCESSING as its execution_phase context
fct_context_attrib = self.context
# curr_context = ContextFlags.PROCESSING
fct_context_attrib.execution_phase = ContextFlags.PROCESSING
curr_context = self.context.flags
# fct_context_attrib.execution_phase = curr_context
fct_context_attrib.flags = curr_context

# CALL function

if function_variable is None:
function_variable = self._parse_function_variable(variable)
# IMPLEMENTATION NOTE: **kwargs is included to accommodate required arguments
# that are specific to particular class of Functions
# (e.g., error_matrix for LearningMechanism and controller for EVCControlMechanism)
return self.function(variable=function_variable, params=runtime_params, context=context, **kwargs)
value = self.function(variable=function_variable, params=runtime_params, context=context, **kwargs)
fct_context_attrib.execution_phase = ContextFlags.IDLE

return value

@property
def execution_count(self):
Expand Down Expand Up @@ -2749,7 +2774,7 @@ def _get_current_execution_time(self, context):
return _get_time(self, context_flags=_get_context(context))

def _update_current_execution_time(self, context):
self._current_execution_time = self._get_current_execution_time(context=context) # cxt-pass
self._current_execution_time = self._get_current_execution_time(context=context)

def _update_value(self, context=None):
"""Evaluate execute method
Expand Down Expand Up @@ -3092,10 +3117,7 @@ def getter(self):

def setter(self, val):
if self.paramValidationPref and hasattr(self, PARAMS_CURRENT):
val_type = val.__class__.__name__
curr_context = SET_ATTRIBUTE + ': ' + val_type + str(val) + ' for ' + name + ' of ' + self.name
# self.prev_context = "nonsense" + str(curr_context)
self._assign_params(request_set={name:val}, context=curr_context)
self._assign_params(request_set={name:val}, context=ContextFlags.PROPERTY)
else:
setattr(self, backing_field, val)

Expand Down
Loading

0 comments on commit bd9917b

Please sign in to comment.