Skip to content

Refactor/emcomposition/externalmemorymechanisms#3595

Merged
jdcpni merged 158 commits into
develfrom
refactor/emcomposition/externalmemorymechanisms
Jul 17, 2026
Merged

Refactor/emcomposition/externalmemorymechanisms#3595
jdcpni merged 158 commits into
develfrom
refactor/emcomposition/externalmemorymechanisms

Conversation

@jdcpni

@jdcpni jdcpni commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

• emcomposition.py:

- fully refactored to replace storage of memories in Projection matrices to use of ExternalMemoryMechanisms for each field

- this version replaces:
  - match_nodes backed by memory Projection matrices with
  - retrieved_nodes backed by memory Projection matrices
  - EMStorageMechanism
  with:
  - one ExternalMemoryMechanism per field, each owning its field memory matrix.
  - storage occurs in each memory_node based on access_condition and its storage_prob using MatrixMemory Function

- the externally visible structure is kept similar to the original EMComposition:
  - input_nodes
  - query_input_nodes
  - value_input_nodes
  - field_weight_nodes
  - weighted_scores_nodes
  - combined_scores_node
  - retrieved_nodes

- internally, field.memory_node is now the memory owner for each field.

- memory_decay_rate: meaning has changed:  
  - (1-memory_decay_rate) is now multipled by memory (rather than memory_decay_rate itself)
    this is so that larger values impose faster decay, rather than the reverse

- add differentiable_storage option (default False): stores keep their autograd graph so gradients flow back through stored entries (ESBN-style, Webb et al. 2021), instead of only through the retrieval query (Giallanza-style). Warning if enabled withoutfull_sequence_mode, where it can have no effect. Minimal ESBN-style equivalence tests intests/composition/test_em_differentiable_storage.py.

- fix RETRIEVE operation to return actual memory norms (not zeros) so the MIN_NORM_INDEX used by STORE selects the correct entry to replace.

• GRUcomposition.py

  • Fix gradient flow for GRUComposition + EMComposition in both full_sequence_mode(full BPTT) and ordinary trial-by-trial mode;
  • add tests against pure-PyTorch references (tests/composition/test_gru_em.py).

jdcpni added 30 commits May 4, 2026 05:30
• emcomposition2.py
  initial implementation
merge from devel
merge from devel
• episodicmemoryfieldmechanism.py: INSTANTIATING
• episodicmemoryfieldmechanism.py: INSTANTIATING / DEBUGGING
• episodicmemoryfieldmechanism.py: INSTANTIATING / DEBUGGING
• episodicmemoryfieldmechanism.py
  - without proper sequencing of node execution or storage
• emcomposition2.py
  - add _set_processing_attributes; working on adding conditions for execution sequencing.
• emcomposition2.py
  - add _set_processing_attributes; working on adding conditions for execution sequencing.
• emcomposition2.py
  - add _set_processing_attributes; working on adding conditions for execution sequencing.
• emcomposition2.py
  - add _set_processing_attributes; working on adding conditions for execution sequencing.
• episodicmemoryfieldmechanism.py
  - with storage scheduling,
  - before implementation of ContentAddressableMemory
• episodicmemoryfieldmechanism.py
  - implement DifferentialbleContentAddressableMemory in EpisodicMemoryFieldMechanism
• emcomposition2.py
  - continued implementation
• emcomposition2.py
  - constructs; now need to debug run
• episodicmemoryfieldmechanism.py
  - implement DifferentialbleContentAddressableMemory in EpisodicMemoryFieldMechanism
• emcomposition2.py
  - refactor _construct_combined_scores_node() to deal with field_weights
  - implement _construct_combined_norms_node()
• emcomposition2.py
  - refactor _construct_combined_scores_node() to deal with field_weights
  - implement _construct_combined_norms_node()
• emcomposition2.py - constructs, now needs run debugging
• emcomposition2.py - constructs, now needs run debugging
• emcomposition2.py
  - refactor _construct_combined_scores_node() to deal with field_weights
  - implement _construct_combined_norms_node()
• emcomposition2.py
  - test_simple_execution_without_learning(): runs but retrieved value is not correct
• emcomposition2.py, episodicmemoryfieldmechanism.py:
  - added support for storage_prob

• test_emcomposition.py
  - test_simple_execution_without_learning(): passes up to [Python-no_learning-3]
• test_emcomposition.py
  - test_simple_execution_without_learning(): passes up to [Python-no_learning-4]
• test_emcomposition.py
  - test_simple_execution_without_learning(): passes up to [Python-no_learning-4]
• episodicmemoryfieldmechanism.py
  - DifferentiableContentAddressableMemory():
    - _store_memory: use 1-memory_decay_rate as actual decay rate
• test_emcomposition.py
  - test_simple_execution_without_learning(): passes up to [Python-no_learning-7]
• episodicmemoryfieldmechanism.py
  - don't update output_ports on STORE (only after RETRIEVE)
• test_emcomposition.py
  - test_simple_execution_without_learning(): passes up to [Python-no_learning-12]
• episodicmemoryfieldmechanism.py
  - refactor to use MatrixMemory Function

• transformfunctions.py
  add MatrixMemory(MatrixTransform) Function

• test_emcomposition.py
  - test_simple_execution_without_learning(): passes up to [Python-no_learning-12]
jdcpni and others added 12 commits June 22, 2026 09:38
…APH' of https://github.com/PrincetonUniversity/PsyNeuLink into refactor/emcomposition/externalmemorymechanisms_SHOW_GRAPH

# Conflicts:
#	psyneulink/library/models/Giallanza2024_EGO_Study2.py
…Link into refactor/emcomposition/externalmemorymechanisms
…Link into refactor/emcomposition/externalmemorymechanisms
…Link into refactor/emcomposition/externalmemorymechanisms
… option to EMComposition

- Fix gradient flow for GRUComposition + EMComposition in both full_sequence_mode
  (full BPTT) and ordinary trial-by-trial mode; add consolidated equivalence tests
  against pure-PyTorch references (tests/composition/test_gru_em.py).
- Add differentiable_storage option to EMComposition (default False): stores keep
  their autograd graph so gradients flow back through stored entries (ESBN-style,
  Webb et al. 2021), instead of only through the retrieval query (Giallanza-style).
  Documented in EMComposition docs; warning if enabled without full_sequence_mode,
  where it can have no effect. Minimal ESBN-style equivalence tests in
  tests/composition/test_em_differentiable_storage.py.
- Fix RETRIEVE operation to return actual memory norms (not zeros) so the
  MIN_NORM_INDEX used by STORE selects the correct entry to replace.
- Gitignore local thesis scripts and show_graph output artifacts.

