From ed92110ddc123a98a60f1c36ad8a5394f0c2a23b Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Fri, 23 Mar 2018 07:43:21 -0400 Subject: [PATCH 01/41] - --- psyneulink/globals/context.py | 85 ++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index f0d371a60b6..68dbf47eccc 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -106,53 +106,56 @@ class ContextStatus(IntEnum): Also used to specify the context in which a value of the Component or its attribute is `logged `. """ OFF = 0 - # """No recording.""" - INITIALIZATION = 1<<1 # 2 + """Not Initialized.""" + DEFERRED_INIT = 0 + """Not Initialized.""" + INITIALIZING = 1<<1 # 2 """Set during execution of the Component's constructor.""" - VALIDATION = 1<<2 # 4 + VALIDATING = 1<<2 # 4 """Set during validation of the value of a Component or its attribute.""" - EXECUTION = 1<<3 # 8 + INITIALIZED = 1<<3 # 8 """Set during any execution of the Component.""" - PROCESSING = 1<<4 # 16 - """Set during the `processing phase ` of execution of a Composition.""" - LEARNING = 1<<5 # 32 - """Set during the `learning phase ` of execution of a Composition.""" - CONTROL = 1<<6 # 64 - """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" - TRIAL = 1<<7 # 128 - """Set at the end of a `TRIAL`.""" - RUN = 1<<8 # 256 - """Set at the end of a `RUN`.""" - SIMULATION = 1<<9 # 512 - # Set during simulation by Composition.controller - COMMAND_LINE = 1<<10 # 1024 - # Component accessed by user CONSTRUCTOR = 1<<11 # 2048 - # Component being constructor (used in call to super.__init__) - ALL_ASSIGNMENTS = \ - INITIALIZATION | VALIDATION | EXECUTION | PROCESSING | LEARNING | CONTROL + # Component being constructed (used in call by subclass __init__ to super.__init__) """Specifies all contexts.""" - @classmethod - def _get_context_string(cls, condition, string=None): - """Return string with the names of all flags that are set in **condition**, prepended by **string**""" - if string: - string += ": " - else: - string = "" - flagged_items = [] - # If OFF or ALL_ASSIGNMENTS, just return that - if condition in (ContextStatus.ALL_ASSIGNMENTS, ContextStatus.OFF): - return condition.name - # Otherwise, append each flag's name to the string - for c in list(cls.__members__): - # Skip ALL_ASSIGNMENTS (handled above) - if c is ContextStatus.ALL_ASSIGNMENTS.name: - continue - if ContextStatus[c] & condition: - flagged_items.append(c) - string += ", ".join(flagged_items) - return string + # @classmethod + # def _get_context_string(cls, condition, string=None): + # """Return string with the names of all flags that are set in **condition**, prepended by **string**""" + # if string: + # string += ": " + # else: + # string = "" + # flagged_items = [] + # # If OFF or ALL_ASSIGNMENTS, just return that + # if condition in (ContextStatus.ALL_ASSIGNMENTS, ContextStatus.OFF): + # return condition.name + # # Otherwise, append each flag's name to the string + # for c in list(cls.__members__): + # # Skip ALL_ASSIGNMENTS (handled above) + # if c is ContextStatus.ALL_ASSIGNMENTS.name: + # continue + # if ContextStatus[c] & condition: + # flagged_items.append(c) + # string += ", ".join(flagged_items) + # return string + +class ContextExecutionPhase(IntEnum): + """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. + Also used to specify the context in which a value of the Component or its attribute is `logged `. + """ + IDLE = 0 + """Not currently executin.""" + PROCESSING = 1 + """Set during the `processing phase ` of execution of a Composition.""" + LEARNING = 2 + """Set during the `learning phase ` of execution of a Composition.""" + CONTROL = 3 + """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" + SIMULATION = 4 + """Set during simulation by Composition.controller""" + COMMAND_LINE = 5 + """Set when executed "manually" by user""" def _get_context(context): From d8942441b373601780587deb778988f80b9509b9 Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Fri, 23 Mar 2018 12:26:56 -0400 Subject: [PATCH 02/41] - --- psyneulink/components/component.py | 6 ++-- psyneulink/globals/context.py | 44 ++++++++++++++++++------------ 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/psyneulink/components/component.py b/psyneulink/components/component.py index e6201d60fd1..bbd136b83db 100644 --- a/psyneulink/components/component.py +++ b/psyneulink/components/component.py @@ -405,7 +405,7 @@ class `UserList `. """ - OFF = 0 + UNINITIALIZED = 0 """Not Initialized.""" - DEFERRED_INIT = 0 - """Not Initialized.""" - INITIALIZING = 1<<1 # 2 - """Set during execution of the Component's constructor.""" - VALIDATING = 1<<2 # 4 + DEFERRED_INIT = 1 + """Set if flagged for deferred initialization.""" + INITIALIZING = 2 + """Set during initialization of the Component.""" + VALIDATING = 3 """Set during validation of the value of a Component or its attribute.""" - INITIALIZED = 1<<3 # 8 - """Set during any execution of the Component.""" - CONSTRUCTOR = 1<<11 # 2048 - # Component being constructed (used in call by subclass __init__ to super.__init__) - """Specifies all contexts.""" + INITIALIZED = 4 + """Set after completion of initialization of the Component.""" + +class Source(IntEnum): + CONSTRUCTOR = 0 + """Call to method from Component's constructor.""" + COMMAND_LINE = 1 + """Direct call to method by user (either interactively from the command line, or in a script).""" + COMPONENT = 2 + """Call to method by the Component.""" + COMPOSITION = 3 + """Call to method by a/the Composition to which the Component belongs.""" # @classmethod # def _get_context_string(cls, condition, string=None): @@ -140,7 +153,7 @@ class ContextStatus(IntEnum): # string += ", ".join(flagged_items) # return string -class ContextExecutionPhase(IntEnum): +class ExecutionPhase(IntEnum): """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. Also used to specify the context in which a value of the Component or its attribute is `logged `. """ @@ -154,9 +167,6 @@ class ContextExecutionPhase(IntEnum): """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" SIMULATION = 4 """Set during simulation by Composition.controller""" - COMMAND_LINE = 5 - """Set when executed "manually" by user""" - def _get_context(context): From eadd37f471d04f2a1e620caebfa26cff99358213 Mon Sep 17 00:00:00 2001 From: jdc Date: Fri, 23 Mar 2018 13:06:55 -0400 Subject: [PATCH 03/41] - --- Scripts/Examples/EVC-Gratton.py | 2 +- psyneulink/components/component.py | 20 +- psyneulink/components/mechanisms/mechanism.py | 20 +- psyneulink/components/process.py | 22 +- .../modulatory/learningprojection.py | 6 +- .../modulatory/modulatoryprojection.py | 2 +- .../projections/pathway/mappingprojection.py | 6 +- .../components/projections/projection.py | 2 +- psyneulink/components/states/inputstate.py | 6 +- .../states/modulatorysignals/controlsignal.py | 6 +- .../states/modulatorysignals/gatingsignal.py | 6 +- .../modulatorysignals/learningsignal.py | 6 +- psyneulink/components/states/outputstate.py | 6 +- psyneulink/components/system.py | 32 +-- psyneulink/globals/context.py | 200 ++++++++++-------- psyneulink/globals/environment.py | 18 +- psyneulink/globals/log.py | 108 +++++----- .../preferences/componentpreferenceset.py | 16 +- .../transfer/recurrenttransfermechanism.py | 6 +- .../library/subsystems/evc/evcauxiliary.py | 4 +- tests/log/test_log.py | 2 +- 21 files changed, 258 insertions(+), 238 deletions(-) diff --git a/Scripts/Examples/EVC-Gratton.py b/Scripts/Examples/EVC-Gratton.py index 239e8b0c715..c3b865d00dc 100644 --- a/Scripts/Examples/EVC-Gratton.py +++ b/Scripts/Examples/EVC-Gratton.py @@ -193,7 +193,7 @@ mySystem.controller.reportOutputPref = True -Flanker_Rep.set_log_conditions((pnl.SLOPE, pnl.ContextStatus.CONTROL)) +Flanker_Rep.set_log_conditions((pnl.SLOPE, pnl.ContextFlags.CONTROL)) mySystem.run( num_trials=nTrials, diff --git a/psyneulink/components/component.py b/psyneulink/components/component.py index bbd136b83db..0ff207575f0 100644 --- a/psyneulink/components/component.py +++ b/psyneulink/components/component.py @@ -405,7 +405,7 @@ class `UserList ` and their current `ContextStatus`. + """Diciontary of items that can be logged in the Component's `log ` and their current `ContextFlags`. This is a convenience method that calls the `loggable_items ` property of the Component's `log `. """ return self.log.loggable_items - from psyneulink.globals.log import ContextStatus - def set_log_conditions(self, items, log_condition=ContextStatus.EXECUTION): + from psyneulink.globals.log import ContextFlags + def set_log_conditions(self, items, log_condition=ContextFlags.EXECUTION): """ set_log_conditions( \ items \ @@ -3130,7 +3130,7 @@ def log_values(self, entries): @property def logged_items(self): - """Dictionary of all items that have entries in the log, and their currently assigned `ContextStatus`\\s + """Dictionary of all items that have entries in the log, and their currently assigned `ContextFlags`\\s This is a convenience method that calls the `logged_items ` property of the Component's `log `. """ diff --git a/psyneulink/components/mechanisms/mechanism.py b/psyneulink/components/mechanisms/mechanism.py index 5faac8e7863..e793e1e6986 100644 --- a/psyneulink/components/mechanisms/mechanism.py +++ b/psyneulink/components/mechanisms/mechanism.py @@ -801,7 +801,7 @@ class `UserList 0: @@ -2115,7 +2115,7 @@ def execute( if not context: # cxt-test context = EXECUTING + " " + PROCESS + " " + self.name # cxt-done - self.context.status = ContextStatus.EXECUTION + self.context.status = ContextFlags.EXECUTION self.context.string = EXECUTING + " " + PROCESS + " " + self.name self.execution_status = ExecutionStatus.EXECUTING from psyneulink.globals.environment import _get_unique_id @@ -2215,8 +2215,8 @@ def _execute_learning(self, target=None, context=None): # FINALLY, execute LearningProjections to MappingProjections in the process' pathway for mech in self._mechs: - mech.context.status &= ~ContextStatus.EXECUTION - mech.context.status |= ContextStatus.LEARNING + mech.context.status &= ~ContextFlags.EXECUTION + mech.context.status |= ContextFlags.LEARNING mech.context.string = self.context.string.replace(EXECUTING, LEARNING + ' ') # IMPLEMENTATION NOTE: @@ -2249,16 +2249,16 @@ def _execute_learning(self, target=None, context=None): # Note: do this rather just calling LearningSignals directly # since parameter_state.update() handles parsing of LearningProjection-specific params context = context.replace(EXECUTING, LEARNING + ' ') # cxt-done cxt-pass ? cxt-push - parameter_state.context.status &= ~ContextStatus.EXECUTION - parameter_state.context.status |= ContextStatus.LEARNING + parameter_state.context.status &= ~ContextFlags.EXECUTION + parameter_state.context.status |= ContextFlags.LEARNING parameter_state.context.string = self.context.string.replace(EXECUTING, LEARNING + ' ') # NOTE: This will need to be updated when runtime params are re-enabled # parameter_state.update(params=params, context=context) parameter_state.update(context=context) # cxt-pass cxt-push - parameter_state.context.status &= ~ContextStatus.LEARNING - parameter_state.context.status |= ContextStatus.EXECUTION + parameter_state.context.status &= ~ContextFlags.LEARNING + parameter_state.context.status |= ContextFlags.EXECUTION parameter_state.context.string = self.context.string.replace(LEARNING, EXECUTING) # Not all Projection subclasses instantiate ParameterStates @@ -2270,8 +2270,8 @@ def _execute_learning(self, target=None, context=None): "while attempting to update {} {} of {}". format(e.args[0], parameter_state.name, ParameterState.__name__, projection.name)) - mech.context.status &= ~ContextStatus.LEARNING - mech.context.status |= ContextStatus.EXECUTION + mech.context.status &= ~ContextFlags.LEARNING + mech.context.status |= ContextFlags.EXECUTION mech.context.string = self.context.string.replace(LEARNING, EXECUTING) diff --git a/psyneulink/components/projections/modulatory/learningprojection.py b/psyneulink/components/projections/modulatory/learningprojection.py index fd23f106bf3..e16c5ad9999 100644 --- a/psyneulink/components/projections/modulatory/learningprojection.py +++ b/psyneulink/components/projections/modulatory/learningprojection.py @@ -181,7 +181,7 @@ PARAMETER_STATE, PARAMETER_STATES, PROJECTION_SENDER, SLOPE from psyneulink.globals.preferences.componentpreferenceset import is_pref_set from psyneulink.globals.preferences.preferenceset import PreferenceLevel -from psyneulink.globals.context import ContextStatus +from psyneulink.globals.context import ContextFlags from psyneulink.globals.utilities import iscompatible, parameter_spec __all__ = [ @@ -651,9 +651,9 @@ def _execute(self, variable, runtime_params=None, context=None): self.receiver.owner.name, matrix)) if EXECUTING in context: # cxt-test - self.context.status = ContextStatus.EXECUTION + self.context.status = ContextFlags.EXECUTION elif LEARNING in context: # cxt-test - self.context.status = ContextStatus.LEARNING + self.context.status = ContextFlags.LEARNING # # MODIFIED 3/20/18 OLD: # self.weight_change_matrix = self.function( diff --git a/psyneulink/components/projections/modulatory/modulatoryprojection.py b/psyneulink/components/projections/modulatory/modulatoryprojection.py index d4827120e73..ed733773b1b 100644 --- a/psyneulink/components/projections/modulatory/modulatoryprojection.py +++ b/psyneulink/components/projections/modulatory/modulatoryprojection.py @@ -86,7 +86,7 @@ from psyneulink.components.component import InitStatus from psyneulink.components.projections.projection import Projection_Base from psyneulink.globals.keywords import EXECUTING, INITIALIZING, MODULATORY_PROJECTION, NAME, kwAssign -from psyneulink.globals.log import LogEntry, ContextStatus +from psyneulink.globals.log import LogEntry, ContextFlags __all__ = [ diff --git a/psyneulink/components/projections/pathway/mappingprojection.py b/psyneulink/components/projections/pathway/mappingprojection.py index 23604332ad7..8ec25425a5b 100644 --- a/psyneulink/components/projections/pathway/mappingprojection.py +++ b/psyneulink/components/projections/pathway/mappingprojection.py @@ -265,7 +265,7 @@ from psyneulink.components.projections.projection import ProjectionError, Projection_Base, projection_keywords from psyneulink.components.states.outputstate import OutputState from psyneulink.globals.keywords import AUTO_ASSIGN_MATRIX, CHANGED, DEFAULT_MATRIX, EXECUTING, FULL_CONNECTIVITY_MATRIX, FUNCTION, FUNCTION_PARAMS, HOLLOW_MATRIX, IDENTITY_MATRIX, INITIALIZING, INPUT_STATE, LEARNING, LEARNING_PROJECTION, MAPPING_PROJECTION, MATRIX, OUTPUT_STATE, PROCESS_INPUT_STATE, PROJECTION_SENDER, SYSTEM_INPUT_STATE, VALUE, kwAssign -from psyneulink.globals.log import ContextStatus, LogEntry +from psyneulink.globals.log import ContextFlags, LogEntry from psyneulink.globals.preferences.componentpreferenceset import is_pref_set from psyneulink.globals.preferences.preferenceset import PreferenceEntry, PreferenceLevel @@ -626,8 +626,8 @@ def _execute(self, variable=None, runtime_params=None, context=None): """ if EXECUTING in context: # cxt-test - self.context.status &= ~(ContextStatus.VALIDATION | ContextStatus.INITIALIZATION) - self.context.status |= ContextStatus.EXECUTION + self.context.status &= ~(ContextFlags.VALIDATION | ContextFlags.INITIALIZATION) + self.context.status |= ContextFlags.EXECUTION self.context.string = context # (7/18/17 CW) note that we don't let MappingProjections related to System inputs execute here (due to a diff --git a/psyneulink/components/projections/projection.py b/psyneulink/components/projections/projection.py index acb87a5725c..de87c40bdb8 100644 --- a/psyneulink/components/projections/projection.py +++ b/psyneulink/components/projections/projection.py @@ -400,7 +400,7 @@ kwAddInputState, kwAddOutputState, kwProjectionComponentCategory from psyneulink.globals.registry import register_category from psyneulink.globals.preferences.preferenceset import PreferenceLevel -from psyneulink.globals.context import ContextStatus +from psyneulink.globals.context import ContextFlags from psyneulink.globals.utilities import ContentAddressableList, is_matrix, is_numeric, iscompatible, type_match __all__ = [ diff --git a/psyneulink/components/states/inputstate.py b/psyneulink/components/states/inputstate.py index 7bf97d059ea..0115d35d638 100644 --- a/psyneulink/components/states/inputstate.py +++ b/psyneulink/components/states/inputstate.py @@ -468,7 +468,7 @@ from psyneulink.globals.keywords import COMMAND_LINE, EXPONENT, FUNCTION, GATING_SIGNAL, INPUT_STATE, INPUT_STATES, INPUT_STATE_PARAMS, LEARNING_SIGNAL, MAPPING_PROJECTION, MATRIX, MECHANISM, OUTPUT_STATE, OUTPUT_STATES, PROCESS_INPUT_STATE, PROJECTIONS, PROJECTION_TYPE, REFERENCE_VALUE, SENDER, SUM, SYSTEM_INPUT_STATE, VARIABLE, WEIGHT from psyneulink.globals.preferences.componentpreferenceset import is_pref_set from psyneulink.globals.preferences.preferenceset import PreferenceLevel -from psyneulink.globals.context import ContextStatus +from psyneulink.globals.context import ContextFlags from psyneulink.globals.utilities import append_type_to_name, is_numeric, iscompatible __all__ = [ @@ -714,11 +714,11 @@ def __init__(self, if context is None: # cxt-test context = COMMAND_LINE # cxt-done - self.context.status = ContextStatus.COMMAND_LINE + self.context.status = ContextFlags.COMMAND_LINE self.context.string = COMMAND_LINE else: context = self # cxt-done - self.context.status = ContextStatus.CONSTRUCTOR + self.context.status = ContextFlags.CONSTRUCTOR if variable is None and size is None and projections is not None: variable = self._assign_variable_from_projection(variable, size, projections) diff --git a/psyneulink/components/states/modulatorysignals/controlsignal.py b/psyneulink/components/states/modulatorysignals/controlsignal.py index 16cbef100c8..c0a99caf586 100644 --- a/psyneulink/components/states/modulatorysignals/controlsignal.py +++ b/psyneulink/components/states/modulatorysignals/controlsignal.py @@ -310,7 +310,7 @@ from psyneulink.globals.keywords import ALLOCATION_SAMPLES, AUTO, COMMAND_LINE, CONTROLLED_PARAMS, CONTROL_PROJECTION, CONTROL_SIGNAL, EXECUTING, FUNCTION, FUNCTION_PARAMS, INTERCEPT, OFF, ON, OUTPUT_STATE_PARAMS, PARAMETER_STATE, PARAMETER_STATES, PROJECTION_TYPE, RECEIVER, SEPARATOR_BAR, SLOPE, SUM, kwAssign from psyneulink.globals.preferences.componentpreferenceset import is_pref_set from psyneulink.globals.preferences.preferenceset import PreferenceLevel -from psyneulink.globals.context import ContextStatus +from psyneulink.globals.context import ContextFlags from psyneulink.globals.utilities import is_numeric, iscompatible, kwCompatibilityLength, kwCompatibilityNumeric, kwCompatibilityType __all__ = [ @@ -684,11 +684,11 @@ def __init__(self, if context is None: # cxt-test context = COMMAND_LINE # cxt-done - self.context.status = ContextStatus.COMMAND_LINE + self.context.status = ContextFlags.COMMAND_LINE self.context.string = COMMAND_LINE else: context = self # cxt-done - self.context.status = ContextStatus.CONSTRUCTOR + self.context.status = ContextFlags.CONSTRUCTOR # Note index and assign are not used by ControlSignal, but included here for consistency with OutputState if params and ALLOCATION_SAMPLES in params and params[ALLOCATION_SAMPLES] is not None: diff --git a/psyneulink/components/states/modulatorysignals/gatingsignal.py b/psyneulink/components/states/modulatorysignals/gatingsignal.py index 31965cc58d0..18a9e764a56 100644 --- a/psyneulink/components/states/modulatorysignals/gatingsignal.py +++ b/psyneulink/components/states/modulatorysignals/gatingsignal.py @@ -237,7 +237,7 @@ from psyneulink.components.states.state import State_Base, _get_state_for_socket, _parse_state_type from psyneulink.globals.keywords import COMMAND_LINE, GATE, GATING_PROJECTION, GATING_SIGNAL, INPUT_STATE, INPUT_STATES, OUTPUT_STATE, OUTPUT_STATES, OUTPUT_STATE_PARAMS, PROJECTIONS, PROJECTION_TYPE, RECEIVER, SUM from psyneulink.globals.preferences.componentpreferenceset import is_pref_set -from psyneulink.globals.context import ContextStatus +from psyneulink.globals.context import ContextFlags from psyneulink.globals.preferences.preferenceset import PreferenceLevel __all__ = [ @@ -428,11 +428,11 @@ def __init__(self, if context is None: # cxt-test context = COMMAND_LINE # cxt-done - self.context.status = ContextStatus.COMMAND_LINE + self.context.status = ContextFlags.COMMAND_LINE self.context.string = COMMAND_LINE else: context = self # cxt-done - self.context.status = ContextStatus.CONSTRUCTOR + self.context.status = ContextFlags.CONSTRUCTOR # Note: assign is not currently used by GatingSignal; # it is included here for consistency with OutputState and possible use by subclasses. diff --git a/psyneulink/components/states/modulatorysignals/learningsignal.py b/psyneulink/components/states/modulatorysignals/learningsignal.py index 5e6d4dad2d6..8ee8e710ce7 100644 --- a/psyneulink/components/states/modulatorysignals/learningsignal.py +++ b/psyneulink/components/states/modulatorysignals/learningsignal.py @@ -179,7 +179,7 @@ PROJECTION_TYPE, RECEIVER, OUTPUT_STATE_PARAMS, PARAMETER_STATE, PARAMETER_STATES, SUM from psyneulink.globals.preferences.componentpreferenceset import is_pref_set from psyneulink.globals.preferences.preferenceset import PreferenceLevel -from psyneulink.globals.context import ContextStatus +from psyneulink.globals.context import ContextFlags from psyneulink.globals.utilities import parameter_spec __all__ = [ @@ -373,11 +373,11 @@ def __init__(self, if context is None: # cxt-test context = COMMAND_LINE # cxt-done - self.context.status = ContextStatus.COMMAND_LINE + self.context.status = ContextFlags.COMMAND_LINE self.context.string = COMMAND_LINE else: context = self # cxt-done - self.context.status = ContextStatus.CONSTRUCTOR + self.context.status = ContextFlags.CONSTRUCTOR # Assign args to params and functionParams dicts (kwConstants must == arg names) params = self._assign_args_to_param_dicts(function=function, diff --git a/psyneulink/components/states/outputstate.py b/psyneulink/components/states/outputstate.py index 2aec2d8318c..1d0a45ac0b2 100644 --- a/psyneulink/components/states/outputstate.py +++ b/psyneulink/components/states/outputstate.py @@ -604,7 +604,7 @@ VALUE, VARIABLE, VARIANCE from psyneulink.globals.preferences.componentpreferenceset import is_pref_set from psyneulink.globals.preferences.preferenceset import PreferenceLevel -from psyneulink.globals.context import ContextStatus +from psyneulink.globals.context import ContextFlags from psyneulink.globals.utilities import UtilitiesError, is_numeric, iscompatible, type_match, recursive_update __all__ = [ @@ -890,11 +890,11 @@ def __init__(self, if context is None: # cxt-test context = COMMAND_LINE # cxt-done - self.context.status = ContextStatus.COMMAND_LINE + self.context.status = ContextFlags.COMMAND_LINE self.context.string = COMMAND_LINE else: context = self # cxt-done - self.context.status = ContextStatus.CONSTRUCTOR + self.context.status = ContextFlags.CONSTRUCTOR # For backward compatibility with CALCULATE, ASSIGN and INDEX if 'calculate' in kwargs: diff --git a/psyneulink/components/system.py b/psyneulink/components/system.py index 77fe2a293c5..ff20e9b3155 100644 --- a/psyneulink/components/system.py +++ b/psyneulink/components/system.py @@ -456,7 +456,7 @@ from psyneulink.globals.preferences.componentpreferenceset import is_pref_set from psyneulink.globals.preferences.preferenceset import PreferenceLevel from psyneulink.globals.registry import register_category -from psyneulink.globals.context import ContextStatus +from psyneulink.globals.context import ContextFlags from psyneulink.globals.utilities import AutoNumber, ContentAddressableList, append_type_to_name, convert_to_np_array, insert_list, iscompatible from psyneulink.scheduling.scheduler import Scheduler from psyneulink.components.mechanisms.processing.objectivemechanism import ObjectiveMechanism @@ -860,7 +860,7 @@ def __init__(self, if not context: # cxt-test context = INITIALIZING + self.name + kwSeparator + SYSTEM_INIT # cxt-done - self.context.status = ContextStatus.INITIALIZATION + self.context.status = ContextFlags.INITIALIZATION self.context.string = INITIALIZING + self.name + kwSeparator + SYSTEM_INIT super().__init__(default_variable=default_variable, size=size, @@ -2519,7 +2519,7 @@ def execute(self, if not context: # cxt-test context = EXECUTING + " " + SYSTEM + " " + self.name # cxt-done - self.context.status = ContextStatus.EXECUTION + self.context.status = ContextFlags.EXECUTION self.context.string = EXECUTING + " " + SYSTEM + " " + self.name self.execution_status = ExecutionStatus.EXECUTING @@ -2619,14 +2619,14 @@ def execute(self, # Don't execute learning for simulation runs if not EVC_SIMULATION in context and self.learning: # cxt-test - # self.context.status &= ~ContextStatus.EXECUTION - self.context.status |= ContextStatus.LEARNING + # self.context.status &= ~ContextFlags.EXECUTION + self.context.status |= ContextFlags.LEARNING self.context.string = self.context.string.replace(EXECUTING, LEARNING + ' ') self._execute_learning(context=context.replace(EXECUTING, LEARNING + ' ')) - self.context.status &= ~ContextStatus.LEARNING - # self.context.status |= ContextStatus.EXECUTION + self.context.status &= ~ContextFlags.LEARNING + # self.context.status |= ContextFlags.EXECUTION self.context.string = self.context.string.replace(LEARNING, EXECUTING) # endregion @@ -2775,8 +2775,8 @@ def _execute_learning(self, context=None): re.sub(r'[\[,\],\n]','',str(process_names)))) # cxt-set cxt-push cxt-pass component.context.composition = self - component.context.status &= ~ContextStatus.EXECUTION - component.context.status |= ContextStatus.LEARNING + component.context.status &= ~ContextFlags.EXECUTION + component.context.status |= ContextFlags.LEARNING component.context.string = context_str # Note: DON'T include input arg, as that will be resolved by mechanism from its sender projections @@ -2784,8 +2784,8 @@ def _execute_learning(self, context=None): # # TEST PRINT: # print ("EXECUTING LEARNING UPDATES: ", component.name) - component.context.status &= ~ContextStatus.LEARNING - component.context.status |= ContextStatus.EXECUTION + component.context.status &= ~ContextFlags.LEARNING + component.context.status |= ContextFlags.EXECUTION # THEN update all MappingProjections @@ -2812,14 +2812,14 @@ def _execute_learning(self, context=None): component_type, component.name, re.sub(r'[\[,\],\n]','',str(process_names)))) # cxt-set cxt-push cxt-pass - component.context.status &= ~ContextStatus.EXECUTION - component.context.status |= ContextStatus.LEARNING + component.context.status &= ~ContextFlags.EXECUTION + component.context.status |= ContextFlags.LEARNING component.context.string = context_str component._parameter_states[MATRIX].update(context=context_str) - component.context.status &= ~ContextStatus.LEARNING - component.context.status |= ContextStatus.EXECUTION + component.context.status &= ~ContextFlags.LEARNING + component.context.status |= ContextFlags.EXECUTION # TEST PRINT: # print ("EXECUTING WEIGHT UPDATES: ", component.name) @@ -3975,7 +3975,7 @@ def __init__(self, owner=None, variable=None, name=None, prefs=None, context=Non self.name = owner.name + "_" + SYSTEM_TARGET_INPUT_STATE else: self.name = owner.name + "_" + name - self.context.status = ContextStatus.INITIALIZATION + self.context.status = ContextFlags.INITIALIZATION self.context.string = context self.prefs = prefs self.log = Log(owner=self) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index 960701b4088..9e9a0e9dfc8 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -21,7 +21,7 @@ __all__ = [ 'Context', - 'ContextStatus', + 'ContextFlags', '_get_context' ] @@ -34,18 +34,100 @@ def __init__(self, error_value): self.error_value = error_value +class ContextFlags(IntEnum): + """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. + Also used to specify the context in which a value of the Component or its attribute is `logged `. + """ + UNINITIALIZED = 0 + """Not Initialized.""" + DEFERRED_INIT = 1 + """Set if flagged for deferred initialization.""" + INITIALIZING = 2 + """Set during initialization of the Component.""" + VALIDATING = 3 + """Set during validation of the value of a Component or its attribute.""" + INITIALIZED = 4 + """Set after completion of initialization of the Component.""" + + +# FIX: REPLACE IntEnum WITH Flags and auto IF/WHEN MOVE TO Python 3.6 +class Status(IntEnum): + """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. + Also used to specify the context in which a value of the Component or its attribute is `logged `. + """ + UNINITIALIZED = 0 + """Not Initialized.""" + DEFERRED_INIT = 1 + """Set if flagged for deferred initialization.""" + INITIALIZING = 2 + """Set during initialization of the Component.""" + VALIDATING = 3 + """Set during validation of the value of a Component or its attribute.""" + INITIALIZED = 4 + """Set after completion of initialization of the Component.""" + +class Source(IntEnum): + CONSTRUCTOR = 0 + """Call to method from Component's constructor.""" + COMMAND_LINE = 1 + """Direct call to method by user (either interactively from the command line, or in a script).""" + COMPONENT = 2 + """Call to method by the Component.""" + COMPOSITION = 3 + """Call to method by a/the Composition to which the Component belongs.""" + + # @classmethod + # def _get_context_string(cls, condition, string=None): + # """Return string with the names of all flags that are set in **condition**, prepended by **string**""" + # if string: + # string += ": " + # else: + # string = "" + # flagged_items = [] + # # If OFF or ALL_ASSIGNMENTS, just return that + # if condition in (ContextFlags.ALL_ASSIGNMENTS, ContextFlags.OFF): + # return condition.name + # # Otherwise, append each flag's name to the string + # for c in list(cls.__members__): + # # Skip ALL_ASSIGNMENTS (handled above) + # if c is ContextFlags.ALL_ASSIGNMENTS.name: + # continue + # if ContextFlags[c] & condition: + # flagged_items.append(c) + # string += ", ".join(flagged_items) + # return string + +class ExecutionPhase(IntEnum): + """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. + Also used to specify the context in which a value of the Component or its attribute is `logged `. + """ + IDLE = 0 + """Not currently executin.""" + PROCESSING = 1 + """Set during the `processing phase ` of execution of a Composition.""" + LEARNING = 2 + """Set during the `learning phase ` of execution of a Composition.""" + CONTROL = 3 + """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" + SIMULATION = 4 + """Set during simulation by Composition.controller""" + + class Context(): __name__ = 'Context' def __init__(self, owner, - status=, + status=Status.UNINITIALIZED, + execution_phase=Status.IDLE, + source=Source.COMPONENT, composition=None, execution_id:UUID=None, string:str='', time=None): self.owner = owner self.status = status - self.execution_phase + self.execution_phase = execution_phase + self.source = source self.composition = composition self.execution_id = execution_id self.execution_time = None @@ -57,18 +139,18 @@ def status(self): @status.setter def status(self, status): - # if isinstance(status, ContextStatus): + # if isinstance(status, ContextFlags): # self._status = status # elif isinstance(status, int): - # self._status = ContextStatus(status) + # self._status = ContextFlags(status) # else: # raise ContextError("{} argument in call to {} must be a {} or an int". - # format(STATUS, self.__name__, ContextStatus.__name__)) - if isinstance(status, (ContextStatus, int)): + # format(STATUS, self.__name__, ContextFlags.__name__)) + if isinstance(status, (ContextFlags, int)): self._status = status else: raise ContextError("{} argument in call to {} must be a {} or an int". - format(STATUS, self.__name__, ContextStatus.__name__)) + format(STATUS, self.__name__, ContextFlags.__name__)) @property def composition(self): @@ -99,96 +181,34 @@ def execution_time(self, time): self._execution_time = time def update_execution_time(self): - if self.status & ContextStatus.EXECUTION: + if self.status & ContextFlags.EXECUTION: self.execution_time = _get_time(self.owner, self.context.status) else: raise ContextError("PROGRAM ERROR: attempt to call update_execution_time for {} " "when 'EXECUTION' was not in its context".format(self.owner.name)) -# FIX: REPLACE IntEnum WITH Flags and auto IF/WHEN MOVE TO Python 3.6 -class Status(IntEnum): - """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. - Also used to specify the context in which a value of the Component or its attribute is `logged `. - """ - UNINITIALIZED = 0 - """Not Initialized.""" - DEFERRED_INIT = 1 - """Set if flagged for deferred initialization.""" - INITIALIZING = 2 - """Set during initialization of the Component.""" - VALIDATING = 3 - """Set during validation of the value of a Component or its attribute.""" - INITIALIZED = 4 - """Set after completion of initialization of the Component.""" - -class Source(IntEnum): - CONSTRUCTOR = 0 - """Call to method from Component's constructor.""" - COMMAND_LINE = 1 - """Direct call to method by user (either interactively from the command line, or in a script).""" - COMPONENT = 2 - """Call to method by the Component.""" - COMPOSITION = 3 - """Call to method by a/the Composition to which the Component belongs.""" - - # @classmethod - # def _get_context_string(cls, condition, string=None): - # """Return string with the names of all flags that are set in **condition**, prepended by **string**""" - # if string: - # string += ": " - # else: - # string = "" - # flagged_items = [] - # # If OFF or ALL_ASSIGNMENTS, just return that - # if condition in (ContextStatus.ALL_ASSIGNMENTS, ContextStatus.OFF): - # return condition.name - # # Otherwise, append each flag's name to the string - # for c in list(cls.__members__): - # # Skip ALL_ASSIGNMENTS (handled above) - # if c is ContextStatus.ALL_ASSIGNMENTS.name: - # continue - # if ContextStatus[c] & condition: - # flagged_items.append(c) - # string += ", ".join(flagged_items) - # return string - -class ExecutionPhase(IntEnum): - """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. - Also used to specify the context in which a value of the Component or its attribute is `logged `. - """ - IDLE = 0 - """Not currently executin.""" - PROCESSING = 1 - """Set during the `processing phase ` of execution of a Composition.""" - LEARNING = 2 - """Set during the `learning phase ` of execution of a Composition.""" - CONTROL = 3 - """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" - SIMULATION = 4 - """Set during simulation by Composition.controller""" - def _get_context(context): - if isinstance(context, ContextStatus): + if isinstance(context, ContextFlags): return context - context_flag = ContextStatus.OFF + context_flag = ContextFlags.OFF if INITIALIZING in context: - context_flag |= ContextStatus.INITIALIZATION + context_flag |= ContextFlags.INITIALIZATION if VALIDATE in context: - context_flag |= ContextStatus.VALIDATION + context_flag |= ContextFlags.VALIDATION if EXECUTING in context: - context_flag |= ContextStatus.EXECUTION + context_flag |= ContextFlags.EXECUTION if CONTROL in context: - context_flag |= ContextStatus.CONTROL + context_flag |= ContextFlags.CONTROL if LEARNING in context: - context_flag |= ContextStatus.LEARNING - if context == ContextStatus.TRIAL.name: # cxt-test - context_flag |= ContextStatus.TRIAL - if context == ContextStatus.RUN.name: - context_flag |= ContextStatus.RUN - if context == ContextStatus.COMMAND_LINE.name: - context_flag |= ContextStatus.COMMAND_LINE + context_flag |= ContextFlags.LEARNING + if context == ContextFlags.TRIAL.name: # cxt-test + context_flag |= ContextFlags.TRIAL + if context == ContextFlags.RUN.name: + context_flag |= ContextFlags.RUN + if context == ContextFlags.COMMAND_LINE.name: + context_flag |= ContextFlags.COMMAND_LINE return context_flag def _get_time(component, context_flags): @@ -230,8 +250,8 @@ def _get_time(component, context_flags): # Get System in which it is being (or was last) executed (if any): # If called from COMMAND_LINE, get context for last time value was assigned: - # if context_flags & ContextStatus.COMMAND_LINE: - if context_flags & (ContextStatus.COMMAND_LINE | ContextStatus.RUN | ContextStatus.TRIAL): + # if context_flags & ContextFlags.COMMAND_LINE: + if context_flags & (ContextFlags.COMMAND_LINE | ContextFlags.RUN | ContextFlags.TRIAL): context_flags = component.prev_context.status execution_context = component.prev_context.string else: @@ -240,14 +260,14 @@ def _get_time(component, context_flags): system = ref_mech.context.composition if system: - # FIX: Add ContextStatus.VALIDATE? - if context_flags == ContextStatus.EXECUTION: + # FIX: Add ContextFlags.VALIDATE? + if context_flags == ContextFlags.EXECUTION: t = system.scheduler_processing.clock.time t = time(t.run, t.trial, t.pass_, t.time_step) - elif context_flags == ContextStatus.CONTROL: + elif context_flags == ContextFlags.CONTROL: t = system.scheduler_processing.clock.time t = time(t.run, t.trial, t.pass_, t.time_step) - elif context_flags == ContextStatus.LEARNING: + elif context_flags == ContextFlags.LEARNING: t = system.scheduler_learning.clock.time t = time(t.run, t.trial, t.pass_, t.time_step) else: diff --git a/psyneulink/globals/environment.py b/psyneulink/globals/environment.py index 78a6148146b..6a3ec2ade1b 100644 --- a/psyneulink/globals/environment.py +++ b/psyneulink/globals/environment.py @@ -615,7 +615,7 @@ def run(object, or of the OutputStates of the `TERMINAL` Mechanisms for the Process or System run. """ - from psyneulink.globals.context import ContextStatus + from psyneulink.globals.context import ContextFlags # small version of 'sequence' format in the once case where it was still working (single origin mechanism) if isinstance(inputs, (list, np.ndarray)): @@ -701,8 +701,8 @@ def run(object, # Class-specific validation: context = context or RUN + "validating " + object.name # cxt-done ? cxt-pass - if object.context.status is ContextStatus.OFF: - object.context.status = ContextStatus.RUN + ContextStatus.VALIDATION + if object.context.status is ContextFlags.OFF: + object.context.status = ContextFlags.RUN + ContextFlags.VALIDATION object.context.string = RUN + "validating " + object.name # INITIALIZATION @@ -756,8 +756,8 @@ def run(object, # MODIFIED 3/16/17 END if RUN in context and not EVC_SIMULATION in context: # cxt-test context = RUN + ": EXECUTING " + object_type.upper() + " " + object.name # cxt-done ? cxt-pass - object.context.status &= ~(ContextStatus.VALIDATION | ContextStatus.INITIALIZATION) - object.context.status |= ContextStatus.EXECUTION + object.context.status &= ~(ContextFlags.VALIDATION | ContextFlags.INITIALIZATION) + object.context.status |= ContextFlags.EXECUTION object.context.string = RUN + ": EXECUTING " + object_type.upper() + " " + object.name object.execution_status = ExecutionStatus.EXECUTING result = object.execute( @@ -781,9 +781,9 @@ def run(object, if call_after_trial: call_after_trial() - from psyneulink.globals.log import _log_trials_and_runs, ContextStatus + from psyneulink.globals.log import _log_trials_and_runs, ContextFlags _log_trials_and_runs(composition=object, - curr_condition=ContextStatus.TRIAL, + curr_condition=ContextFlags.TRIAL, context=context) try: @@ -804,9 +804,9 @@ def run(object, else: object._learning_enabled = learning_state_buffer - from psyneulink.globals.log import _log_trials_and_runs, ContextStatus + from psyneulink.globals.log import _log_trials_and_runs, ContextFlags _log_trials_and_runs(composition=object, - curr_condition=ContextStatus.RUN, + curr_condition=ContextFlags.RUN, context=context) return object.results diff --git a/psyneulink/globals/log.py b/psyneulink/globals/log.py index a80d9ac75e5..4293b6c6145 100644 --- a/psyneulink/globals/log.py +++ b/psyneulink/globals/log.py @@ -112,38 +112,38 @@ Logging Conditions ~~~~~~~~~~~~~~~~~~ -Configuring a Component to be logged is done using a condition, that specifies a `ContextStatus` under which its +Configuring a Component to be logged is done using a condition, that specifies a `ContextFlags` under which its `value ` should be entered in its Log. These can be specified in the `set_log_conditions -` method of a Log, or directly by specifying a `ContextStatus` for the value a Component's +` method of a Log, or directly by specifying a `ContextFlags` for the value a Component's `logPref ` item of its `prefs ` attribute. The former is easier, and allows multiple Components to be specied at once, while the latter affords more control over the specification (see -`Preferences`). `ContextStates ` are treated as binary "flags", and can be combined to permit logging -under more than one condition using bitwise operators on the `ContextStates `. For convenience, they +`Preferences`). `ContextStates ` are treated as binary "flags", and can be combined to permit logging +under more than one condition using bitwise operators on the `ContextStates `. For convenience, they can also be referred to by their names, and combined by specifying a list. For example, all of the following specify that the `value ` of ``my_mech`` be logged both during execution and learning:: >>> import psyneulink as pnl >>> my_mech = pnl.TransferMechanism() - >>> my_mech.set_log_conditions('value', pnl.ContextStatus.EXECUTION | pnl.ContextStatus.LEARNING) - >>> my_mech.set_log_conditions('value', pnl.ContextStatus.EXECUTION + pnl.ContextStatus.LEARNING) + >>> my_mech.set_log_conditions('value', pnl.ContextFlags.EXECUTION | pnl.ContextFlags.LEARNING) + >>> my_mech.set_log_conditions('value', pnl.ContextFlags.EXECUTION + pnl.ContextFlags.LEARNING) >>> my_mech.set_log_conditions('value', [pnl.EXECUTION, LEARNING]) .. note:: - Currently, the `VALIDATION` `ContextStatus` is not implemented. + Currently, the `VALIDATION` `ContextFlags` is not implemented. .. note:: - Using `ContextStatus.INITIALIZATION` to log the `value ` of a Component during its initialization + Using `ContextFlags.INITIALIZATION` to log the `value ` of a Component during its initialization requires that it be assigned in the **prefs** argument of the Component's constructor. For example:: COMMENT: FIX: THIS EXAMPLE CAN'T CURRENTLY BE EXECUTED AS IT PERMANENTLY SETS THE LogPref FOR ALL TransferMechanism COMMENT >>> my_mech = pnl.TransferMechanism( - ... prefs={pnl.LOG_PREF: pnl.PreferenceEntry(pnl.ContextStatus.INITIALIZATION, pnl.PreferenceLevel.INSTANCE)}) + ... prefs={pnl.LOG_PREF: pnl.PreferenceEntry(pnl.ContextFlags.INITIALIZATION, pnl.PreferenceLevel.INSTANCE)}) .. hint:: - `ContextStatus.TRIAL` logs the `value ` of a Component at the end of a `TRIAL`. To log its + `ContextFlags.TRIAL` logs the `value ` of a Component at the end of a `TRIAL`. To log its `value ` at the start of a `TRIAL`, use its `log_values ` method in the **call_before_trial** argument of the System's `run ` method. @@ -153,7 +153,7 @@ --------- The value of a Component is recorded to a Log when the condition assigned to its `logPref ` is met. -This is specified as a `ContextStatus` or a boolean combination of them (see `Log_Conditions`). The default ContextStatus +This is specified as a `ContextFlags` or a boolean combination of them (see `Log_Conditions`). The default ContextFlags is `OFF`. .. _Log_Examples: @@ -187,7 +187,7 @@ >>> my_mech_A.set_log_conditions([pnl.NOISE, pnl.RESULTS]) >>> proj_A_to_B.set_log_conditions(pnl.MATRIX) -Note that since no `condition ` was specified, the default (ContextStatus.EXECUTION) is used. +Note that since no `condition ` was specified, the default (ContextFlags.EXECUTION) is used. Executing the Process generates entries in the Logs, that can then be displayed in several ways:: COMMENT: @@ -307,7 +307,7 @@ IMPLEMENTATION NOTE: Name of owner Component is aliases to VALUE in loggable_items and logged_items, but is the Component's actual name in log_entries -Entries are made to the Log based on the `ContextStatus` specified in the +Entries are made to the Log based on the `ContextFlags` specified in the `logPref` item of the component's `prefs ` attribute. Adding an item to prefs.logPref will validate and add an entry for that attribute to the Log dict @@ -319,7 +319,7 @@ * it is included in the *LOG_ENTRIES* entry of a `parameter specification dictionary ` assigned to the **params** argument of the constructor for the Component; .. -* the current `ContextStatus` is one specified in the logPref setting of the owner Component +* the current `ContextFlags` is one specified in the logPref setting of the owner Component Entry values are added by the setter method for the attribute being logged. @@ -331,7 +331,7 @@ - any variables listed in the params[LOG_ENTRIES] of a Mechanism -DEFAULT ContextStatus FOR ALL COMPONENTS IS *OFF* +DEFAULT ContextFlags FOR ALL COMPONENTS IS *OFF* Structure @@ -345,12 +345,12 @@ - context (str): the context in which it was recorded (i.e., where the attribute value was assigned) - value (value): the value assigned to the attribute -The ContextStatus class (see declaration above) defines six levels of logging: +The ContextFlags class (see declaration above) defines six levels of logging: + OFF: No logging for attributes of the owner object + EXECUTION: Log values for all assignments during execution (e.g., including aggregation of projections) + VALIDATION: Log value assignments during validation as well as execution and initialization + ALL_ASSIGNMENTS: Log all value assignments (e.g., including initialization) - Note: ContextStatus is an IntEnum, and thus its values can be used directly in numerical comparisons + Note: ContextFlags is an IntEnum, and thus its values can be used directly in numerical comparisons Entries can also be added programmatically by: - including them in the logPref of a PreferenceSet @@ -395,7 +395,7 @@ from psyneulink.globals.utilities import ContentAddressableList, AutoNumber, is_component from psyneulink.globals.keywords \ import INITIALIZING, EXECUTING, VALIDATE, CONTROL, LEARNING, TRIAL, RUN, COMMAND_LINE, CONTEXT, VALUE, TIME, ALL -from psyneulink.globals.context import ContextStatus, _get_context, _get_time +from psyneulink.globals.context import ContextFlags, _get_context, _get_time __all__ = [ @@ -527,19 +527,19 @@ class Log: An attribute is recorded if: - it is one automatically included in logging (see below) - it is included in params[LOG_ENTRIES] of the owner object - - the context of the assignment is above the ContextStatus specified in the logPref setting of the owner object + - the context of the assignment is above the ContextFlags specified in the logPref setting of the owner object Entry values are added by the setter method for the attribute being logged The following entries are automatically included in self.entries for a Mechanism object: - the value attribute of every State for which the Mechanism is an owner [TBI: - value of every projection that sends to those States] - the system variables defined in SystemLogEntries (see declaration above) - any variables listed in the params[LOG_ENTRIES] of a Mechanism - The ContextStatus class (see declaration above) defines five levels of logging: + The ContextFlags class (see declaration above) defines five levels of logging: + OFF: No logging for attributes of the owner object + EXECUTION: Log values for all assignments during exeuction (e.g., including aggregation of projections) + VALIDATION: Log value assignments during validation as well as execution + ALL_ASSIGNMENTS: Log all value assignments (e.g., including initialization) - Note: ContextStatus is an IntEnum, and thus its values can be used directly in numerical comparisons + Note: ContextFlags is an IntEnum, and thus its values can be used directly in numerical comparisons # Entries can also be added programmtically by: # - including them in the logPref of a PreferenceSet @@ -596,7 +596,7 @@ class Log: loggable_items : Dict[Component.name: List[LogEntry]] identifies Components that can be logged by the owner; the key of each entry is the name of a Component, - and the value is its currently assigned `ContextStatus`. + and the value is its currently assigned `ContextFlags`. entries : Dict[Component.name: List[LogEntry]] contains the logged information for `loggable_components `; the key of each entry @@ -605,7 +605,7 @@ class Log: logged_items : Dict[Component.name: List[LogEntry]] identifies Components that currently have entries in the Log; the key for each entry is the name - of a Component, and the value is its currently assigned `ContextStatus`. + of a Component, and the value is its currently assigned `ContextFlags`. """ @@ -625,8 +625,8 @@ def __init__(self, owner, entries=None): if entries is None: return - def set_log_conditions(self, items, log_condition=ContextStatus.EXECUTION): - """Specifies items to be logged at the specified `ContextStatus`\\(s). + def set_log_conditions(self, items, log_condition=ContextFlags.EXECUTION): + """Specifies items to be logged at the specified `ContextFlags`\\(s). Arguments --------- @@ -636,12 +636,12 @@ def set_log_conditions(self, items, log_condition=ContextStatus.EXECUTION): Each item must be a: * string that is the name of a `loggable_item` ` of the Log's `owner `; * a reference to a Component; - * tuple, the first item of which is one of the above, and the second a `ContextStatus` to use for the item. + * tuple, the first item of which is one of the above, and the second a `ContextFlags` to use for the item. - log_condition : ContextStatus : default ContextStatus.EXECUTION - specifies `ContextStatus` to use as the default for items not specified in tuples (see above). - For convenience, the name of a ContextStatus can be used in place of its full specification - (e.g., *EXECUTION* instead of `ContextStatus.EXECUTION`). + log_condition : ContextFlags : default ContextFlags.EXECUTION + specifies `ContextFlags` to use as the default for items not specified in tuples (see above). + For convenience, the name of a ContextFlags can be used in place of its full specification + (e.g., *EXECUTION* instead of `ContextFlags.EXECUTION`). params_set : list : default None list of parameters to include as loggable items; these must be attributes of the `owner ` @@ -657,13 +657,13 @@ def assign_log_condition(item, level): # Handle multiple level assignments (as ContextStates or strings in a list) if not isinstance(level, list): level = [level] - levels = ContextStatus.OFF + levels = ContextFlags.OFF for l in level: try: - l = ContextStatus[l.upper()] if isinstance(l, str) else l + l = ContextFlags[l.upper()] if isinstance(l, str) else l except KeyError: raise LogError("\'{}\' is not a value of {}". - format(l, ContextStatus.__name__)) + format(l, ContextFlags.__name__)) levels |= l level = levels @@ -674,7 +674,7 @@ def assign_log_condition(item, level): component = next(c for c in self.loggable_components if self._alias_owner_name(c.name) == item) component.logPref=PreferenceEntry(level, PreferenceLevel.INSTANCE) except AttributeError: - raise LogError("PROGRAM ERROR: Unable to set ContextStatus for {} of {}".format(item, self.owner.name)) + raise LogError("PROGRAM ERROR: Unable to set ContextFlags for {} of {}".format(item, self.owner.name)) if items is ALL: for component in self.loggable_components: @@ -697,8 +697,8 @@ def _log_value(self, value, time=None, context=None): """Add LogEntry to an entry in the Log If **value** is a LogEntry, it is assigned to the entry - If **context** is a ContextStatus, it is used to determine whether the entry should be made; - **time** must be passed; the name of the ContextStatus(s) specified are assigned to the context of LogEntry + If **context** is a ContextFlags, it is used to determine whether the entry should be made; + **time** must be passed; the name of the ContextFlags(s) specified are assigned to the context of LogEntry Otherwise, uses string (or Component) passed in **context**, or searches stack (see note) to determine the context, and uses that to determine the scheduler and, from that, the time; If value is None, uses owner's `value ` attribute. @@ -718,19 +718,19 @@ def _log_value(self, value, time=None, context=None): else: - if isinstance(context, ContextStatus): # cxt-test + if isinstance(context, ContextFlags): # cxt-test context_flags = context - context = ContextStatus._get_context_string(context) # cxt-set + context = ContextFlags._get_context_string(context) # cxt-set if not time: - raise LogError("Use of ContextStatus ({}) by {} to specify context requires specification of time". + raise LogError("Use of ContextFlags ({}) by {} to specify context requires specification of time". format(context, self.owner.name )) elif context is COMMAND_LINE: - context_flags = ContextStatus.COMMAND_LINE + context_flags = ContextFlags.COMMAND_LINE elif self.owner.context.status: # cxt-test context_flags = self.owner.context.status - context = ContextStatus._get_context_string(context_flags) + context = ContextFlags._get_context_string(context_flags) # Get context else: @@ -775,18 +775,18 @@ def _log_value(self, value, time=None, context=None): context_flags = _get_context(context) - context_flags_string = ContextStatus._get_context_string(context_flags) - context_status_string = ContextStatus._get_context_string(self.owner.context.status) + context_flags_string = ContextFlags._get_context_string(context_flags) + context_status_string = ContextFlags._get_context_string(self.owner.context.status) # assert context_flags_string == context_status_string log_pref = self.owner.prefs.logPref if self.owner.prefs else None # Get time and log value if logging condition is satisfied or called for programmatically - if (log_pref and log_pref & context_flags) or context_flags & ContextStatus.COMMAND_LINE: + if (log_pref and log_pref & context_flags) or context_flags & ContextFlags.COMMAND_LINE: time = time or _get_time(self.owner, context_flags) self.entries[self.owner.name] = LogEntry(time, context_flags_string, value) - if not context_flags & ContextStatus.COMMAND_LINE: # cxt-test + if not context_flags & ContextFlags.COMMAND_LINE: # cxt-test self.owner.prev_context = self.owner.context @tc.typecheck @@ -954,7 +954,7 @@ class options(IntEnum): if long_context: context = datum.context # cxt-set else: - context = ContextStatus._get_context_string(_get_context(datum.context)) # cxt-set + context = ContextFlags._get_context_string(_get_context(datum.context)) # cxt-set c_width = max(c_width, len(context)) context_width = min(context_width, c_width) @@ -1019,8 +1019,8 @@ class options(IntEnum): # Use context from LogEntry context = repr(context) # cxt-set else: - # Get names of ContextStatus flag(s) from parse of context string - context = ContextStatus._get_context_string(_get_context(context)) # cxt-set + # Get names of ContextFlags flag(s) from parse of context string + context = ContextFlags._get_context_string(_get_context(context)) # cxt-set if len(context) > context_width: context = context[:context_width-3] + "..." # cxt-set data_str = data_str + context.ljust(context_width, spacer) @@ -1447,10 +1447,10 @@ def loggable_items(self): name = self._alias_owner_name(c.name) try: # log_pref_names = c.logPref.name - log_pref_names = ContextStatus._get_context_string(c.logPref) + log_pref_names = ContextFlags._get_context_string(c.logPref) except: log_pref_names = None - # log_pref_names = ContextStatus._get_condition_string(c.logPref) + # log_pref_names = ContextFlags._get_condition_string(c.logPref) loggable_items[name] = log_pref_names return loggable_items @@ -1472,10 +1472,10 @@ def loggable_components(self): @property def logged_items(self): - """Dict of items that have logged `entries `, indicating their specified `ContextStatus`. + """Dict of items that have logged `entries `, indicating their specified `ContextFlags`. """ - log_condition = 'ContextStatus.' - # Return ContextStatus for items in log.entries + log_condition = 'ContextFlags.' + # Return ContextFlags for items in log.entries logged_items = {key: value for (key, value) in # [(l, self.loggable_components[l].logPref.name) @@ -1494,7 +1494,7 @@ def logged_entries(self): # def save_log(self): # print("Saved") -def _log_trials_and_runs(composition, curr_condition:tc.enum(ContextStatus.TRIAL, ContextStatus.RUN), context): +def _log_trials_and_runs(composition, curr_condition:tc.enum(ContextFlags.TRIAL, ContextFlags.RUN), context): # FIX: ALSO CHECK TIME FOR scheduler_learning, AND CHECK DATE FOR BOTH, AND USE WHICHEVER IS LATEST # FIX: BUT WHAT IF THIS PARTICULAR COMPONENT WAS RUN IN THE LAST TIME_STEP?? for mech in composition.mechanisms: diff --git a/psyneulink/globals/preferences/componentpreferenceset.py b/psyneulink/globals/preferences/componentpreferenceset.py index 75aa4031704..0dc489ca207 100644 --- a/psyneulink/globals/preferences/componentpreferenceset.py +++ b/psyneulink/globals/preferences/componentpreferenceset.py @@ -13,7 +13,7 @@ import inspect from psyneulink.globals.keywords import NAME, kwDefaultPreferenceSetOwner, kwPrefLevel, kwPreferenceSetName, kwPrefs, kwPrefsOwner -from psyneulink.globals.log import ContextStatus +from psyneulink.globals.log import ContextFlags from psyneulink.globals.preferences.preferenceset import PreferenceEntry, PreferenceLevel, PreferenceSet from psyneulink.globals.utilities import Modulation @@ -57,7 +57,7 @@ kpVerbosePref: PreferenceEntry(False, PreferenceLevel.SYSTEM), kpParamValidationPref: PreferenceEntry(True, PreferenceLevel.SYSTEM), kpReportOutputPref: PreferenceEntry(False, PreferenceLevel.SYSTEM), - kpLogPref: PreferenceEntry(ContextStatus.OFF, PreferenceLevel.CATEGORY), + kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), kpRuntimeParamModulationPref: PreferenceEntry(Modulation.MULTIPLY, PreferenceLevel.SYSTEM), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.SYSTEM)} @@ -66,7 +66,7 @@ kpVerbosePref: PreferenceEntry(False, PreferenceLevel.CATEGORY), kpParamValidationPref: PreferenceEntry(True, PreferenceLevel.CATEGORY), kpReportOutputPref: PreferenceEntry(False, PreferenceLevel.CATEGORY), - kpLogPref: PreferenceEntry(ContextStatus.OFF, PreferenceLevel.CATEGORY), + kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), kpRuntimeParamModulationPref: PreferenceEntry(Modulation.MULTIPLY,PreferenceLevel.CATEGORY), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.CATEGORY)} @@ -75,7 +75,7 @@ kpVerbosePref: PreferenceEntry(False, PreferenceLevel.TYPE), kpParamValidationPref: PreferenceEntry(True, PreferenceLevel.TYPE), kpReportOutputPref: PreferenceEntry(False, PreferenceLevel.TYPE), - kpLogPref: PreferenceEntry(ContextStatus.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms + kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms kpRuntimeParamModulationPref: PreferenceEntry(Modulation.ADD,PreferenceLevel.TYPE), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.TYPE)} @@ -84,7 +84,7 @@ kpVerbosePref: PreferenceEntry(False, PreferenceLevel.SUBTYPE), kpParamValidationPref: PreferenceEntry(True, PreferenceLevel.SUBTYPE), kpReportOutputPref: PreferenceEntry(False, PreferenceLevel.SUBTYPE), - kpLogPref: PreferenceEntry(ContextStatus.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms + kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms kpRuntimeParamModulationPref: PreferenceEntry(Modulation.ADD,PreferenceLevel.SUBTYPE), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.SUBTYPE)} @@ -93,7 +93,7 @@ kpVerbosePref: PreferenceEntry(False, PreferenceLevel.INSTANCE), kpParamValidationPref: PreferenceEntry(False, PreferenceLevel.INSTANCE), kpReportOutputPref: PreferenceEntry(False, PreferenceLevel.INSTANCE), - kpLogPref: PreferenceEntry(ContextStatus.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms + kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms kpRuntimeParamModulationPref: PreferenceEntry(Modulation.OVERRIDE, PreferenceLevel.INSTANCE), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.INSTANCE)} @@ -131,7 +131,7 @@ class ComponentPreferenceSet(PreferenceSet): - verbose (bool): enables/disables reporting of (non-exception) warnings and system function - paramValidation (bool): enables/disables run-time validation of the execute method of a Function object - reportOutput (bool): enables/disables reporting of execution of execute method - - log (bool): sets ContextStatus for a given Component + - log (bool): sets ContextFlags for a given Component - functionRunTimeParams (Modulation): uses run-time params to modulate execute method params Implement the following preference levels: - SYSTEM: System level default settings (Function.classPreferences) @@ -230,7 +230,7 @@ class ComponentPreferenceSet(PreferenceSet): kpVerbosePref: PreferenceEntry(False, PreferenceLevel.SYSTEM), kpParamValidationPref: PreferenceEntry(True, PreferenceLevel.SYSTEM), kpReportOutputPref: PreferenceEntry(True, PreferenceLevel.SYSTEM), - kpLogPref: PreferenceEntry(ContextStatus.OFF, PreferenceLevel.CATEGORY), + kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), kpRuntimeParamModulationPref: PreferenceEntry(Modulation.MULTIPLY, PreferenceLevel.SYSTEM), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.SYSTEM) diff --git a/psyneulink/library/mechanisms/processing/transfer/recurrenttransfermechanism.py b/psyneulink/library/mechanisms/processing/transfer/recurrenttransfermechanism.py index 8dd45ce90aa..a11ca47b9bf 100644 --- a/psyneulink/library/mechanisms/processing/transfer/recurrenttransfermechanism.py +++ b/psyneulink/library/mechanisms/processing/transfer/recurrenttransfermechanism.py @@ -178,7 +178,7 @@ from psyneulink.components.states.state import _instantiate_state from psyneulink.globals.keywords import AUTO, COMMAND_LINE, ENERGY, ENTROPY, HOLLOW_MATRIX, HETERO, INITIALIZING, MATRIX, MEAN, MEDIAN, NAME, PARAMS_CURRENT, RECURRENT_TRANSFER_MECHANISM, RESULT, SET_ATTRIBUTE, STANDARD_DEVIATION, VARIANCE from psyneulink.globals.preferences.componentpreferenceset import is_pref_set -from psyneulink.globals.context import ContextStatus +from psyneulink.globals.context import ContextFlags from psyneulink.globals.utilities import is_numeric_or_none, parameter_spec from psyneulink.library.mechanisms.adaptive.learning.autoassociativelearningmechanism import AutoAssociativeLearningMechanism from psyneulink.scheduling.time import TimeScale @@ -1053,8 +1053,8 @@ def configure_learning(self, learning_function=None, learning_rate=None, context self.learning_rate = learning_rate context = context or COMMAND_LINE # cxt-done cxt-pass ? cxt-push - if self.context.status is ContextStatus.OFF: - self.context.status = ContextStatus.COMMAND_LINE + if self.context.status is ContextFlags.OFF: + self.context.status = ContextFlags.COMMAND_LINE self.learning_mechanism = self._instantiate_learning_mechanism(activity_vector=self.output_state, learning_function=self.learning_function, diff --git a/psyneulink/library/subsystems/evc/evcauxiliary.py b/psyneulink/library/subsystems/evc/evcauxiliary.py index 8dbe21c9a45..c2f015d6cea 100644 --- a/psyneulink/library/subsystems/evc/evcauxiliary.py +++ b/psyneulink/library/subsystems/evc/evcauxiliary.py @@ -21,7 +21,7 @@ from psyneulink.globals.keywords import COMBINE_OUTCOME_AND_COST_FUNCTION, COST_FUNCTION, EVC_SIMULATION, EXECUTING, FUNCTION_OUTPUT_TYPE_CONVERSION, INITIALIZING, PARAMETER_STATE_PARAMS, SAVE_ALL_VALUES_AND_POLICIES, VALUE_FUNCTION, kwPreferenceSetName, kwProgressBarChar from psyneulink.globals.preferences.componentpreferenceset import is_pref_set, kpReportOutputPref, kpRuntimeParamStickyAssignmentPref from psyneulink.globals.preferences.preferenceset import PreferenceEntry, PreferenceLevel -from psyneulink.globals.context import ContextStatus +from psyneulink.globals.context import ContextFlags from psyneulink.scheduling.time import TimeScale __all__ = [ @@ -311,7 +311,7 @@ def function( # Reset context so that System knows this is a simulation (to avoid infinitely recursive loop) context = context.replace(EXECUTING, '{0} {1} of '.format(controller.name, EVC_SIMULATION)) # cxt-done cxt-pass - controller.context.status = ContextStatus.SIMULATION # FIX IS Controller correct for this, or System?? + controller.context.status = ContextFlags.SIMULATION # FIX IS Controller correct for this, or System?? controller.context.string = context.replace(EXECUTING, '{0} {1} of '.format(controller.name, EVC_SIMULATION)) # Print progress bar if controller.prefs.reportOutputPref: diff --git a/tests/log/test_log.py b/tests/log/test_log.py index 8072a4c70cb..8e75190f42a 100644 --- a/tests/log/test_log.py +++ b/tests/log/test_log.py @@ -100,7 +100,7 @@ def test_log(self): def test_log_initialization(self): T = pnl.TransferMechanism( - prefs={pnl.LOG_PREF: pnl.PreferenceEntry(pnl.ContextStatus.INITIALIZATION, pnl.PreferenceLevel.INSTANCE)} + prefs={pnl.LOG_PREF: pnl.PreferenceEntry(pnl.ContextFlags.INITIALIZATION, pnl.PreferenceLevel.INSTANCE)} ) assert T.logged_items == {'value': 'INITIALIZATION'} From 4eb523049a4c866b16b2a3e36c900c8b4472e815 Mon Sep 17 00:00:00 2001 From: jdc Date: Fri, 23 Mar 2018 13:27:21 -0400 Subject: [PATCH 04/41] - --- psyneulink/globals/context.py | 191 +++++++++++++++++++++------------- 1 file changed, 117 insertions(+), 74 deletions(-) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index 9e9a0e9dfc8..a651a146bf7 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -38,88 +38,94 @@ class ContextFlags(IntEnum): """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. Also used to specify the context in which a value of the Component or its attribute is `logged `. """ - UNINITIALIZED = 0 - """Not Initialized.""" - DEFERRED_INIT = 1 - """Set if flagged for deferred initialization.""" - INITIALIZING = 2 - """Set during initialization of the Component.""" - VALIDATING = 3 - """Set during validation of the value of a Component or its attribute.""" - INITIALIZED = 4 - """Set after completion of initialization of the Component.""" - -# FIX: REPLACE IntEnum WITH Flags and auto IF/WHEN MOVE TO Python 3.6 -class Status(IntEnum): - """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. - Also used to specify the context in which a value of the Component or its attribute is `logged `. - """ + # INITIALIZATION = 1<<1 # 2 + # """Set during execution of the Component's constructor.""" + # VALIDATION = 1<<2 # 4 + # """Set during validation of the value of a Component or its attribute.""" + # EXECUTION = 1<<3 # 8 + # """Set during any execution of the Component.""" + # PROCESSING = 1<<4 # 16 + # """Set during the `processing phase ` of execution of a Composition.""" + # LEARNING = 1<<5 # 32 + # """Set during the `learning phase ` of execution of a Composition.""" + # CONTROL = 1<<6 # 64 + # """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" + # TRIAL = 1<<7 # 128 + # """Set at the end of a `TRIAL`.""" + # RUN = 1<<8 # 256 + # """Set at the end of a `RUN`.""" + # SIMULATION = 1<<9 # 512 + # # Set during simulation by Composition.controller + # COMMAND_LINE = 1<<10 # 1024 + # # Component accessed by user + # CONSTRUCTOR = 1<<11 # 2048 + + # Status flags UNINITIALIZED = 0 """Not Initialized.""" - DEFERRED_INIT = 1 + DEFERRED_INIT = 1<<1 # 2 """Set if flagged for deferred initialization.""" - INITIALIZING = 2 + INITIALIZING = 1<<2 # 4 """Set during initialization of the Component.""" - VALIDATING = 3 + VALIDATING = 1<<3 # 8 """Set during validation of the value of a Component or its attribute.""" - INITIALIZED = 4 + INITIALIZED = 1<<4 # 16 """Set after completion of initialization of the Component.""" -class Source(IntEnum): - CONSTRUCTOR = 0 + # Source-of-call flags + CONSTRUCTOR = 1<<5 # 32 """Call to method from Component's constructor.""" - COMMAND_LINE = 1 + COMMAND_LINE = 1<<6 # 64 """Direct call to method by user (either interactively from the command line, or in a script).""" - COMPONENT = 2 + COMPONENT = 1<<7 # 128 """Call to method by the Component.""" - COMPOSITION = 3 + COMPOSITION = 1<<8 # 256 """Call to method by a/the Composition to which the Component belongs.""" - # @classmethod - # def _get_context_string(cls, condition, string=None): - # """Return string with the names of all flags that are set in **condition**, prepended by **string**""" - # if string: - # string += ": " - # else: - # string = "" - # flagged_items = [] - # # If OFF or ALL_ASSIGNMENTS, just return that - # if condition in (ContextFlags.ALL_ASSIGNMENTS, ContextFlags.OFF): - # return condition.name - # # Otherwise, append each flag's name to the string - # for c in list(cls.__members__): - # # Skip ALL_ASSIGNMENTS (handled above) - # if c is ContextFlags.ALL_ASSIGNMENTS.name: - # continue - # if ContextFlags[c] & condition: - # flagged_items.append(c) - # string += ", ".join(flagged_items) - # return string - -class ExecutionPhase(IntEnum): - """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. - Also used to specify the context in which a value of the Component or its attribute is `logged `. - """ - IDLE = 0 - """Not currently executin.""" - PROCESSING = 1 + # #Execution phase flags + IDLE = 1<<9 #512 + """Not currently executing.""" + PROCESSING = 1<<10 #1024 """Set during the `processing phase ` of execution of a Composition.""" - LEARNING = 2 + LEARNING = 1<<11 #2048 """Set during the `learning phase ` of execution of a Composition.""" - CONTROL = 3 + CONTROL = 1<<12 #4096 """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" - SIMULATION = 4 + SIMULATION = 1<<13 #8192 """Set during simulation by Composition.controller""" + @classmethod + def _get_context_string(cls, condition, string=None): + """Return string with the names of all flags that are set in **condition**, prepended by **string**""" + if string: + string += ": " + else: + string = "" + flagged_items = [] + # If OFF or ALL_ASSIGNMENTS, just return that + if condition in (ContextFlags.ALL_ASSIGNMENTS, ContextFlags.OFF): + return condition.name + # Otherwise, append each flag's name to the string + for c in list(cls.__members__): + # Skip ALL_ASSIGNMENTS (handled above) + if c is ContextFlags.ALL_ASSIGNMENTS.name: + continue + if ContextFlags[c] & condition: + flagged_items.append(c) + string += ", ".join(flagged_items) + return string + + class Context(): __name__ = 'Context' def __init__(self, owner, - status=Status.UNINITIALIZED, - execution_phase=Status.IDLE, - source=Source.COMPONENT, + flags=None, + status=ContextFlags.UNINITIALIZED, + execution_phase=ContextFlags.IDLE, + source=ContextFlags.COMPONENT, composition=None, execution_id:UUID=None, string:str='', time=None): @@ -128,14 +134,49 @@ def __init__(self, self.status = status self.execution_phase = execution_phase self.source = source + if flags: + if (status != ContextFlags.UNINITIALIZED) and not (flags & status_mask & status): + raise ContextError("Conflict in assignment to flags ({}) and status ({}) arguments of Context for {}". + format(_get_context_string(flags), _get_context_string(status), self.owner.name)) + if (execution_phase != ContextFlags.UNINITIALIZED) and not (flags & execution_phase_mask & execution_phase): + raise ContextError("Conflict in assignment to flags ({}) and execution_phase ({}) arguments " + "of Context for {}".format(_get_context_string(flags), + _get_context_string(execution_phase), self.owner.name)) + if (source != ContextFlags.UNINITIALIZED) and not (flags & source_mask & source): + raise ContextError("Conflict in assignment to flags ({}) and source ({}) arguments of Context for {}". + format(_get_context_string(flags), _get_context_string(source), self.owner.name)) + self.composition = composition self.execution_id = execution_id self.execution_time = None self.string = string + @property + def composition(self): + try: + return self._composition + except AttributeError: + self._composition = None + + @composition.setter + def composition(self, composition): + # from psyneulink.composition import Composition + # if isinstance(composition, Composition): + if composition is None or composition.__class__.__name__ in {'Composition', 'System'}: + self._composition = composition + else: + raise ContextError("Assignment to context.composition for {} ({}) " + "must be a Composition (or \'None\').".format(self.owner.name, composition)) + + @property + def flags(self): + return self._flags + + @ + @property def status(self): - return self._status + return self._flags @status.setter def status(self, status): @@ -153,21 +194,23 @@ def status(self, status): format(STATUS, self.__name__, ContextFlags.__name__)) @property - def composition(self): - try: - return self._composition - except AttributeError: - self._composition = None + def status(self): + return self. - @composition.setter - def composition(self, composition): - # from psyneulink.composition import Composition - # if isinstance(composition, Composition): - if composition is None or composition.__class__.__name__ in {'Composition', 'System'}: - self._composition = composition - else: - raise ContextError("Assignment to context.composition for {} ({}) " - "must be a Composition (or \'None\').".format(self.owner.name, composition)) + @status.setter + def status(self, flag): + + @property + def execution_phase(self): + + @execution_phase.setter + def execution_phase(self, flag): + + @property + def source(self): + + @source.setter + def source(self, flag): @property def execution_time(self): From 1ede55767ee1a52717cca94e552788683d8fd974 Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Fri, 23 Mar 2018 15:59:07 -0400 Subject: [PATCH 05/41] - --- psyneulink/globals/context.py | 133 +++++++++++++++++++++++---------- psyneulink/globals/keywords.py | 3 +- psyneulink/globals/log.py | 2 +- 3 files changed, 95 insertions(+), 43 deletions(-) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index a651a146bf7..8789143d64a 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -8,14 +8,15 @@ # # ******************************************** System Defaults ******************************************************** - from uuid import UUID from enum import IntEnum from collections import namedtuple + +import typecheck as tc import warnings -from psyneulink.globals.keywords import INITIALIZING, VALIDATE, EXECUTING, CONTROL, LEARNING +from psyneulink.globals.keywords import FLAGS, INITIALIZING, VALIDATE, EXECUTING, CONTROL, LEARNING # from psyneulink.composition import Composition @@ -72,6 +73,7 @@ class ContextFlags(IntEnum): """Set during validation of the value of a Component or its attribute.""" INITIALIZED = 1<<4 # 16 """Set after completion of initialization of the Component.""" + STATUS_MASK = UNINITIALIZED | DEFERRED_INIT | INITIALIZING | VALIDATING | INITIALIZED # Source-of-call flags CONSTRUCTOR = 1<<5 # 32 @@ -82,6 +84,7 @@ class ContextFlags(IntEnum): """Call to method by the Component.""" COMPOSITION = 1<<8 # 256 """Call to method by a/the Composition to which the Component belongs.""" + SOURCE_MASK = CONSTRUCTOR | COMMAND_LINE | COMPONENT | COMPOSITION # #Execution phase flags IDLE = 1<<9 #512 @@ -94,7 +97,10 @@ class ContextFlags(IntEnum): """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" SIMULATION = 1<<13 #8192 """Set during simulation by Composition.controller""" + EXECUTION_PHASE_MASK = IDLE | PROCESSING | LEARNING | CONTROL | SIMULATION + + ALL_FLAGS = STATUS_MASK | SOURCE_MASK | EXECUTION_PHASE_MASK @classmethod def _get_context_string(cls, condition, string=None): @@ -104,49 +110,71 @@ def _get_context_string(cls, condition, string=None): else: string = "" flagged_items = [] - # If OFF or ALL_ASSIGNMENTS, just return that - if condition in (ContextFlags.ALL_ASSIGNMENTS, ContextFlags.OFF): + # If OFF or ALL_FLAGS, just return that + if condition in (ContextFlags.ALL_FLAGS, ContextFlags.OFF): return condition.name # Otherwise, append each flag's name to the string for c in list(cls.__members__): - # Skip ALL_ASSIGNMENTS (handled above) - if c is ContextFlags.ALL_ASSIGNMENTS.name: + # Skip ALL_FLAGS (handled above) + if c is ContextFlags.ALL_FLAGS.name: continue if ContextFlags[c] & condition: flagged_items.append(c) string += ", ".join(flagged_items) return string +STATUS_FLAGS = {ContextFlags.UNINITIALIZED, + ContextFlags.DEFERRED_INIT, + ContextFlags.INITIALIZING, + ContextFlags.VALIDATING, + ContextFlags.INITIALIZED} + +SOURCE_FLAGS = {ContextFlags.CONSTRUCTOR, + ContextFlags.COMMAND_LINE, + ContextFlags.COMPONENT, + ContextFlags.COMPOSITION} + +EXECUTION_PHASE_FLAGS = {ContextFlags.IDLE, + ContextFlags.PROCESSING, + ContextFlags.LEARNING, + ContextFlags.CONTROL, + ContextFlags.SIMULATION} + class Context(): __name__ = 'Context' def __init__(self, owner, + composition=None, flags=None, status=ContextFlags.UNINITIALIZED, execution_phase=ContextFlags.IDLE, source=ContextFlags.COMPONENT, - composition=None, execution_id:UUID=None, string:str='', time=None): self.owner = owner + self.composition = composition self.status = status self.execution_phase = execution_phase self.source = source if flags: - if (status != ContextFlags.UNINITIALIZED) and not (flags & status_mask & status): + if (status != ContextFlags.UNINITIALIZED) and not (flags & ContextFlags.STATUS_MASK & status): raise ContextError("Conflict in assignment to flags ({}) and status ({}) arguments of Context for {}". - format(_get_context_string(flags), _get_context_string(status), self.owner.name)) - if (execution_phase != ContextFlags.UNINITIALIZED) and not (flags & execution_phase_mask & execution_phase): + format(ContextFlags._get_context_string(flags & ContextFlags.STATUS_MASK), + ContextFlags._get_context_string(status), + self.owner.name)) + if ((execution_phase != ContextFlags.IDLE) and + not (flags & ContextFlags.EXECUTION_PHASE_MASK & execution_phase)): raise ContextError("Conflict in assignment to flags ({}) and execution_phase ({}) arguments " - "of Context for {}".format(_get_context_string(flags), - _get_context_string(execution_phase), self.owner.name)) - if (source != ContextFlags.UNINITIALIZED) and not (flags & source_mask & source): + "of Context for {}". + format(ContextFlags._get_context_string(flags & ContextFlags.EXECUTION_PHASE_MASK), + ContextFlags._get_context_string(execution_phase), self.owner.name)) + if (source != ContextFlags.COMPONENT) and not (flags & ContextFlags.SOURCE_MASK & source): raise ContextError("Conflict in assignment to flags ({}) and source ({}) arguments of Context for {}". - format(_get_context_string(flags), _get_context_string(source), self.owner.name)) - - self.composition = composition + format(ContextFlags._get_context_string(flags & ContextFlags.SOURCE_MASK), + ContextFlags._get_context_string(source), + self.owner.name)) self.execution_id = execution_id self.execution_time = None self.string = string @@ -172,45 +200,63 @@ def composition(self, composition): def flags(self): return self._flags - @ - - @property - def status(self): - return self._flags - - @status.setter - def status(self, status): - # if isinstance(status, ContextFlags): - # self._status = status - # elif isinstance(status, int): - # self._status = ContextFlags(status) - # else: - # raise ContextError("{} argument in call to {} must be a {} or an int". - # format(STATUS, self.__name__, ContextFlags.__name__)) - if isinstance(status, (ContextFlags, int)): - self._status = status + @flags.setter + def flags(self, flags): + if isinstance(flags, (ContextFlags, int)): + self._flags = flags else: - raise ContextError("{} argument in call to {} must be a {} or an int". - format(STATUS, self.__name__, ContextFlags.__name__)) + raise ContextError("\'{}\'{} argument in call to {} must be a {} or an int". + format(FLAGS, self.__name__, ContextFlags.__name__)) @property def status(self): - return self. + return self.flags & ContextFlags.STATUS_MASK @status.setter def status(self, flag): + """Check that a flag is one and only one status flag """ + flag &= ContextFlags.STATUS_MASK + if flag in STATUS_FLAGS: + self._flags |= flag + elif not flag: + raise ContextError("Attempt to assign a flag ({}) to {}.context.status that is not a STATUS flag". + format(ContextFlags._get_context_string(flag), self.owner.name)) + else: + raise ContextError("Attempt to assign more than one flag ({}) to {}.context.status". + format(ContextFlags._get_context_string(flag), self.owner.name)) @property def execution_phase(self): + return self.flags & ContextFlags.EXECUTION_PHASE_MASK @execution_phase.setter def execution_phase(self, flag): + """Check that a flag is one and only one execution_phase flag """ + if flag in EXECUTION_PHASE_FLAGS: + self._flags |= flag + elif not flag & ContextFlags.EXECUTION_PHASE_MASK: + raise ContextError("Attempt to assign a flag ({}) to {}.context.execution_phase " + "that is not an EXECUTION_PHASE flag". + format(ContextFlags._get_context_string(flag), self.owner.name)) + else: + raise ContextError("Attempt to assign more than one flag ({}) to {}.context.execution_phase". + format(ContextFlags._get_context_string(flag), self.owner.name)) @property def source(self): + return self.flags & ContextFlags.SOURCE_MASK @source.setter def source(self, flag): + """Check that a flag is one and only one source flag """ + if flag in SOURCE_FLAGS: + self._flags |= flag + elif not flag & ContextFlags.SOURCE_MASK: + raise ContextError("Attempt to assign a flag ({}) to {}.context.source that is not a SOURCE flag". + format(ContextFlags._get_context_string(flag), self.owner.name)) + else: + raise ContextError("Attempt to assign more than one flag ({}) to {}.context.source". + format(ContextFlags._get_context_string(flag), self.owner.name)) @property def execution_time(self): @@ -231,17 +277,22 @@ def update_execution_time(self): "when 'EXECUTION' was not in its context".format(self.owner.name)) -def _get_context(context): +@tc.typecheck +def _get_context(context:tc.any(ContextFlags, str)): + """Set flags based on a string of ContextFlags keywords + If context is already a ContextFlags mask, return that + Otherwise, return mask with flags set corresponding to keywords in context + """ if isinstance(context, ContextFlags): return context - context_flag = ContextFlags.OFF + context_flag = ContextFlags.UNINITIALIZED if INITIALIZING in context: - context_flag |= ContextFlags.INITIALIZATION + context_flag |= ContextFlags.INITIALIZING if VALIDATE in context: - context_flag |= ContextFlags.VALIDATION + context_flag |= ContextFlags.VALIDATING if EXECUTING in context: - context_flag |= ContextFlags.EXECUTION + context_flag |= ContextFlags.EXECUTING if CONTROL in context: context_flag |= ContextFlags.CONTROL if LEARNING in context: diff --git a/psyneulink/globals/keywords.py b/psyneulink/globals/keywords.py index b0b7f5073e5..b5e3150f221 100644 --- a/psyneulink/globals/keywords.py +++ b/psyneulink/globals/keywords.py @@ -40,7 +40,7 @@ 'ENABLE_CONTROLLER', 'ENABLED', 'ENERGY', 'ENTROPY', 'ERROR_DERIVATIVE_FUNCTION', 'EUCLIDEAN', 'EVC_MECHANISM', 'EVC_SIMULATION', 'EXAMPLE_FUNCTION_TYPE', 'EXECUTING', 'EXECUTION', 'EXECUTION_COUNT', 'EXECUTION_TIME', 'EXPONENT', 'EXPONENTIAL_DIST_FUNCTION', 'EXPONENTIAL_FUNCTION', 'EXPONENTS', - 'FHN_INTEGRATOR_FUNCTION', 'FINAL', 'FULL', 'FULL_CONNECTIVITY_MATRIX', + 'FHN_INTEGRATOR_FUNCTION', 'FINAL', 'FLAGS', 'FULL', 'FULL_CONNECTIVITY_MATRIX', 'FUNCTION', 'FUNCTIONS', 'FUNCTION_CHECK_ARGS', 'FUNCTION_OUTPUT_TYPE', 'FUNCTION_OUTPUT_TYPE_CONVERSION', 'FUNCTION_PARAMS', 'GAIN', 'GAMMA_DIST_FUNCTION', 'GATE', 'GATING', 'GATING_MECHANISM', 'GATING_POLICY', 'GATING_PROJECTION', 'GATING_PROJECTION_PARAMS', 'GATING_PROJECTIONS', @@ -335,6 +335,7 @@ def _is_metric(metric): SEPARATOR_BAR = ' | ' kwProgressBarChar = '.' # kwValueSuffix = '_value' +FLAGS = 'flags' INITIALIZING = " INITIALIZING " # Used as status and context for Log INITIALIZED = " INITIALIZED " # Used as status kwInstantiate = " INSTANTIATING " # Used as context for Log diff --git a/psyneulink/globals/log.py b/psyneulink/globals/log.py index 4293b6c6145..4a620dc5539 100644 --- a/psyneulink/globals/log.py +++ b/psyneulink/globals/log.py @@ -625,7 +625,7 @@ def __init__(self, owner, entries=None): if entries is None: return - def set_log_conditions(self, items, log_condition=ContextFlags.EXECUTION): + def set_log_conditions(self, items, log_condition=ContextFlags.EXECUTING): """Specifies items to be logged at the specified `ContextFlags`\\(s). Arguments From ce82dcda0b0c7216785b0da16bf68f08f59cf136 Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Fri, 23 Mar 2018 16:05:19 -0400 Subject: [PATCH 06/41] - --- psyneulink/components/component.py | 4 ++-- psyneulink/components/mechanisms/mechanism.py | 9 ++++----- psyneulink/components/process.py | 1 - psyneulink/components/system.py | 1 - psyneulink/globals/environment.py | 1 - 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/psyneulink/components/component.py b/psyneulink/components/component.py index 0ff207575f0..b3e663e4312 100644 --- a/psyneulink/components/component.py +++ b/psyneulink/components/component.py @@ -3111,8 +3111,8 @@ def set_log_conditions(self, items, log_condition=ContextFlags.EXECUTION): ) Specifies items to be logged; these must be be `loggable_items ` of the Component's - `log `. This is a convenience method that calls the `set_log_conditions ` method - of the Component's `log `. + `log `. This is a convenience method that calls the `set_log_conditions ` + method of the Component's `log `. """ self.log.set_log_conditions(items=items, log_condition=log_condition) diff --git a/psyneulink/components/mechanisms/mechanism.py b/psyneulink/components/mechanisms/mechanism.py index e793e1e6986..407620b03f9 100644 --- a/psyneulink/components/mechanisms/mechanism.py +++ b/psyneulink/components/mechanisms/mechanism.py @@ -1982,11 +1982,11 @@ def execute(self, if not INITIALIZING in context: self.context.status &= ~ContextFlags.INITIALIZATION if EXECUTING in context: - self.context.status |= ContextFlags.EXECUTION - if EVC_SIMULATION in context: - self.context.status |= ContextFlags.SIMULATION + self.context.status |= ContextFlags.PROCESSING if LEARNING in context: self.context.status |= ContextFlags.LEARNING + if EVC_SIMULATION in context: + self.context.status |= ContextFlags.SIMULATION # IMPLEMENTATION NOTE: Re-write by calling execute methods according to their order in functionDict: # for func in self.functionDict: @@ -2081,9 +2081,8 @@ def execute(self, else: if context is COMMAND_LINE: # cxt-test context = EXECUTING + ' ' + append_type_to_name(self) # cxt-done - self.context.status = ContextFlags.EXECUTION + self.context.status = ContextFlags.PROCESSING self.context.string = EXECUTING + ' ' + append_type_to_name(self) - self.execution_status = ExecutionStatus.EXECUTING if input is None: input = self.instance_defaults.variable variable = self._update_variable(self._get_variable_from_input(input)) diff --git a/psyneulink/components/process.py b/psyneulink/components/process.py index 39b5b80db1a..959b12ff37b 100644 --- a/psyneulink/components/process.py +++ b/psyneulink/components/process.py @@ -2117,7 +2117,6 @@ def execute( context = EXECUTING + " " + PROCESS + " " + self.name # cxt-done self.context.status = ContextFlags.EXECUTION self.context.string = EXECUTING + " " + PROCESS + " " + self.name - self.execution_status = ExecutionStatus.EXECUTING from psyneulink.globals.environment import _get_unique_id self._execution_id = execution_id or _get_unique_id() for mech in self.mechanisms: diff --git a/psyneulink/components/system.py b/psyneulink/components/system.py index ff20e9b3155..d32d8224f38 100644 --- a/psyneulink/components/system.py +++ b/psyneulink/components/system.py @@ -2521,7 +2521,6 @@ def execute(self, context = EXECUTING + " " + SYSTEM + " " + self.name # cxt-done self.context.status = ContextFlags.EXECUTION self.context.string = EXECUTING + " " + SYSTEM + " " + self.name - self.execution_status = ExecutionStatus.EXECUTING # Update execution_id for self and all mechanisms in graph (including learning) and controller from psyneulink.globals.environment import _get_unique_id diff --git a/psyneulink/globals/environment.py b/psyneulink/globals/environment.py index 6a3ec2ade1b..03ef69ee877 100644 --- a/psyneulink/globals/environment.py +++ b/psyneulink/globals/environment.py @@ -759,7 +759,6 @@ def run(object, object.context.status &= ~(ContextFlags.VALIDATION | ContextFlags.INITIALIZATION) object.context.status |= ContextFlags.EXECUTION object.context.string = RUN + ": EXECUTING " + object_type.upper() + " " + object.name - object.execution_status = ExecutionStatus.EXECUTING result = object.execute( input=execution_inputs, execution_id=execution_id, From 61aad3d38a022cbb1b9a4eaa0f3f5b1bcc60e910 Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Sat, 24 Mar 2018 12:13:01 -0400 Subject: [PATCH 07/41] - --- psyneulink/components/component.py | 13 ++++--------- psyneulink/components/mechanisms/mechanism.py | 2 +- psyneulink/components/process.py | 2 +- psyneulink/components/system.py | 2 +- psyneulink/globals/context.py | 2 +- psyneulink/globals/environment.py | 2 +- 6 files changed, 9 insertions(+), 14 deletions(-) diff --git a/psyneulink/components/component.py b/psyneulink/components/component.py index b3e663e4312..2e558981a64 100644 --- a/psyneulink/components/component.py +++ b/psyneulink/components/component.py @@ -409,7 +409,7 @@ class `UserList Date: Sat, 24 Mar 2018 12:54:28 -0400 Subject: [PATCH 08/41] - --- psyneulink/globals/context.py | 47 +++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index 7de9c65679b..fffb1626ff4 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -87,16 +87,20 @@ class ContextFlags(IntEnum): SOURCE_MASK = CONSTRUCTOR | COMMAND_LINE | COMPONENT | COMPOSITION # #Execution phase flags - IDLE = 1<<9 #512 + IDLE = 1<<9 # 512 """Not currently executing.""" - PROCESSING = 1<<10 #1024 + PROCESSING = 1<<10 # 1024 """Set during the `processing phase ` of execution of a Composition.""" - LEARNING = 1<<11 #2048 + LEARNING = 1<<11 # 2048 """Set during the `learning phase ` of execution of a Composition.""" - CONTROL = 1<<12 #4096 + CONTROL = 1<<12 # 4096 """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" - SIMULATION = 1<<13 #8192 + SIMULATION = 1<<13 # 8192 """Set during simulation by Composition.controller""" + TRIAL = 1<<14 # 16384 + """Set at the end of a `TRIAL`.""" + RUN = 1<<15 # 32768 + """Set at the end of a `RUN`.""" EXECUTION_PHASE_MASK = IDLE | PROCESSING | LEARNING | CONTROL | SIMULATION @@ -140,6 +144,39 @@ def _get_context_string(cls, condition, string=None): ContextFlags.CONTROL, ContextFlags.SIMULATION} +# For backward compatibility +class ContextStatus(IntEnum): + """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. + Also used to specify the context in which a value of the Component or its attribute is `logged `. + """ + OFF = 0 + # """No recording.""" + INITIALIZATION = ContextFlags.INITIALIZING + """Set during execution of the Component's constructor.""" + VALIDATION = ContextFlags.VALIDATING + """Set during validation of the value of a Component or its attribute.""" + EXECUTION = XXX + """Set during any execution of the Component.""" + PROCESSING = ContextFlags.PROCESSING + """Set during the `processing phase ` of execution of a Composition.""" + LEARNING = ContextFlags.LEARNING + """Set during the `learning phase ` of execution of a Composition.""" + CONTROL = ContextFlags.LEARNING + """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" + TRIAL = ContextFlags.TRIAL + """Set at the end of a `TRIAL`.""" + RUN = ContextFlags.RUN + """Set at the end of a `RUN`.""" + SIMULATION = ContextFlags.SIMULATION + # Set during simulation by Composition.controller + COMMAND_LINE = ContextFlags.COMMAND_LINE + # Component accessed by user + CONSTRUCTOR = ContextFlags.CONSTRUCTOR + # Component being constructor (used in call to super.__init__) + ALL_ASSIGNMENTS = \ + INITIALIZATION | VALIDATION | EXECUTION | PROCESSING | LEARNING | CONTROL + """Specifies all contexts.""" + class Context(): __name__ = 'Context' From f626ed3dda6ab50a52f39e70247fecaaf52497de Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Sat, 24 Mar 2018 13:21:20 -0400 Subject: [PATCH 09/41] - --- psyneulink/globals/context.py | 125 +++++++++++++++++++++------------- 1 file changed, 76 insertions(+), 49 deletions(-) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index fffb1626ff4..a87673dbad5 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -62,7 +62,7 @@ class ContextFlags(IntEnum): # # Component accessed by user # CONSTRUCTOR = 1<<11 # 2048 - # Status flags + # Initialization status flags UNINITIALIZED = 0 """Not Initialized.""" DEFERRED_INIT = 1<<1 # 2 @@ -73,38 +73,43 @@ class ContextFlags(IntEnum): """Set during validation of the value of a Component or its attribute.""" INITIALIZED = 1<<4 # 16 """Set after completion of initialization of the Component.""" - STATUS_MASK = UNINITIALIZED | DEFERRED_INIT | INITIALIZING | VALIDATING | INITIALIZED + INITIALIZATION_MASK = UNINITIALIZED | DEFERRED_INIT | INITIALIZING | VALIDATING | INITIALIZED + + # Execution status flags + IDLE = 1<<5 # 32 + """Set if Component is initialized but not currently executing.""" + EXECUTING = 1<<6 # 64 + """Set while Component is executing""" + TRIAL = 1<<7 # 128 + """Set at the end of a `TRIAL`.""" + RUN = 1<<8 # 256 + """Set at the end of a `RUN`.""" + EXECUTION_MASK = IDLE | EXECUTING | TRIAL | RUN + + # #Execution phase flags + PROCESSING = 1<<9 # 512 + """Set during the `processing phase ` of execution of a Composition.""" + LEARNING = 1<<10 # 1024 + """Set during the `learning phase ` of execution of a Composition.""" + CONTROL = 1<<11 # 2048 + """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" + SIMULATION = 1<<12 # 4096 + """Set during simulation by Composition.controller""" + EXECUTION_PHASE_MASK = PROCESSING | LEARNING | CONTROL | SIMULATION # Source-of-call flags - CONSTRUCTOR = 1<<5 # 32 + CONSTRUCTOR = 1<<13 # 8192 """Call to method from Component's constructor.""" - COMMAND_LINE = 1<<6 # 64 + COMMAND_LINE = 1<<14 # 16384 """Direct call to method by user (either interactively from the command line, or in a script).""" - COMPONENT = 1<<7 # 128 + COMPONENT = 1<<15 # 32768 """Call to method by the Component.""" - COMPOSITION = 1<<8 # 256 + COMPOSITION = 1<<16 # 65536 """Call to method by a/the Composition to which the Component belongs.""" SOURCE_MASK = CONSTRUCTOR | COMMAND_LINE | COMPONENT | COMPOSITION - # #Execution phase flags - IDLE = 1<<9 # 512 - """Not currently executing.""" - PROCESSING = 1<<10 # 1024 - """Set during the `processing phase ` of execution of a Composition.""" - LEARNING = 1<<11 # 2048 - """Set during the `learning phase ` of execution of a Composition.""" - CONTROL = 1<<12 # 4096 - """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" - SIMULATION = 1<<13 # 8192 - """Set during simulation by Composition.controller""" - TRIAL = 1<<14 # 16384 - """Set at the end of a `TRIAL`.""" - RUN = 1<<15 # 32768 - """Set at the end of a `RUN`.""" - EXECUTION_PHASE_MASK = IDLE | PROCESSING | LEARNING | CONTROL | SIMULATION - - ALL_FLAGS = STATUS_MASK | SOURCE_MASK | EXECUTION_PHASE_MASK + ALL_FLAGS = INITIALIZATION_MASK | EXECUTION_MASK | EXECUTION_PHASE_MASK | SOURCE_MASK @classmethod def _get_context_string(cls, condition, string=None): @@ -127,23 +132,27 @@ def _get_context_string(cls, condition, string=None): string += ", ".join(flagged_items) return string -STATUS_FLAGS = {ContextFlags.UNINITIALIZED, - ContextFlags.DEFERRED_INIT, - ContextFlags.INITIALIZING, - ContextFlags.VALIDATING, - ContextFlags.INITIALIZED} +INITIALIZATION_STATUS_FLAGS = {ContextFlags.UNINITIALIZED, + ContextFlags.DEFERRED_INIT, + ContextFlags.INITIALIZING, + ContextFlags.VALIDATING, + ContextFlags.INITIALIZED} -SOURCE_FLAGS = {ContextFlags.CONSTRUCTOR, - ContextFlags.COMMAND_LINE, - ContextFlags.COMPONENT, - ContextFlags.COMPOSITION} +EXECUTION_STATUS_FLAGS = {ContextFlags.IDLE, + ContextFlags.EXECUTING, + ContextFlags.TRIAL, + ContextFlags.RUN} -EXECUTION_PHASE_FLAGS = {ContextFlags.IDLE, - ContextFlags.PROCESSING, +EXECUTION_PHASE_FLAGS = {ContextFlags.PROCESSING, ContextFlags.LEARNING, ContextFlags.CONTROL, ContextFlags.SIMULATION} +SOURCE_FLAGS = {ContextFlags.CONSTRUCTOR, + ContextFlags.COMMAND_LINE, + ContextFlags.COMPONENT, + ContextFlags.COMPOSITION} + # For backward compatibility class ContextStatus(IntEnum): """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. @@ -155,7 +164,7 @@ class ContextStatus(IntEnum): """Set during execution of the Component's constructor.""" VALIDATION = ContextFlags.VALIDATING """Set during validation of the value of a Component or its attribute.""" - EXECUTION = XXX + EXECUTION = ContextFlags.EXECUTING """Set during any execution of the Component.""" PROCESSING = ContextFlags.PROCESSING """Set during the `processing phase ` of execution of a Composition.""" @@ -196,9 +205,9 @@ def __init__(self, self.execution_phase = execution_phase self.source = source if flags: - if (status != ContextFlags.UNINITIALIZED) and not (flags & ContextFlags.STATUS_MASK & status): + if (status != ContextFlags.UNINITIALIZED) and not (flags & ContextFlags.INITIALIZATION_MASK & status): raise ContextError("Conflict in assignment to flags ({}) and status ({}) arguments of Context for {}". - format(ContextFlags._get_context_string(flags & ContextFlags.STATUS_MASK), + format(ContextFlags._get_context_string(flags & ContextFlags.INITIALIZATION_MASK), ContextFlags._get_context_string(status), self.owner.name)) if ((execution_phase != ContextFlags.IDLE) and @@ -243,23 +252,41 @@ def flags(self, flags): self._flags = flags else: raise ContextError("\'{}\'{} argument in call to {} must be a {} or an int". - format(FLAGS, self.__name__, ContextFlags.__name__)) + format(FLAGS, flags, self.__name__, ContextFlags.__name__)) @property - def status(self): - return self.flags & ContextFlags.STATUS_MASK + def initialization_status(self): + return self.flags & ContextFlags.INITIALIZATION_MASK - @status.setter - def status(self, flag): + @initialization_status.setter + def initialization_status(self, flag): """Check that a flag is one and only one status flag """ - flag &= ContextFlags.STATUS_MASK - if flag in STATUS_FLAGS: + flag &= ContextFlags.INITIALIZATION_MASK + if flag in INITIALIZATION_STATUS_FLAGS: self._flags |= flag elif not flag: - raise ContextError("Attempt to assign a flag ({}) to {}.context.status that is not a STATUS flag". + raise ContextError("Attempt to assign a flag ({}) to {}.context.status " + "that is not an initialization status flag". + format(ContextFlags._get_context_string(flag), self.owner.name)) + else: + raise ContextError("Attempt to assign more than one flag ({}) to {}.context.initialization_status". + format(ContextFlags._get_context_string(flag), self.owner.name)) + + @property + def execution_status(self): + return self.flags & ContextFlags.EXECUTION_STATUS_MASK + + @execution_status.setter + def execution_status(self, flag): + """Check that a flag is one and only one execution_phase flag """ + if flag in EXECUTION_STATUS_FLAGS: + self._flags |= flag + elif not flag & ContextFlags.EXECUTION_STATUS_MASK: + raise ContextError("Attempt to assign a flag ({}) to {}.context.execution_status " + "that is not an execution status flag". format(ContextFlags._get_context_string(flag), self.owner.name)) else: - raise ContextError("Attempt to assign more than one flag ({}) to {}.context.status". + raise ContextError("Attempt to assign more than one flag ({}) to {}.context.execution_status". format(ContextFlags._get_context_string(flag), self.owner.name)) @property @@ -273,7 +300,7 @@ def execution_phase(self, flag): self._flags |= flag elif not flag & ContextFlags.EXECUTION_PHASE_MASK: raise ContextError("Attempt to assign a flag ({}) to {}.context.execution_phase " - "that is not an EXECUTION_PHASE flag". + "that is not an execution phase flag". format(ContextFlags._get_context_string(flag), self.owner.name)) else: raise ContextError("Attempt to assign more than one flag ({}) to {}.context.execution_phase". @@ -289,7 +316,7 @@ def source(self, flag): if flag in SOURCE_FLAGS: self._flags |= flag elif not flag & ContextFlags.SOURCE_MASK: - raise ContextError("Attempt to assign a flag ({}) to {}.context.source that is not a SOURCE flag". + raise ContextError("Attempt to assign a flag ({}) to {}.context.source that is not a source flag". format(ContextFlags._get_context_string(flag), self.owner.name)) else: raise ContextError("Attempt to assign more than one flag ({}) to {}.context.source". From b7e865362484fc29d5ef0adbf3fe950f18140f0e Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Sat, 24 Mar 2018 14:13:23 -0400 Subject: [PATCH 10/41] - --- psyneulink/globals/context.py | 55 +++++++++-------------------------- 1 file changed, 14 insertions(+), 41 deletions(-) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index a87673dbad5..fe4533b3a45 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -75,17 +75,6 @@ class ContextFlags(IntEnum): """Set after completion of initialization of the Component.""" INITIALIZATION_MASK = UNINITIALIZED | DEFERRED_INIT | INITIALIZING | VALIDATING | INITIALIZED - # Execution status flags - IDLE = 1<<5 # 32 - """Set if Component is initialized but not currently executing.""" - EXECUTING = 1<<6 # 64 - """Set while Component is executing""" - TRIAL = 1<<7 # 128 - """Set at the end of a `TRIAL`.""" - RUN = 1<<8 # 256 - """Set at the end of a `RUN`.""" - EXECUTION_MASK = IDLE | EXECUTING | TRIAL | RUN - # #Execution phase flags PROCESSING = 1<<9 # 512 """Set during the `processing phase ` of execution of a Composition.""" @@ -95,7 +84,8 @@ class ContextFlags(IntEnum): """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" SIMULATION = 1<<12 # 4096 """Set during simulation by Composition.controller""" - EXECUTION_PHASE_MASK = PROCESSING | LEARNING | CONTROL | SIMULATION + EXECUTING = PROCESSING | LEARNING | CONTROL | SIMULATION + EXECUTION_PHASE_MASK = EXECUTING # Source-of-call flags CONSTRUCTOR = 1<<13 # 8192 @@ -109,7 +99,7 @@ class ContextFlags(IntEnum): SOURCE_MASK = CONSTRUCTOR | COMMAND_LINE | COMPONENT | COMPOSITION - ALL_FLAGS = INITIALIZATION_MASK | EXECUTION_MASK | EXECUTION_PHASE_MASK | SOURCE_MASK + ALL_FLAGS = INITIALIZATION_MASK | EXECUTION_PHASE_MASK | SOURCE_MASK @classmethod def _get_context_string(cls, condition, string=None): @@ -160,27 +150,27 @@ class ContextStatus(IntEnum): """ OFF = 0 # """No recording.""" - INITIALIZATION = ContextFlags.INITIALIZING + INITIALIZATION = LogCondition.INITIALIZING """Set during execution of the Component's constructor.""" - VALIDATION = ContextFlags.VALIDATING + VALIDATION = LogCondition.VALIDATING """Set during validation of the value of a Component or its attribute.""" - EXECUTION = ContextFlags.EXECUTING + EXECUTION = LogCondition.EXECUTING """Set during any execution of the Component.""" - PROCESSING = ContextFlags.PROCESSING + PROCESSING = LogCondition.PROCESSING """Set during the `processing phase ` of execution of a Composition.""" - LEARNING = ContextFlags.LEARNING + LEARNING = LogCondition.LEARNING """Set during the `learning phase ` of execution of a Composition.""" - CONTROL = ContextFlags.LEARNING + CONTROL = LogCondition.LEARNING """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" - TRIAL = ContextFlags.TRIAL + TRIAL = LogCondition.TRIAL """Set at the end of a `TRIAL`.""" - RUN = ContextFlags.RUN + RUN = LogCondition.RUN """Set at the end of a `RUN`.""" - SIMULATION = ContextFlags.SIMULATION + SIMULATION = LogCondition.SIMULATION # Set during simulation by Composition.controller - COMMAND_LINE = ContextFlags.COMMAND_LINE + COMMAND_LINE = LogCondition.COMMAND_LINE # Component accessed by user - CONSTRUCTOR = ContextFlags.CONSTRUCTOR + CONSTRUCTOR = LogCondition.CONSTRUCTOR # Component being constructor (used in call to super.__init__) ALL_ASSIGNMENTS = \ INITIALIZATION | VALIDATION | EXECUTION | PROCESSING | LEARNING | CONTROL @@ -272,23 +262,6 @@ def initialization_status(self, flag): raise ContextError("Attempt to assign more than one flag ({}) to {}.context.initialization_status". format(ContextFlags._get_context_string(flag), self.owner.name)) - @property - def execution_status(self): - return self.flags & ContextFlags.EXECUTION_STATUS_MASK - - @execution_status.setter - def execution_status(self, flag): - """Check that a flag is one and only one execution_phase flag """ - if flag in EXECUTION_STATUS_FLAGS: - self._flags |= flag - elif not flag & ContextFlags.EXECUTION_STATUS_MASK: - raise ContextError("Attempt to assign a flag ({}) to {}.context.execution_status " - "that is not an execution status flag". - format(ContextFlags._get_context_string(flag), self.owner.name)) - else: - raise ContextError("Attempt to assign more than one flag ({}) to {}.context.execution_status". - format(ContextFlags._get_context_string(flag), self.owner.name)) - @property def execution_phase(self): return self.flags & ContextFlags.EXECUTION_PHASE_MASK From 412a5b9ad8b8b33c701e3135b876c16b457b70ba Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Sat, 24 Mar 2018 14:25:19 -0400 Subject: [PATCH 11/41] - --- psyneulink/globals/context.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index fe4533b3a45..f00fe66f912 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -75,7 +75,7 @@ class ContextFlags(IntEnum): """Set after completion of initialization of the Component.""" INITIALIZATION_MASK = UNINITIALIZED | DEFERRED_INIT | INITIALIZING | VALIDATING | INITIALIZED - # #Execution phase flags + # Execution phase flags PROCESSING = 1<<9 # 512 """Set during the `processing phase ` of execution of a Composition.""" LEARNING = 1<<10 # 1024 @@ -87,6 +87,8 @@ class ContextFlags(IntEnum): EXECUTING = PROCESSING | LEARNING | CONTROL | SIMULATION EXECUTION_PHASE_MASK = EXECUTING + # Run flags + # Source-of-call flags CONSTRUCTOR = 1<<13 # 8192 """Call to method from Component's constructor.""" @@ -150,27 +152,27 @@ class ContextStatus(IntEnum): """ OFF = 0 # """No recording.""" - INITIALIZATION = LogCondition.INITIALIZING + INITIALIZATION = ContextFlags.INITIALIZING """Set during execution of the Component's constructor.""" - VALIDATION = LogCondition.VALIDATING + VALIDATION = ContextFlags.VALIDATING """Set during validation of the value of a Component or its attribute.""" - EXECUTION = LogCondition.EXECUTING + EXECUTION = ContextFlags.EXECUTING """Set during any execution of the Component.""" - PROCESSING = LogCondition.PROCESSING + PROCESSING = ContextFlags.PROCESSING """Set during the `processing phase ` of execution of a Composition.""" - LEARNING = LogCondition.LEARNING + LEARNING = ContextFlags.LEARNING """Set during the `learning phase ` of execution of a Composition.""" - CONTROL = LogCondition.LEARNING + CONTROL = ContextFlags.LEARNING """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" - TRIAL = LogCondition.TRIAL + TRIAL = ContextFlags.TRIAL """Set at the end of a `TRIAL`.""" - RUN = LogCondition.RUN + RUN = ContextFlags.RUN """Set at the end of a `RUN`.""" - SIMULATION = LogCondition.SIMULATION + SIMULATION = ContextFlags.SIMULATION # Set during simulation by Composition.controller - COMMAND_LINE = LogCondition.COMMAND_LINE + COMMAND_LINE = ContextFlags.COMMAND_LINE # Component accessed by user - CONSTRUCTOR = LogCondition.CONSTRUCTOR + CONSTRUCTOR = ContextFlags.CONSTRUCTOR # Component being constructor (used in call to super.__init__) ALL_ASSIGNMENTS = \ INITIALIZATION | VALIDATION | EXECUTION | PROCESSING | LEARNING | CONTROL From 02bbed1bd3f5f35a851e3b0a5fc5628df7006947 Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Sat, 24 Mar 2018 14:26:07 -0400 Subject: [PATCH 12/41] - --- psyneulink/globals/context.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index f00fe66f912..f2500080d4d 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -88,6 +88,10 @@ class ContextFlags(IntEnum): EXECUTION_PHASE_MASK = EXECUTING # Run flags + TRIAL = 1<<7 # 128 + """Set at the end of a `TRIAL`.""" + RUN = 1<<8 # 256 + """Set at the end of a `RUN`.""" # Source-of-call flags CONSTRUCTOR = 1<<13 # 8192 From 92413186052b862e34fb22418c460a68664a49be Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Sat, 24 Mar 2018 14:55:13 -0400 Subject: [PATCH 13/41] - --- psyneulink/globals/context.py | 38 +++++++++---------------- psyneulink/globals/log.py | 52 ++++++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index f2500080d4d..2abcdda13b5 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -76,35 +76,28 @@ class ContextFlags(IntEnum): INITIALIZATION_MASK = UNINITIALIZED | DEFERRED_INIT | INITIALIZING | VALIDATING | INITIALIZED # Execution phase flags - PROCESSING = 1<<9 # 512 + PROCESSING = 1<<5 # 32 """Set during the `processing phase ` of execution of a Composition.""" - LEARNING = 1<<10 # 1024 + LEARNING = 1<<6 # 64 """Set during the `learning phase ` of execution of a Composition.""" - CONTROL = 1<<11 # 2048 + CONTROL = 1<<7 # 128 """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" - SIMULATION = 1<<12 # 4096 + SIMULATION = 1<<8 # 256 """Set during simulation by Composition.controller""" - EXECUTING = PROCESSING | LEARNING | CONTROL | SIMULATION - EXECUTION_PHASE_MASK = EXECUTING - - # Run flags - TRIAL = 1<<7 # 128 - """Set at the end of a `TRIAL`.""" - RUN = 1<<8 # 256 - """Set at the end of a `RUN`.""" + EXECUTION_PHASE_MASK = PROCESSING | LEARNING | CONTROL | SIMULATION + EXECUTING = EXECUTION_PHASE_MASK # Source-of-call flags - CONSTRUCTOR = 1<<13 # 8192 + CONSTRUCTOR = 1<<9 # 512 """Call to method from Component's constructor.""" - COMMAND_LINE = 1<<14 # 16384 + COMMAND_LINE = 1<<10 # 1024 """Direct call to method by user (either interactively from the command line, or in a script).""" - COMPONENT = 1<<15 # 32768 + COMPONENT = 1<<11 # 2048 """Call to method by the Component.""" - COMPOSITION = 1<<16 # 65536 + COMPOSITION = 1<<12 # 4096 """Call to method by a/the Composition to which the Component belongs.""" SOURCE_MASK = CONSTRUCTOR | COMMAND_LINE | COMPONENT | COMPOSITION - ALL_FLAGS = INITIALIZATION_MASK | EXECUTION_PHASE_MASK | SOURCE_MASK @classmethod @@ -134,11 +127,6 @@ def _get_context_string(cls, condition, string=None): ContextFlags.VALIDATING, ContextFlags.INITIALIZED} -EXECUTION_STATUS_FLAGS = {ContextFlags.IDLE, - ContextFlags.EXECUTING, - ContextFlags.TRIAL, - ContextFlags.RUN} - EXECUTION_PHASE_FLAGS = {ContextFlags.PROCESSING, ContextFlags.LEARNING, ContextFlags.CONTROL, @@ -154,7 +142,7 @@ class ContextStatus(IntEnum): """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. Also used to specify the context in which a value of the Component or its attribute is `logged `. """ - OFF = 0 + OFF = LogCondition.OFF # """No recording.""" INITIALIZATION = ContextFlags.INITIALIZING """Set during execution of the Component's constructor.""" @@ -168,9 +156,9 @@ class ContextStatus(IntEnum): """Set during the `learning phase ` of execution of a Composition.""" CONTROL = ContextFlags.LEARNING """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" - TRIAL = ContextFlags.TRIAL + TRIAL = LogCondition.TRIAL """Set at the end of a `TRIAL`.""" - RUN = ContextFlags.RUN + RUN = LogCondition.RUN """Set at the end of a `RUN`.""" SIMULATION = ContextFlags.SIMULATION # Set during simulation by Composition.controller diff --git a/psyneulink/globals/log.py b/psyneulink/globals/log.py index 4a620dc5539..a789441ae7a 100644 --- a/psyneulink/globals/log.py +++ b/psyneulink/globals/log.py @@ -307,7 +307,7 @@ IMPLEMENTATION NOTE: Name of owner Component is aliases to VALUE in loggable_items and logged_items, but is the Component's actual name in log_entries -Entries are made to the Log based on the `ContextFlags` specified in the +Entries are made to the Log based on the `LogCondition` specified in the `logPref` item of the component's `prefs ` attribute. Adding an item to prefs.logPref will validate and add an entry for that attribute to the Log dict @@ -319,7 +319,7 @@ * it is included in the *LOG_ENTRIES* entry of a `parameter specification dictionary ` assigned to the **params** argument of the constructor for the Component; .. -* the current `ContextFlags` is one specified in the logPref setting of the owner Component +* the current `LogCondition` is one specified in the logPref setting of the owner Component Entry values are added by the setter method for the attribute being logged. @@ -331,7 +331,7 @@ - any variables listed in the params[LOG_ENTRIES] of a Mechanism -DEFAULT ContextFlags FOR ALL COMPONENTS IS *OFF* +DEFAULT LogCondition FOR ALL COMPONENTS IS *OFF* Structure @@ -345,10 +345,14 @@ - context (str): the context in which it was recorded (i.e., where the attribute value was assigned) - value (value): the value assigned to the attribute -The ContextFlags class (see declaration above) defines six levels of logging: +The LogCondition class (see declaration above) defines the conditions under which a value can be logged: + OFF: No logging for attributes of the owner object - + EXECUTION: Log values for all assignments during execution (e.g., including aggregation of projections) + + INITIALIZATION: Log value when the Component is initialized + VALIDATION: Log value assignments during validation as well as execution and initialization + + EXECUTION: Log value of Component during all phases of execution (processing, learning and control) + + PROCESSING + + + ALL_ASSIGNMENTS: Log all value assignments (e.g., including initialization) Note: ContextFlags is an IntEnum, and thus its values can be used directly in numerical comparisons @@ -405,6 +409,41 @@ LogEntry = namedtuple('LogEntry', 'time, context, value') + +class LogCondition(IntEnum): + """Used to specify the context in which a value of the Component or its attribute is `logged `. + """ + OFF = 0 + # """No recording.""" + INITIALIZATION = ContextFlags.INITIALIZING + """Set during execution of the Component's constructor.""" + VALIDATION = ContextFlags.VALIDATING + """Set during validation of the value of a Component or its attribute.""" + EXECUTION = ContextFlags.EXECUTING + """Set during all `phases of execution ` of the Component.""" + PROCESSING = ContextFlags.PROCESSING + """Set during the `processing phase ` of execution of a Composition.""" + LEARNING = ContextFlags.LEARNING + """Set during the `learning phase ` of execution of a Composition.""" + CONTROL = ContextFlags.CONTROL + """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" + SIMULATION = ContextFlags.SIMULATION + # Set during simulation by Composition.controller + TRIAL = ContextFlags.SIMULAION<<1 + """Set at the end of a `TRIAL`.""" + RUN = ContextFlags.SIMULATION<<2 + """Set at the end of a `RUN`.""" + + # COMMAND_LINE = ContextFlags.COMMAND_LINE + # # Component accessed by user + # CONSTRUCTOR = ContextFlags.CONSTRUCTOR + # # Component being constructor (used in call to super.__init__) + ALL_ASSIGNMENTS = \ + INITIALIZATION | VALIDATION | EXECUTION | PROCESSING | LEARNING | CONTROL + """Specifies all contexts.""" + + + TIME_NOT_SPECIFIED = 'Time Not Specified' @@ -699,8 +738,7 @@ def _log_value(self, value, time=None, context=None): If **value** is a LogEntry, it is assigned to the entry If **context** is a ContextFlags, it is used to determine whether the entry should be made; **time** must be passed; the name of the ContextFlags(s) specified are assigned to the context of LogEntry - Otherwise, uses string (or Component) passed in **context**, or searches stack (see note) to determine the - context, and uses that to determine the scheduler and, from that, the time; + Otherwise, uses string (or Component) passed in **context**; If value is None, uses owner's `value ` attribute. .. note:: From 3f546b2ec3de275246bcf913d30249746eb840bd Mon Sep 17 00:00:00 2001 From: jdcpni Date: Sat, 24 Mar 2018 14:59:36 -0400 Subject: [PATCH 14/41] - --- psyneulink/globals/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psyneulink/globals/log.py b/psyneulink/globals/log.py index a789441ae7a..6a53e86477a 100644 --- a/psyneulink/globals/log.py +++ b/psyneulink/globals/log.py @@ -439,7 +439,7 @@ class LogCondition(IntEnum): # CONSTRUCTOR = ContextFlags.CONSTRUCTOR # # Component being constructor (used in call to super.__init__) ALL_ASSIGNMENTS = \ - INITIALIZATION | VALIDATION | EXECUTION | PROCESSING | LEARNING | CONTROL + INITIALIZATION | VALIDATION | EXECUTION | PROCESSING | LEARNING | CONTROL | SIMULATION | TRIAL | RUN """Specifies all contexts.""" From d5823e79ce2a98c09568454fd767196a386d4a6c Mon Sep 17 00:00:00 2001 From: jdcpni Date: Sat, 24 Mar 2018 15:36:38 -0400 Subject: [PATCH 15/41] =?UTF-8?q?=E2=80=A2=20Log=20=20=20LogCondition=20-?= =?UTF-8?q?=20subset=20of=20ContextFlags=20used=20to=20specified=20logPref?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Context ContextFlags - implemented as common set of context flags for: - initialization - execution tracking - logging ContextStatus - aliases to ContextFlags (for backward compatibility) --- psyneulink/globals/context.py | 3 +- psyneulink/globals/log.py | 103 ++++++++++-------- .../preferences/componentpreferenceset.py | 6 +- 3 files changed, 61 insertions(+), 51 deletions(-) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index 2abcdda13b5..6bbadecb9fc 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -109,7 +109,7 @@ def _get_context_string(cls, condition, string=None): string = "" flagged_items = [] # If OFF or ALL_FLAGS, just return that - if condition in (ContextFlags.ALL_FLAGS, ContextFlags.OFF): + if condition in (ContextFlags.ALL_FLAGS, ContextFlags.UNINITIALIZED): return condition.name # Otherwise, append each flag's name to the string for c in list(cls.__members__): @@ -142,6 +142,7 @@ class ContextStatus(IntEnum): """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. Also used to specify the context in which a value of the Component or its attribute is `logged `. """ + from psyneulink.globals.log import LogCondition OFF = LogCondition.OFF # """No recording.""" INITIALIZATION = ContextFlags.INITIALIZING diff --git a/psyneulink/globals/log.py b/psyneulink/globals/log.py index 6a53e86477a..63798b5f739 100644 --- a/psyneulink/globals/log.py +++ b/psyneulink/globals/log.py @@ -112,38 +112,38 @@ Logging Conditions ~~~~~~~~~~~~~~~~~~ -Configuring a Component to be logged is done using a condition, that specifies a `ContextFlags` under which its +Configuring a Component to be logged is done using a condition, that specifies a `LogCondition` under which its `value ` should be entered in its Log. These can be specified in the `set_log_conditions -` method of a Log, or directly by specifying a `ContextFlags` for the value a Component's +` method of a Log, or directly by specifying a `LogCondition` for the value a Component's `logPref ` item of its `prefs ` attribute. The former is easier, and allows multiple Components to be specied at once, while the latter affords more control over the specification (see -`Preferences`). `ContextStates ` are treated as binary "flags", and can be combined to permit logging -under more than one condition using bitwise operators on the `ContextStates `. For convenience, they +`Preferences`). `LogConditions ` are treated as binary "flags", and can be combined to permit logging +under more than one condition using bitwise operators on the `LogConditions `. For convenience, they can also be referred to by their names, and combined by specifying a list. For example, all of the following specify that the `value ` of ``my_mech`` be logged both during execution and learning:: >>> import psyneulink as pnl >>> my_mech = pnl.TransferMechanism() - >>> my_mech.set_log_conditions('value', pnl.ContextFlags.EXECUTION | pnl.ContextFlags.LEARNING) - >>> my_mech.set_log_conditions('value', pnl.ContextFlags.EXECUTION + pnl.ContextFlags.LEARNING) + >>> my_mech.set_log_conditions('value', pnl.LogCondition.EXECUTION | pnl.LogCondition.LEARNING) + >>> my_mech.set_log_conditions('value', pnl.LogCondition.EXECUTION + pnl.LogCondition.LEARNING) >>> my_mech.set_log_conditions('value', [pnl.EXECUTION, LEARNING]) .. note:: - Currently, the `VALIDATION` `ContextFlags` is not implemented. + Currently, the `VALIDATION` `LogCondition` is not implemented. .. note:: - Using `ContextFlags.INITIALIZATION` to log the `value ` of a Component during its initialization + Using `LogCondition.INITIALIZATION` to log the `value ` of a Component during its initialization requires that it be assigned in the **prefs** argument of the Component's constructor. For example:: COMMENT: FIX: THIS EXAMPLE CAN'T CURRENTLY BE EXECUTED AS IT PERMANENTLY SETS THE LogPref FOR ALL TransferMechanism COMMENT >>> my_mech = pnl.TransferMechanism( - ... prefs={pnl.LOG_PREF: pnl.PreferenceEntry(pnl.ContextFlags.INITIALIZATION, pnl.PreferenceLevel.INSTANCE)}) + ... prefs={pnl.LOG_PREF: pnl.PreferenceEntry(pnl.LogCondition.INITIALIZATION, pnl.PreferenceLevel.INSTANCE)}) .. hint:: - `ContextFlags.TRIAL` logs the `value ` of a Component at the end of a `TRIAL`. To log its + `LogCondition.TRIAL` logs the `value ` of a Component at the end of a `TRIAL`. To log its `value ` at the start of a `TRIAL`, use its `log_values ` method in the **call_before_trial** argument of the System's `run ` method. @@ -153,7 +153,7 @@ --------- The value of a Component is recorded to a Log when the condition assigned to its `logPref ` is met. -This is specified as a `ContextFlags` or a boolean combination of them (see `Log_Conditions`). The default ContextFlags +This is specified as a `LogCondition` or a boolean combination of them (see `Log_Conditions`). The default LogCondition is `OFF`. .. _Log_Examples: @@ -187,7 +187,7 @@ >>> my_mech_A.set_log_conditions([pnl.NOISE, pnl.RESULTS]) >>> proj_A_to_B.set_log_conditions(pnl.MATRIX) -Note that since no `condition ` was specified, the default (ContextFlags.EXECUTION) is used. +Note that since no `condition ` was specified, the default (LogCondition.EXECUTION) is used. Executing the Process generates entries in the Logs, that can then be displayed in several ways:: COMMENT: @@ -304,22 +304,26 @@ COMMENT: -IMPLEMENTATION NOTE: Name of owner Component is aliases to VALUE in loggable_items and logged_items, +IMPLEMENTATION NOTE(S): + +Name of owner Component is aliased to VALUE in loggable_items and logged_items, but is the Component's actual name in log_entries +LogCondition flags are compared bitwise against the ContextFlags currently set for the Component + Entries are made to the Log based on the `LogCondition` specified in the `logPref` item of the component's `prefs ` attribute. -Adding an item to prefs.logPref will validate and add an entry for that attribute to the Log dict +# Adding an item to prefs.logPref validates it and adds an entry for that attribute to the Log dict An attribute is logged if: -* it is one `automatically included ` in logging; -.. +# * it is one `automatically included ` in logging; + * it is included in the *LOG_ENTRIES* entry of a `parameter specification dictionary ` assigned to the **params** argument of the constructor for the Component; -.. -* the current `LogCondition` is one specified in the logPref setting of the owner Component + +* the LogCondition(s) specified in a Component's logpref match the current `ContextFlags` in its context attribute Entry values are added by the setter method for the attribute being logged. @@ -333,7 +337,6 @@ DEFAULT LogCondition FOR ALL COMPONENTS IS *OFF* - Structure --------- @@ -345,16 +348,7 @@ - context (str): the context in which it was recorded (i.e., where the attribute value was assigned) - value (value): the value assigned to the attribute -The LogCondition class (see declaration above) defines the conditions under which a value can be logged: - + OFF: No logging for attributes of the owner object - + INITIALIZATION: Log value when the Component is initialized - + VALIDATION: Log value assignments during validation as well as execution and initialization - + EXECUTION: Log value of Component during all phases of execution (processing, learning and control) - + PROCESSING - - - + ALL_ASSIGNMENTS: Log all value assignments (e.g., including initialization) - Note: ContextFlags is an IntEnum, and thus its values can be used directly in numerical comparisons +The LogCondition class (see declaration below) defines the conditions under which a value can be logged. Entries can also be added programmatically by: - including them in the logPref of a PreferenceSet @@ -412,6 +406,9 @@ class LogCondition(IntEnum): """Used to specify the context in which a value of the Component or its attribute is `logged `. + .. note:: + This is meant to be a subset of (and therefore references) ContextFlags bitwise enum, with the exception of + TRIAL and RUN, which are bit-shifted to follow the ContextFlags.SIMULATION value. """ OFF = 0 # """No recording.""" @@ -433,15 +430,30 @@ class LogCondition(IntEnum): """Set at the end of a `TRIAL`.""" RUN = ContextFlags.SIMULATION<<2 """Set at the end of a `RUN`.""" - - # COMMAND_LINE = ContextFlags.COMMAND_LINE - # # Component accessed by user - # CONSTRUCTOR = ContextFlags.CONSTRUCTOR - # # Component being constructor (used in call to super.__init__) ALL_ASSIGNMENTS = \ - INITIALIZATION | VALIDATION | EXECUTION | PROCESSING | LEARNING | CONTROL | SIMULATION | TRIAL | RUN + INITIALIZATION | VALIDATION | EXECUTION | PROCESSING | LEARNING | CONTROL """Specifies all contexts.""" + @classmethod + def _get_context_string(cls, condition, string=None): + """Return string with the names of all flags that are set in **condition**, prepended by **string**""" + if string: + string += ": " + else: + string = "" + flagged_items = [] + # If OFF or ALL_ASSIGNMENTS, just return that + if condition in (LogCondition.ALL_ASSIGNMENTS, LogCondition.OFF): + return condition.name + # Otherwise, append each flag's name to the string + for c in list(cls.__members__): + # Skip ALL_ASSIGNMENTS (handled above) + if c is LogCondition.ALL_ASSIGNMENTS.name: + continue + if LogCondition[c] & condition: + flagged_items.append(c) + string += ", ".join(flagged_items) + return string TIME_NOT_SPECIFIED = 'Time Not Specified' @@ -635,7 +647,7 @@ class Log: loggable_items : Dict[Component.name: List[LogEntry]] identifies Components that can be logged by the owner; the key of each entry is the name of a Component, - and the value is its currently assigned `ContextFlags`. + and the value is its currently assigned `LogCondition`. entries : Dict[Component.name: List[LogEntry]] contains the logged information for `loggable_components `; the key of each entry @@ -644,7 +656,7 @@ class Log: logged_items : Dict[Component.name: List[LogEntry]] identifies Components that currently have entries in the Log; the key for each entry is the name - of a Component, and the value is its currently assigned `ContextFlags`. + of a Component, and the value is its currently assigned `LogCondition`. """ @@ -665,7 +677,7 @@ def __init__(self, owner, entries=None): return def set_log_conditions(self, items, log_condition=ContextFlags.EXECUTING): - """Specifies items to be logged at the specified `ContextFlags`\\(s). + """Specifies items to be logged at the specified `LogCondition`\\(s). Arguments --------- @@ -677,10 +689,10 @@ def set_log_conditions(self, items, log_condition=ContextFlags.EXECUTING): * a reference to a Component; * tuple, the first item of which is one of the above, and the second a `ContextFlags` to use for the item. - log_condition : ContextFlags : default ContextFlags.EXECUTION - specifies `ContextFlags` to use as the default for items not specified in tuples (see above). - For convenience, the name of a ContextFlags can be used in place of its full specification - (e.g., *EXECUTION* instead of `ContextFlags.EXECUTION`). + log_condition : LogCondition : default LogCondition.EXECUTION + specifies `LogCondition` to use as the default for items not specified in tuples (see above). + For convenience, the name of a LogCondition can be used in place of its full specification + (e.g., *EXECUTION* instead of `LogCondition.EXECUTION`). params_set : list : default None list of parameters to include as loggable items; these must be attributes of the `owner ` @@ -693,7 +705,7 @@ def set_log_conditions(self, items, log_condition=ContextFlags.EXECUTING): def assign_log_condition(item, level): - # Handle multiple level assignments (as ContextStates or strings in a list) + # Handle multiple level assignments (as LogCondition or strings in a list) if not isinstance(level, list): level = [level] levels = ContextFlags.OFF @@ -737,7 +749,7 @@ def _log_value(self, value, time=None, context=None): If **value** is a LogEntry, it is assigned to the entry If **context** is a ContextFlags, it is used to determine whether the entry should be made; - **time** must be passed; the name of the ContextFlags(s) specified are assigned to the context of LogEntry + **time** must be passed; the name of the ContextFlags specified are assigned to the context of LogEntry Otherwise, uses string (or Component) passed in **context**; If value is None, uses owner's `value ` attribute. @@ -1484,11 +1496,9 @@ def loggable_items(self): for c in self.loggable_components: name = self._alias_owner_name(c.name) try: - # log_pref_names = c.logPref.name log_pref_names = ContextFlags._get_context_string(c.logPref) except: log_pref_names = None - # log_pref_names = ContextFlags._get_condition_string(c.logPref) loggable_items[name] = log_pref_names return loggable_items @@ -1516,7 +1526,6 @@ def logged_items(self): # Return ContextFlags for items in log.entries logged_items = {key: value for (key, value) in - # [(l, self.loggable_components[l].logPref.name) [(self._alias_owner_name(l), self.loggable_items[self._alias_owner_name(l)]) for l in self.logged_entries.keys()]} diff --git a/psyneulink/globals/preferences/componentpreferenceset.py b/psyneulink/globals/preferences/componentpreferenceset.py index 0dc489ca207..a54deeafffe 100644 --- a/psyneulink/globals/preferences/componentpreferenceset.py +++ b/psyneulink/globals/preferences/componentpreferenceset.py @@ -57,7 +57,7 @@ kpVerbosePref: PreferenceEntry(False, PreferenceLevel.SYSTEM), kpParamValidationPref: PreferenceEntry(True, PreferenceLevel.SYSTEM), kpReportOutputPref: PreferenceEntry(False, PreferenceLevel.SYSTEM), - kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), + kpLogPref: PreferenceEntry(LogCondition.OFF, PreferenceLevel.CATEGORY), kpRuntimeParamModulationPref: PreferenceEntry(Modulation.MULTIPLY, PreferenceLevel.SYSTEM), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.SYSTEM)} @@ -75,7 +75,7 @@ kpVerbosePref: PreferenceEntry(False, PreferenceLevel.TYPE), kpParamValidationPref: PreferenceEntry(True, PreferenceLevel.TYPE), kpReportOutputPref: PreferenceEntry(False, PreferenceLevel.TYPE), - kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms + kpLogPref: PreferenceEntry(LogCondition.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms kpRuntimeParamModulationPref: PreferenceEntry(Modulation.ADD,PreferenceLevel.TYPE), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.TYPE)} @@ -93,7 +93,7 @@ kpVerbosePref: PreferenceEntry(False, PreferenceLevel.INSTANCE), kpParamValidationPref: PreferenceEntry(False, PreferenceLevel.INSTANCE), kpReportOutputPref: PreferenceEntry(False, PreferenceLevel.INSTANCE), - kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms + kpLogPref: PreferenceEntry(LogCondition.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms kpRuntimeParamModulationPref: PreferenceEntry(Modulation.OVERRIDE, PreferenceLevel.INSTANCE), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.INSTANCE)} From c23ceba1d5b532cf04a702450513d5d9b6ce76f0 Mon Sep 17 00:00:00 2001 From: jdcpni Date: Sat, 24 Mar 2018 15:44:24 -0400 Subject: [PATCH 16/41] =?UTF-8?q?=E2=80=A2=20Log=20=20=20LogCondition=20-?= =?UTF-8?q?=20subset=20of=20ContextFlags=20used=20to=20specified=20logPref?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Context ContextFlags - implemented as common set of context flags for: - initialization - execution tracking - logging ContextStatus - aliases to ContextFlags (for backward compatibility) --- psyneulink/globals/context.py | 8 ++++---- psyneulink/globals/environment.py | 3 ++- psyneulink/globals/log.py | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index 6bbadecb9fc..cde8fbfc22a 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -329,10 +329,10 @@ def _get_context(context:tc.any(ContextFlags, str)): context_flag |= ContextFlags.CONTROL if LEARNING in context: context_flag |= ContextFlags.LEARNING - if context == ContextFlags.TRIAL.name: # cxt-test - context_flag |= ContextFlags.TRIAL - if context == ContextFlags.RUN.name: - context_flag |= ContextFlags.RUN + # if context == ContextFlags.TRIAL.name: # cxt-test + # context_flag |= ContextFlags.TRIAL + # if context == ContextFlags.RUN.name: + # context_flag |= ContextFlags.RUN if context == ContextFlags.COMMAND_LINE.name: context_flag |= ContextFlags.COMMAND_LINE return context_flag diff --git a/psyneulink/globals/environment.py b/psyneulink/globals/environment.py index 1879189f9a4..edfc56f4bb5 100644 --- a/psyneulink/globals/environment.py +++ b/psyneulink/globals/environment.py @@ -702,7 +702,8 @@ def run(object, # Class-specific validation: context = context or RUN + "validating " + object.name # cxt-done ? cxt-pass if object.context.status is ContextFlags.OFF: - object.context.status = ContextFlags.RUN + ContextFlags.VALIDATION + # object.context.status = ContextFlags.RUN + ContextFlags.VALIDATION + object.context.status = ContextFlags.VALIDATION object.context.string = RUN + "validating " + object.name # INITIALIZATION diff --git a/psyneulink/globals/log.py b/psyneulink/globals/log.py index 63798b5f739..986339e630d 100644 --- a/psyneulink/globals/log.py +++ b/psyneulink/globals/log.py @@ -1541,7 +1541,7 @@ def logged_entries(self): # def save_log(self): # print("Saved") -def _log_trials_and_runs(composition, curr_condition:tc.enum(ContextFlags.TRIAL, ContextFlags.RUN), context): +def _log_trials_and_runs(composition, curr_condition:tc.enum(LogCondition.TRIAL, LogCondition.RUN), context): # FIX: ALSO CHECK TIME FOR scheduler_learning, AND CHECK DATE FOR BOTH, AND USE WHICHEVER IS LATEST # FIX: BUT WHAT IF THIS PARTICULAR COMPONENT WAS RUN IN THE LAST TIME_STEP?? for mech in composition.mechanisms: From e038bd103e9acc028450ba2dd61fa3603c710e4a Mon Sep 17 00:00:00 2001 From: jdcpni Date: Sat, 24 Mar 2018 16:04:44 -0400 Subject: [PATCH 17/41] =?UTF-8?q?=E2=80=A2=20Log=20=20=20LogCondition=20-?= =?UTF-8?q?=20subset=20of=20ContextFlags=20used=20to=20specified=20logPref?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Context ContextFlags - implemented as common set of context flags for: - initialization - execution tracking - logging ContextStatus - aliases to ContextFlags (for backward compatibility) --- psyneulink/components/component.py | 2 +- psyneulink/globals/context.py | 18 +++++++----------- psyneulink/globals/log.py | 2 +- .../preferences/componentpreferenceset.py | 10 +++++----- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/psyneulink/components/component.py b/psyneulink/components/component.py index 2e558981a64..56ddb7764e9 100644 --- a/psyneulink/components/component.py +++ b/psyneulink/components/component.py @@ -873,7 +873,7 @@ def __init__(self, # return context = context + INITIALIZING + ": " + COMPONENT_INIT # cxt-done self.context.status = ContextFlags.INITIALIZING - self.context.execution_phase = ContextFlags.IDLE + self.context.execution_phase = None self.context.source = ContextFlags.COMPONENT self.context.string = context + INITIALIZING + ": " + COMPONENT_INIT diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index cde8fbfc22a..6076f951e6b 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -142,8 +142,7 @@ class ContextStatus(IntEnum): """Used to identify the status of a `Component` when its value or one of its attributes is being accessed. Also used to specify the context in which a value of the Component or its attribute is `logged `. """ - from psyneulink.globals.log import LogCondition - OFF = LogCondition.OFF + OFF = 0 # """No recording.""" INITIALIZATION = ContextFlags.INITIALIZING """Set during execution of the Component's constructor.""" @@ -157,10 +156,6 @@ class ContextStatus(IntEnum): """Set during the `learning phase ` of execution of a Composition.""" CONTROL = ContextFlags.LEARNING """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" - TRIAL = LogCondition.TRIAL - """Set at the end of a `TRIAL`.""" - RUN = LogCondition.RUN - """Set at the end of a `RUN`.""" SIMULATION = ContextFlags.SIMULATION # Set during simulation by Composition.controller COMMAND_LINE = ContextFlags.COMMAND_LINE @@ -179,7 +174,7 @@ def __init__(self, composition=None, flags=None, status=ContextFlags.UNINITIALIZED, - execution_phase=ContextFlags.IDLE, + execution_phase=None, source=ContextFlags.COMPONENT, execution_id:UUID=None, string:str='', time=None): @@ -195,8 +190,7 @@ def __init__(self, format(ContextFlags._get_context_string(flags & ContextFlags.INITIALIZATION_MASK), ContextFlags._get_context_string(status), self.owner.name)) - if ((execution_phase != ContextFlags.IDLE) and - not (flags & ContextFlags.EXECUTION_PHASE_MASK & execution_phase)): + if (execution_phase and not (flags & ContextFlags.EXECUTION_PHASE_MASK & execution_phase)): raise ContextError("Conflict in assignment to flags ({}) and execution_phase ({}) arguments " "of Context for {}". format(ContextFlags._get_context_string(flags & ContextFlags.EXECUTION_PHASE_MASK), @@ -266,6 +260,8 @@ def execution_phase(self, flag): """Check that a flag is one and only one execution_phase flag """ if flag in EXECUTION_PHASE_FLAGS: self._flags |= flag + elif flag is None: + self._flags &= ~ContextFlags.EXECUTING elif not flag & ContextFlags.EXECUTION_PHASE_MASK: raise ContextError("Attempt to assign a flag ({}) to {}.context.execution_phase " "that is not an execution phase flag". @@ -376,8 +372,8 @@ def _get_time(component, context_flags): # Get System in which it is being (or was last) executed (if any): # If called from COMMAND_LINE, get context for last time value was assigned: - # if context_flags & ContextFlags.COMMAND_LINE: - if context_flags & (ContextFlags.COMMAND_LINE | ContextFlags.RUN | ContextFlags.TRIAL): + if context_flags & ContextFlags.COMMAND_LINE: + # if context_flags & (ContextFlags.COMMAND_LINE | ContextFlags.RUN | ContextFlags.TRIAL): context_flags = component.prev_context.status execution_context = component.prev_context.string else: diff --git a/psyneulink/globals/log.py b/psyneulink/globals/log.py index 986339e630d..f3ec160a683 100644 --- a/psyneulink/globals/log.py +++ b/psyneulink/globals/log.py @@ -426,7 +426,7 @@ class LogCondition(IntEnum): """Set during the `control phase System_Execution_Control>` of execution of a Composition.""" SIMULATION = ContextFlags.SIMULATION # Set during simulation by Composition.controller - TRIAL = ContextFlags.SIMULAION<<1 + TRIAL = ContextFlags.SIMULATION<<1 """Set at the end of a `TRIAL`.""" RUN = ContextFlags.SIMULATION<<2 """Set at the end of a `RUN`.""" diff --git a/psyneulink/globals/preferences/componentpreferenceset.py b/psyneulink/globals/preferences/componentpreferenceset.py index a54deeafffe..1f9e9ee708a 100644 --- a/psyneulink/globals/preferences/componentpreferenceset.py +++ b/psyneulink/globals/preferences/componentpreferenceset.py @@ -13,7 +13,7 @@ import inspect from psyneulink.globals.keywords import NAME, kwDefaultPreferenceSetOwner, kwPrefLevel, kwPreferenceSetName, kwPrefs, kwPrefsOwner -from psyneulink.globals.log import ContextFlags +from psyneulink.globals.log import LogCondition from psyneulink.globals.preferences.preferenceset import PreferenceEntry, PreferenceLevel, PreferenceSet from psyneulink.globals.utilities import Modulation @@ -66,7 +66,7 @@ kpVerbosePref: PreferenceEntry(False, PreferenceLevel.CATEGORY), kpParamValidationPref: PreferenceEntry(True, PreferenceLevel.CATEGORY), kpReportOutputPref: PreferenceEntry(False, PreferenceLevel.CATEGORY), - kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), + kpLogPref: PreferenceEntry(LogCondition.OFF, PreferenceLevel.CATEGORY), kpRuntimeParamModulationPref: PreferenceEntry(Modulation.MULTIPLY,PreferenceLevel.CATEGORY), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.CATEGORY)} @@ -84,7 +84,7 @@ kpVerbosePref: PreferenceEntry(False, PreferenceLevel.SUBTYPE), kpParamValidationPref: PreferenceEntry(True, PreferenceLevel.SUBTYPE), kpReportOutputPref: PreferenceEntry(False, PreferenceLevel.SUBTYPE), - kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms + kpLogPref: PreferenceEntry(LogCondition.OFF, PreferenceLevel.CATEGORY), # This gives control to Mechanisms kpRuntimeParamModulationPref: PreferenceEntry(Modulation.ADD,PreferenceLevel.SUBTYPE), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.SUBTYPE)} @@ -131,7 +131,7 @@ class ComponentPreferenceSet(PreferenceSet): - verbose (bool): enables/disables reporting of (non-exception) warnings and system function - paramValidation (bool): enables/disables run-time validation of the execute method of a Function object - reportOutput (bool): enables/disables reporting of execution of execute method - - log (bool): sets ContextFlags for a given Component + - log (bool): sets LogCondition for a given Component - functionRunTimeParams (Modulation): uses run-time params to modulate execute method params Implement the following preference levels: - SYSTEM: System level default settings (Function.classPreferences) @@ -230,7 +230,7 @@ class ComponentPreferenceSet(PreferenceSet): kpVerbosePref: PreferenceEntry(False, PreferenceLevel.SYSTEM), kpParamValidationPref: PreferenceEntry(True, PreferenceLevel.SYSTEM), kpReportOutputPref: PreferenceEntry(True, PreferenceLevel.SYSTEM), - kpLogPref: PreferenceEntry(ContextFlags.OFF, PreferenceLevel.CATEGORY), + kpLogPref: PreferenceEntry(LogCondition.OFF, PreferenceLevel.CATEGORY), kpRuntimeParamModulationPref: PreferenceEntry(Modulation.MULTIPLY, PreferenceLevel.SYSTEM), kpRuntimeParamStickyAssignmentPref: PreferenceEntry(False, PreferenceLevel.SYSTEM) From 3fe767969b9a69cba87d4c598985fc185d99dd4f Mon Sep 17 00:00:00 2001 From: jdcpni Date: Sat, 24 Mar 2018 16:21:47 -0400 Subject: [PATCH 18/41] - --- psyneulink/components/component.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/psyneulink/components/component.py b/psyneulink/components/component.py index 56ddb7764e9..95655cde794 100644 --- a/psyneulink/components/component.py +++ b/psyneulink/components/component.py @@ -406,6 +406,7 @@ class `UserList Date: Sun, 25 Mar 2018 22:58:43 -0400 Subject: [PATCH 19/41] - --- psyneulink/components/component.py | 6 ++-- psyneulink/components/mechanisms/mechanism.py | 10 +++---- psyneulink/components/process.py | 19 ++++++------ .../modulatory/learningprojection.py | 4 +-- .../projections/pathway/mappingprojection.py | 4 +-- psyneulink/components/system.py | 20 ++++++++----- psyneulink/globals/context.py | 29 ++++++++++++------- psyneulink/globals/environment.py | 15 +++++----- psyneulink/globals/log.py | 8 ++--- tests/log/test_log.py | 2 +- 10 files changed, 65 insertions(+), 52 deletions(-) diff --git a/psyneulink/components/component.py b/psyneulink/components/component.py index 95655cde794..25a085355b7 100644 --- a/psyneulink/components/component.py +++ b/psyneulink/components/component.py @@ -405,7 +405,7 @@ class `UserList 0: @@ -2115,7 +2115,7 @@ def execute( if not context: # cxt-test context = EXECUTING + " " + PROCESS + " " + self.name # cxt-done - self.context.status = ContextFlags.EXECUTION + self.context.status = ContextFlags.PROCESSING self.context.string = EXECUTING + " " + PROCESS + " " + self.name from psyneulink.globals.environment import _get_unique_id self._execution_id = execution_id or _get_unique_id() @@ -2145,8 +2145,12 @@ def execute( (isinstance(mechanism, ObjectiveMechanism) and mechanism._role is LEARNING)): continue + # Execute Mechanism # Note: DON'T include input arg, as that will be resolved by mechanism from its sender projections + mechanism.context.execution_status = ContextFlags.PROCESSING mechanism.execute(context=context) # cxt-pass ? cxt-push + mechanism.context.execution_status = ContextFlags.IDLE + if report_output: # FIX: USE clamp_input OPTION HERE, AND ADD HARD_CLAMP AND SOFT_CLAMP self._report_mechanism_execution(mechanism) @@ -2156,7 +2160,7 @@ def execute( # in case it is repeated in the pathway or receives a recurrent Projection variable = self._update_variable(variable * 0) - # Execute LearningMechanism + # Execute LearningMechanisms if self._learning_enabled: self._execute_learning(target=target, context=context) @@ -2214,8 +2218,7 @@ def _execute_learning(self, target=None, context=None): # FINALLY, execute LearningProjections to MappingProjections in the process' pathway for mech in self._mechs: - mech.context.status &= ~ContextFlags.EXECUTION - mech.context.status |= ContextFlags.LEARNING + mech.context.execution_status = ContextFlags.LEARNING mech.context.string = self.context.string.replace(EXECUTING, LEARNING + ' ') # IMPLEMENTATION NOTE: @@ -2248,16 +2251,14 @@ def _execute_learning(self, target=None, context=None): # Note: do this rather just calling LearningSignals directly # since parameter_state.update() handles parsing of LearningProjection-specific params context = context.replace(EXECUTING, LEARNING + ' ') # cxt-done cxt-pass ? cxt-push - parameter_state.context.status &= ~ContextFlags.EXECUTION - parameter_state.context.status |= ContextFlags.LEARNING + parameter_state.context.execution_status = ContextFlags.LEARNING parameter_state.context.string = self.context.string.replace(EXECUTING, LEARNING + ' ') # NOTE: This will need to be updated when runtime params are re-enabled # parameter_state.update(params=params, context=context) parameter_state.update(context=context) # cxt-pass cxt-push - parameter_state.context.status &= ~ContextFlags.LEARNING - parameter_state.context.status |= ContextFlags.EXECUTION + parameter_state.context.status = ContextFlags.IDLE parameter_state.context.string = self.context.string.replace(LEARNING, EXECUTING) # Not all Projection subclasses instantiate ParameterStates diff --git a/psyneulink/components/projections/modulatory/learningprojection.py b/psyneulink/components/projections/modulatory/learningprojection.py index e16c5ad9999..479739363ad 100644 --- a/psyneulink/components/projections/modulatory/learningprojection.py +++ b/psyneulink/components/projections/modulatory/learningprojection.py @@ -651,9 +651,9 @@ def _execute(self, variable, runtime_params=None, context=None): self.receiver.owner.name, matrix)) if EXECUTING in context: # cxt-test - self.context.status = ContextFlags.EXECUTION + self.context.execution_status = ContextFlags.EXECUTING elif LEARNING in context: # cxt-test - self.context.status = ContextFlags.LEARNING + self.context.execution_status = ContextFlags.LEARNING # # MODIFIED 3/20/18 OLD: # self.weight_change_matrix = self.function( diff --git a/psyneulink/components/projections/pathway/mappingprojection.py b/psyneulink/components/projections/pathway/mappingprojection.py index 8ec25425a5b..9b513abe708 100644 --- a/psyneulink/components/projections/pathway/mappingprojection.py +++ b/psyneulink/components/projections/pathway/mappingprojection.py @@ -626,8 +626,8 @@ def _execute(self, variable=None, runtime_params=None, context=None): """ if EXECUTING in context: # cxt-test - self.context.status &= ~(ContextFlags.VALIDATION | ContextFlags.INITIALIZATION) - self.context.status |= ContextFlags.EXECUTION + self.context.status &= ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING) + self.context.execution_status = ContextFlags.PROCESSING self.context.string = context # (7/18/17 CW) note that we don't let MappingProjections related to System inputs execute here (due to a diff --git a/psyneulink/components/system.py b/psyneulink/components/system.py index 1d162649c03..785d0741ff3 100644 --- a/psyneulink/components/system.py +++ b/psyneulink/components/system.py @@ -860,7 +860,7 @@ def __init__(self, if not context: # cxt-test context = INITIALIZING + self.name + kwSeparator + SYSTEM_INIT # cxt-done - self.context.status = ContextFlags.INITIALIZATION + self.context.status = ContextFlags.INITIALIZING self.context.string = INITIALIZING + self.name + kwSeparator + SYSTEM_INIT super().__init__(default_variable=default_variable, size=size, @@ -2519,7 +2519,7 @@ def execute(self, if not context: # cxt-test context = EXECUTING + " " + SYSTEM + " " + self.name # cxt-done - self.context.status = ContextFlags.EXECUTION + self.context.status = ContextFlags.PROCESSING self.context.string = EXECUTING + " " + SYSTEM + " " + self.name # Update execution_id for self and all mechanisms in graph (including learning) and controller @@ -2616,9 +2616,10 @@ def execute(self, # region EXECUTE LEARNING FOR EACH PROCESS - # Don't execute learning for simulation runs + # Execute learning except for simulation runs if not EVC_SIMULATION in context and self.learning: # cxt-test # self.context.status &= ~ContextFlags.EXECUTION + # self.context.status &= ~ContextFlags.PROCESSING self.context.status |= ContextFlags.LEARNING self.context.string = self.context.string.replace(EXECUTING, LEARNING + ' ') @@ -2684,7 +2685,10 @@ def _execute_processing(self, context=None): context + "| Mechanism: " + mechanism.name + " [in processes: " + str(process_names) + "]" # mechanism.context.string = context # cxt-push ? (note: currently also assigned in Mechanism.execute()) mechanism.context.composition = self + + mechanism.context.status |= ContextFlags.PROCESSING mechanism.execute(runtime_params=rt_params, context=context) # cxt-pass + mechanism.context.status &= ~ContextFlags.PROCESSING if self._report_system_output and self._report_process_output: @@ -2774,7 +2778,7 @@ def _execute_learning(self, context=None): re.sub(r'[\[,\],\n]','',str(process_names)))) # cxt-set cxt-push cxt-pass component.context.composition = self - component.context.status &= ~ContextFlags.EXECUTION + component.context.status &= ~ContextFlags.PROCESSING component.context.status |= ContextFlags.LEARNING component.context.string = context_str @@ -2784,7 +2788,7 @@ def _execute_learning(self, context=None): # print ("EXECUTING LEARNING UPDATES: ", component.name) component.context.status &= ~ContextFlags.LEARNING - component.context.status |= ContextFlags.EXECUTION + component.context.status |= ContextFlags.PROCESSING # THEN update all MappingProjections @@ -2811,14 +2815,14 @@ def _execute_learning(self, context=None): component_type, component.name, re.sub(r'[\[,\],\n]','',str(process_names)))) # cxt-set cxt-push cxt-pass - component.context.status &= ~ContextFlags.EXECUTION + component.context.status &= ~ContextFlags.PROCESSING component.context.status |= ContextFlags.LEARNING component.context.string = context_str component._parameter_states[MATRIX].update(context=context_str) component.context.status &= ~ContextFlags.LEARNING - component.context.status |= ContextFlags.EXECUTION + component.context.status |= ContextFlags.PROCESSING # TEST PRINT: # print ("EXECUTING WEIGHT UPDATES: ", component.name) @@ -3974,7 +3978,7 @@ def __init__(self, owner=None, variable=None, name=None, prefs=None, context=Non self.name = owner.name + "_" + SYSTEM_TARGET_INPUT_STATE else: self.name = owner.name + "_" + name - self.context.status = ContextFlags.INITIALIZATION + self.context.status = ContextFlags.INITIALIZING self.context.string = context self.prefs = prefs self.log = Log(owner=self) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index 6076f951e6b..3d585d59db0 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -86,6 +86,7 @@ class ContextFlags(IntEnum): """Set during simulation by Composition.controller""" EXECUTION_PHASE_MASK = PROCESSING | LEARNING | CONTROL | SIMULATION EXECUTING = EXECUTION_PHASE_MASK + IDLE = ~EXECUTION_PHASE_MASK # Source-of-call flags CONSTRUCTOR = 1<<9 # 512 @@ -109,8 +110,10 @@ def _get_context_string(cls, condition, string=None): string = "" flagged_items = [] # If OFF or ALL_FLAGS, just return that - if condition in (ContextFlags.ALL_FLAGS, ContextFlags.UNINITIALIZED): - return condition.name + if condition == ContextFlags.ALL_FLAGS: + return ContextFlags.ALL_FLAGS.name + if condition == ContextFlags.UNINITIALIZED: + return ContextFlags.UNINITIALIZED.name # Otherwise, append each flag's name to the string for c in list(cls.__members__): # Skip ALL_FLAGS (handled above) @@ -223,7 +226,11 @@ def composition(self, composition): @property def flags(self): - return self._flags + try: + return self._flags + except: + self._flags = ContextFlags.UNINITIALIZED |ContextFlags.COMPONENT + return self._flags @flags.setter def flags(self, flags): @@ -242,7 +249,7 @@ def initialization_status(self, flag): """Check that a flag is one and only one status flag """ flag &= ContextFlags.INITIALIZATION_MASK if flag in INITIALIZATION_STATUS_FLAGS: - self._flags |= flag + self.flags |= flag elif not flag: raise ContextError("Attempt to assign a flag ({}) to {}.context.status " "that is not an initialization status flag". @@ -259,9 +266,9 @@ def execution_phase(self): def execution_phase(self, flag): """Check that a flag is one and only one execution_phase flag """ if flag in EXECUTION_PHASE_FLAGS: - self._flags |= flag - elif flag is None: - self._flags &= ~ContextFlags.EXECUTING + self.flags |= flag + elif flag is None or flag is ContextFlags.IDLE: + self.flags &= ContextFlags.IDLE elif not flag & ContextFlags.EXECUTION_PHASE_MASK: raise ContextError("Attempt to assign a flag ({}) to {}.context.execution_phase " "that is not an execution phase flag". @@ -278,7 +285,7 @@ def source(self): def source(self, flag): """Check that a flag is one and only one source flag """ if flag in SOURCE_FLAGS: - self._flags |= flag + self.flags |= flag elif not flag & ContextFlags.SOURCE_MASK: raise ContextError("Attempt to assign a flag ({}) to {}.context.source that is not a source flag". format(ContextFlags._get_context_string(flag), self.owner.name)) @@ -298,11 +305,11 @@ def execution_time(self, time): self._execution_time = time def update_execution_time(self): - if self.status & ContextFlags.EXECUTION: + if self.status & ContextFlags.EXECUTING: self.execution_time = _get_time(self.owner, self.context.status) else: raise ContextError("PROGRAM ERROR: attempt to call update_execution_time for {} " - "when 'EXECUTION' was not in its context".format(self.owner.name)) + "when 'EXECUTING' was not in its context".format(self.owner.name)) @tc.typecheck @@ -383,7 +390,7 @@ def _get_time(component, context_flags): if system: # FIX: Add ContextFlags.VALIDATE? - if context_flags == ContextFlags.EXECUTION: + if context_flags == ContextFlags.PROCESSING: t = system.scheduler_processing.clock.time t = time(t.run, t.trial, t.pass_, t.time_step) elif context_flags == ContextFlags.CONTROL: diff --git a/psyneulink/globals/environment.py b/psyneulink/globals/environment.py index edfc56f4bb5..1a9ba4b921c 100644 --- a/psyneulink/globals/environment.py +++ b/psyneulink/globals/environment.py @@ -493,6 +493,7 @@ from psyneulink.components.process import ProcessInputState from psyneulink.components.shellclasses import Mechanism, Process_Base, System_Base from psyneulink.globals.keywords import EVC_SIMULATION, MECHANISM, PROCESS, PROCESSES_DIM, RUN, SAMPLE, SYSTEM, TARGET +from psyneulink.globals.log import LogCondition from psyneulink.globals.utilities import append_type_to_name, iscompatible from psyneulink.scheduling.time import TimeScale @@ -701,9 +702,9 @@ def run(object, # Class-specific validation: context = context or RUN + "validating " + object.name # cxt-done ? cxt-pass - if object.context.status is ContextFlags.OFF: - # object.context.status = ContextFlags.RUN + ContextFlags.VALIDATION - object.context.status = ContextFlags.VALIDATION + if not object.context.status: + # object.context.status = ContextFlags.RUN + ContextFlags.VALIDATING + object.context.status = ContextFlags.VALIDATING object.context.string = RUN + "validating " + object.name # INITIALIZATION @@ -757,8 +758,8 @@ def run(object, # MODIFIED 3/16/17 END if RUN in context and not EVC_SIMULATION in context: # cxt-test context = RUN + ": EXECUTING " + object_type.upper() + " " + object.name # cxt-done ? cxt-pass - object.context.status &= ~(ContextFlags.VALIDATION | ContextFlags.INITIALIZATION) - object.context.status |= ContextFlags.EXECUTION + object.context.status &= ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING) + object.context.status |= ContextFlags.EXECUTING object.context.string = RUN + ": EXECUTING " + object_type.upper() + " " + object.name result = object.execute( input=execution_inputs, @@ -783,7 +784,7 @@ def run(object, from psyneulink.globals.log import _log_trials_and_runs, ContextFlags _log_trials_and_runs(composition=object, - curr_condition=ContextFlags.TRIAL, + curr_condition=LogCondition.TRIAL, context=context) try: @@ -806,7 +807,7 @@ def run(object, from psyneulink.globals.log import _log_trials_and_runs, ContextFlags _log_trials_and_runs(composition=object, - curr_condition=ContextFlags.RUN, + curr_condition=LogCondition.RUN, context=context) return object.results diff --git a/psyneulink/globals/log.py b/psyneulink/globals/log.py index f3ec160a683..da535cc8fc7 100644 --- a/psyneulink/globals/log.py +++ b/psyneulink/globals/log.py @@ -676,7 +676,7 @@ def __init__(self, owner, entries=None): if entries is None: return - def set_log_conditions(self, items, log_condition=ContextFlags.EXECUTING): + def set_log_conditions(self, items, log_condition=LogCondition.EXECUTION): """Specifies items to be logged at the specified `LogCondition`\\(s). Arguments @@ -708,13 +708,13 @@ def assign_log_condition(item, level): # Handle multiple level assignments (as LogCondition or strings in a list) if not isinstance(level, list): level = [level] - levels = ContextFlags.OFF + levels = LogCondition.OFF for l in level: try: - l = ContextFlags[l.upper()] if isinstance(l, str) else l + l = LogCondition[l.upper()] if isinstance(l, str) else l except KeyError: raise LogError("\'{}\' is not a value of {}". - format(l, ContextFlags.__name__)) + format(l, LogCondition.__name__)) levels |= l level = levels diff --git a/tests/log/test_log.py b/tests/log/test_log.py index 8e75190f42a..0ad85fe0559 100644 --- a/tests/log/test_log.py +++ b/tests/log/test_log.py @@ -100,7 +100,7 @@ def test_log(self): def test_log_initialization(self): T = pnl.TransferMechanism( - prefs={pnl.LOG_PREF: pnl.PreferenceEntry(pnl.ContextFlags.INITIALIZATION, pnl.PreferenceLevel.INSTANCE)} + prefs={pnl.LOG_PREF: pnl.PreferenceEntry(pnl.ContextFlags.INITIALIZING, pnl.PreferenceLevel.INSTANCE)} ) assert T.logged_items == {'value': 'INITIALIZATION'} From f364806761c67dd1a570c56d28ba2c7fcc5f976e Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Sun, 25 Mar 2018 23:07:04 -0400 Subject: [PATCH 20/41] - --- psyneulink/globals/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psyneulink/globals/log.py b/psyneulink/globals/log.py index da535cc8fc7..25e945c2031 100644 --- a/psyneulink/globals/log.py +++ b/psyneulink/globals/log.py @@ -416,7 +416,7 @@ class LogCondition(IntEnum): """Set during execution of the Component's constructor.""" VALIDATION = ContextFlags.VALIDATING """Set during validation of the value of a Component or its attribute.""" - EXECUTION = ContextFlags.EXECUTING + EXECUTION = ContextFlags.PROCESSING """Set during all `phases of execution ` of the Component.""" PROCESSING = ContextFlags.PROCESSING """Set during the `processing phase ` of execution of a Composition.""" From 6ad1fe51317d0a5b8ac1f4a82a74460256a67087 Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Tue, 27 Mar 2018 13:28:29 -0400 Subject: [PATCH 21/41] - --- psyneulink/components/process.py | 8 ++++---- .../projections/modulatory/learningprojection.py | 4 ++-- .../components/projections/pathway/mappingprojection.py | 3 ++- psyneulink/globals/log.py | 2 +- tests/learning/test_multilayer.py | 4 ++-- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/psyneulink/components/process.py b/psyneulink/components/process.py index d6dcc07b4b2..39e07e50bd4 100644 --- a/psyneulink/components/process.py +++ b/psyneulink/components/process.py @@ -2147,9 +2147,9 @@ def execute( # Execute Mechanism # Note: DON'T include input arg, as that will be resolved by mechanism from its sender projections - mechanism.context.execution_status = ContextFlags.PROCESSING + mechanism.context.execution_phase = ContextFlags.PROCESSING mechanism.execute(context=context) # cxt-pass ? cxt-push - mechanism.context.execution_status = ContextFlags.IDLE + mechanism.context.execution_phase = ContextFlags.IDLE if report_output: # FIX: USE clamp_input OPTION HERE, AND ADD HARD_CLAMP AND SOFT_CLAMP @@ -2218,7 +2218,7 @@ def _execute_learning(self, target=None, context=None): # FINALLY, execute LearningProjections to MappingProjections in the process' pathway for mech in self._mechs: - mech.context.execution_status = ContextFlags.LEARNING + mech.context.execution_phase = ContextFlags.LEARNING mech.context.string = self.context.string.replace(EXECUTING, LEARNING + ' ') # IMPLEMENTATION NOTE: @@ -2251,7 +2251,7 @@ def _execute_learning(self, target=None, context=None): # Note: do this rather just calling LearningSignals directly # since parameter_state.update() handles parsing of LearningProjection-specific params context = context.replace(EXECUTING, LEARNING + ' ') # cxt-done cxt-pass ? cxt-push - parameter_state.context.execution_status = ContextFlags.LEARNING + parameter_state.context.execution_phase = ContextFlags.LEARNING parameter_state.context.string = self.context.string.replace(EXECUTING, LEARNING + ' ') # NOTE: This will need to be updated when runtime params are re-enabled diff --git a/psyneulink/components/projections/modulatory/learningprojection.py b/psyneulink/components/projections/modulatory/learningprojection.py index 479739363ad..1bf65ed3785 100644 --- a/psyneulink/components/projections/modulatory/learningprojection.py +++ b/psyneulink/components/projections/modulatory/learningprojection.py @@ -651,9 +651,9 @@ def _execute(self, variable, runtime_params=None, context=None): self.receiver.owner.name, matrix)) if EXECUTING in context: # cxt-test - self.context.execution_status = ContextFlags.EXECUTING + self.context.execution_phase = ContextFlags.EXECUTING elif LEARNING in context: # cxt-test - self.context.execution_status = ContextFlags.LEARNING + self.context.execution_phase = ContextFlags.LEARNING # # MODIFIED 3/20/18 OLD: # self.weight_change_matrix = self.function( diff --git a/psyneulink/components/projections/pathway/mappingprojection.py b/psyneulink/components/projections/pathway/mappingprojection.py index 9b513abe708..8aad96516d5 100644 --- a/psyneulink/components/projections/pathway/mappingprojection.py +++ b/psyneulink/components/projections/pathway/mappingprojection.py @@ -625,9 +625,10 @@ def _execute(self, variable=None, runtime_params=None, context=None): """ + # FIX: MOVE THIS TO SUPER if EXECUTING in context: # cxt-test self.context.status &= ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING) - self.context.execution_status = ContextFlags.PROCESSING + self.context.execution_phase = ContextFlags.PROCESSING self.context.string = context # (7/18/17 CW) note that we don't let MappingProjections related to System inputs execute here (due to a diff --git a/psyneulink/globals/log.py b/psyneulink/globals/log.py index 25e945c2031..da535cc8fc7 100644 --- a/psyneulink/globals/log.py +++ b/psyneulink/globals/log.py @@ -416,7 +416,7 @@ class LogCondition(IntEnum): """Set during execution of the Component's constructor.""" VALIDATION = ContextFlags.VALIDATING """Set during validation of the value of a Component or its attribute.""" - EXECUTION = ContextFlags.PROCESSING + EXECUTION = ContextFlags.EXECUTING """Set during all `phases of execution ` of the Component.""" PROCESSING = ContextFlags.PROCESSING """Set during the `processing phase ` of execution of a Composition.""" diff --git a/tests/learning/test_multilayer.py b/tests/learning/test_multilayer.py index a6c6ca90eeb..f276eea844d 100644 --- a/tests/learning/test_multilayer.py +++ b/tests/learning/test_multilayer.py @@ -5,7 +5,7 @@ from psyneulink.components.process import Process from psyneulink.components.projections.pathway.mappingprojection import MappingProjection from psyneulink.components.system import System -from psyneulink.globals.keywords import SOFT_CLAMP, EXECUTION, LEARNING, VALUE +from psyneulink.globals.keywords import SOFT_CLAMP, EXECUTION, PROCESSING, LEARNING, VALUE from psyneulink.globals.preferences.componentpreferenceset import REPORT_OUTPUT_PREF, VERBOSE_PREF from psyneulink.library.mechanisms.processing.objective.comparatormechanism import MSE @@ -98,7 +98,7 @@ def test_multilayer(): }, ) - Middle_Weights.set_log_conditions(('matrix', EXECUTION)) + Middle_Weights.set_log_conditions(('matrix', PROCESSING)) stim_list = {Input_Layer: [[-1, 30]]} target_list = {Output_Layer: [[0, 0, 1]]} From 9bbb7984e92d34a32f687d01cf0e4cf5eef53cde Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Thu, 29 Mar 2018 13:27:14 -0400 Subject: [PATCH 22/41] - --- Scripts/McClure.py | 222 ++++++++++++++++++ psyneulink/components/component.py | 16 +- psyneulink/components/mechanisms/mechanism.py | 18 +- psyneulink/components/process.py | 9 +- .../projections/pathway/mappingprojection.py | 2 +- psyneulink/components/states/inputstate.py | 4 +- .../states/modulatorysignals/controlsignal.py | 4 +- .../states/modulatorysignals/gatingsignal.py | 4 +- .../modulatorysignals/learningsignal.py | 4 +- psyneulink/components/states/outputstate.py | 4 +- psyneulink/components/states/state.py | 2 +- psyneulink/components/system.py | 31 +-- psyneulink/globals/context.py | 29 ++- psyneulink/globals/environment.py | 8 +- psyneulink/globals/log.py | 6 +- .../transfer/recurrenttransfermechanism.py | 3 +- .../library/subsystems/evc/evcauxiliary.py | 2 +- 17 files changed, 294 insertions(+), 74 deletions(-) create mode 100644 Scripts/McClure.py diff --git a/Scripts/McClure.py b/Scripts/McClure.py new file mode 100644 index 00000000000..00c67c59da7 --- /dev/null +++ b/Scripts/McClure.py @@ -0,0 +1,222 @@ +import functools +import psyneulink as pnl +import numpy as np +from matplotlib import pyplot as plt +np.random.seed(2) + +a = 0.50 # Parameter describing shape of the FitzHugh–Nagumo cubic nullcline for the fast excitation variable v +d = 0.50 # Baseline level of intrinsic, uncorrelated LC activity +G = 0.50 # Base level of gain applied to decision and response units +k = 3.00 # Scaling factor for transforming NE release (u) to gain (g) on potentiated units + +#SD = 0.1 # Standard deviation of Gaussian noise distributions | NOTE: 0.22 in Gilzenrat paper + +tau_v = 0.05 # Time constant for fast LC excitation variable v | NOTE: tau_v is misstated in the Gilzenrat paper(0.5) +tau_u = 5.00 # Time constant for slow LC recovery variable (‘NE release’) u +dt = 0.02 # Time step size for numerical integration + +C = 0.95 # Mode ("coherence") - high +initial_hv = 0.07 # Initial value for h(v) +initial_u = 0.14 # initial value u + +# C = 0.55 # Mode ("coherence") - low +# initial_hv = 0.2 # Initial value for h(v) with low C +# initial_u = 0.2 # Initial value for u with low C + +initial_v = (initial_hv - (1 - C) * d) / C # get initial v from initial h(v) + + +input_layer = pnl.TransferMechanism(size=2, + name='INPUT LAYER') + + +action_selection = pnl.TransferMechanism(size=2, + function=pnl.SoftMax( + output=pnl.ALL, + gain=1.0), + output_states=[{pnl.NAME: 'SELECTED ACTION', + pnl.VARIABLE: [(pnl.INPUT_STATE_VARIABLES, 0), + (pnl.OWNER_VALUE, 0)], + pnl.FUNCTION: pnl.OneHot(mode=pnl.PROB).function}, + {pnl.NAME: 'REWARD RATE', + pnl.VARIABLE: [pnl.OWNER_VALUE], + pnl.FUNCTION: pnl.AdaptiveIntegrator(rate=0.2)}, + {pnl.NAME: 'CONFLICT K', + pnl.VARIABLE: [pnl.OWNER_VALUE], + #Jon said this should also work and would be safer: [(pnl.OWNER_VALUE, 0), + #(pnl.OWNER_VALUE, 1)], but it doesn't work (maybe I did sth wrong) + pnl.FUNCTION: pnl.Stability(metric=pnl.ENERGY, + normalize=True)}, + ], + #as stated in the paper 'Response conflict was calculated as a normalized measure of the energy in the response units during the trial' + name='Action Selection') + + + + + +# rate = pnl.ObjectiveMechanism(monitored_output_states=[action_selection.output_states[0]], +# function=pnl.AdaptiveIntegrator(rate=0.2, +# noise=reward, +# time_step_size=0.02), +# name='REWARD RATE') + +# K = pnl.ObjectiveMechanism(#size=1, +# monitored_output_states=[action_selection.output_state], +# function=pnl.Stability(metric=pnl.ENERGY, +# normalize=True), +# name='K') + +conflicts = pnl.IntegratorMechanism(input_states=[action_selection.output_states[2]], + function=pnl.AGTUtilityIntegrator(short_term_gain=6.0, + long_term_gain=6.0, + short_term_rate=0.05, + long_term_rate=0.2), + name='Short- and Long-term conflict') + +decision_process = pnl.Process(default_variable=[0, 0], + pathway=[input_layer, + action_selection], + learning=pnl.LearningProjection(learning_function=pnl.Reinforcement( + learning_rate=0.03)), # if learning rate set to .3 output state values annealing to [0., 0.] + # which leads to error in reward function + target=0 + ) + +print('reward prediction weights: \n', action_selection.input_state.path_afferents[0].matrix) +print('target_mechanism weights: \n', action_selection.output_state.efferents[0].matrix) + +conflict_process = pnl.Process(pathway=[action_selection, conflicts]) + +LC_NE = pnl.LCControlMechanism(objective_mechanism=pnl.ObjectiveMechanism(monitored_output_states=[action_selection], + name='LC-NE ObjectiveMech'), + modulated_mechanisms=[action_selection], + integration_method='EULER', + initial_w_FHN=initial_u, + initial_v_FHN=initial_v, + time_step_size_FHN=dt, + t_0_FHN=0.0, + a_v_FHN=-1.0, + b_v_FHN=1.0, + c_v_FHN=1.0, + d_v_FHN=0.0, + e_v_FHN=-1.0, + f_v_FHN=1.0, + time_constant_v_FHN=tau_v, + a_w_FHN=1.0, + b_w_FHN=-1.0, + c_w_FHN=0.0, + threshold_FHN=a, + time_constant_w_FHN=tau_u, + mode_FHN=C, + uncorrelated_activity_FHN=d, + base_level_gain=G, + scaling_factor_gain=k, + name='LC-NE') + +updateC = pnl.ControlMechanism(objective_mechanism=pnl.ObjectiveMechanism( + monitor_for_control=[action_selection.output_states[1], conflicts.output_state]), + control_signals=[LC_NE.parameter_states[35]], + name='C Update') + +update_process = pnl.Process(pathway=[LC_NE], + name='UPDATE PROCESS') + + +actions = ['left', 'right'] +reward_values = np.array([1, 0]) +first_reward = 0 + +action_selection.output_state.value = [0, 1] + + +def reward(): + print(reward_values, action_selection.output_state.value) + return [reward_values[int(np.nonzero(action_selection.output_state.value)[0])]] + + +rrate = [0.] +conflictK = [0.] +coherence = [0.] +update = [0.] +cons = [0.] + + +def print_header(system): + print("\n\n**** Time: ", system.scheduler_processing.clock.simple_time) + + +def show_weights(): + # print('Reward prediction weights: \n', action_selection.input_state.path_afferents[0].matrix) + # print( + # '\nAction selected: {}; predicted reward: {}'.format( + # np.nonzero(action_selection.output_state.value)[0][0], + # action_selection.output_state.value[np.nonzero(action_selection.output_state.value)][0] + # ) + assert True + comparator = action_selection.output_state.efferents[0].receiver.owner + learn_mech = action_selection.output_state.efferents[1].receiver.owner + print('\n' + '\naction_selection value: {} ' + '\naction_selection output: {} ' + '\ncomparator sample: {} ' + '\ncomparator target: {} ' + '\nlearning mech act in: {} ' + '\nlearning mech act out: {} ' + '\nlearning mech error in: {} ' + '\nlearning mech error out: {} ' + '\nlearning mech learning_sig: {} ' + '\npredicted reward: {} ' + '\nreward rate: {} ' + '\nconflict K: {} ' + '\ncoherence C: {} ' + '\nshort-long-term conflict: {} '. + format( + action_selection.value, + action_selection.output_state.value, + comparator.input_states[pnl.SAMPLE].value, + comparator.input_states[pnl.TARGET].value, + learn_mech.input_states[pnl.ACTIVATION_INPUT].value, + learn_mech.input_states[pnl.ACTIVATION_OUTPUT].value, + learn_mech.input_states[pnl.ERROR_SIGNAL].value, + learn_mech.output_states[pnl.ERROR_SIGNAL].value, + learn_mech.output_states[pnl.LEARNING_SIGNAL].value, + action_selection.output_state.value[np.nonzero(action_selection.output_state.value)][0], + rrate.append(action_selection.output_states[1].value), + conflictK.append(action_selection.output_states[2].value), + coherence.append(LC_NE.parameter_states[35].value), + update.append(updateC.output_state.value), + cons.append(conflicts.output_state.value) + ) + ) + + +decision_process.run(num_trials=10, + inputs=[[1, 1]], + targets=reward + ) + + +# inputs = np.tile(np.repeat(np.array([[1., 0.], [0., 0.], [0., 1.], [0., 0.]]), 20, axis=0), (4, 1)) +# input_dict = {input_layer: inputs} +input_dict = {input_layer: [1, 0]} + +DA_sys = pnl.System( + processes=[decision_process, conflict_process, + update_process], + controller=updateC, + targets=[0], + name='NE-DA System' +) + +DA_sys.show_graph(show_learning=pnl.ALL, + show_control=pnl.ALL, + show_dimensions=True) + +DA_sys.run( + num_trials=10, + inputs=input_dict, + targets=reward, + call_after_trial=show_weights +) + diff --git a/psyneulink/components/component.py b/psyneulink/components/component.py index 25a085355b7..49d87137800 100644 --- a/psyneulink/components/component.py +++ b/psyneulink/components/component.py @@ -873,7 +873,7 @@ def __init__(self, # # del self.init_args['__class__'] # return context = context + INITIALIZING + ": " + COMPONENT_INIT # cxt-done - self.context.status = ContextFlags.INITIALIZING + self.context.initialization_status = ContextFlags.INITIALIZING self.context.execution_phase = None self.context.source = ContextFlags.COMPONENT self.context.string = context + INITIALIZING + ": " + COMPONENT_INIT @@ -1962,7 +1962,7 @@ def assign_params(self, request_set=None, context=None): """ if context is None: - self.context.status = ContextFlags.COMMAND_LINE # cxt-push + self.context.source = ContextFlags.COMMAND_LINE # cxt-push self.context.string = COMMAND_LINE context = context or COMMAND_LINE # cxt-done self._assign_params(request_set=request_set, context=context) @@ -2031,7 +2031,7 @@ def _assign_params(self, request_set:tc.optional(dict)=None, context=None): validated_set_param_names = list(validated_set.keys()) - curr_context = self.context.status # cxt-buffer + curr_context = self.context.flags # cxt-buffer curr_context_str = self.context.string # If an input_state is being added from the command line, @@ -2040,7 +2040,7 @@ def _assign_params(self, request_set:tc.optional(dict)=None, context=None): # 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.status = ContextFlags.COMMAND_LINE # cxt-push + self.context.source = ContextFlags.COMMAND_LINE # cxt-push self._instantiate_attributes_before_function(context=COMMAND_LINE) # cxt-done # Give owner a chance to instantiate function and/or function params # (e.g., wrap in UserDefineFunction, as per EVCControlMechanism) @@ -2051,7 +2051,7 @@ def _assign_params(self, request_set:tc.optional(dict)=None, context=None): # 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.status = COMMAND_LINE # cxt-push + self.context.source = COMMAND_LINE # cxt-push self._instantiate_function(context=COMMAND_LINE) # cxt-done # FIX: WHY SHOULD IT BE CALLED DURING STANDRD INIT PROCEDURE? # # MODIFIED 5/5/17 OLD: @@ -2059,10 +2059,10 @@ def _assign_params(self, request_set:tc.optional(dict)=None, context=None): # 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 # MODIFIED 5/5/17 END - self.context.status = COMMAND_LINE # cxt-push + self.context.source = COMMAND_LINE # cxt-push self._instantiate_attributes_after_function(context=COMMAND_LINE) # cxt-done - self.context.status = curr_context # cxt-pop + self.context.flags = curr_context # cxt-pop self.context.string = curr_context_str def reset_params(self, mode=ResetMode.INSTANCE_TO_CLASS): @@ -2825,7 +2825,7 @@ def _execute(self, variable=None, runtime_params=None, context=None): if isinstance(self, Function): pass # Functions don't have a Logs or maintain execution_counts or time else: - if self.context.status & ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING): + if self.context.initialization_status & ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING): self._increment_execution_count() self._update_current_execution_time(context=context) # cxt-pass # MODIFIED 3/20/18 END diff --git a/psyneulink/components/mechanisms/mechanism.py b/psyneulink/components/mechanisms/mechanism.py index 11e498e7517..6e1e6067385 100644 --- a/psyneulink/components/mechanisms/mechanism.py +++ b/psyneulink/components/mechanisms/mechanism.py @@ -1269,7 +1269,7 @@ def __init__(self, output_states = list(output_states) # Mark initialization in context - self.context.status = ContextFlags.INITIALIZING + self.context.initialization_status = ContextFlags.INITIALIZING if not context or isinstance(context, object) or inspect.isclass(context): # cxt-test context = INITIALIZING + self.name + SEPARATOR_BAR + self.__class__.__name__ # cxt-done self.context.string = INITIALIZING + self.name + SEPARATOR_BAR + self.__class__.__name__ @@ -1973,20 +1973,20 @@ def execute(self, """ self.ignore_execution_id = ignore_execution_id context = context or COMMAND_LINE # cxt-done - if not self.context.status or context is COMMAND_LINE: - self.context.status = ContextFlags.COMMAND_LINE + if not self.context.source or context is COMMAND_LINE: + self.context.source = ContextFlags.COMMAND_LINE self.context.string = COMMAND_LINE else: # These need to be set for states to use as context self.context.string = context if not INITIALIZING in context: # cxt-set - self.context.status &= ~ContextFlags.INITIALIZING + self.context.initialization_status &= ~ContextFlags.INITIALIZING if EXECUTING in context: - self.context.status |= ContextFlags.PROCESSING + self.context.execution_phase = ContextFlags.PROCESSING if LEARNING in context: - self.context.status |= ContextFlags.LEARNING + self.context.execution_phase = ContextFlags.LEARNING if EVC_SIMULATION in context: - self.context.status |= ContextFlags.SIMULATION + self.context.execution_phase = ContextFlags.SIMULATION # IMPLEMENTATION NOTE: Re-write by calling execute methods according to their order in functionDict: # for func in self.functionDict: @@ -2081,7 +2081,7 @@ def execute(self, else: if context is COMMAND_LINE: # cxt-test context = EXECUTING + ' ' + append_type_to_name(self) # cxt-done - self.context.status = ContextFlags.PROCESSING + self.context.execution_phase = ContextFlags.PROCESSING self.context.string = EXECUTING + ' ' + append_type_to_name(self) if input is None: input = self.instance_defaults.variable @@ -2156,7 +2156,7 @@ def execute(self, # transmittted back via recurrent Projections as initial inputs self.output_states[state].value = self.output_states[state].value * 0.0 - if self.context.status & ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING): + if self.context.initialization_status & ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING): self._increment_execution_count() self._update_current_execution_time(context=context) # cxt-pass diff --git a/psyneulink/components/process.py b/psyneulink/components/process.py index 39e07e50bd4..6dd6e34357e 100644 --- a/psyneulink/components/process.py +++ b/psyneulink/components/process.py @@ -859,7 +859,7 @@ def __init__(self, if not context: # cxt-test # context = self.__class__.__name__ context = INITIALIZING + self.name + kwSeparator + PROCESS_INIT # cxt-done - self.context.status = ContextFlags.INITIALIZING + self.context.initialization_status = ContextFlags.INITIALIZING self.context.string = INITIALIZING + self.name + kwSeparator + PROCESS_INIT # If input was not provided, generate defaults to match format of ORIGIN mechanisms for process if default_variable is None and len(pathway) > 0: @@ -2115,7 +2115,7 @@ def execute( if not context: # cxt-test context = EXECUTING + " " + PROCESS + " " + self.name # cxt-done - self.context.status = ContextFlags.PROCESSING + self.context.execution_phase = ContextFlags.PROCESSING self.context.string = EXECUTING + " " + PROCESS + " " + self.name from psyneulink.globals.environment import _get_unique_id self._execution_id = execution_id or _get_unique_id() @@ -2258,7 +2258,7 @@ def _execute_learning(self, target=None, context=None): # parameter_state.update(params=params, context=context) parameter_state.update(context=context) # cxt-pass cxt-push - parameter_state.context.status = ContextFlags.IDLE + parameter_state.context.execution_phase = ContextFlags.IDLE parameter_state.context.string = self.context.string.replace(LEARNING, EXECUTING) # Not all Projection subclasses instantiate ParameterStates @@ -2270,8 +2270,7 @@ def _execute_learning(self, target=None, context=None): "while attempting to update {} {} of {}". format(e.args[0], parameter_state.name, ParameterState.__name__, projection.name)) - mech.context.status &= ~ContextFlags.LEARNING - mech.context.status |= ContextFlags.EXECUTION + mech.context.execution_phase = ContextFlags.IDLE mech.context.string = self.context.string.replace(LEARNING, EXECUTING) diff --git a/psyneulink/components/projections/pathway/mappingprojection.py b/psyneulink/components/projections/pathway/mappingprojection.py index 8aad96516d5..7f5077772f3 100644 --- a/psyneulink/components/projections/pathway/mappingprojection.py +++ b/psyneulink/components/projections/pathway/mappingprojection.py @@ -627,7 +627,7 @@ def _execute(self, variable=None, runtime_params=None, context=None): # FIX: MOVE THIS TO SUPER if EXECUTING in context: # cxt-test - self.context.status &= ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING) + self.context.initialization_status &= ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING) self.context.execution_phase = ContextFlags.PROCESSING self.context.string = context diff --git a/psyneulink/components/states/inputstate.py b/psyneulink/components/states/inputstate.py index 0115d35d638..0ed4e01011f 100644 --- a/psyneulink/components/states/inputstate.py +++ b/psyneulink/components/states/inputstate.py @@ -714,11 +714,11 @@ def __init__(self, if context is None: # cxt-test context = COMMAND_LINE # cxt-done - self.context.status = ContextFlags.COMMAND_LINE + self.context.source = ContextFlags.COMMAND_LINE self.context.string = COMMAND_LINE else: context = self # cxt-done - self.context.status = ContextFlags.CONSTRUCTOR + self.context.source = ContextFlags.CONSTRUCTOR if variable is None and size is None and projections is not None: variable = self._assign_variable_from_projection(variable, size, projections) diff --git a/psyneulink/components/states/modulatorysignals/controlsignal.py b/psyneulink/components/states/modulatorysignals/controlsignal.py index c0a99caf586..3506ac6065c 100644 --- a/psyneulink/components/states/modulatorysignals/controlsignal.py +++ b/psyneulink/components/states/modulatorysignals/controlsignal.py @@ -684,11 +684,11 @@ def __init__(self, if context is None: # cxt-test context = COMMAND_LINE # cxt-done - self.context.status = ContextFlags.COMMAND_LINE + self.context.source = ContextFlags.COMMAND_LINE self.context.string = COMMAND_LINE else: context = self # cxt-done - self.context.status = ContextFlags.CONSTRUCTOR + self.context.source = ContextFlags.CONSTRUCTOR # Note index and assign are not used by ControlSignal, but included here for consistency with OutputState if params and ALLOCATION_SAMPLES in params and params[ALLOCATION_SAMPLES] is not None: diff --git a/psyneulink/components/states/modulatorysignals/gatingsignal.py b/psyneulink/components/states/modulatorysignals/gatingsignal.py index 18a9e764a56..07ae0580733 100644 --- a/psyneulink/components/states/modulatorysignals/gatingsignal.py +++ b/psyneulink/components/states/modulatorysignals/gatingsignal.py @@ -428,11 +428,11 @@ def __init__(self, if context is None: # cxt-test context = COMMAND_LINE # cxt-done - self.context.status = ContextFlags.COMMAND_LINE + self.context.source = ContextFlags.COMMAND_LINE self.context.string = COMMAND_LINE else: context = self # cxt-done - self.context.status = ContextFlags.CONSTRUCTOR + self.context.source = ContextFlags.CONSTRUCTOR # Note: assign is not currently used by GatingSignal; # it is included here for consistency with OutputState and possible use by subclasses. diff --git a/psyneulink/components/states/modulatorysignals/learningsignal.py b/psyneulink/components/states/modulatorysignals/learningsignal.py index 8ee8e710ce7..37af59601b0 100644 --- a/psyneulink/components/states/modulatorysignals/learningsignal.py +++ b/psyneulink/components/states/modulatorysignals/learningsignal.py @@ -373,11 +373,11 @@ def __init__(self, if context is None: # cxt-test context = COMMAND_LINE # cxt-done - self.context.status = ContextFlags.COMMAND_LINE + self.context.source = ContextFlags.COMMAND_LINE self.context.string = COMMAND_LINE else: context = self # cxt-done - self.context.status = ContextFlags.CONSTRUCTOR + self.context.source = ContextFlags.CONSTRUCTOR # Assign args to params and functionParams dicts (kwConstants must == arg names) params = self._assign_args_to_param_dicts(function=function, diff --git a/psyneulink/components/states/outputstate.py b/psyneulink/components/states/outputstate.py index 1d0a45ac0b2..b843e6ac5b8 100644 --- a/psyneulink/components/states/outputstate.py +++ b/psyneulink/components/states/outputstate.py @@ -890,11 +890,11 @@ def __init__(self, if context is None: # cxt-test context = COMMAND_LINE # cxt-done - self.context.status = ContextFlags.COMMAND_LINE + self.context.source = ContextFlags.COMMAND_LINE self.context.string = COMMAND_LINE else: context = self # cxt-done - self.context.status = ContextFlags.CONSTRUCTOR + self.context.source = ContextFlags.CONSTRUCTOR # For backward compatibility with CALCULATE, ASSIGN and INDEX if 'calculate' in kwargs: diff --git a/psyneulink/components/states/state.py b/psyneulink/components/states/state.py index b3af43f1264..4c615c9b90c 100644 --- a/psyneulink/components/states/state.py +++ b/psyneulink/components/states/state.py @@ -1829,7 +1829,7 @@ def update(self, params=None, context=None): """ # Set context to owner's context - self.context.status = self.owner.context.status + self.context.execution_phase = self.owner.context.execution_phase self.context.string = self.owner.context.string # SET UP ------------------------------------------------------------------------------------------------ diff --git a/psyneulink/components/system.py b/psyneulink/components/system.py index 785d0741ff3..11653293ada 100644 --- a/psyneulink/components/system.py +++ b/psyneulink/components/system.py @@ -828,7 +828,7 @@ def __init__(self, # Required to defer assignment of self.controller by setter # until the rest of the System has been instantiated - self.status = INITIALIZING + self.initialization_status = INITIALIZING processes = processes or [] if not isinstance(processes, list): processes = [processes] @@ -860,7 +860,7 @@ def __init__(self, if not context: # cxt-test context = INITIALIZING + self.name + kwSeparator + SYSTEM_INIT # cxt-done - self.context.status = ContextFlags.INITIALIZING + self.context.initialization_status = ContextFlags.INITIALIZING self.context.string = INITIALIZING + self.name + kwSeparator + SYSTEM_INIT super().__init__(default_variable=default_variable, size=size, @@ -869,7 +869,7 @@ def __init__(self, prefs=prefs, context=context) - self.status = INITIALIZED + self.initialization_status = INITIALIZED self._execution_id = None # Assign controller @@ -2519,7 +2519,7 @@ def execute(self, if not context: # cxt-test context = EXECUTING + " " + SYSTEM + " " + self.name # cxt-done - self.context.status = ContextFlags.PROCESSING + self.context.execution_phase = ContextFlags.PROCESSING self.context.string = EXECUTING + " " + SYSTEM + " " + self.name # Update execution_id for self and all mechanisms in graph (including learning) and controller @@ -2620,12 +2620,12 @@ def execute(self, if not EVC_SIMULATION in context and self.learning: # cxt-test # self.context.status &= ~ContextFlags.EXECUTION # self.context.status &= ~ContextFlags.PROCESSING - self.context.status |= ContextFlags.LEARNING + self.context.execution_phase = ContextFlags.LEARNING self.context.string = self.context.string.replace(EXECUTING, LEARNING + ' ') self._execute_learning(context=context.replace(EXECUTING, LEARNING + ' ')) - self.context.status &= ~ContextFlags.LEARNING + self.context.execution_phase = ContextFlags.IDLE # self.context.status |= ContextFlags.EXECUTION self.context.string = self.context.string.replace(LEARNING, EXECUTING) # endregion @@ -2686,10 +2686,9 @@ def _execute_processing(self, context=None): mechanism.context.string = context # cxt-push ? (note: currently also assigned in Mechanism.execute()) mechanism.context.composition = self - mechanism.context.status |= ContextFlags.PROCESSING + mechanism.context.execution_phase = ContextFlags.PROCESSING mechanism.execute(runtime_params=rt_params, context=context) # cxt-pass - mechanism.context.status &= ~ContextFlags.PROCESSING - + mechanism.context.execution_phase = ContextFlags.IDLE if self._report_system_output and self._report_process_output: @@ -2778,8 +2777,7 @@ def _execute_learning(self, context=None): re.sub(r'[\[,\],\n]','',str(process_names)))) # cxt-set cxt-push cxt-pass component.context.composition = self - component.context.status &= ~ContextFlags.PROCESSING - component.context.status |= ContextFlags.LEARNING + component.context.execution_phase = ContextFlags.LEARNING component.context.string = context_str # Note: DON'T include input arg, as that will be resolved by mechanism from its sender projections @@ -2787,8 +2785,7 @@ def _execute_learning(self, context=None): # # TEST PRINT: # print ("EXECUTING LEARNING UPDATES: ", component.name) - component.context.status &= ~ContextFlags.LEARNING - component.context.status |= ContextFlags.PROCESSING + component.context.execution_phase = ContextFlags.IDLE # THEN update all MappingProjections @@ -2815,14 +2812,12 @@ def _execute_learning(self, context=None): component_type, component.name, re.sub(r'[\[,\],\n]','',str(process_names)))) # cxt-set cxt-push cxt-pass - component.context.status &= ~ContextFlags.PROCESSING - component.context.status |= ContextFlags.LEARNING + component.context.execution_phase = ContextFlags.LEARNING component.context.string = context_str component._parameter_states[MATRIX].update(context=context_str) - component.context.status &= ~ContextFlags.LEARNING - component.context.status |= ContextFlags.PROCESSING + component.context.execution_phase = ContextFlags.IDLE # TEST PRINT: # print ("EXECUTING WEIGHT UPDATES: ", component.name) @@ -3978,7 +3973,7 @@ def __init__(self, owner=None, variable=None, name=None, prefs=None, context=Non self.name = owner.name + "_" + SYSTEM_TARGET_INPUT_STATE else: self.name = owner.name + "_" + name - self.context.status = ContextFlags.INITIALIZING + self.context.initialization_status = ContextFlags.INITIALIZING self.context.string = context self.prefs = prefs self.log = Log(owner=self) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index 3d585d59db0..71b78551188 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -62,7 +62,7 @@ class ContextFlags(IntEnum): # # Component accessed by user # CONSTRUCTOR = 1<<11 # 2048 - # Initialization status flags + # initialization_status flags UNINITIALIZED = 0 """Not Initialized.""" DEFERRED_INIT = 1<<1 # 2 @@ -73,9 +73,12 @@ class ContextFlags(IntEnum): """Set during validation of the value of a Component or its attribute.""" INITIALIZED = 1<<4 # 16 """Set after completion of initialization of the Component.""" - INITIALIZATION_MASK = UNINITIALIZED | DEFERRED_INIT | INITIALIZING | VALIDATING | INITIALIZED + REINITIALIZED = 1<<4 # 16 + """Set on stateful Components when they are re-initialized.""" - # Execution phase flags + INITIALIZATION_MASK = UNINITIALIZED | DEFERRED_INIT | INITIALIZING | VALIDATING | INITIALIZED | REINITIALIZED + + # execution_phase flags PROCESSING = 1<<5 # 32 """Set during the `processing phase ` of execution of a Composition.""" LEARNING = 1<<6 # 64 @@ -88,7 +91,7 @@ class ContextFlags(IntEnum): EXECUTING = EXECUTION_PHASE_MASK IDLE = ~EXECUTION_PHASE_MASK - # Source-of-call flags + # source (source-of-call) flags CONSTRUCTOR = 1<<9 # 512 """Call to method from Component's constructor.""" COMMAND_LINE = 1<<10 # 1024 @@ -128,7 +131,8 @@ def _get_context_string(cls, condition, string=None): ContextFlags.DEFERRED_INIT, ContextFlags.INITIALIZING, ContextFlags.VALIDATING, - ContextFlags.INITIALIZED} + ContextFlags.INITIALIZED, + ContextFlags.REINITIALIZED} EXECUTION_PHASE_FLAGS = {ContextFlags.PROCESSING, ContextFlags.LEARNING, @@ -176,7 +180,7 @@ def __init__(self, owner, composition=None, flags=None, - status=ContextFlags.UNINITIALIZED, + initialization_status=ContextFlags.UNINITIALIZED, execution_phase=None, source=ContextFlags.COMPONENT, execution_id:UUID=None, @@ -184,14 +188,15 @@ def __init__(self, self.owner = owner self.composition = composition - self.status = status + self.initialization_status = initialization_status self.execution_phase = execution_phase self.source = source if flags: - if (status != ContextFlags.UNINITIALIZED) and not (flags & ContextFlags.INITIALIZATION_MASK & status): + if (initialization_status != (ContextFlags.UNINITIALIZED) and + not (flags & ContextFlags.INITIALIZATION_MASK & initialization_status)): raise ContextError("Conflict in assignment to flags ({}) and status ({}) arguments of Context for {}". format(ContextFlags._get_context_string(flags & ContextFlags.INITIALIZATION_MASK), - ContextFlags._get_context_string(status), + ContextFlags._get_context_string(initialization_status), self.owner.name)) if (execution_phase and not (flags & ContextFlags.EXECUTION_PHASE_MASK & execution_phase)): raise ContextError("Conflict in assignment to flags ({}) and execution_phase ({}) arguments " @@ -305,8 +310,8 @@ def execution_time(self, time): self._execution_time = time def update_execution_time(self): - if self.status & ContextFlags.EXECUTING: - self.execution_time = _get_time(self.owner, self.context.status) + if self.execution & ContextFlags.EXECUTING: + self.execution_time = _get_time(self.owner, self.context.flags) else: raise ContextError("PROGRAM ERROR: attempt to call update_execution_time for {} " "when 'EXECUTING' was not in its context".format(self.owner.name)) @@ -381,7 +386,7 @@ def _get_time(component, context_flags): # If called from COMMAND_LINE, get context for last time value was assigned: if context_flags & ContextFlags.COMMAND_LINE: # if context_flags & (ContextFlags.COMMAND_LINE | ContextFlags.RUN | ContextFlags.TRIAL): - context_flags = component.prev_context.status + context_flags = component.prev_context.flags execution_context = component.prev_context.string else: execution_context = component.context.string diff --git a/psyneulink/globals/environment.py b/psyneulink/globals/environment.py index 1a9ba4b921c..07e980852a3 100644 --- a/psyneulink/globals/environment.py +++ b/psyneulink/globals/environment.py @@ -702,9 +702,9 @@ def run(object, # Class-specific validation: context = context or RUN + "validating " + object.name # cxt-done ? cxt-pass - if not object.context.status: + if not object.context.flags: # object.context.status = ContextFlags.RUN + ContextFlags.VALIDATING - object.context.status = ContextFlags.VALIDATING + object.context.initialization_status = ContextFlags.VALIDATING object.context.string = RUN + "validating " + object.name # INITIALIZATION @@ -758,8 +758,8 @@ def run(object, # MODIFIED 3/16/17 END if RUN in context and not EVC_SIMULATION in context: # cxt-test context = RUN + ": EXECUTING " + object_type.upper() + " " + object.name # cxt-done ? cxt-pass - object.context.status &= ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING) - object.context.status |= ContextFlags.EXECUTING + object.context.initialization_status &= ~(ContextFlags.VALIDATING | ContextFlags.INITIALIZING) + object.context.execution_phase = ContextFlags.EXECUTING object.context.string = RUN + ": EXECUTING " + object_type.upper() + " " + object.name result = object.execute( input=execution_inputs, diff --git a/psyneulink/globals/log.py b/psyneulink/globals/log.py index da535cc8fc7..0d9c8f04ae2 100644 --- a/psyneulink/globals/log.py +++ b/psyneulink/globals/log.py @@ -778,8 +778,8 @@ def _log_value(self, value, time=None, context=None): elif context is COMMAND_LINE: context_flags = ContextFlags.COMMAND_LINE - elif self.owner.context.status: # cxt-test - context_flags = self.owner.context.status + elif self.owner.context.flags: # cxt-test + context_flags = self.owner.context.flags context = ContextFlags._get_context_string(context_flags) # Get context @@ -826,7 +826,7 @@ def _log_value(self, value, time=None, context=None): context_flags = _get_context(context) context_flags_string = ContextFlags._get_context_string(context_flags) - context_status_string = ContextFlags._get_context_string(self.owner.context.status) + context_status_string = ContextFlags._get_context_string(self.owner.context.flags) # assert context_flags_string == context_status_string log_pref = self.owner.prefs.logPref if self.owner.prefs else None diff --git a/psyneulink/library/mechanisms/processing/transfer/recurrenttransfermechanism.py b/psyneulink/library/mechanisms/processing/transfer/recurrenttransfermechanism.py index a11ca47b9bf..ce68e410eb7 100644 --- a/psyneulink/library/mechanisms/processing/transfer/recurrenttransfermechanism.py +++ b/psyneulink/library/mechanisms/processing/transfer/recurrenttransfermechanism.py @@ -1053,8 +1053,7 @@ def configure_learning(self, learning_function=None, learning_rate=None, context self.learning_rate = learning_rate context = context or COMMAND_LINE # cxt-done cxt-pass ? cxt-push - if self.context.status is ContextFlags.OFF: - self.context.status = ContextFlags.COMMAND_LINE + self.context.source = self.context.source or ContextFlags.COMMAND_LINE self.learning_mechanism = self._instantiate_learning_mechanism(activity_vector=self.output_state, learning_function=self.learning_function, diff --git a/psyneulink/library/subsystems/evc/evcauxiliary.py b/psyneulink/library/subsystems/evc/evcauxiliary.py index c2f015d6cea..417fc1331d0 100644 --- a/psyneulink/library/subsystems/evc/evcauxiliary.py +++ b/psyneulink/library/subsystems/evc/evcauxiliary.py @@ -311,7 +311,7 @@ def function( # Reset context so that System knows this is a simulation (to avoid infinitely recursive loop) context = context.replace(EXECUTING, '{0} {1} of '.format(controller.name, EVC_SIMULATION)) # cxt-done cxt-pass - controller.context.status = ContextFlags.SIMULATION # FIX IS Controller correct for this, or System?? + controller.context.execution_phase = ContextFlags.SIMULATION # FIX IS Controller correct for this, or System?? controller.context.string = context.replace(EXECUTING, '{0} {1} of '.format(controller.name, EVC_SIMULATION)) # Print progress bar if controller.prefs.reportOutputPref: From 338f03c331edf2c3c922aab5ae096ac087cb3da5 Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Fri, 30 Mar 2018 13:42:13 -0400 Subject: [PATCH 23/41] =?UTF-8?q?=E2=80=A2=20Context=20=20=20context.statu?= =?UTF-8?q?s=20replaced=20with=20specific=20field=20assignments=20=20=20(.?= =?UTF-8?q?initialization=5Fphase,=20.execution=5Fphase,=20and=20.source)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- psyneulink/globals/context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psyneulink/globals/context.py b/psyneulink/globals/context.py index 71b78551188..e6019686619 100644 --- a/psyneulink/globals/context.py +++ b/psyneulink/globals/context.py @@ -256,7 +256,7 @@ def initialization_status(self, flag): if flag in INITIALIZATION_STATUS_FLAGS: self.flags |= flag elif not flag: - raise ContextError("Attempt to assign a flag ({}) to {}.context.status " + raise ContextError("Attempt to assign a flag ({}) to {}.context.flags " "that is not an initialization status flag". format(ContextFlags._get_context_string(flag), self.owner.name)) else: From a35225331c490196614789171738e335c0f2c1fc Mon Sep 17 00:00:00 2001 From: "jdc@princeton.edu" Date: Fri, 30 Mar 2018 16:38:59 -0400 Subject: [PATCH 24/41] =?UTF-8?q?=E2=80=A2=20Context=20=20=20context.statu?= =?UTF-8?q?s=20replaced=20with=20specific=20field=20assignments=20=20=20(.?= =?UTF-8?q?initialization=5Fphase,=20.execution=5Fphase,=20and=20.source)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/runConfigurations/EVC_Gratton.xml | 9 +++++---- .idea/runConfigurations/Tests.xml | 7 +++---- .idea/runConfigurations/_Multilayer_Learning.xml | 9 +++++---- .../py_test_for_tests_control_test_EVC_test_EVC.xml | 12 +++++++----- psyneulink/globals/context.py | 13 +++++++++---- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/.idea/runConfigurations/EVC_Gratton.xml b/.idea/runConfigurations/EVC_Gratton.xml index 9a0afcc7bc8..92042729edd 100644 --- a/.idea/runConfigurations/EVC_Gratton.xml +++ b/.idea/runConfigurations/EVC_Gratton.xml @@ -1,21 +1,22 @@ - + + \ No newline at end of file diff --git a/.idea/runConfigurations/Tests.xml b/.idea/runConfigurations/Tests.xml index 9cc9603ae5f..862b226348a 100644 --- a/.idea/runConfigurations/Tests.xml +++ b/.idea/runConfigurations/Tests.xml @@ -1,14 +1,13 @@ - + +