Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/ocm/state features #2299

Merged
merged 312 commits into from
Jan 27, 2022
Merged

Feat/ocm/state features #2299

merged 312 commits into from
Jan 27, 2022

Conversation

jdcpni
Copy link
Collaborator

@jdcpni jdcpni commented Jan 27, 2022

Main changes:

  • defer validation of state_features until run time (i.e., after Composition is fully constructed)
  • support set format for ocm state_feature_specs
  • various additional warnings and error messages for violations of state_features format expectations

TBD: document set format for state_features

• composition.py:

  • run():
    • set context.execution_phase to ContextFlags.PREPARING at entry
      and reinstate entry context just before executing trials
  • _complete_init_of_partially_initialized_nodes():
    • set needs_update_controller based on return value of ocm._update_state_input_ports_for_controller()

• optimizationcontrolmechanism.py:

  • _parse_state_feature_specs(), _validate_state_features():
    • support set format
    • further insure that ordering is same as in list in agent_rep.nodes,
    • support updating of state_features and state_input_ports for nodes added after add_controller is initially called
    • support spec of comp if it is an INPUT node in set format(unpacks to INPUT Nodes within it)
    • support None in list format (ignores INPUT Node at specified point in order)
    • errors for comp spec in list or SHADOW_INPUTS dict (TBI: replace by expansion to INPUT Nodes of comp)
    • refactor to manage INPUT Nodes (self._specified_input_nodes_in_order)
      and state_input_port source specs (state_feature_specs) as parallel lists
    • _update_state_input_ports_for_controller():
      • restrict call to _validate_state_features() to run time (ContextFlags.PROCESSING)
      • return True if passes, None otherwise
    • enforce list format for agent_rep = COMPOSITION_FUNCTION_APPROXIMATOR
  • _validate_state_features():
    • add warning for number of state_features < or > agent_rep INPUT Nodes

• inputport.py:

  • _parse_self_port_type_spec(): change name of shadowed inputports to use full_name

• test_control.py:

  • test_args_specific_to_ocm()
    • add run() to test to preciptitate error detected in _validate_state_feature_specs()
  • test_ocm_state_feature_specs_and_warnings_and_errors():
    • add error tests for comp spec in list or SHADOW_INPUTS dict (replace with checks when expansion of these is handled)
    • add error tests for set spec in SHADOW_INPUTS dict
    • reinstate 'too_many_inputs_warning' condition
  • test_partial_deferred_init():
    • add conditions for list, set and dict specs

jdcpni and others added 30 commits November 16, 2021 07:57
  moved calls to _update_controller to _complete_init_of_partially_initialized_nodes
  moved _update_controller to ocm._update_state_input_ports
  _instantiate_controller_shadow_projections [still needs to be implemented]

• optimizationcontrolmechanism.py:
  added _update_state_input_ports [**still needed work**]
  added needs_update_controller
  - implemented self.needs_update_controller
  - moved implementation of controlsignal projections
    from add_controller to _instantiate_control_projections
    that is called in _complete_init_of_partially_initialized_nodes

Note: still need to set  self.needs_update_controller to False
      after instantiating state_input_ports and projections to them
  - _update_state_input_ports_for_controller: handle nested input nodes
  _update_state_input_ports_for_controller:  fixed bug with > 1 INPUT node in Composition
jdcpni and others added 26 commits January 21, 2022 17:26
…ub.com/PrincetonUniversity/PsyNeuLink into feat/ocm/state_features_parallel_lists

� Conflicts:
�	psyneulink/core/components/mechanisms/modulatory/control/optimizationcontrolmechanism.py
…osition IS FULLY CONSTRUCTED)

• composition.py:
  - run():
    - set context.execution_phase to ContextFlags.PREPARING at start
      and reinstate entry context just before executing trials
  - _complete_init_of_partially_initialized_nodes():
    - set needs_update_controller based on return value of ocm._update_state_input_ports_for_controller()