Co-authored-by: Cursor <cursoragent@cursor.com>
Style-only whitespace fixes flagged by CI: missing whitespace around
arithmetic operators, missing whitespace after keyword, and trailing
whitespace in docstrings/comments.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
emcomposition.py imported torch unconditionally at module scope, breaking
the whole psyneulink import chain when torch isn't installed (torch is
only actually used inside a function gated on torch_available).
• Updates to EGO Model docstrings (though may be more to do)
   - add differentiable_storage option (default False): stores keep their autograd graph so gradients flow back through stored entries (ESBN-style, Webb et al. 2021), instead of only through the retrieval query (Giallanza-style). Warning if enabled withoutfull_sequence_mode, where it can have no effect. Minimal ESBN-style equivalence tests intests/composition/test_em_differentiable_storage.py.

    - fix RETRIEVE operation to return actual memory norms (not zeros) so the MIN_NORM_INDEX used by STORE selects the correct entry to replace.

• GRUcomposition.py
  - Fix gradient flow for GRUComposition + EMComposition in both full_sequence_mode(full BPTT) and ordinary trial-by-trial mode;
  - add tests against pure-PyTorch references (tests/composition/test_gru_em.py).
…Link into refactor/emcomposition/externalmemorymechanisms

# Conflicts:
#	.gitignore

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

@github-actions

Copy link
Copy Markdown

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

diff -r docs-base/AutodiffComposition.html docs-head/AutodiffComposition.html
1499a1500,1507
> <dt class="sig sig-object py" id="psyneulink.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function">
> <span class="sig-name descname"><span class="pre">execute_function</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">function</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">fct_has_mult_args</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.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function" title="Link to this definition">¶</a></dt>
> <dd><p>Execute _gen_pytorch_fct on variable, enforce result to be 2d, and return it.
> If fct_has_mult_args is True, treat each item in variable as an arg to the function
> If False, compute function for each item in variable and return results in a list</p>
> </dd></dl>
> 
> <dl class="py method">
1587c1595
< <span class="sig-name descname"><span class="pre">_mech_is_receiver_in_learnable_pathway</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">mech_output_port</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.library.compositions.autodiffcomposition.AutodiffComposition._mech_is_receiver_in_learnable_pathway" title="Link to this definition">¶</a></dt>
---
> <span class="sig-name descname"><span class="pre">_mech_is_receiver_in_learnable_pathway</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">mech_output_port</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">visited</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.library.compositions.autodiffcomposition.AutodiffComposition._mech_is_receiver_in_learnable_pathway" title="Link to this definition">¶</a></dt>
2407a2416
> <li><a class="reference internal" href="#psyneulink.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function"><code class="docutils literal notranslate"><span class="pre">AutodiffComposition.PytorchMechanismWrapper.execute_function()</span></code></a></li>
diff -r docs-base/Composition.html docs-head/Composition.html
2266c2266
< <p>Executing a Composition returns the results of the last <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIAL</span></code></a> executed. If either <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.run" title="psyneulink.core.compositions.composition.Composition.run"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">run</span></code></a> or <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.learn" title="psyneulink.core.compositions.composition.Composition.learn"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">learn</span></code></a> is called, the results of all <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIALS</span></code></a> executed
---
> <p>Executing a Composition returns the result of the last <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIAL</span></code></a> executed. If either <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.run" title="psyneulink.core.compositions.composition.Composition.run"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">run</span></code></a> or <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.learn" title="psyneulink.core.compositions.composition.Composition.learn"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">learn</span></code></a> is called, the results of all <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIALS</span></code></a> executed
5429c5429,5434
< <dd><p>Implement dict with all INPUT Nodes of Composition as keys and their assigned inputs or defaults as values
---
> <dd><dl class="field-list simple">
> <dt class="field-odd">Return type<span class="colon">:</span></dt>
> <dd class="field-odd"><p><span class="sphinx_autodoc_typehints-type"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></span></p>
> </dd>
> </dl>
> <p>Implement dict with all INPUT Nodes of Composition as keys and their assigned inputs or defaults as values
diff -r docs-base/EMComposition.html docs-head/EMComposition.html
213a214
> <li><p><a class="reference internal" href="ExternalMemoryMechanism.html"><span class="doc">ExternalMemoryMechanism</span></a></p></li>
231,235c232,271
< <li><p><a class="reference internal" href="#emcomposition-memory-specification"><span class="std std-ref">Memory</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-memory-capacity"><span class="std std-ref">Capacity</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-fields"><span class="std std-ref">Fields</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-retrieval-storage"><span class="std std-ref">Storage and Retrieval</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-learning-creation"><span class="std std-ref">Learning</span></a></p></li>
---
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-memory-specification"><span class="std std-ref">Memory Structue Specification</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-memory-template"><span class="std std-ref">Memory Template</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-fill"><span class="std std-ref">Memory Fill</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-capacity"><span class="std std-ref">Memory Capacity</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-fields"><span class="std std-ref">Field Characteristics</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-field-specification-dict"><span class="std std-ref">Field Specification Dict</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-names"><span class="std std-ref">Field Names</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-weights"><span class="std std-ref">Field Weights</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-normalize-field-weights"><span class="std std-ref">Normalize Field Weights</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-concatenate-queries"><span class="std std-ref">Concatenate Queries</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-retrieval-storage"><span class="std std-ref">Retrieval and Storage</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-softmax-choice"><span class="std std-ref">Softmax Choice</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-gain"><span class="std std-ref">Softmax Gain</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-threshold"><span class="std std-ref">Softmax Threshold</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-storage-prob"><span class="std std-ref">Storage Probability</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-decay-rate"><span class="std std-ref">Memory Decay Rate</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-learning-creation"><span class="std std-ref">Learning</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-error-backpropagation"><span class="std std-ref">Backpropagation of Error</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-target-fields"><span class="std std-ref">TARGET Fields for Learning</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-weights-learning"><span class="std std-ref">Learning Field Weights</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
251c287,301
< <li><p><a class="reference internal" href="#emcomposition-processing"><span class="std std-ref">Processing</span></a></p></li>
---
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-processing"><span class="std std-ref">Processing</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-compute-similarity-scores"><span class="std std-ref">Compute Similarity Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-compute-norms"><span class="std std-ref">Compute Norms</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-query-concatenation"><span class="std std-ref">Concatenate Queries</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-weight-fields"><span class="std std-ref">Weight Fields</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-combine-scores"><span class="std std-ref">Combine Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-normalize-scores"><span class="std std-ref">Softmax Normalize Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-retrieve-values"><span class="std std-ref">Retrieve Values</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-decay-memories"><span class="std std-ref">Decay Memories</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-store-values"><span class="std std-ref">Store Values</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
259,260c309
< <li><p><a class="reference internal" href="#emcomposition-example-memory-template"><span class="std std-ref">Memory Template and Fill</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-example-field-weights"><span class="std std-ref">Field Weights</span></a></p></li>
---
> <li><p><a class="reference internal" href="#emcomposition-example-case"><span class="std std-ref">Example Case</span></a></p></li>
271,298c320,337
< <p>The EMComposition implements a configurable, content-addressable form of episodic (or external) memory. It emulates
< an <a class="reference internal" href="EpisodicMemoryMechanism.html"><span class="doc">EpisodicMemoryMechanism</span></a> – reproducing all of the functionality of its <a class="reference internal" href="MemoryFunctions.html#psyneulink.core.components.functions.stateful.memoryfunctions.ContentAddressableMemory" title="psyneulink.core.components.functions.stateful.memoryfunctions.ContentAddressableMemory"><code class="xref any py py-class docutils literal notranslate"><span class="pre">ContentAddressableMemory</span></code></a> <a class="reference internal" href="Function.html"><span class="doc">Function</span></a> –
< in the form of an <a class="reference internal" href="AutodiffComposition.html"><span class="doc">AutodiffComposition</span></a>. This allows it to backpropagate error signals based retrieved values to
< it inputs, and learn how to differentially weight cues (queries) used for retrieval. It also adds the capability for
< <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory_decay_rate" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory_decay_rate"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory_decay</span></code></a>. In these respects, it implements a variant of a <a class="reference external" href="https://en.wikipedia.org/wiki/Modern_Hopfield_network">Modern Hopfield
< Network</a>, as well as some of the features of a <a class="reference external" href="https://en.wikipedia.org/wiki/Transformer_(deep_learning_architecture)">Transformer</a></p>
< <p>The <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory</span></code></a> of an EMComposition is configured using two arguments of its constructor:
< the <strong>memory_template</strong> argument, that defines the overall structure of its <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory</span></code></a> (the
< number of fields in each entry, the length of each field, and the number of entries); and <strong>fields</strong> argument, that
< defines which fields are used as cues for retrieval (i.e., as “keys”), including whether and how they are weighted in
< the match process used for retrieval, which fields are treated as “values” that are stored retrieved but not used by
< the match process, and which are involved in learning. The inputs to an EMComposition, corresponding to its keys and
< values, are assigned to each of its <a class="reference internal" href="Composition.html#psyneulink.core.compositions.composition.NodeRole.INPUT" title="psyneulink.core.compositions.composition.NodeRole.INPUT"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">INPUT</span></code></a> <a class="reference internal" href="Composition.html#composition-nodes"><span class="std std-ref">Nodes</span></a>: inputs to be matched to keys
< (i.e., used as “queries”) are assigned to its <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.query_input_nodes" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.query_input_nodes"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">query_input_nodes</span></code></a>; and the remaining
< inputs assigned to it <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.value_input_nodes" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.value_input_nodes"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">value_input_nodes</span></code></a>. When the EMComposition is executed, the
< retrieved values for all fields are returned as the result, and recorded in its <code class="xref any docutils literal notranslate"><span class="pre">results</span></code>
< attribute. The value for each field is assigned as the <a class="reference internal" href="OutputPort.html#psyneulink.core.components.ports.outputport.OutputPo
...

See CI logs for the full diff.

@coveralls

coveralls commented Jul 15, 2026

Copy link
Copy Markdown

Coverage Status

Coverage is 84.186%refactor/emcomposition/externalmemorymechanisms into devel. No base build found for devel.

@github-actions

Copy link
Copy Markdown

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

diff -r docs-base/AutodiffComposition.html docs-head/AutodiffComposition.html
1499a1500,1507
> <dt class="sig sig-object py" id="psyneulink.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function">
> <span class="sig-name descname"><span class="pre">execute_function</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">function</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">fct_has_mult_args</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.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function" title="Link to this definition">¶</a></dt>
> <dd><p>Execute _gen_pytorch_fct on variable, enforce result to be 2d, and return it.
> If fct_has_mult_args is True, treat each item in variable as an arg to the function
> If False, compute function for each item in variable and return results in a list</p>
> </dd></dl>
> 
> <dl class="py method">
1587c1595
< <span class="sig-name descname"><span class="pre">_mech_is_receiver_in_learnable_pathway</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">mech_output_port</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.library.compositions.autodiffcomposition.AutodiffComposition._mech_is_receiver_in_learnable_pathway" title="Link to this definition">¶</a></dt>
---
> <span class="sig-name descname"><span class="pre">_mech_is_receiver_in_learnable_pathway</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">mech_output_port</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">visited</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.library.compositions.autodiffcomposition.AutodiffComposition._mech_is_receiver_in_learnable_pathway" title="Link to this definition">¶</a></dt>
2407a2416
> <li><a class="reference internal" href="#psyneulink.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function"><code class="docutils literal notranslate"><span class="pre">AutodiffComposition.PytorchMechanismWrapper.execute_function()</span></code></a></li>
diff -r docs-base/Composition.html docs-head/Composition.html
2266c2266
< <p>Executing a Composition returns the results of the last <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIAL</span></code></a> executed. If either <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.run" title="psyneulink.core.compositions.composition.Composition.run"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">run</span></code></a> or <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.learn" title="psyneulink.core.compositions.composition.Composition.learn"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">learn</span></code></a> is called, the results of all <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIALS</span></code></a> executed
---
> <p>Executing a Composition returns the result of the last <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIAL</span></code></a> executed. If either <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.run" title="psyneulink.core.compositions.composition.Composition.run"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">run</span></code></a> or <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.learn" title="psyneulink.core.compositions.composition.Composition.learn"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">learn</span></code></a> is called, the results of all <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIALS</span></code></a> executed
5429c5429,5434
< <dd><p>Implement dict with all INPUT Nodes of Composition as keys and their assigned inputs or defaults as values
---
> <dd><dl class="field-list simple">
> <dt class="field-odd">Return type<span class="colon">:</span></dt>
> <dd class="field-odd"><p><span class="sphinx_autodoc_typehints-type"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></span></p>
> </dd>
> </dl>
> <p>Implement dict with all INPUT Nodes of Composition as keys and their assigned inputs or defaults as values
diff -r docs-base/EMComposition.html docs-head/EMComposition.html
213a214
> <li><p><a class="reference internal" href="ExternalMemoryMechanism.html"><span class="doc">ExternalMemoryMechanism</span></a></p></li>
231,235c232,271
< <li><p><a class="reference internal" href="#emcomposition-memory-specification"><span class="std std-ref">Memory</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-memory-capacity"><span class="std std-ref">Capacity</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-fields"><span class="std std-ref">Fields</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-retrieval-storage"><span class="std std-ref">Storage and Retrieval</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-learning-creation"><span class="std std-ref">Learning</span></a></p></li>
---
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-memory-specification"><span class="std std-ref">Memory Structue Specification</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-memory-template"><span class="std std-ref">Memory Template</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-fill"><span class="std std-ref">Memory Fill</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-capacity"><span class="std std-ref">Memory Capacity</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-fields"><span class="std std-ref">Field Characteristics</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-field-specification-dict"><span class="std std-ref">Field Specification Dict</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-names"><span class="std std-ref">Field Names</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-weights"><span class="std std-ref">Field Weights</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-normalize-field-weights"><span class="std std-ref">Normalize Field Weights</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-concatenate-queries"><span class="std std-ref">Concatenate Queries</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-retrieval-storage"><span class="std std-ref">Retrieval and Storage</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-softmax-choice"><span class="std std-ref">Softmax Choice</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-gain"><span class="std std-ref">Softmax Gain</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-threshold"><span class="std std-ref">Softmax Threshold</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-storage-prob"><span class="std std-ref">Storage Probability</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-decay-rate"><span class="std std-ref">Memory Decay Rate</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-learning-creation"><span class="std std-ref">Learning</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-error-backpropagation"><span class="std std-ref">Backpropagation of Error</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-target-fields"><span class="std std-ref">TARGET Fields for Learning</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-weights-learning"><span class="std std-ref">Learning Field Weights</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
251c287,301
< <li><p><a class="reference internal" href="#emcomposition-processing"><span class="std std-ref">Processing</span></a></p></li>
---
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-processing"><span class="std std-ref">Processing</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-compute-similarity-scores"><span class="std std-ref">Compute Similarity Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-compute-norms"><span class="std std-ref">Compute Norms</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-query-concatenation"><span class="std std-ref">Concatenate Queries</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-weight-fields"><span class="std std-ref">Weight Fields</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-combine-scores"><span class="std std-ref">Combine Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-normalize-scores"><span class="std std-ref">Softmax Normalize Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-retrieve-values"><span class="std std-ref">Retrieve Values</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-decay-memories"><span class="std std-ref">Decay Memories</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-store-values"><span class="std std-ref">Store Values</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
259,260c309
< <li><p><a class="reference internal" href="#emcomposition-example-memory-template"><span class="std std-ref">Memory Template and Fill</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-example-field-weights"><span class="std std-ref">Field Weights</span></a></p></li>
---
> <li><p><a class="reference internal" href="#emcomposition-example-case"><span class="std std-ref">Example Case</span></a></p></li>
271,298c320,337
< <p>The EMComposition implements a configurable, content-addressable form of episodic (or external) memory. It emulates
< an <a class="reference internal" href="EpisodicMemoryMechanism.html"><span class="doc">EpisodicMemoryMechanism</span></a> – reproducing all of the functionality of its <a class="reference internal" href="MemoryFunctions.html#psyneulink.core.components.functions.stateful.memoryfunctions.ContentAddressableMemory" title="psyneulink.core.components.functions.stateful.memoryfunctions.ContentAddressableMemory"><code class="xref any py py-class docutils literal notranslate"><span class="pre">ContentAddressableMemory</span></code></a> <a class="reference internal" href="Function.html"><span class="doc">Function</span></a> –
< in the form of an <a class="reference internal" href="AutodiffComposition.html"><span class="doc">AutodiffComposition</span></a>. This allows it to backpropagate error signals based retrieved values to
< it inputs, and learn how to differentially weight cues (queries) used for retrieval. It also adds the capability for
< <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory_decay_rate" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory_decay_rate"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory_decay</span></code></a>. In these respects, it implements a variant of a <a class="reference external" href="https://en.wikipedia.org/wiki/Modern_Hopfield_network">Modern Hopfield
< Network</a>, as well as some of the features of a <a class="reference external" href="https://en.wikipedia.org/wiki/Transformer_(deep_learning_architecture)">Transformer</a></p>
< <p>The <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory</span></code></a> of an EMComposition is configured using two arguments of its constructor:
< the <strong>memory_template</strong> argument, that defines the overall structure of its <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory</span></code></a> (the
< number of fields in each entry, the length of each field, and the number of entries); and <strong>fields</strong> argument, that
< defines which fields are used as cues for retrieval (i.e., as “keys”), including whether and how they are weighted in
< the match process used for retrieval, which fields are treated as “values” that are stored retrieved but not used by
< the match process, and which are involved in learning. The inputs to an EMComposition, corresponding to its keys and
< values, are assigned to each of its <a class="reference internal" href="Composition.html#psyneulink.core.compositions.composition.NodeRole.INPUT" title="psyneulink.core.compositions.composition.NodeRole.INPUT"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">INPUT</span></code></a> <a class="reference internal" href="Composition.html#composition-nodes"><span class="std std-ref">Nodes</span></a>: inputs to be matched to keys
< (i.e., used as “queries”) are assigned to its <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.query_input_nodes" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.query_input_nodes"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">query_input_nodes</span></code></a>; and the remaining
< inputs assigned to it <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.value_input_nodes" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.value_input_nodes"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">value_input_nodes</span></code></a>. When the EMComposition is executed, the
< retrieved values for all fields are returned as the result, and recorded in its <code class="xref any docutils literal notranslate"><span class="pre">results</span></code>
< attribute. The value for each field is assigned as the <a class="reference internal" href="OutputPort.html#psyneulink.core.components.ports.outputport.OutputPo
...