• optmizationcontrolmechanism.py:
  _ _update_state_input_ports_for_controller():
     - restrict call to _validate_state_features() to run time (ContextFlags.PROCESSING)
     - return True if passes, None otherwise
  - _validate_state_features():
     - reinstate warning for number of state_features > agent_rep INPUT Nodes

 • test_control.py:
   -test_args_specific_to_ocm()
     - add run() to test to preciptitate error detected in _validate_state_feature_specs()
   - test_ocm_state_feature_specs_and_warnings_and_errors():
     - reinstate 'too_many_inputs_warning' condition
  deal with deferred INPUT nodes in state_features
  - add _validate_input_nodes()
  - add _instantiate_pending_state_features() - STUB at present
  - state_features:  updated after adding nodes to comp
• optimizationcontrolmechanism.py
  - state_features:  correct to properly include updated INPUT nodes
…ommit)

• optimizationcontrolmechanism.py
  - _parse_state_feature_specs() & state_features:  further fixes to properly include added INPUT nodes
  _parse_state_feature_specs() & _validate_state_features(): add mention of missing nodes to warning / error messages
  add _get_nodes_not_in_agent_rep()
  - _parse_state_feature_specs():  enforce list spec for agent_rep_type == COMPOSITION_FUNCTION_APPROXIMATOR
@lgtm-com
Copy link
Contributor

lgtm-com bot commented Jan 27, 2022

This pull request introduces 2 alerts and fixes 2 when merging 88f05fc into b207320 - view on LGTM.com

new alerts:

  • 2 for Comparison using is when operands support `__eq__`

fixed alerts:

  • 1 for Wrong name for an argument in a call
  • 1 for Comparison using is when operands support `__eq__`

@github-actions
Copy link

This PR causes the following changes to the html docs (ubuntu-latest-3.7-x64):