See CI logs for the full diff.

jdcpni added 2 commits July 16, 2026 15:26
• test_giallanza_ego:
  catch exception fo missing torch.mps.manual_seed
@github-actions

Copy link
Copy Markdown

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

diff -r docs-base/AutodiffComposition.html docs-head/AutodiffComposition.html
1499a1500,1507
> <dt class="sig sig-object py" id="psyneulink.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function">
> <span class="sig-name descname"><span class="pre">execute_function</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">function</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">fct_has_mult_args</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.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function" title="Link to this definition">¶</a></dt>
> <dd><p>Execute _gen_pytorch_fct on variable, enforce result to be 2d, and return it.
> If fct_has_mult_args is True, treat each item in variable as an arg to the function
> If False, compute function for each item in variable and return results in a list</p>
> </dd></dl>
> 
> <dl class="py method">
1587c1595
< <span class="sig-name descname"><span class="pre">_mech_is_receiver_in_learnable_pathway</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">mech_output_port</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.library.compositions.autodiffcomposition.AutodiffComposition._mech_is_receiver_in_learnable_pathway" title="Link to this definition">¶</a></dt>
---
> <span class="sig-name descname"><span class="pre">_mech_is_receiver_in_learnable_pathway</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">mech_output_port</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">visited</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.library.compositions.autodiffcomposition.AutodiffComposition._mech_is_receiver_in_learnable_pathway" title="Link to this definition">¶</a></dt>
2407a2416
> <li><a class="reference internal" href="#psyneulink.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function"><code class="docutils literal notranslate"><span class="pre">AutodiffComposition.PytorchMechanismWrapper.execute_function()</span></code></a></li>
diff -r docs-base/Composition.html docs-head/Composition.html
2266c2266
< <p>Executing a Composition returns the results of the last <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIAL</span></code></a> executed. If either <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.run" title="psyneulink.core.compositions.composition.Composition.run"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">run</span></code></a> or <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.learn" title="psyneulink.core.compositions.composition.Composition.learn"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">learn</span></code></a> is called, the results of all <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIALS</span></code></a> executed
---
> <p>Executing a Composition returns the result of the last <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIAL</span></code></a> executed. If either <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.run" title="psyneulink.core.compositions.composition.Composition.run"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">run</span></code></a> or <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.learn" title="psyneulink.core.compositions.composition.Composition.learn"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">learn</span></code></a> is called, the results of all <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIALS</span></code></a> executed
5429c5429,5434
< <dd><p>Implement dict with all INPUT Nodes of Composition as keys and their assigned inputs or defaults as values
---
> <dd><dl class="field-list simple">
> <dt class="field-odd">Return type<span class="colon">:</span></dt>
> <dd class="field-odd"><p><span class="sphinx_autodoc_typehints-type"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></span></p>
> </dd>
> </dl>
> <p>Implement dict with all INPUT Nodes of Composition as keys and their assigned inputs or defaults as values
diff -r docs-base/EMComposition.html docs-head/EMComposition.html
213a214
> <li><p><a class="reference internal" href="ExternalMemoryMechanism.html"><span class="doc">ExternalMemoryMechanism</span></a></p></li>
231,235c232,271
< <li><p><a class="reference internal" href="#emcomposition-memory-specification"><span class="std std-ref">Memory</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-memory-capacity"><span class="std std-ref">Capacity</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-fields"><span class="std std-ref">Fields</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-retrieval-storage"><span class="std std-ref">Storage and Retrieval</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-learning-creation"><span class="std std-ref">Learning</span></a></p></li>
---
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-memory-specification"><span class="std std-ref">Memory Structue Specification</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-memory-template"><span class="std std-ref">Memory Template</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-fill"><span class="std std-ref">Memory Fill</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-capacity"><span class="std std-ref">Memory Capacity</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-fields"><span class="std std-ref">Field Characteristics</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-field-specification-dict"><span class="std std-ref">Field Specification Dict</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-names"><span class="std std-ref">Field Names</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-weights"><span class="std std-ref">Field Weights</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-normalize-field-weights"><span class="std std-ref">Normalize Field Weights</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-concatenate-queries"><span class="std std-ref">Concatenate Queries</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-retrieval-storage"><span class="std std-ref">Retrieval and Storage</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-softmax-choice"><span class="std std-ref">Softmax Choice</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-gain"><span class="std std-ref">Softmax Gain</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-threshold"><span class="std std-ref">Softmax Threshold</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-storage-prob"><span class="std std-ref">Storage Probability</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-decay-rate"><span class="std std-ref">Memory Decay Rate</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-learning-creation"><span class="std std-ref">Learning</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-error-backpropagation"><span class="std std-ref">Backpropagation of Error</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-target-fields"><span class="std std-ref">TARGET Fields for Learning</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-weights-learning"><span class="std std-ref">Learning Field Weights</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
251c287,301
< <li><p><a class="reference internal" href="#emcomposition-processing"><span class="std std-ref">Processing</span></a></p></li>
---
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-processing"><span class="std std-ref">Processing</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-compute-similarity-scores"><span class="std std-ref">Compute Similarity Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-compute-norms"><span class="std std-ref">Compute Norms</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-query-concatenation"><span class="std std-ref">Concatenate Queries</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-weight-fields"><span class="std std-ref">Weight Fields</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-combine-scores"><span class="std std-ref">Combine Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-normalize-scores"><span class="std std-ref">Softmax Normalize Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-retrieve-values"><span class="std std-ref">Retrieve Values</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-decay-memories"><span class="std std-ref">Decay Memories</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-store-values"><span class="std std-ref">Store Values</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
259,260c309
< <li><p><a class="reference internal" href="#emcomposition-example-memory-template"><span class="std std-ref">Memory Template and Fill</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-example-field-weights"><span class="std std-ref">Field Weights</span></a></p></li>
---
> <li><p><a class="reference internal" href="#emcomposition-example-case"><span class="std std-ref">Example Case</span></a></p></li>
271,298c320,337
< <p>The EMComposition implements a configurable, content-addressable form of episodic (or external) memory. It emulates
< an <a class="reference internal" href="EpisodicMemoryMechanism.html"><span class="doc">EpisodicMemoryMechanism</span></a> – reproducing all of the functionality of its <a class="reference internal" href="MemoryFunctions.html#psyneulink.core.components.functions.stateful.memoryfunctions.ContentAddressableMemory" title="psyneulink.core.components.functions.stateful.memoryfunctions.ContentAddressableMemory"><code class="xref any py py-class docutils literal notranslate"><span class="pre">ContentAddressableMemory</span></code></a> <a class="reference internal" href="Function.html"><span class="doc">Function</span></a> –
< in the form of an <a class="reference internal" href="AutodiffComposition.html"><span class="doc">AutodiffComposition</span></a>. This allows it to backpropagate error signals based retrieved values to
< it inputs, and learn how to differentially weight cues (queries) used for retrieval. It also adds the capability for
< <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory_decay_rate" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory_decay_rate"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory_decay</span></code></a>. In these respects, it implements a variant of a <a class="reference external" href="https://en.wikipedia.org/wiki/Modern_Hopfield_network">Modern Hopfield
< Network</a>, as well as some of the features of a <a class="reference external" href="https://en.wikipedia.org/wiki/Transformer_(deep_learning_architecture)">Transformer</a></p>
< <p>The <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory</span></code></a> of an EMComposition is configured using two arguments of its constructor:
< the <strong>memory_template</strong> argument, that defines the overall structure of its <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory</span></code></a> (the
< number of fields in each entry, the length of each field, and the number of entries); and <strong>fields</strong> argument, that
< defines which fields are used as cues for retrieval (i.e., as “keys”), including whether and how they are weighted in
< the match process used for retrieval, which fields are treated as “values” that are stored retrieved but not used by
< the match process, and which are involved in learning. The inputs to an EMComposition, corresponding to its keys and
< values, are assigned to each of its <a class="reference internal" href="Composition.html#psyneulink.core.compositions.composition.NodeRole.INPUT" title="psyneulink.core.compositions.composition.NodeRole.INPUT"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">INPUT</span></code></a> <a class="reference internal" href="Composition.html#composition-nodes"><span class="std std-ref">Nodes</span></a>: inputs to be matched to keys
< (i.e., used as “queries”) are assigned to its <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.query_input_nodes" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.query_input_nodes"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">query_input_nodes</span></code></a>; and the remaining
< inputs assigned to it <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.value_input_nodes" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.value_input_nodes"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">value_input_nodes</span></code></a>. When the EMComposition is executed, the
< retrieved values for all fields are returned as the result, and recorded in its <code class="xref any docutils literal notranslate"><span class="pre">results</span></code>
< attribute. The value for each field is assigned as the <a class="reference internal" href="OutputPort.html#psyneulink.core.components.ports.outputport.OutputPo
...

See CI logs for the full diff.

@github-actions

Copy link
Copy Markdown

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

diff -r docs-base/AutodiffComposition.html docs-head/AutodiffComposition.html
1499a1500,1507
> <dt class="sig sig-object py" id="psyneulink.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function">
> <span class="sig-name descname"><span class="pre">execute_function</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">function</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">fct_has_mult_args</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.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function" title="Link to this definition">¶</a></dt>
> <dd><p>Execute _gen_pytorch_fct on variable, enforce result to be 2d, and return it.
> If fct_has_mult_args is True, treat each item in variable as an arg to the function
> If False, compute function for each item in variable and return results in a list</p>
> </dd></dl>
> 
> <dl class="py method">
1587c1595
< <span class="sig-name descname"><span class="pre">_mech_is_receiver_in_learnable_pathway</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">mech_output_port</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.library.compositions.autodiffcomposition.AutodiffComposition._mech_is_receiver_in_learnable_pathway" title="Link to this definition">¶</a></dt>
---
> <span class="sig-name descname"><span class="pre">_mech_is_receiver_in_learnable_pathway</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">mech_output_port</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">visited</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.library.compositions.autodiffcomposition.AutodiffComposition._mech_is_receiver_in_learnable_pathway" title="Link to this definition">¶</a></dt>
2407a2416
> <li><a class="reference internal" href="#psyneulink.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function"><code class="docutils literal notranslate"><span class="pre">AutodiffComposition.PytorchMechanismWrapper.execute_function()</span></code></a></li>
diff -r docs-base/Composition.html docs-head/Composition.html
2266c2266
< <p>Executing a Composition returns the results of the last <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIAL</span></code></a> executed. If either <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.run" title="psyneulink.core.compositions.composition.Composition.run"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">run</span></code></a> or <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.learn" title="psyneulink.core.compositions.composition.Composition.learn"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">learn</span></code></a> is called, the results of all <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIALS</span></code></a> executed
---
> <p>Executing a Composition returns the result of the last <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIAL</span></code></a> executed. If either <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.run" title="psyneulink.core.compositions.composition.Composition.run"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">run</span></code></a> or <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.learn" title="psyneulink.core.compositions.composition.Composition.learn"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">learn</span></code></a> is called, the results of all <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIALS</span></code></a> executed
5429c5429,5434
< <dd><p>Implement dict with all INPUT Nodes of Composition as keys and their assigned inputs or defaults as values
---
> <dd><dl class="field-list simple">
> <dt class="field-odd">Return type<span class="colon">:</span></dt>
> <dd class="field-odd"><p><span class="sphinx_autodoc_typehints-type"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></span></p>
> </dd>
> </dl>
> <p>Implement dict with all INPUT Nodes of Composition as keys and their assigned inputs or defaults as values
diff -r docs-base/EMComposition.html docs-head/EMComposition.html
213a214
> <li><p><a class="reference internal" href="ExternalMemoryMechanism.html"><span class="doc">ExternalMemoryMechanism</span></a></p></li>
231,235c232,271
< <li><p><a class="reference internal" href="#emcomposition-memory-specification"><span class="std std-ref">Memory</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-memory-capacity"><span class="std std-ref">Capacity</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-fields"><span class="std std-ref">Fields</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-retrieval-storage"><span class="std std-ref">Storage and Retrieval</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-learning-creation"><span class="std std-ref">Learning</span></a></p></li>
---
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-memory-specification"><span class="std std-ref">Memory Structue Specification</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-memory-template"><span class="std std-ref">Memory Template</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-fill"><span class="std std-ref">Memory Fill</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-capacity"><span class="std std-ref">Memory Capacity</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-fields"><span class="std std-ref">Field Characteristics</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-field-specification-dict"><span class="std std-ref">Field Specification Dict</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-names"><span class="std std-ref">Field Names</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-weights"><span class="std std-ref">Field Weights</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-normalize-field-weights"><span class="std std-ref">Normalize Field Weights</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-concatenate-queries"><span class="std std-ref">Concatenate Queries</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-retrieval-storage"><span class="std std-ref">Retrieval and Storage</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-softmax-choice"><span class="std std-ref">Softmax Choice</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-gain"><span class="std std-ref">Softmax Gain</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-threshold"><span class="std std-ref">Softmax Threshold</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-storage-prob"><span class="std std-ref">Storage Probability</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-decay-rate"><span class="std std-ref">Memory Decay Rate</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-learning-creation"><span class="std std-ref">Learning</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-error-backpropagation"><span class="std std-ref">Backpropagation of Error</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-target-fields"><span class="std std-ref">TARGET Fields for Learning</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-weights-learning"><span class="std std-ref">Learning Field Weights</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
251c287,301
< <li><p><a class="reference internal" href="#emcomposition-processing"><span class="std std-ref">Processing</span></a></p></li>
---
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-processing"><span class="std std-ref">Processing</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-compute-similarity-scores"><span class="std std-ref">Compute Similarity Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-compute-norms"><span class="std std-ref">Compute Norms</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-query-concatenation"><span class="std std-ref">Concatenate Queries</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-weight-fields"><span class="std std-ref">Weight Fields</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-combine-scores"><span class="std std-ref">Combine Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-normalize-scores"><span class="std std-ref">Softmax Normalize Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-retrieve-values"><span class="std std-ref">Retrieve Values</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-decay-memories"><span class="std std-ref">Decay Memories</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-store-values"><span class="std std-ref">Store Values</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
259,260c309
< <li><p><a class="reference internal" href="#emcomposition-example-memory-template"><span class="std std-ref">Memory Template and Fill</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-example-field-weights"><span class="std std-ref">Field Weights</span></a></p></li>
---
> <li><p><a class="reference internal" href="#emcomposition-example-case"><span class="std std-ref">Example Case</span></a></p></li>
271,298c320,337
< <p>The EMComposition implements a configurable, content-addressable form of episodic (or external) memory. It emulates
< an <a class="reference internal" href="EpisodicMemoryMechanism.html"><span class="doc">EpisodicMemoryMechanism</span></a> – reproducing all of the functionality of its <a class="reference internal" href="MemoryFunctions.html#psyneulink.core.components.functions.stateful.memoryfunctions.ContentAddressableMemory" title="psyneulink.core.components.functions.stateful.memoryfunctions.ContentAddressableMemory"><code class="xref any py py-class docutils literal notranslate"><span class="pre">ContentAddressableMemory</span></code></a> <a class="reference internal" href="Function.html"><span class="doc">Function</span></a> –
< in the form of an <a class="reference internal" href="AutodiffComposition.html"><span class="doc">AutodiffComposition</span></a>. This allows it to backpropagate error signals based retrieved values to
< it inputs, and learn how to differentially weight cues (queries) used for retrieval. It also adds the capability for
< <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory_decay_rate" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory_decay_rate"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory_decay</span></code></a>. In these respects, it implements a variant of a <a class="reference external" href="https://en.wikipedia.org/wiki/Modern_Hopfield_network">Modern Hopfield
< Network</a>, as well as some of the features of a <a class="reference external" href="https://en.wikipedia.org/wiki/Transformer_(deep_learning_architecture)">Transformer</a></p>
< <p>The <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory</span></code></a> of an EMComposition is configured using two arguments of its constructor:
< the <strong>memory_template</strong> argument, that defines the overall structure of its <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory</span></code></a> (the
< number of fields in each entry, the length of each field, and the number of entries); and <strong>fields</strong> argument, that
< defines which fields are used as cues for retrieval (i.e., as “keys”), including whether and how they are weighted in
< the match process used for retrieval, which fields are treated as “values” that are stored retrieved but not used by
< the match process, and which are involved in learning. The inputs to an EMComposition, corresponding to its keys and
< values, are assigned to each of its <a class="reference internal" href="Composition.html#psyneulink.core.compositions.composition.NodeRole.INPUT" title="psyneulink.core.compositions.composition.NodeRole.INPUT"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">INPUT</span></code></a> <a class="reference internal" href="Composition.html#composition-nodes"><span class="std std-ref">Nodes</span></a>: inputs to be matched to keys
< (i.e., used as “queries”) are assigned to its <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.query_input_nodes" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.query_input_nodes"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">query_input_nodes</span></code></a>; and the remaining
< inputs assigned to it <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.value_input_nodes" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.value_input_nodes"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">value_input_nodes</span></code></a>. When the EMComposition is executed, the
< retrieved values for all fields are returned as the result, and recorded in its <code class="xref any docutils literal notranslate"><span class="pre">results</span></code>
< attribute. The value for each field is assigned as the <a class="reference internal" href="OutputPort.html#psyneulink.core.components.ports.outputport.OutputPo
...

See CI logs for the full diff.

davidt0x added 2 commits July 17, 2026 12:05
Convert the Giallanza EGO test inputs to NumPy before passing them through PsyNeuLink's input parser, avoiding failures with the older Torch and NumPy versions used by Python 3.8 jobs.

Skip the known-unsupported EMComposition MDF conversions instead of marking them xfail. On Windows/Python 3.8, dill can hit a native stack overflow while traversing recursive WeakSet state, killing the xdist worker before xfail can handle the error.

Update the nested PyTorch show_graph expectation to exclude a projection owned by another composition, and restore .asv/ to .gitignore.
@github-actions

Copy link
Copy Markdown

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

diff -r docs-base/AutodiffComposition.html docs-head/AutodiffComposition.html
1499a1500,1507
> <dt class="sig sig-object py" id="psyneulink.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function">
> <span class="sig-name descname"><span class="pre">execute_function</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">function</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">variable</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">fct_has_mult_args</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.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function" title="Link to this definition">¶</a></dt>
> <dd><p>Execute _gen_pytorch_fct on variable, enforce result to be 2d, and return it.
> If fct_has_mult_args is True, treat each item in variable as an arg to the function
> If False, compute function for each item in variable and return results in a list</p>
> </dd></dl>
> 
> <dl class="py method">
1587c1595
< <span class="sig-name descname"><span class="pre">_mech_is_receiver_in_learnable_pathway</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">mech_output_port</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#psyneulink.library.compositions.autodiffcomposition.AutodiffComposition._mech_is_receiver_in_learnable_pathway" title="Link to this definition">¶</a></dt>
---
> <span class="sig-name descname"><span class="pre">_mech_is_receiver_in_learnable_pathway</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">mech_output_port</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">visited</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.library.compositions.autodiffcomposition.AutodiffComposition._mech_is_receiver_in_learnable_pathway" title="Link to this definition">¶</a></dt>
2407a2416
> <li><a class="reference internal" href="#psyneulink.library.compositions.autodiffcomposition.AutodiffComposition.PytorchMechanismWrapper.execute_function"><code class="docutils literal notranslate"><span class="pre">AutodiffComposition.PytorchMechanismWrapper.execute_function()</span></code></a></li>
diff -r docs-base/Composition.html docs-head/Composition.html
2266c2266
< <p>Executing a Composition returns the results of the last <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIAL</span></code></a> executed. If either <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.run" title="psyneulink.core.compositions.composition.Composition.run"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">run</span></code></a> or <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.learn" title="psyneulink.core.compositions.composition.Composition.learn"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">learn</span></code></a> is called, the results of all <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIALS</span></code></a> executed
---
> <p>Executing a Composition returns the result of the last <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIAL</span></code></a> executed. If either <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.run" title="psyneulink.core.compositions.composition.Composition.run"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">run</span></code></a> or <a class="reference internal" href="#psyneulink.core.compositions.composition.Composition.learn" title="psyneulink.core.compositions.composition.Composition.learn"><code class="xref any py py-meth docutils literal notranslate"><span class="pre">learn</span></code></a> is called, the results of all <a class="reference internal" href="Time.html#psyneulink.core.scheduling.time.TimeScale.TRIAL" title="psyneulink.core.scheduling.time.TimeScale.TRIAL"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">TRIALS</span></code></a> executed
5429c5429,5434
< <dd><p>Implement dict with all INPUT Nodes of Composition as keys and their assigned inputs or defaults as values
---
> <dd><dl class="field-list simple">
> <dt class="field-odd">Return type<span class="colon">:</span></dt>
> <dd class="field-odd"><p><span class="sphinx_autodoc_typehints-type"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></span></p>
> </dd>
> </dl>
> <p>Implement dict with all INPUT Nodes of Composition as keys and their assigned inputs or defaults as values
diff -r docs-base/EMComposition.html docs-head/EMComposition.html
213a214
> <li><p><a class="reference internal" href="ExternalMemoryMechanism.html"><span class="doc">ExternalMemoryMechanism</span></a></p></li>
231,235c232,271
< <li><p><a class="reference internal" href="#emcomposition-memory-specification"><span class="std std-ref">Memory</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-memory-capacity"><span class="std std-ref">Capacity</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-fields"><span class="std std-ref">Fields</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-retrieval-storage"><span class="std std-ref">Storage and Retrieval</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-learning-creation"><span class="std std-ref">Learning</span></a></p></li>
---
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-memory-specification"><span class="std std-ref">Memory Structue Specification</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-memory-template"><span class="std std-ref">Memory Template</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-fill"><span class="std std-ref">Memory Fill</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-capacity"><span class="std std-ref">Memory Capacity</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-fields"><span class="std std-ref">Field Characteristics</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-field-specification-dict"><span class="std std-ref">Field Specification Dict</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-names"><span class="std std-ref">Field Names</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-weights"><span class="std std-ref">Field Weights</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-normalize-field-weights"><span class="std std-ref">Normalize Field Weights</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-concatenate-queries"><span class="std std-ref">Concatenate Queries</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-retrieval-storage"><span class="std std-ref">Retrieval and Storage</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-softmax-choice"><span class="std std-ref">Softmax Choice</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-gain"><span class="std std-ref">Softmax Gain</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-threshold"><span class="std std-ref">Softmax Threshold</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-storage-prob"><span class="std std-ref">Storage Probability</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-memory-decay-rate"><span class="std std-ref">Memory Decay Rate</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-learning-creation"><span class="std std-ref">Learning</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-error-backpropagation"><span class="std std-ref">Backpropagation of Error</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-target-fields"><span class="std std-ref">TARGET Fields for Learning</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-field-weights-learning"><span class="std std-ref">Learning Field Weights</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
251c287,301
< <li><p><a class="reference internal" href="#emcomposition-processing"><span class="std std-ref">Processing</span></a></p></li>
---
> <li><dl class="simple">
> <dt><a class="reference internal" href="#emcomposition-processing"><span class="std std-ref">Processing</span></a></dt><dd><ul>
> <li><p><a class="reference internal" href="#emcomposition-compute-similarity-scores"><span class="std std-ref">Compute Similarity Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-compute-norms"><span class="std std-ref">Compute Norms</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-query-concatenation"><span class="std std-ref">Concatenate Queries</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-weight-fields"><span class="std std-ref">Weight Fields</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-combine-scores"><span class="std std-ref">Combine Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-softmax-normalize-scores"><span class="std std-ref">Softmax Normalize Scores</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-retrieve-values"><span class="std std-ref">Retrieve Values</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-decay-memories"><span class="std std-ref">Decay Memories</span></a></p></li>
> <li><p><a class="reference internal" href="#emcomposition-store-values"><span class="std std-ref">Store Values</span></a></p></li>
> </ul>
> </dd>
> </dl>
> </li>
259,260c309
< <li><p><a class="reference internal" href="#emcomposition-example-memory-template"><span class="std std-ref">Memory Template and Fill</span></a></p></li>
< <li><p><a class="reference internal" href="#emcomposition-example-field-weights"><span class="std std-ref">Field Weights</span></a></p></li>
---
> <li><p><a class="reference internal" href="#emcomposition-example-case"><span class="std std-ref">Example Case</span></a></p></li>
271,298c320,337
< <p>The EMComposition implements a configurable, content-addressable form of episodic (or external) memory. It emulates
< an <a class="reference internal" href="EpisodicMemoryMechanism.html"><span class="doc">EpisodicMemoryMechanism</span></a> – reproducing all of the functionality of its <a class="reference internal" href="MemoryFunctions.html#psyneulink.core.components.functions.stateful.memoryfunctions.ContentAddressableMemory" title="psyneulink.core.components.functions.stateful.memoryfunctions.ContentAddressableMemory"><code class="xref any py py-class docutils literal notranslate"><span class="pre">ContentAddressableMemory</span></code></a> <a class="reference internal" href="Function.html"><span class="doc">Function</span></a> –
< in the form of an <a class="reference internal" href="AutodiffComposition.html"><span class="doc">AutodiffComposition</span></a>. This allows it to backpropagate error signals based retrieved values to
< it inputs, and learn how to differentially weight cues (queries) used for retrieval. It also adds the capability for
< <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory_decay_rate" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory_decay_rate"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory_decay</span></code></a>. In these respects, it implements a variant of a <a class="reference external" href="https://en.wikipedia.org/wiki/Modern_Hopfield_network">Modern Hopfield
< Network</a>, as well as some of the features of a <a class="reference external" href="https://en.wikipedia.org/wiki/Transformer_(deep_learning_architecture)">Transformer</a></p>
< <p>The <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory</span></code></a> of an EMComposition is configured using two arguments of its constructor:
< the <strong>memory_template</strong> argument, that defines the overall structure of its <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.memory"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">memory</span></code></a> (the
< number of fields in each entry, the length of each field, and the number of entries); and <strong>fields</strong> argument, that
< defines which fields are used as cues for retrieval (i.e., as “keys”), including whether and how they are weighted in
< the match process used for retrieval, which fields are treated as “values” that are stored retrieved but not used by
< the match process, and which are involved in learning. The inputs to an EMComposition, corresponding to its keys and
< values, are assigned to each of its <a class="reference internal" href="Composition.html#psyneulink.core.compositions.composition.NodeRole.INPUT" title="psyneulink.core.compositions.composition.NodeRole.INPUT"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">INPUT</span></code></a> <a class="reference internal" href="Composition.html#composition-nodes"><span class="std std-ref">Nodes</span></a>: inputs to be matched to keys
< (i.e., used as “queries”) are assigned to its <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.query_input_nodes" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.query_input_nodes"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">query_input_nodes</span></code></a>; and the remaining
< inputs assigned to it <a class="reference internal" href="#psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.value_input_nodes" title="psyneulink.library.compositions.emcomposition.emcomposition.EMComposition.value_input_nodes"><code class="xref any py py-attr docutils literal notranslate"><span class="pre">value_input_nodes</span></code></a>. When the EMComposition is executed, the
< retrieved values for all fields are returned as the result, and recorded in its <code class="xref any docutils literal notranslate"><span class="pre">results</span></code>
< attribute. The value for each field is assigned as the <a class="reference internal" href="OutputPort.html#psyneulink.core.components.ports.outputport.OutputPo
...

See CI logs for the full diff.

@jdcpni
jdcpni merged commit f561867 into devel Jul 17, 2026
129 of 131 checks passed
@jdcpni
jdcpni deleted the refactor/emcomposition/externalmemorymechanisms branch July 17, 2026 19:45
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.

5 participants