diff -r docs-base/OptimizationControlMechanism.html docs-head/OptimizationControlMechanism.html
344c344
< <figure class="align-default" id="id4">
---
> <figure class="align-default" id="id5">
354c354
< <a class="reference internal" href="CompositionFunctionApproximator.html"><span class="doc">CompositionFunctionApproximator</span></a> as the <a class="reference internal" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism.agent_rep" title="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism.agent_rep"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">agent_rep</span></code></a>.</span><a class="headerlink" href="#id4" title="Permalink to this image">¶</a></p>
---
> <a class="reference internal" href="CompositionFunctionApproximator.html"><span class="doc">CompositionFunctionApproximator</span></a> as the <a class="reference internal" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism.agent_rep" title="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism.agent_rep"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">agent_rep</span></code></a>.</span><a class="headerlink" href="#id5" title="Permalink to this image">¶</a></p>
560d559
< <p>State features can also be added to an existing OptimizationControlMechanism using its <a class="reference internal" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism.add_state_features" title="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism.add_state_features"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">add_state_features</span></code></a> method.</p>
1047c1046
< <a class="reference internal" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism.state_features" title="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism.state_features"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">state</span> <span class="pre">features</span></code></a>, that are the sources of its
---
> <a class="reference internal" href="#id4" title="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism.state_features"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">state</span> <span class="pre">features</span></code></a>, that are the sources of its
1307,1310c1306,1351
< <dt class="sig sig-object py" id="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._validate_monitor_for_control">
< <span class="sig-name descname"><span class="pre">_validate_monitor_for_control</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">nodes</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._validate_monitor_for_control" title="Permalink to this definition">¶</a></dt>
< <dd><p>Ensure all of the Components being monitored for control are in the Composition being controlled
< If monitor_for_control is specified as an ObjectiveMechanism, warn and move to objective_mecahnism arg</p>
---
> <dt class="sig sig-object py" id="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._get_agent_rep_input_nodes">
> <span class="sig-name descname"><span class="pre">_get_agent_rep_input_nodes</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">comp</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">comp_as_node</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._get_agent_rep_input_nodes" title="Permalink to this definition">¶</a></dt>
> <dd><p>Return all input_nodes of agent_rep, including those for any Composition nested one level down.
> If an INPUT Node is a Composition, and include_comp_as_node is:
> - False, include the nested Composition’s INPUT Nodes, but not the Composition
> - True, include the nested Composition but not its INPUT Nodes
> - ALL, include the nested Composition AND its INPUT Nodes</p>
> </dd></dl>
> 
> <dl class="py method">
> <dt class="sig sig-object py" id="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._validate_input_nodes">
> <span class="sig-name descname"><span class="pre">_validate_input_nodes</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">nodes</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">enforce</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._validate_input_nodes" title="Permalink to this definition">¶</a></dt>
> <dd><p>Check that nodes are INPUT Nodes of agent_rep
> Raise exception for non-INPUT Nodes if <strong>enforce</strong> is specified; else warn.</p>
> </dd></dl>
> 
> <dl class="py method">
> <dt class="sig sig-object py" id="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._parse_state_feature_specs">
> <span class="sig-name descname"><span class="pre">_parse_state_feature_specs</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">state_feature_specs</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">feature_functions</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">context</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._parse_state_feature_specs" title="Permalink to this definition">¶</a></dt>
> <dd><p>Parse entries of state_features specifications into InputPort spec dictionaries.</p>
> <p>Called from _instantiate_input_ports()</p>
> <dl class="simple">
> <dt>state_features specify sources of values assigned to state_feature_values, and passed to agent_rep.evaluate()</dt><dd><p>as the inputs to its INPUT Nodes.</p>
> </dd>
> </dl>
> <p>Each is used to create Projection(s) from specified source (may be direct or indirect from a nested Composition)
> If the number of state_features specified is less than the number of agent_rep INPUT Nodes,</p>
> <blockquote>
> <div><p>do not construct a state_input_port (as a result, no input is provided to the corresponding INPUT Node
> when agent_rep.evaluate() executes, and the value of that NODE from its last execution is used.</p>
> </div></blockquote>
> <dl class="simple">
> <dt>If shadowing is specified, set INTERNAL_ONLY to True in entry of params dict for state_input_port’s InputPort</dt><dd><p>specification dictionary (so that inputs to Composition are not required if the specified state_feature
> is for an INPUT Node).</p>
> </dd>
> <dt>If an INPUT Node is specified that is not (yet) in agent_rep, and/or a source is specified that is not yet</dt><dd><p>in the self.composition, warn and defer creating a state_input_port;  final check is made (and error
> generated for unresolved specifications at run time.</p>
> </dd>
> </dl>
> <p>Handle four formats:
> - list:  list of sources; must be listed in same order as INPUT Nodes of agent_rep to which they correspond;
> - dict:  keys are INPUT Nodes of agent_rep and values are corresponding sources;
> - set: INPUT Nodes for which shadowing is specified
> - SHADOW_INPUTS dict:  single entry with key=’SHADOW_INPUTS” and values=list of sources (see above).</p>
> <p>Assign functions specified in <strong>state_feature_functions</strong> to InputPorts for all state_features</p>
> <p>Return list of InputPort specification dictionaries for state_input_ports</p>
1333a1375,1397
> <p>Return True if successful, None if not performed.</p>
> </dd></dl>
> 
> <dl class="py method">
> <dt class="sig sig-object py" id="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._validate_state_features">
> <span class="sig-name descname"><span class="pre">_validate_state_features</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._validate_state_features" title="Permalink to this definition">¶</a></dt>
> <dd><p>Validate that state_features are legal and consistent with agent_rep.</p>
> <p>Called by _update_state_input_ports_for_controller,
> - after new Nodes have been added to Composition
> - and/or in run() as final check before execution.</p>
> <p>Ensure that:
> - if state_feature_specs are speified as a user dict, keys are valid INPUT Nodes of agent_rep;
> - all InputPorts shadowed by specified state_input_ports are in agent_rep or one of its nested Compositions;
> - any Projections received from output_ports are from Nodes in agent_rep or its nested Compositions;
> - all InputPorts shadowed by state_input_ports reference INPUT Nodes of agent_rep or of a nested Composition;
> - state_features are compatible with input format for agent_rep Composition</p>
> </dd></dl>
> 
> <dl class="py method">
> <dt class="sig sig-object py" id="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._validate_monitor_for_control">
> <span class="sig-name descname"><span class="pre">_validate_monitor_for_control</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">nodes</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._validate_monitor_for_control" title="Permalink to this definition">¶</a></dt>
> <dd><p>Ensure all of the Components being monitored for control are in the Composition being controlled
> If monitor_for_control is specified as an ObjectiveMechanism, warn and move to objective_mecahnism arg</p>
1391,1407c1455,1463
< <dl class="py method">
< <dt class="sig sig-object py" id="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._get_agent_rep_input_nodes">
< <span class="sig-name descname"><span class="pre">_get_agent_rep_input_nodes</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">comp</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._get_agent_rep_input_nodes" title="Permalink to this definition">¶</a></dt>
< <dd><p>Return all input_nodes of agent_rep, including those for any Composition nested one level down.
< Note: more deeply nested Compositions will either be served by their containing one(s) or own controllers</p>
< </dd></dl>
< 
< <dl class="py method">
< <dt class="sig sig-object py" id="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._parse_state_feature_specs">
< <span class="sig-name descname"><span class="pre">_parse_state_feature_specs</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">state_features</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">feature_functions</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">context</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._parse_state_feature_specs" title="Permalink to this definition">¶</a></dt>
< <dd><p>Parse entries of state_features into InputPort spec dictionaries
< For entries specifying shadowing, set INTERNAL_ONLY entry of params dict for InputPort spec dictionary to True</p>
< <blockquote>
< <div><p>(so that inputs to Composition are not required if the specified state feature is on an INPUT Mechanism)</p>
< </div></blockquote>
< <p>Assign functions specified in <strong>state_feature_functions</strong> to InputPorts for all state_features
< Return list of InputPort specification dictionaries for state_input_ports</p>
---
> <dl class="py property">
> <dt class="sig sig-object py" id="id4">
> <em class="property"><span class="pre">property</span> </em><span class="sig-name descname"><span class="pre">state_features</span></span><a class="headerlink" href="#id4" title="Permalink to this definition">¶</a></dt>
> <dd><p>source} entries for specifications in <strong>state_features</strong> arg of constructor.</p>
> <dl class="field-list simple">
> <dt class="field-odd">Type</dt>
> <dd class="field-odd"><p>Return dict with {INPUT Node</p>
> </dd>
> </dl>
1421,1428d1476
< </dd></dl>
< 
< <dl class="py method">
< <dt class="sig sig-object py" id="psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism.add_state_features">
< <span class="sig-name descname"><span class="pre">add_state_features</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">features</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">context</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism.add_state_features" title="Permalink to this definition">¶</a></dt>
< <dd><p>Add InputPorts and Projections to OptimizationControlMechanism for state_features used to
< predict <a class="reference internal" href="ControlMechanism.html#psyneulink.core.components.mechanisms.modulatory.control.controlmechanism.ControlMechanism.net_outcome" title="psyneulink.core.components.mechanisms.modulatory.control.controlmechanism.ControlMechanism.net_outcome"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">net_outcome</span></code></a></p>
< <p><strong>state_features</strong> argument can use any of the forms of specification allowed for InputPort(s)</p>
diff -r docs-base/genindex.html docs-head/genindex.html
936a937,938
>       <li><a href="OptimizationControlMechanism.html#psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism._validate_input_nodes">_validate_input_nodes() (psyneulink.core.components.mechanisms.modulatory.control.optimizationcontrolmechanism.OptimizationControlMechanism method)</a>
> </li>
1052a1055,105
...

See CI logs for the full diff.

@jdcpni jdcpni merged commit c8f5f89 into devel Jan 27, 2022
@jdcpni jdcpni deleted the feat/ocm/state_features branch January 27, 2022 22:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants