# Composition¶

## Overview¶

Warning

As of PsyNeuLink 0.7.5, the API for using Compositions for Learning has been slightly changed! Please see this link for more details.

Composition is the base class for objects that combine PsyNeuLink Components into an executable model. It defines a common set of attributes possessed, and methods used by all Composition objects.

Composition Nodes are Mechanisms and/or nested Compositions. Projections connect pairs of Nodes. The Composition’s graph stores the structural relationships among the Nodes of a Composition and the Projections that connect them. The Composition’s scheduler generates an execution queue based on these structural dependencies, allowing for other user-specified scheduling and termination conditions to be specified.

## Creating a Composition¶

A Composition can be created by calling the constructor and specifying Components to be added, using either arguments of the constructor and/or methods that allow Components to be added once it has been constructed.

Hint

Although Components (Nodes and Projections) can be added individually to a Composition, it is often easier to use Pathways to construct a Composition, which in many cases can automaticially construct the Projections needed without having to specify those explicitly.

### Using the Constructor¶

The following arguments of the Composition’s constructor can be used to add Compnents when it is constructed:

• nodes

adds the specified Nodes to the Composition; this is equivalent to constructing the Composition and then calling its add_nodes method, and takes the same values as the nodes argument of that method.

• projections

adds the specified Projections to the Composition; this is equivalent to constructing the Composition and then calling its add_projections method, and takes the same values as the projections argument of that method.

• pathways

adds one or more Pathways to the Composition; this is equivalent to constructing the Composition and then calling its add_pathways method, and can use the same forms of specification as the pathways argument of that method. If any learning Pathways are included, then the constructor’s disable_learning argument can be used to disable learning on those by default (though it will still allow learning to occur on any other Compositions, either nested within the current one, or within which the current one is nested (see Learning in a Composition for a full description).

• controller

adds the specified ControlMechanism (typically an OptimizationControlMechanism) as the controller of the Composition, that can be used to simulate and optimize performance of the Composition. If this is specified, then the enable_controller, controller_mode, controller_condition and retain_old_simulation_data can be used to configure the controller’s operation (see Controlling a Composition for full description).

The methods used for adding individual Components and Pathways to a Composition are described briefly below. Examples of their their use are provided in Creating a Composition.

The following methods can be used to add individual Components to an existing Composition:

These methods can be used to add Pathways to an existing Composition:

Note

Only Mechanisms and Projections added to a Composition using the methods above belong to a Composition, even if other Mechanism and/or Projections are constructed in the same Python script.

A Node can be removed from a Composition using the remove_node method.

A Composition can be used as a Node of another Composition, either in the nodes argument of its consructor, in a Pathway specified in its pathways argument, or in one of the Composition’s addition methods. Projections can be specifed to and from the nested composition (or created automatically if specified in a Pathway) just as for any other Node.

## Composition Structure¶

This section provides an overview of the structure of a Composition and its Components. Later sections describe these in greater detail, and how they are used to implement various forms of Composition.

### Graph¶

The structure of a Composition is a computational graph, the Nodes of which are Mechanisms and/or nested Composition(s) that carry out computations; and the edges of which can be thought of as Composition’s Projections, that transmit the computational results from one Node to another Node (though see below for a fuller description). The information about a Composition’s structure is stored in its graph attribute, that is a Graph object describing its Nodes and the dependencies determined by its Projections. There are no restrictions on the structure of the graph, which can be acyclic or cyclic, and/or hierarchical (i.e., contain one or more nested Compositions) as described below. A Composition’s graph can be displayed using the Compositon’s show_graph method (see Use of the show_graph Method).

#### Acyclic and Cyclic Graphs¶

Projections are always directed (that is, information is transimtted in only one direction). Therefore, if the Projections among the Nodes of the Compostion never form a loop, then it is a directed acyclic graph (DAG), and the order in which its Nodes are executed can be determined by the structure of the graph itself. However if the Composition contains loops, then its structure is a cyclic graph, and how the Nodes in the loop are initialized and the order in which they execute must be determined in order to execute the graph. PsyNeuLink has procedures both for automatically detecting handling such cycles, and also for allowing the user to specify how this is done (see Cycles and Feedback).

### Nodes¶

Every Node in a Composition’s graph must be either a Mechanism or a nested Composition. The Nodes of a Composition’s graph are listed in its nodes attribute. Each Node is assigned one or more NodeRoles that designate its status in the graph. Nodes are assigned one or more NodeRoles automatically when a Composition is constructed, and when Nodes or Pathways are added to it. However, some of these can be explicitly assigned by specifying the desired NodeRole in any of the following places:

• a tuple specifying the Node in the pathways argument of the Compositon’s constructor, a Pathway's constructor, or in one of the methods used to add a Pathway to the Composition (see Creating a Composition); the Node must be the first item of the tuple, and the NodeRole its 2nd item.

• the roles argument of the require_node_roles called for an an existing Node.

For example, by default, the ORIGIN Nodes of a Composition are assigned as its INPUT nodes (that is, ones that receive the external input when it is run), and similarly its TERMINAL Nodes are assigned as its OUTPUT Nodes (the values of which are reported as the results of running the Composition). However, any other Nodes can be specified as the INPUT or OUTPUT Nodes using the methods above, in addition to those assigned by default. It is also possible to exclude some roles from being assigned by default, using the exclude_node_roles method. The description of each NodeRole indicates whether it is modifiable using these methods. All of the roles assigned to a particular Node can be listed using the get_roles_by_node method, and all of the nodes assigned a particular role can be listed using the get_nodes_by_role method.

### Nested Compositions¶

A nested Composition is one that is a Node within another Composition. When the outer Composition is executed, the nested Composition is executed when its Node in the outer is called to execute by the outer Composition’s scheduler. Any Node within the outer Composition can send aProjection <Projection> to any INPUT Node, and can receive a Projection from any OUTPUT Node within the nested Composition. Similarly, a ControlMechanism within the outer Composition can modulate the parameter of any Mechanism within the nested Composition.

If a nested Composition is an INPUT Node of the outermost Composition then, when the latter is executed, the inputs specified to its execution method must include the InputPorts of the nested Composition. These can be accessed using the Composition’s exernal_input_ports attribute.

A nested Composition can also contain one or more learning Pathways, however a learning Pathway may not extend from an enclosing Composition to one nested within it or vice versa. The learning Pathways within a nested Composition are executed when that Composition is run, just like any other (see Execution of Learning). Any depth of nesting of Compositions within others is allowed.

### Projections¶

Projections can be thought of as directed edges of the Composition’s graph, insofar as they are always from one Node to a single other Node, and serve to convey the results of the sender’s computation as input to the receiver. However, they are not edges in the strictest senese, for two reasons: First, they too can carry out (restricted) computations, such as matrix transformation by a MappingProjection. Second, they can be the receiver of a Projection, as in the case of a MappingProjection that receives a LearningProjection used to modify its matrix parameter. Nevertheless, since they define the connections and therefore dependencies among the Composition’s Nodes, they determine the structure of its graph.

Because Projections are not strictly edges, they are assigned to vertices in the Composition’s graph, along with its Nodes. The actual edges are implicit in the dependencies determined by the Projections, and listed in the graph’s dependency_dict.

Although individual Projections are directed, pairs of Nodes can be connected with Projections in each direction (forming a local cycle), and the AutoAssociativeProjection class of Projection can even connect a Node with itself. Projections can also connect the Node(s) of a Composition to one(s) nested within it.

Although Projections can be specified to and from Nodes within a nested Composition, these are actually implemented as Projections to or from the nested Composition’s input_CIM,parameter_CIM <Composition.parameter_CIM> or output_CIM, respectively; those, in turn, send or receive Projections to the specified Nodes within the nested Composition.

Subsets of Nodes connected by Projections are often defined as a Pathway, as decribed in the next section.

### Pathways¶

A Pathway is an alternating sequence of Nodes and Projections in a Composition. Although a Composition is not required to have any Pathways, these are useful for constructing Compositions, and are required for implementing learning in a Composition. Pathways can be specified in the pathways argument of the Composition’s constructor, or using one of its Pathway addition methods. Pathways must be linear (that is, the cannot have branches), but they can be continguous, overlapping, intersecting, or disjoint, and can have one degree of converging and/or diverging branches (meaning that their branches can’t branch). Each Pathway has a name (that can be assigned when it is constructed) and a set of attributes, including a pathway attribute that lists the Nodes and Projections in the Pathway, a roles attribute that lists the PathwayRoles assigned to it (based on the NodeRoles assigned to its Nodes), and attributes for particular types of nodes (e.g., INPUT and OUTPUT) if the Pathway includes nodes assigned the corresponding NodeRoles. If a Pathway does not have a particular type of Node, then its attribute returns None. There are two types of Pathways: processing Pathways and learning Pathways. Processing Pathways are ones not configured for learning; learning Pathways are described under Learning in a Composition. All of the Pathways in a Composition are listed in its pathways attribute.

## Controlling a Composition¶

A Composition can be assigned a controller. This is a ControlMechanism, or a subclass of one, that modulates the parameters of Components within the Composition (including Components of nested Compositions). It typically does this based on the output of an ObjectiveMechanism that evaluates the value of other Mechanisms in the Composition, and provides the result to the controller.

### Assigning a Controller¶

A controller can be assigned either by specifying it in the controller argument of the Composition’s constructor, or using its add_controller method.

### Controller Execution¶

The controller is executed only if the Composition’s enable_controller attribute is True. This generally done automatically when the controller is assigned. If enabled, the controller is generally executed either before or after all of the other Components in the Composition have been executed within a given TimeScale, as determined by the Composition’s controller_time_scale and controller_mode attributes. The Composition’s controller_condition attribute can be used to further customize when it is executed. All three of these attributes can be specified in corresponding arguments of the Composition’s constructor, or programmatically after it is constructed by assigning the desired value to the corresponding attribute.

## Learning in a Composition¶

Learning is used to modify the Projections between Mechanisms in a Composition. More specifically, it modifies the matrix parameter of the MappingProjections within a learning Pathway, which implement the conection weights (i.e., strengths of associations between representations in the Mechanisms) within a Pathway.

### Configuring Learning in a Composition¶

There are three ways of configuring learning in a Composition:

1. using the AutodiffComposition – a specialized subclass of Composition that executes learning using PyTorch

2. using UserDefinedFunctions.

The advantage of using standard PsyNeuLink compoments is that it assigns each operation involved in learning to a dedicated Component. This helps make clear exactly what those operations are, the sequence in which they are carried out, and how they interact with one another. However, this can also make execution inefficient, due to the overhead incurred by distributing the calculations over different Components. If more efficient computation is critical, then the AutodiffComposition can be used to execute a compatible PsyNeuLink Composition in PyTorch, or one or more UserDefinedFunctions can be assigned to either PyTorch functions or those in any other Python environment that implements learning and accepts and returns tensors. Each of these approaches is described in more detail below.

### Learning Using AutodiffCompositon¶

AutodiffCompositions provide the ability to execute a composition using PyTorch (see example in Basics and Primer). The AutodiffComposition constructor provides arguments for configuring the PyTorch implementation in various ways; the Composition is then built using the same methods (e.g., add_node, add_projection, add_linear_processing_pathway, etc.) as any other Composition. Note that there is no need to use any learning methods — AutodiffCompositions automatically creates backpropagation learning pathways <Composition_Learning_Pathway> between all input - output Node paths. It can be run just as a standard Composition would - using learn for learning mode, and run for test mode.

The advantage of this approach is that it allows the Composition to be implemented in PsyNeuLink, while exploiting the efficiency of execution in PyTorch (which can yield as much as three orders of magnitude improvement). However, a disadvantage is that there are restrictions on the kinds of Compositions that be implemented in this way. First, because it relies on PyTorch, it is best suited for use with supervised learning, although it can be used for some forms of unsupervised learning that are supported in PyTorch (e.g., self-organized maps). Second, all of the Components in the Composition are be subject to and must be with compatible with learning. This means that it cannot be used with a Composition that contains any modulatory components or that are subject to modulation, whether by ControlMechanisms within or outside the Composition; this includes a controller or any LearningMechanisms. An AutodiffComposition can be nested in a Composition that has such other Components. During learning, none of the internal Components of the AutodiffComposition (e.g., intermediate layers of a neural network model) are accessible to the other Components of the outer Composition, (e.g., as sources of information, or for modulation). However, when learning turned off, then the AutodiffComposition functions like any other, and all of its internal Components accessible to other Components of the outer Composition. Thus, as long as access to its internal Components is not needed during learning, an AutodiffComposition can be trained, and then used to execute the trained Composition like any other.

### Learning Using UserDefinedFunctions¶

If execution efficiency is critical and the AutodiffComposition is too restrictive, a function from any Python environment that supports learning can be assigned as the function of a Mechanism, in which case it is automatically wrapped as UserDefinedFunction. For example, the forward and backward methods of a PyTorch object can be assigned in this way. The advanatage of this approach is that it can be applied to any Python function that adheres to the requirements of a UserDefinedFunction. It must be carefully coordinated with the execution of other learning-related Components in the Composition, to insure that each function is called at the appropriate times during execution. Furthermore, as with an AutodiffComposition, the internal constituents of the object (e.g., intermediates layers of a neural network model) are not accessible to other Components in the Composition (e.g., as a source of information or for modulation).

## Executing a Composition¶

There are three methods for executing a Composition:

• run - executes one or more TRIALs without learning;

• learn - executes one or more TRIALs with learning, if the network is configured for learning.

• execute - executes a single TRIAL without learning.

The run and learn methods are the most commonly used. Both of these can execute multiple trials (specified in their num_trials argument), calling the Composition’s execute method for each TRIAL. The execute method can also be called directly, but this is useful mostly for debugging.

Inputs. All methods of executing a Composition require specification of an inputs argument, which designates the values assigned to the INPUT Nodes of the Composition for each TRIAL. A TRIAL is defined as the opportunity for every Node in the Composition to execute for a given set of inputs. The inputs for each TRIAL can be specified using an input dictionary; for the run and learn methods, they can also be specified programmatically (see Input formats (including targets for learning)). The same number of inputs must be specified for every INPUT Node, unless only one value is specified for a Node (in which case that value is provided as the input to that Node for all TRIALs executed). If the inputs argument is not specified for the run or execute methods, the default_variable for each INPUT Node is used as its input on TRIAL. If it is not specified for the learn method, an error is generated unless its targets argument is specified (see below).

Results. At the end of a TRIAL (a list of the output_values for all of its OUTPUT Nodes) are added to the Composition’s results attribute, and the output_values for the last TRIAL executed is returned by the execution method.

Number of trials. If the the execute method is used, a single TRIAL is executed; if the inputs specifies more than one TRIALs worth of input, an error is generated. For the run and learn, the num_trials argument can be used to specify the number of TRIALs to execute; if its value execeeds the number of inputs provided for each Node in the inputs argument, then the inputs are recycled from the beginning of the lists, until the number of TRIALs specified in num_trials has been executed. If num_trials is not specified, then a number of TRIALs is executed equal to the number of inputs provided for each Node in inputs argument.

Learning. If a Composition is configured for learning then, for learning to occur, its learn method must be used in place of the run method, and its disable_learning attribute must be False (the default). A set of targets must also be specified (see below). The run and execute methods can also be used to execute the Composition, but no learning will occur, irrespective of the value of the disable_learning attribute.

### Input formats (including targets for learning)¶

The inputs argument of the Composition’s execution methods (and, for learning, the targets argument of the learn method) is used to specify the inputs to the Composition for each TRIAL. These are provided to the Composition’s INPUT Nodes (including its TARGET_MECHANISMS for learning) each time it is executed. There are two ways to specify inputs:

• using a dictionary, in which the inputs are specified or each TRIAL explicitly;

• programmtically, using a function, generator or generator function that constructs the inputs dynamically on a TRIAL by TRIAL basis.

The inputs argument of the run and learn methods (and the targets argument of the learn method) can be specified in either way; however, only the dictionary format can be used for the execute method, since it executes only one TRIAL at a time, and therefore can only accept inputs for asingle TRIAL.

Inputs and input_ports. All formats must specify the inputs to be assigned, on each TRIAL, to the InputPorts of the Composition’s INPUT Nodes that require external inputs. These are listed in the external_input_ports attribute of the Composition’s INPUT Mechanisms, and the corresponding attribute (external_input_ports) of any nested Composition that is an INPUT Node of the Composition being executed (see above)

Note

Most Mechanisms have only a single InputPort, and thus require only a single input to be specified for them for each TRIAL. However some Mechanisms have more than one InputPort (for example, a ComparatorMechanism), in which case an input must be specified for each InputPort of that Mechanism. Conversely, some Mechanisms have input_ports that are marked as internal_only (for example, the input_port for a RecurrentTransferMechanism, if its has_recurrent_input_port is True), in which case no input should be specified for that input_port. Similar considerations extend to the external_input_ports of a nested Composition, based on the Mechanisms (and/or additionally nested Compositions) that comprise its set of INPUT Nodes.

These factors determine the format of each entry in an inputs dictionary, or the return value of the function or generator used for programmatic specification of inputs, as described in detail below (also see examples).

#### Input Dictionary¶

The simplest way to specificy inputs (including targets for learning) is using a dict, in which each entry specifies the inputs to a given INPUT Node. The key of each entry is a Node, and the value is a list of the inputs to that Node, one for each TRIAL to be executed (i.e., the i-th item of the list represents the input to the Node on TRIAL i). The same number of input values must be specified in each entry, unless only a single input value is specified is in an entry, in which case that input is presented to the corresonding Node in every TRIAL.

Example input dict specification, in which the first entry is for Mechanism a with one InputPort that takes an array of length 2 as its input, and for which two TRIALs worth of input are specified ([1.0, 2.0] and [3,0, 4.0]); the second entry is for Mechanism b with two InputPorts, one of which takes an array of length 1 as its input and the other an array of length 2, and for which two TRIALs worth of input are also specified ([[1.0], [2.0, 3.0]] and [[4.0], [5.0, 6.0]]); and, finaly, a third entry is for Mechanism c with only one InputPort that takes an array of length 1 as its input, and for which only one input is specified ([1.0]), which is therefore provided as the input to Mechanism c on every TRIAL.

Each input value must be compatible with the number of InputPorts that receive external input for that Node. These are listed in its external_input_ports attribute (here if it is Mechanism, or here if it is a Composition). More specifically, the shape of the input value must be compatible with the shape of the Node’s extrernal_input_values attribute (here if it is Mechanism, or here if it is a Composition). While these are always 2d arrays, the number and size of the items (corresponding to each InputPort) may vary; in some case shorthand notations are allowed, as illustrated in the examples below.

For learning, inputs must also be specified for the TARGET_MECHANISM of each learning Pathway in the Composition. This can be done in either the inputs argument or targets argument of the learn method. If the inputs argument is used, it must include an entry for each TARGET_MECHANISM; if the targets argument is used, it must be assigned a dictionary containing entries in which the key is either an OUTPUT_MECHANISM (i.e., the final Node) of a learning Pathway, or the corresponding TARGET_MECHANISM. The value of each entry specifies the inputs for each trial, formatted asdescribed above.

#### Specifying Inputs Programmatically¶

Inputs can also be specified programmticaly, in a TRIAL by TRIAL manner, using a function, generator, or generator function.

A function used as input must take as its sole argument the current TRIAL number and return a value that satisfies all rules above for standard input specification. The only difference is that on each execution, the function must return the input values for each INPUT Node for a single TRIAL.

Note

Default behavior when passing a function as input to a Composition is to execute for only one TRIAL. Remember to set the num_trials argument of Composition.run if you intend to cycle through multiple TRIALs.

Complete input specification:

>>> a = pnl.TransferMechanism(name='a',
...                           default_variable=[[1.0, 2.0, 3.0]])
>>> b = pnl.TransferMechanism(name='b')

>>> pathway1 = [a, b]

>>> comp = pnl.Composition(name='comp')

>>> def function_as_input(trial_num):
...     a_inputs = [[1.0, 2.0, 3.0],[4.0, 5.0, 6.0]]
...     this_trials_inputs = {
...         a: a_inputs[trial_num]
...     }
...     return this_trials_inputs

>>> comp.run(inputs=function_as_input,
...          num_trials=2)

A generator can also be used as input. On each yield, it should return a value that satisfies all rules above for standard input specification. The only difference is that on each execution, the generator must yield the input values for each INPUT Node for a single TRIAL.

Note

Default behavior when passing a generator is to execute until the generator is exhausted. If the num_trials argument of Composition.run is set, the Composition will execute EITHER until exhaustion, or until num_trials has been reached - whichever comes first.

Complete input specification:

>>> a = pnl.TransferMechanism(name='a',default_variable = [[1.0, 2.0, 3.0]])
>>> b = pnl.TransferMechanism(name='b')

>>> pathway1 = [a, b]

>>> comp = pnl.Composition(name='comp')

>>> def generator_as_input():
...    a_inputs = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]
...    for i in range(len(a_inputs)):
...        this_trials_inputs = {a: a_inputs[i]}
...        yield this_trials_inputs

>>> generator_instance = generator_as_input()

>>> # Because the num_trials argument is set to 2, the below call to run will result in only 2 executions of
... # comp, even though it would take three executions to exhaust the generator.
>>> comp.run(inputs=generator_instance,
...          num_trials=2)

If a generator function is used, the Composition will instantiate the generator and use that as its input. Thus, the returned generator instance of a generator function must follow the same rules as a generator instance passed directly to the Composition.

Complete input specification:

>>> a = pnl.TransferMechanism(name='a',default_variable = [[1.0, 2.0, 3.0]])
>>> b = pnl.TransferMechanism(name='b')

>>> pathway1 = [a, b]

>>> comp = pnl.Composition(name='comp')

>>> def generator_function_as_input():
...    a_inputs = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]
...    for i in range(len(a_inputs)):
...        this_trials_inputs = {a: a_inputs[i]}
...        yield this_trials_inputs

>>> comp.run(inputs=generator_function_as_input)

### Runtime Parameters¶

The value of one or more of a Composition’s Nodes can be temporarily modified during execution using the runtime_params argument of one of its execution methods. These are handled as described for Runtime Parameters of Mechanisms, with the addition that one or more Conditions can be specified such that a value will apply only when the specificied Conditions are satisfied; otherwise the parameter’s previously assigned value (or, if none, then its default) will be used, and those values are always restored after execution.

Runtime parameter values for a Composition are specified in a dictionary assigned to the runtime_params argument of a Composition’s execution method. The key of each entry is a Node of the Composition, and the value is a subdictionary specifying the runtime_params argument that will be passed to the Node when it is executed. The format of the dictionary for each Node follows that for a Mechanism’s runtime specification dictionary, except that in addition to specifying the value of a parameter directly (in which case, the value will apply throughout the execution), its value can also be placed in a tuple together with a Condition specifying when that value should be applied, as follows:

• Dictionary assigned to runtime_parms argument: {<Node>: Runtime Parameter Specification Dictionary}
• key - Node

• value - Runtime Parameter Specification Dictionary

• Runtime Parameter Specification Dictionary: {<parameter name>: (<parameter value>, Condition)}
• key - str name of a Parameter of the Node, its function, or a keyword specifying a subdictionary containing runtime parameter specifications for Component(s) of the Node (see below);

• value - (<parameter value>, Condition), <parameter value>, or subdictionary (see below) Condition specifies when the value is applied; otherwise, its previously assigned value or default is used; if the parameter values appears alone in a tuple or outside of one, then the Condtion Always is applied.

See Runtime Parameter Specification Dictionary for additional details.

As in a standard runtime parameter specification dictionary, the key for an entry can be used to specify a subdictionary specifying the runtime parameters for a Mechanism’s Ports, and/or any of their afferent Projections (see Runtime specification ditionary: parameters of a Mechanism’s Ports and Projections). The subdictionaries used to specify those can be placed placed in a tuple, as can any of the specification of parameter values within them. A tuple used to specify a subdictionary determines when any of the parameters specified within it are eligible to apply: If its Condition is not satisfied, then none of the parameters specified within it will apply; if its Condition is satisfied, then any parameter specified within it for which the Condition is satisified will also apply.

### Cycles and Feedback¶

If Projections among any or all of the Nodes in a Composition form loops — that is, there are any cycles in its graph — then the order in which the Nodes are executed must be determined. This is handled in one of two ways:

• Flatten cycle - if the cycle does not have any feedback Projections, then the cycle is “flattened” and all of the Nodes are executed synchronously.

• Break cycle - if cycle has any feedback Projections, they are used to break the cycle at those points, and the remaining Projections are used to execute the Nodes sequentially, with the receiver of each feedback Projection executed first, its sender executed last, and the receiver getting the sender’s value on its next execution.

Each of these approaches is described in greater detail below.

#### Cycles and synchronous execution¶

Cycles. A cycle is formed when the Projections among a set of Nodes form a loop, and none of the Projections is designated as a feedback Projection. Any cycle nested within another is added to the one in which it is nested, and all are treated as part of the same cycle. All Nodes within a cycle are assigned the NodeRole CYCLE.

Note

A RecurrentTransferMechanism (and its subclaseses) are treated as single-Node cylces, formed by their AutoAssociativeProjection (since the latter is subclass of MappingProjection and thus not designated as feedback (see below).

Synchronous execution. Cycles are “flattened” for execution, meaning that all of the Nodes within a cycle are executed in the same TIME_STEP). The input that each Node in a cycle receives from those that project to it from within the cycle is the value of those Nodes when the cycle was last executed in the same execution context; this ensures not only that the execute in synchrony, but that the inputs received from any Nodes within the cycle are synchronized (i.e., from the same earlier TIME_STEP of execution). However, this presents a problem for the first execution of the cycle since, by definition, none of the Nodes have a value from a previous execution. In that case, each sender passes the value to which it has been initialized which, by default, is its default value. However, this can be overridden, as described below.

Note

Although all the Nodes in a cycle receive either the initial value or previous value of other Nodes in the cycle, they receive the current value of any Nodes that project to them from outisde the cycle, and pass their current value (i.e., the ones computed in the current execution of the cycle) to any Nodes to which they project outside of the cycle. The former means that any Nodes within the cycle that receive such input are “a step ahead” of those within the cycle and also, unless the use a StatefulFunction, others within the cycle will not see the effects of that input within or across TRIALS.

Initialization. The initialization of Nodes in a cycle using their default values can be overridden using the initialize_cycle_values argument of the Composition’s run or learn methods. This can be used to specify an initial value for any Node in a cycle. On the first call to run or learn, nodes specified in initialize_cycle_values are initialized using the assigned values, and any Nodes in the cycle that are not specified are assigned their default value. In subsequent calls to run or learn, Nodes specified in initialize_cycle_values will be re-initialized to the assigned values for the first execution of the cycle in that run, whereas any Nodes not specified will retain the last value they were assigned in the uprevious call to run or learn.

Nodes in a cycle can also be initialized outside of a call to run or learn using the initialize method.

Note

If a Mechanism belonging to a cycle in a Composition is first executed on its own (i.e., using its own execute method), the value it is assigned will be used as its initial value when it is executed within the Composition, unless an execution_id is assigned to the context argument of the Mechanism’s execute method when it is called. This is because the first time a Mechanism is executed in a Composition, its initial value is copied from the value last assigned in the None context. As described aove, this can be overridden by specifying an initial value for the Mechanism in the initialize_cycle_values argument of the call to the Composition’s run or learn methods.

#### Feedback and sequential execution¶

Feedback designation. If any Projections in a loop are designated as feedback they are used to break the cycle of execution that would otherwise be formed, and the Nodes are executed sequentially as described below. Each Node that sends a feedback Projection is assigned the NodeRole FEEDBACK_SENDER, and the receiver is assigned the NodeRole FEEDBACK_RECEIVER. By default, MappingProjections are not specified as feedback, and therefore loops containing only MappingProjections are left as cycles by default. In contrast, ModulatoryProjections are designated as feedback by default, and therefore any loops containing one or more ModulatoryProjections are broken by default, with the Mechanism that is modulated designated as the FEEDBACK_RECEIVER and the ModulatoryMechanism that projects to it designated as the FEEDBACK_SENDER. However, the feedback status of any Projection can be specified explicitly, either in a tuple with the Projection where it is specified in a Pathway or in the Composition’s add_projections method, or by using the feedback argument of the Composition’s add_projection method. Specifying True or the keyword FEEDBACK forces its assignment as a feedback Projection, whereas False precludes it from being assigned as a feedback Projection (e.g., a ControlProjection that forms a cycle).

Warning

Designating a Projection as feeedback that is not in a loop is allowed, but will issue a warning and can produce unexpected results. Designating more than one Projection as feedback within a loop is also permitted, by can also lead to complex and unexpected results. In both cases, the FEEDBACK_RECEIVER for any Projection designated as feedback will receive a value from the Projection that is based either on the FEEDBACK_SENDER's initial_value (the first time it is executed) or its previous value (in subsequent executions), rather than its most recently computed value whether or not it is in a cycle (see below).

Sequential execution. The FEEDBACK_RECEIVER is the first of the Nodes that were in a loop to execute in a given PASS, receiving a value from the FEEDBACK_SENDER as described below. It is followed in each subsequent TIME_STEP by the next Node in the sequence, with the FEEDBACK_SENDER executing last.

Initialization. The receiver of a feedback Projection (its FEEDBACK_RECEIVER) is treated in the same way as a CYCLE Node: the first time it executes, it receives input from the FEEDBACK_SENDER based on the value to which it was initialized . On subsequent executions, its input from the FEEDBACK_SENDER is based on the value of that Node after it was last executed in the same execution context.

The FEEDBACK_SENDERs of a Composition are listed in its feedback_senders attribute, and its FEEDBACK_RECEIVERs in feedback_senders. These can also be listed using the Composition’s get_nodes_by_role method. The feedback Projections of a Composition are listed in its feedback_projections attribute, and the feedback status of a Projection in a Composition is returned by its get_feedback_status method.

### Execution Contexts¶

A Composition is always executed in a designated execution context, specified by an execution_id that can be provided to the context argument of the method used to execute the Composition. Execution contexts make several capabilities possible, the two most important of which are:

• a Component can be assigned to, and executed in more than one Composition, preserving its value and that of its parameters independently for each of the Compositions to which it is assigned;

• the same Composition can be exectued independently in different contexts; this can be used for parallelizing parameter estimation, both for data fitting (see ParamEstimationFunction), and for simulating the Composition in model-based optimization (see OptimizationControlMechanism).

If no execution_id is specified, the default execution_id is used, which is generally the Composition’s name; however, any hashable value (e.g., a string, a number, or Component) can be used. That execution_id can then be used to retrieve the value of any of the Composition’s Components or their parameters that were assigned during the execution. If a Component is executed outside of a Composition (e.g, a Mechanism is executed on its own using its execute method), then any assignments to its value and/or that of its parameters is given an execution_id of None.

Note

If the value of a Component or a parameter is queried using dot notation, then its most recently assigned value is returned. To retrieve the value associated with a particular execution context, the parameter’s get method must be used: <Component>.parameters.<parameter_name>.get(execution_id), where value can be used as the parameter_name to retrieve the Component’s value, and the name of any of its other parameters to get their value.

See Execution Contexts for examples.

### Resetting Parameters of StatefulFunctions¶

StatefulFunctions (such as IntegratorFunctions and “non-parametric” MemoryFunctions) have a previous_value attribute that maintains a record of the Function’s values for each execution context in which it is executed, within and between calls to the Composition’s execute methods. This record can be cleared and previous_value reset to either the Function’s default value or another one, using either the Composition’s reset method or in arguments to its run and learn methods, as described below (see Reset Paramters of Stateful Functions for examples):

• reset – this is a method of the Composition that calls the reset method of Nodes in the Composition that have a StatefulFunction, each of which resets the stateful parameters of those Functions. of its StatefulFunction. If it is called without any arguments, it calls the reset method for every Node in the Composition that has a StatefulFunction. It can also be called with a dictionary that specifies a subsset of Nodes to reset (see format descdribed for reset_stateful_functions_when below).

• reset_stateful_functions_when and reset_stateful_functions_to – these are arguments of the Composition’s run and learn methods, that can be used to specify the Conditions under which the reset method of all or a particular subset of Nodes are called during that run, and optionally the values they are assigned when reset. As with runtime_params, these specifications apply only for the duration of the call to run or learn, and the reset_stateful_function_when of all Nodes are restored to their prior values upon completion.

• reset_stateful_functions_when – this specifies the Condition(s) under which the reset method will be called for Nodes with StatefulFunctions. If a single Condition is specified, it is applied to all of the Composition’s Nodes that have StatefulFunctions; a dictionary can also be specified, in which the key for each entry is a Node, its value is a Condition under which that Node’s reset method should be called.

Note

If a single Condition is specified, it applies only to Nodes for which the reset_stateful_function_when attribute has not otherwise been specified. If a dictionary is specified, then the Condition specified for each Node applies to that Node, superceding any prior specification of its reset_stateful_function_when attribute for the duration of the call to run or learn.

• reset_stateful_functions_to – this specifies the values used by each Node to reset the stateful parameters of its StatefulFunction(s). It must be a dictionary of {Node:value} pairs, in which the value specifies the value(s) passed to the reset method of the specified Node. If the reset method of a Node takes more than one value (see Note below), then a list of values must be provided (i.e., as {node:[value_0, value_1,… value_n]}) that matches the number of arguments taken by the reset method. Any Nodes not specified in the dictionary are reset using their default value(s).

Note

The reset method of most Nodes with a StatefulFunction takes only a single value, that is used to reset the previous_value attribute of the Function. However some (such as those that use DualAdaptiveIntegrator) take more than one value. For such Nodes, a list of values must be specified as the value of their dicitonary entry in reset_stateful_functions_to.

The reset_stateful_functions_when and reset_stateful_functions_to arguments can be used in conjunction or independently of one another. For example, the Condition(s) under which a Mechanism with a StatefulFunction is reset using to its default values can be specified by including it in reset_stateful_functions_when but not reset_stateful_functions_to. Conversely, the value to which the StatefulFunction of a Mechanism is reset can be specified without changing the Condition under which this occurs, by including it in reset_stateful_functions_to but not reset_stateful_functions_when – in that case, the Condition specified by its own reset_stateful_function_when parameter will be used.

### Compilation¶

By default, a Composition is executed using the Python interpreter used to run the script from which it is called. In many cases, a Composition can also be executed in a compiled mode. While this can add some time to initiate execution, execution itself can be several orders of magnitude faster than using the Python interpreter. Thus, using a compiled mode can be useful for executing Compositions that are complex and/or for large numbers of TRIALs. Compilation is supported for most CPUs (including x86, arm64, and powerpc64le). Several modes can be specified, that that tradeoff power (i.e., degree of speed-up) against level of support (i.e., likelihood of success). Most PsyNeuLink Components and methods are supported for compilation; however, Python native functions and methods (e.g., used to specify the function of a Component) are not supported at present. Users who wish to compile custom functions should refer to compiled User Defined Functions for more information. Users are strongly urged to report any other compilation failures to psyneulinkhelp@princeton.edu, or as an issue here. Known failure conditions are listed here.

Warning

Compiled modes are continuing to be developed and refined, and therefore it is still possible that there are bugs that will not cause compilation to fail, but could produce erroneous results. Therefore, it is strongly advised that if compilation is used, suitable tests are conducted that the results generated are identical to those generated when the Composition is executed using the Python interpreter.

The bin_execute argument of an execution method specifies whether to use a compiled mode and, if so, which. If True is specified, an attempt is made to use the most powerful mode (LLVMRun) and, if that fails, to try progressively less powerful modes (issueing a warning indicating the unsupported feature that caused the failure), reverting to the Python interpreter if all compiled modes fail. If a particular mode is specified and fails, an error is generated indicating the unsupported feature that failed. The compiled modes, in order of their power, are:

• True – try to use the one that yields the greatesst improvement, progressively reverting to less powerful but more forgiving modes, in the order listed below, for each that fails;

• LLVMRun – compile and run multiple TRIALs; if successful, the compiled binary is semantically equivalent to the execution of the run method using the Python interpreter;

• LLVMExec – compile and run each TRIAL, using the Python interpreter to iterate over them; if successful, the compiled binary for each TRIAL is semantically equivalent the execution of the execute method using the Python interpreter;

• LLVM – compile and run Node of the Composition and their Projections, using the Python interpreter to call the Composition’s scheduler, execute each Node and iterate over TRIALs; note that, in this mode, scheduling Conditions that rely on Node Parameters is not supported;

• Python (same as False; the default) – use the Python interpreter to execute the Composition.

GPU support. In addition to compilation for CPUs, support is being developed for CUDA capable Invidia GPUs. This can be invoked by specifying one of the following modes in the bin_execute argument of a Composition execution method:

• PTXExec|PTXRun – equivalent to the LLVM counterparts but run in a single thread of a CUDA capable GPU.

This requires that a working pycuda package is installed, and that CUDA execution is explicitly enabled by setting the PNL_LLVM_DEBUG environment variable to cuda. At present compilation using these modes runs on a single GPU thread, and therefore does not produce any performance benefits over running in compiled mode on a CPU; (see this for progress extending support of parallization in compiled modes).

XXX - ADD EXAMPLE OF NESTED COMPOSITION XXX - ADD DISCUSSION OF show_controller AND show_learning

## Composition Examples¶

### Creating a Composition¶

Create Mechanisms:

>>> A = pnl.ProcessingMechanism(name='A')
>>> B = pnl.ProcessingMechanism(name='B')
>>> C = pnl.ProcessingMechanism(name='C')

Create Projections:

>>> A_to_B = pnl.MappingProjection(name="A-to-B")
>>> B_to_C = pnl.MappingProjection(name="B-to-C")

>>> comp_0 = pnl.Composition(name='comp-0')
>>> comp_0.add_linear_processing_pathway(pathway=[A, A_to_B, B, B_to_C, C])

>>> comp_1 = pnl.Composition(name='comp-1')

>>> comp_2 = pnl.Composition(name='comp-2')

Run each Composition:

>>> input_dict = {A: [[[1.0]]]}
>>> comp_0_output = comp_0.run(inputs=input_dict)
>>> comp_1_output = comp_1.run(inputs=input_dict)
>>> comp_2_output = comp_2.run(inputs=input_dict)

Create outer Composition:

>>> outer_A = pnl.ProcessingMechanism(name='outer_A')
>>> outer_B = pnl.ProcessingMechanism(name='outer_B')
>>> outer_comp = pnl.Composition(name='outer_comp')

Create and configure inner Composition:

>>> inner_A = pnl.ProcessingMechanism(name='inner_A')
>>> inner_B = pnl.ProcessingMechanism(name='inner_B')
>>> inner_comp = pnl.Composition(name='inner_comp')

Nest inner Composition within outer Composition using add_node:

Create Projections:

>>> input_dict = {outer_A: [[[1.0]]]}

### Run Composition¶

>>> outer_comp.run(inputs=input_dict)

Using add_linear_processing_pathway with nested compositions for brevity:

>>> outer_A = pnl.ProcessingMechanism(name='outer_A')
>>> outer_B = pnl.ProcessingMechanism(name='outer_B')
>>> outer_comp = pnl.Composition(name='outer_comp')
>>> inner_A = pnl.ProcessingMechanism(name='inner_A')
>>> inner_B = pnl.ProcessingMechanism(name='inner_B')
>>> inner_comp = pnl.Composition(name='inner_comp')
>>> input_dict = {outer_A: [[[1.0]]]}
>>> outer_comp.run(inputs=input_dict)

### Learning¶

The following example implements a simple three-layered network that learns the XOR function (see figure):

# Construct Composition:
>>> input = TransferMechanism(name='Input', default_variable=np.zeros(2))
>>> hidden = TransferMechanism(name='Hidden', default_variable=np.zeros(10), function=Logistic())
>>> output = TransferMechanism(name='Output', default_variable=np.zeros(1), function=Logistic())
>>> input_weights = MappingProjection(name='Input Weights', matrix=np.random.rand(2,10))
>>> output_weights = MappingProjection(name='Output Weights', matrix=np.random.rand(10,1))
>>> xor_comp = Composition('XOR Composition')
>>>                       pathway=[input, input_weights, hidden, output_weights, output])

# Create inputs:            Trial 1  Trial 2  Trial 3  Trial 4
>>> xor_inputs = {'stimuli':[[0, 0],  [0, 1],  [1, 0],  [1, 1]],
>>>               'targets':[  [0],     [1],     [1],     [0] ]}
>>> xor_comp.learn(inputs={input:xor_inputs['stimuli'],
>>>                      backprop_pathway.target:xor_inputs['targets']},
>>>              num_trials=1,
>>>              animate={'show_learning':True})

### Input Formats¶

#### Examples of Input Dictionary Specifications¶

The following is an example in which the inputs argument of the run method is specified as an input dictionary, with entries for the two INPUT Nodes of the Composition:

>>> a = pnl.TransferMechanism(name='a',
...                           default_variable=[[0.0, 0.0]])
>>> b = pnl.TransferMechanism(name='b',
...                           default_variable=[[0.0], [0.0]])
>>> c = pnl.TransferMechanism(name='c')

>>> pathway1 = [a, c]
>>> pathway2 = [b, c]

>>> comp = Composition(name='comp', pathways=[patway1, pathway2])

>>> input_dictionary = {a: [[[1.0, 1.0]], [[1.0, 1.0]]],
...                     b: [[[2.0], [3.0]], [[2.0], [3.0]]]}

>>> comp.run(inputs=input_dictionary)

Since the specification of the default_variable for Mechanism a is a single array of length 2, it is constructed with a single InputPort (see InputPorts) that takes an array of that shape as its input; therefore, the input value specified for each TRIAL is a length 2 array ([1.0, 1.0]). In contrast, since the default_variable for Mechanism b is two length 1 arrays, so it is constructed with two InputPorts, each of which takes a length 1 array as its input; therefore, the input specified for each TRIAL must be two length 1 arrays. See figure for an illustration of the format for an input dictionary.

Note

A Node's external_input_values attribute is always a 2d list in which the index i element is the value of the i’th element of the Node’s external_input_ports attribute. For Mechanisms, the external_input_values is often the same as its variable. However, some Mechanisms may have InputPorts marked as internal_only which are excluded from its external_input_ports and therefore its external_input_values, and so should not receive an input value. The same considerations extend to the external_input_ports and external_input_values of a Composition, based on the Mechanisms and/or nested Compositions that comprise its INPUT Nodes.

If num_trials is not in use, the number of inputs provided determines the number of TRIALs in the run. For example, if five inputs are provided for each INPUT Node, and num_trials is not specified, the Composition executes five times.

 Trial # 0 1 2 3 4 Input to Mechanism a 1 2 3 4 5
>>> a = pnl.TransferMechanism(name='a')
>>> b = pnl.TransferMechanism(name='b')
>>> pathway1 = [a, b]
>>> comp = Composition(name='comp')
>>> input_dictionary = {a: [[[1.0]], [[2.0]], [[3.0]], [[4.0]], [[5.0]]]}
>>> comp.run(inputs=input_dictionary)

The number of inputs specified must be the same for all Nodes in the input dictionary (except for any Nodes for which only one input is specified). In other words, all of the values in the input dictionary must have the same length as each other (or length 1).

If num_trials is in use, run iterates over the inputs until num_trials is reached. For example, if five inputs are provided for each INPUT Node, and num_trials is not specified, the Composition executes five times., and num_trials = 7, the Composition executes seven times. The input values from TRIALs 0 and 1 are used again on TRIALs 5 and 6, respectively.

 Trial # 0 1 2 3 4 5 6 Input to Mechanism a 1 2 3 4 5 1 2
>>> a = pnl.TransferMechanism(name='a')
>>> b = pnl.TransferMechanism(name='b')
>>> pathway1 = [a, b]
>>> comp = Composition(name='comp')
>>> input_dictionary = {a: [[[1.0]], [[2.0]], [[3.0]], [[4.0]], [[5.0]]]}
>>> comp.run(inputs=input_dictionary,
...          num_trials=7)

For convenience, condensed versions of the input specification described above are also accepted in the following situations:

 Trial # 0 1 2 3 4 Input to Mechanism a 1 2 3 4 5

Complete input specification:

>>> a = pnl.TransferMechanism(name='a')
>>> b = pnl.TransferMechanism(name='b')
>>> pathway1 = [a, b]
>>> comp = Composition(name='comp')
>>> input_dictionary = {a: [[[1.0]], [[2.0]], [[3.0]], [[4.0]], [[5.0]]]}
>>> comp.run(inputs=input_dictionary)

Shorthand - drop the outer list on each input because Mechanism a only has one InputPort:

>>> input_dictionary = {a: [[1.0], [2.0], [3.0], [4.0], [5.0]]}
>>> comp.run(inputs=input_dictionary)

Shorthand - drop the remaining list on each input because Mechanism a’s one InputPort’s value is length 1:

>>> input_dictionary = {a: [1.0, 2.0, 3.0, 4.0, 5.0]}
>>> comp.run(inputs=input_dictionary)
• Case 2: Only one input is provided for the INPUT Node

 Trial # 0 Input to Mechanism a [[1.0], [2.0]]

Complete input specification:

>>> a = pnl.TransferMechanism(name='a',
default_variable=[[0.0], [0.0]])
>>> b = pnl.TransferMechanism(name='b')
>>> pathway1 = [a, b]
>>> comp = Composition(name='comp')
>>> input_dictionary = {a: [[[1.0], [2.0]]]}
>>> comp.run(inputs=input_dictionary)

Shorthand - drop the outer list on Mechanism a’s input specification because there is only one TRIAL:

>>> input_dictionary = {a: [[1.0], [2.0]]}
>>> comp.run(inputs=input_dictionary)
• Case 3: The same input is used on all TRIALs

 Trial # 0 1 2 3 4 Input to Mechanism a [[1.0], [2.0]] [[1.0], [2.0]] [[1.0], [2.0]] [[1.0], [2.0]] [[1.0], [2.0]]

Complete input specification:

>>> a = pnl.TransferMechanism(name='a',
...                           default_variable=[[0.0], [0.0]])
>>> b = pnl.TransferMechanism(name='b')

>>> pathway1 = [a, b]

>>> comp = Composition(name='comp')

>>> input_dictionary = {a: [[[1.0], [2.0]], [[1.0], [2.0]], [[1.0], [2.0]], [[1.0], [2.0]], [[1.0], [2.0]]]}

>>> comp.run(inputs=input_dictionary)

Shorthand - drop the outer list on Mechanism a’s input specification and use num_trials to repeat the input value

>>> input_dictionary = {a: [[1.0], [2.0]]}

>>> comp.run(inputs=input_dictionary,
...          num_trials=5)
 Trial # 0 1 Input to Mechanism a [1.0, 2.0, 3.0] [1.0, 2.0, 3.0]

Complete input specification:

>>> a = pnl.TransferMechanism(name='a',
...                           default_variable=[[1.0, 2.0, 3.0]])
>>> b = pnl.TransferMechanism(name='b')

>>> pathway1 = [a, b]

>>> comp = Composition(name='comp')

>>> input_dictionary = input_dictionary = {a: [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]]}

>>> comp.run(inputs=input_dictionary)

Shorthand - specify Mechanism a’s inputs in a list because it is the only INPUT Node:

>>> input_list = [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]]

>>> comp.run(inputs=input_list)

### Runtime Parameters¶

If a runtime parameter is meant to be used throughout the Run, then the Condition may be omitted and the Always Condition will be assigned by default:

>>> T = pnl.TransferMechanism()
>>> C = pnl.Composition(pathways=[T])
>>> T.function.slope  # slope starts out at 1.0
1.0
>>> # During the following run, 10.0 will be used as the slope
>>> C.run(inputs={T: 2.0},
...       runtime_params={T: {"slope": 10.0}})
[array([20.])]
>>> T.function.slope  # After the run, T.slope resets to 1.0
1.0

Otherwise, the runtime parameter value will be used on all executions of the Run during which the Condition is True:

>>> T = pnl.TransferMechanism()
>>> C = pnl.Composition(pathways=[T])
>>> T.function.intercept     # intercept starts out at 0.0
0.0
>>> T.function.slope         # slope starts out at 1.0
1.0
>>> C.run(inputs={T: 2.0},
...       runtime_params={T: {"intercept": (5.0, pnl.AfterTrial(1)),
...                           "slope": (2.0, pnl.AtTrial(3))}},
...       num_trials=5)
[array([7.])]
>>> C.results
[[array([2.])], [array([2.])], [array([7.])], [array([9.])], [array([7.])]]

The table below shows how runtime parameters were applied to the intercept and slope parameters of Mechanism T in the example above.

Trial 0

Trial 1

Trial 2

Trial 3

Trial 4

Intercept

0.0

0.0

5.0

5.0

5.0

Slope

1.0

1.0

1.0

2.0

0.0

Value

2.0

2.0

7.0

9.0

7.0

as indicated by the results of S.run(), the original parameter values were used on trials 0 and 1, the runtime intercept was used on trials 2, 3, and 4, and the runtime slope was used on trial 3.

Note

Runtime parameter values are subject to the same type, value, and shape requirements as the original parameter value.

### Execution Contexts¶

An execution context is a scope of execution which has its own set of values for Components and their parameters. This is designed to prevent computations from interfering with each other, when Components are reused, which often occurs when using multiple or nested Compositions, or running simulations. Each execution context is or is associated with an execution_id, which is often a user-readable string. An execution_id can be specified in a call to Composition.run, or left unspecified, in which case the Composition’s default execution_id would be used. When looking for values after a run, it’s important to know the execution context you are interested in, as shown below.

>>> c = pnl.Composition()
>>> d = pnl.Composition()
>>> t = pnl.TransferMechanism()

>>> t.execute(1)
array([[1.]])
>>> c.run({t: 5})
[[array([5.])]]
>>> d.run({t: 10})
[[array([10.])]]
>>> c.run({t: 20}, context='custom execution id')
[[array([20.])]]

# context None
>>> print(t.parameters.value.get())
[[1.]]
>>> print(t.parameters.value.get(c))
[[5.]]
>>> print(t.parameters.value.get(d))
[[10.]]
>>> print(t.parameters.value.get('custom execution id'))
[[20.]]Composition_Controller

### Reset Paramters of Stateful Functions¶

Example composition with two Mechanisms containing stateful functions:

>>> A = TransferMechanism(
>>>     name='A',
>>>     integrator_mode=True,
>>>     integration_rate=0.5
>>> )
>>> B = TransferMechanism(
>>>     name='B',
>>>     integrator_mode=True,
>>>     integration_rate=0.5
>>> )
>>> C = TransferMechanism(name='C')
>>>
>>> comp = Composition(
>>>     pathways=[[A, C], [B, C]]
>>> )

Example 1) A blanket reset of all stateful functions to their default values:

>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>>     num_trials=3
>>> )
>>>
>>> # Trial 1: 0.5, Trial 2: 0.75, Trial 3: 0.875
>>> print(A.value)
>>> # [[0.875]]
>>>
>>> comp.reset()
>>>
>>> # The Mechanisms' stateful functions are now in their default states, which is identical
>>> # to their states prior to Trial 1. Thus, if we call run again with the same inputs,
>>> # we see the same results that we saw on Trial 1.
>>>
>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>> )
>>>
>>> # Trial 3: 0.5
>>> print(A.value)
>>> # [[0.5]]

Example 2) A blanket reset of all stateful functions to custom values:

>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>>     num_trials=3
>>> )
>>>
>>> # Trial 0: 0.5, Trial 1: 0.75, Trial 2: 0.875
>>> print(A.value)
>>> # [[0.875]]
>>> # Mechanism B is currently identical to Mechanism A
>>> print(B.value)
>>> # [[0.875]]
>>>
>>> # Reset Mechanism A to 0.5 and Mechanism B to 0.75, corresponding to their values at the end of
>>> # trials 0 and 1, respectively. Thus, if we call run again with the same inputs, the values of the
>>> # Mechanisms will match their values after trials 1 and 2, respectively.
>>> comp.reset({A: 0.5,
>>>             B: 0.75})
>>>
>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>> )
>>>
>>> # Trial 3: 0.75
>>> print(A.value)
>>> # [[0.75]]
>>>
>>> # Trial 3: 0.875
>>> print(B.value)
>>> # [[0.875]]

Example 3) Schedule resets for both Mechanisms to their default values, to occur at different times

>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>>     reset_stateful_functions_when = {
>>>         A: AtTrial(1),
>>>         B: AtTrial(2)
>>>     },
>>>     num_trials=5
>>> )
>>> # Mechanism A - resets to its default (0) at the beginning of Trial 1. Its value at the end of Trial 1 will
>>> # be exactly one step of integration forward from its default.
>>> # Trial 0: 0.5, Trial 1: 0.5, Trial 2: 0.75, Trial 3: 0.875, Trial 4: 0.9375
>>> print(A.value)
>>> # [[0.9375]]
>>>
>>> # Mechanism B - resets to its default (0) at the beginning of Trial 2. Its value at the end of Trial 2 will
>>> # be exactly one step of integration forward from its default.
>>> # Trial 0: 0.5, Trial 1: 0.75, Trial 2: 0.5, Trial 3: 0.75. Trial 4: 0.875
>>> print(B.value)
>>> # [[0.875]]

Example 4) Schedule resets for both Mechanisms to custom values, to occur at different times

>>> comp.run(
>>>     inputs={A: [1.0],
>>>             B: [1.0]},
>>>     reset_stateful_functions_when={
>>>         A: AtTrial(3),
>>>         B: AtTrial(4)
>>>     },
>>>     reset_stateful_functions_to={
>>>         A: 0.5,
>>>         B: 0.5
>>>     },
>>>     num_trials=5
>>> )
>>> # Mechanism A - resets to 0.5 at the beginning of Trial 3. Its value at the end of Trial 3 will
>>> # be exactly one step of integration forward from 0.5.
>>> # Trial 0: 0.5, Trial 1: 0.75, Trial 2: 0.875, Trial 3: 0.75, Trial 4:  0.875
>>> print(A.value)
>>> # [[0.875]]
>>>
>>> # Mechanism B - resets to 0.5 at the beginning of Trial 4. Its value at the end of Trial 4 will
>>> # be exactly one step of integration forward from 0.5.
>>> # Trial 0: 0.5, Trial 1: 0.75, Trial 2: 0.875, Trial 3: 0.9375. Trial 4: 0.75
>>> print(B.value)
>>> # [[0.75]]

## Class Reference¶

class psyneulink.core.compositions.composition.Composition(pathways=None, nodes=None, projections=None, disable_learning=False, controller=None, enable_controller=None, controller_mode='after', controller_time_scale=<TimeScale.TRIAL: 2>, controller_condition=<psyneulink.core.scheduling.condition.Always object>, retain_old_simulation_data=None, show_graph_attributes=None, name=None, prefs=None, **param_defaults)

Base class for Composition.

Parameters
• pathways (Pathway specification or list[Pathway specification...]) – specifies one or more Pathways to add to the Compositions (see pathways argument of add_pathways Composition.add_pathways for specification format).

• nodes (Mechanism, Composition or list[Mechanism, Composition] : default None) – specifies one or more Nodes to add to the Composition; these are each treated as SINGLETONs unless they are explicitly assigned Projections.

• projections (Projection or list[Projection] : default None) – specifies one or more Projections to add to the Composition; these are not functional unless they are explicitly assigned a sender and receiver.

• disable_learning (bool : default False) – specifies whether LearningMechanisms in the Composition are executed when run in learning mode.

• controller (OptimizationControlmechanism : default None) – specifies the OptimizationControlMechanism to use as the Composition’s controller (see Controlling a Composition for details).

• enable_controller (bool : default None) – specifies whether the Composition’s controller is executed when the Composition is executed. Set to True by default if controller specified; if set to False, the controller is ignored when the Composition is executed.

• controller_mode (enum.Enum[BEFORE|AFTER] : default AFTER) – specifies whether the controller is executed before or after the rest of the Composition in each run, trial, pass, or time step. Must be either the keyword BEFORE or AFTER.

• controller_time_scale (TimeScale[TIME_STEP, PASS, TRIAL, RUN] : default TRIAL) – specifies with what frequency the the controller should be executed.

• controller_condition (Condition : default Always) – specifies when the Composition’s controller is executed in a trial.

• retain_old_simulation_data (bool : default False) – specifies whether or not to retain Parameter values generated during simulations of the Composition (see retain_old_simulation_data for additional details).

• show_graph_attributes (dict : None) – specifies features of how the Composition is displayed when its show_graph method is called or animate is specified in a call to its run method (see ShowGraph for list of attributes and their values).

• name (str : default see name) – specifies the name of the Composition.

• prefs (PreferenceSet or specification dict : default Composition.classPreferences) – specifies the PreferenceSet for the Composition; see prefs for details.

graph

the full Graph associated with the Composition. Contains both Nodes (Mechanisms or Compositions) and Projections.

Type

Graph

nodes

a list of all Nodes in the Composition.

Type

node_ordering

a list of all Nodes in the order in which they were added to the Composition.

Type

list[Mechanism or Composition]

required_node_roles

a list of tuples, each containing a Node and a NodeRole assigned to it.

Type

list[(Mechanism or Composition, NodeRole)]

excluded_node_roles

a list of tuples, each containing a Node and a NodeRole that is excluded from being assigned to it.

Type

list[(Mechanism or Composition, NodeRole)]

feedback_senders

list of Nodes that have one or more efferent Projections designated as feedback.

Type

list of Nodes that have one or more afferents designated as feedback.

Type

feedback_projections

list of Projections in the Composition designated as feedback.

Type

mechanisms

list of Mechanisms in Composition, that provides access to some of they key attributes.

Type

MechanismList

pathways

a list of all Pathways in the Composition that were specified in the pathways argument of the Composition’s constructor and/or one of its Pathway addition methods; each item is a list of nodes (Mechanisms and/or Compositions) intercolated with the Projection between each pair of nodes.

Type

input_CIM

mediates input values for the INPUT Nodes of the Composition. If the Composition is nested, then the input_CIM and its InputPorts.

Type

CompositionInterfaceMechanism

input_CIM_ports

a dictionary in which the key of each entry is the InputPort of an INPUT Node in the Composition, and its value is a list containing two items:

Type

dict

parameter_CIM

mediates modulatory values for all Nodes of the Composition. If the Composition is nested, then the parameter_CIM and its InputPorts serve as proxies for the Composition itself for its afferent ModulatoryProjections.

Type

CompositionInterfaceMechanism

parameter_CIM_ports

a dictionary in which keys are ParameterPorts of Nodes in the Composition, and values are lists containing two items:

Type

dict

afferents

a list of all of the Projections to either the Composition’s input_CIM (PathwayProjections and ModulatoryProjections).

Type

external_input_ports

a list of the InputPorts of the Composition’s input_CIM; these receive input provided to the Composition when it is executed, either from the inputs argument of one of its execution methods or, if it is a nested Composition, then from any Nodes in the outer composition that project to the nested Composition (either itself, as a Node in the outer Composition, or to any of its own Nodes).

Type

list[InputPort]

external_input_values

a list of the values of associated with the InputPorts listed in external_input_ports; any input to the Composition must be compatible with the shape of this, whether received from the input_ports argument of oneo f the Composition’sexecution methods <Composition_Execution_Methods> or, if it is a nested Composition, from the outer Composition.

Type

list[InputPort]

output_CIM

aggregates output values from the OUTPUT nodes of the Composition. If the Composition is nested, then the output_CIM and its OutputPorts serve as proxies for Composition itself in terms of efferent projections.

Type

CompositionInterfaceMechanism

output_CIM_ports

a dictionary in which the key of each entry is the OutputPort of an OUTPUT Node in the Composition, and its value is a list containing two items:

Type

dict

efferents

a list of all of the Projections from the Composition’s output_CIM.

Type

cims

a list containing references to the Composition’s input_CIM, parameter_CIM, and output_CIM.

Type

list

env

stores a Gym Forager Environment so that the Composition may interact with this environment within a single call to run.

Type

Gym Forager Environment : default: None

a dictionary in which the keys are all in the Composition and the values are lists of any Nodes that shadow the original Node’s input.

Type

dict

controller

identifies the OptimizationControlMechanism used as the Composition’s controller (see Controlling a Composition for details).

Type

OptimizationControlMechanism

enable_controller

determines whether the Composition’s controller is executed in each trial (see controller_mode <Composition.controller_mode> for timing of execution). Set to True by default if controller is specified. Setting it to False suppresses exectuion of the controller.

Type

bool

controller_mode

determines whether the controller is executed before or after the rest of the Composition is executed on each trial.

Type

BEFORE or AFTER

controller_condition

specifies whether the controller is executed in a given trial. The default is Always, which executes the controller on every trial.

Type

Condition

default_execution_id

if no context is specified in a call to run, this context is used; by default, it is the Composition’s name.

execution_ids

stores all execution_ids used by the Composition.

Type

set

disable_learning

determines whether LearningMechanisms in the Composition are executed when run in learning mode.

Type

bool : default False

learning_components

a list of the learning-related components in the Composition, all or many of which may have been created automatically in a call to one of its add_<*learning_type*>_pathway' methods (see Composition_Learning for details). This does not contain the ProcessingMechanisms or MappingProjections in the pathway(s) being learned; those are contained in learning_pathways attribute.

Type

list[list]

learned_components

a list of the components subject to learning in the Composition (ProcessingMechanisms and MappingProjections); this does not contain the components used for learning; those are contained in learning_components attribute.

Type

list[list]

results

a list of the output_values of the OUTPUT Nodes in the Composition for every TRIAL executed in a call to run. Each item in the outermos list is a list of values for a given trial; each item within a trial corresponds to the output_values of an OUTPUT Mechanism for that trial.

Type

list[list[list]]

output_values

a list of the output_values of the OUTPUT Nodes in the Composition for the last TRIAL executed in a call to one of the Composition’s execution methods, and the value returned by that method; this is the same as results[0], and provides consistency of access to the values of a Composition’s Nodes when one or more is a nested Composition.

Type

list[list]

simulation_results

a list of the results for simulations of the Composition when it is executed using its evaluate method by an OptimizationControlMechanism.

Type

list[list[list]]

retain_old_simulation_data

if True, all Parameter values generated during simulations are saved; if False, simulation values are deleted unless otherwise specified by individual Parameters.

Type

bool

input_specification

stores the inputs for executions of the Composition when it is executed using its run method.

Type

None or dict or list or generator or function

name

the name of the Composition; if it is not specified in the name argument of the constructor, a default is assigned by CompositionRegistry (see Naming for conventions used for default and duplicate names).

Type

str

prefs

the PreferenceSet for the Composition; if it is not specified in the prefs argument of the constructor, a default is assigned using classPreferences defined in __init__.py (see Preferences for details).

Type

PreferenceSet or specification dict

class _CompilationData(owner, parent=None)
ptx_execution = None
parameter_struct = None
state_struct = None
data_struct = None
scheduler_conditions = None
property graph_processing

The Composition’s processing graph (contains only Mechanisms.

Getter

Returns the processing graph, and builds the graph if it needs updating since the last access.

property scheduler

A default Scheduler automatically generated by the Composition, and used for its execution when it is run.

Getter

Returns the default scheduler, and builds it if it needs updating since the last access.

_analyze_graph(context=None)

Assigns NodeRoles to nodes based on the structure of the Graph.

By default, if _analyze_graph determines that a Node is ORIGIN, it is also given the role INPUT. Similarly, if _analyze_graph determines that a Node is TERMINAL, it is also given the role OUTPUT.

However, if the required_roles argument of add_node is used to set any Node in the Composition to INPUT, then the ORIGIN nodes are not set to INPUT by default. If the required_roles argument of add_node is used to set any Node in the Composition to OUTPUT, then the TERMINAL nodes are not set to OUTPUT by default.

_update_processing_graph()

Constructs the processing graph (the graph that contains only Nodes as vertices) from the composition’s full graph

Parameters
• node (Mechanism or Composition) – the Node to be added to the Composition

• required_roles (NodeRole or list of NodeRoles) – any NodeRoles roles that this Node should have in addition to those determined by analyze graph.

_instantiate_deferred_init_control(node, context=None)

If node is a Composition with a controller, activate its nodes’ deferred init control specs for its controller. If it does not have a controller, but self does, activate them for self’s controller.

If node is a Node that has deferred init control specs and self has a controller, activate the deferred init control specs for self’s controller.

Returns

Return type

list of hanging control specs that were not able to be assigned for a controller at any level.

Add a list of Nodes to the Composition.

Parameters
• nodes (list) – the nodes to be added to the Composition. Each item of the list must be a Mechanism, a Composition or a role-specification tuple with a Mechanism or Composition as the first item, and a NodeRole or list of those as the second item; any NodeRoles in a role-specification tuple are applied in addition to those specified in the required_roles argument.

• required_roles (NodeRole or list of NodeRoles) – NodeRoles to assign to the nodes in addition to those determined by analyze graph; these apply to any items in the list of nodes that are not in a tuple; these apply to any specified in any role-specification tuples in the nodes argument.

Assign the NodeRole specified by role to node. Remove exclusion of that NodeRole if it had previously been specified in exclude_node_roles.

Parameters
require_node_roles(node, roles, context=None)

Assign the NodeRole(s) specified in roles to node. Remove exclusion of those NodeRoles if it any had previously been specified in exclude_node_roles.

Parameters
exclude_node_roles(node, roles, context)

Excludes the NodeRole(s) specified in roles from being assigned to node.

Removes specified roles if they had been previous assigned either by default as a required_node_role or using the required_node_roles method.

Parameters
get_roles_by_node(node)

Return a list of NodeRoles assigned to node.

Parameters

node (Node) – Node for which assigned NodeRoles are desired.

Returns

list of NodeRoles assigned to node.

Return type

List[Mechanisms and/or Compositions]

get_nodes_by_role(role)

Return a list of Nodes in the Composition that are assigned the NodeRole specified in role.

Parameters

role (NodeRole) – role for which Nodes are desired.

Returns

list of Nodes assigned the NodeRole specified in role

Return type

list[Mechanisms and/or Compositions]

_get_input_nodes_by_CIM_input_order()

Return a list with the INPUT Nodes of the Composition in the same order as their corresponding InputPorts on Composition’s input_CIM.

_get_nested_nodes(nested_nodes=NotImplemented, root_composition=NotImplemented, visited_compositions=NotImplemented)
Recursive search that returns all nodes of all nested compositions in a tuple with the composition they are

embedded in.

:return

A list of tuples in format (node, composition) containing all nodes of all nested compositions.

_get_nested_compositions(nested_compositions=NotImplemented, visited_compositions=NotImplemented)

Recursive search that returns all nested compositions.

:return

A list of nested compositions.

_determine_origin_and_terminal_nodes_from_consideration_queue()

Assigns NodeRole.ORIGIN to all nodes in the first entry of the consideration queue and NodeRole.TERMINAL to all nodes in the last entry of the consideration queue. The ObjectiveMechanism of a Composition’s controller may not be NodeRole.TERMINAL, so if the ObjectiveMechanism is the only node in the last entry of the consideration queue, then the second-to-last entry is NodeRole.TERMINAL instead.

Returns

Return type

list containing references to all invalid aux components

_complete_init_of_partially_initialized_nodes(context=None)
Attempt to complete initialization of aux components for any nodes with

aux components that were not previously compatible with Composition

_determine_node_roles(context=None)

Assign NodeRoles to Nodes in Composition

Note

Assignments are not subject to user-modification (i.e., “programmatic assignment”) unless otherwise noted.

Assignment criteria:

ORIGIN:
• all Nodes that are in first consideration_set (i.e., self.scheduler.consideration_queue[0]).

INPUT:
• all ORIGIN Nodes for which INPUT has not been removed and/or excluded using exclude_node_roles();

• all Nodes for which INPUT has been assigned as a required_node_role by user (i.e., in self.required_node_roles[NodeRole.INPUT].

SINGLETON:
• all Nodes that are both ORIGIN and TERMINAL

INTERNAL:
• all Nodes that are neither ORIGIN nor TERMINAL

CYCLE:
• all Nodes that identified as being in a cycle by self.graph_processing (i.e., in self.graph_processing.cycle_vertices)

FEEDBACK_SENDER:
• all Nodes that send a Projection designated as feedback by self.graph_processing OR specified as feedback by user

• all Nodes that receive a Projection designated as feedback by self.graph_processing OR specified as feedback by user

CONTROL_OBJECTIVE
• ObjectiveMechanism assigned CONTROL_OBJECTIVE as a required_node_role in ControlMechanism’s _instantiate_objective_mechanism()

Note

• not the same as CONTROLLER_OBJECTIVE

• all project to a ControlMechanism

CONTROLLER_OBJECTIVE
• ObjectiveMechanism assigned CONTROLLER_OBJECTIVE as a required_node_role in add_controller()

Note

• also assigned CONTROL_OBJECTIVE

• not the same as CONTROL_OBJECTIVE

LEARNING
• all Nodes for which LEARNING is assigned as a required_noded_role in add_linear_learning_pathway() or _create_terminal_backprop_learning_components()

TARGET
• all Nodes for which TARGET has been assigned as a required_noded_role in add_linear_learning_pathway() or _create_terminal_backprop_learning_components()

Note

• receive a Projection from input_CIM, and project to LEARNING_OBJECTIVE and output_CIM

• also assigned ORIGIN, INPUT, LEARNING, OUTPUT, and TERMINAL

LEARNING_OBJECTIVE
• all Nodes for which LEARNING_OBJECTIVE is assigned required_noded_role in add_linear_learning_pathway(), _create_non_terminal_backprop_learning_components, or _create_terminal_backprop_learning_components()

Note

• also assigned LEARNING

• must project to a LearningMechanism

OUTPUT:
• all TERMINAL Nodes unless they are: - a ModulatoryMechanism (i.e., ControlMechanism or LearningMechanism) - an ObjectiveMechanisms associated with ModulatoryMechanism

• all Nodes that project only to: - a ModulatoryMechanism - an ObjectiveMechanism designated CONTROL_OBJECTIVE, CONTROLLER_OBJECTIVE or LEARNING_OBJECTIVE ? unless it is the ??TARGET_MECHANISM for a ‘learning pathway <Composition_Learning_Pathway>

this is currently the case, but is inconsistent with the analog in Control, where monitored Mechanisms are allowed to be OUTPUT; therefore, might be worth allowing TARGET_MECHANISM to be assigned as OUTPUT

• all Nodes for which OUTPUT has been assigned as a required_node_role, inculding by user (i.e., in self.required_node_roles[NodeRole.OUTPUT]

TERMINAL:
• all Nodes that - are not an ObjectiveMechanism assigned the role CONTROLLER_OBJECTIVE - or have no efferent projections OR - or for for which any efferent projections are either:

• to output_CIM OR

• assigned as feedback (i.e., self.graph.comp_to_vertex[efferent].feedback == EdgeType.FEEDBACK

_get_external_modulatory_projections()
Returns

list of Modulatory Projections that originate from enclosing Compositions and that modulate a parameter of a Node of the current Composition

Return type

list[Modulatory Projections]

_create_CIM_ports(context=None)
• remove the default InputPort and OutputPort from the CIMs if this is the first time that real InputPorts and OutputPorts are being added to the CIMs

• create a corresponding InputPort and OutputPort on the input_CIM for each InputPort of each INPUT node. Connect the OutputPort on the input_CIM to the INPUT node’s corresponding InputPort via a standard MappingProjection.

• create a corresponding InputPort and OutputPort on the output_CIM for each OutputPort of each OUTPUT node. Connect the OUTPUT node’s OutputPort to the output_CIM’s corresponding InputPort via a standard MappingProjection.

• create a corresponding InputPort and ControlSignal on the parameter_CIM for each InputPort of each node in the Composition that receives a modulatory projection from an enclosing Composition. Connect the original ControlSignal to the parameter_CIM’s corresponding InputPort via a standard MappingProjection, then activate the projections that are created automatically during instantiation of the ControlSignals to carry that signal to the target ParameterPort.

• build three dictionaries:

1. input_CIM_ports = { INPUT Node InputPort: (InputCIM InputPort, InputCIM OutputPort) }

2. output_CIM_ports = { OUTPUT Node OutputPort: (OutputCIM InputPort, OutputCIM OutputPort) }

3. parameter_CIM_ports = { ( Signal Owner, Signal Receiver ): (ParameterCIM InputPort, ParameterCIM OutputPort) }

• if the Node has any shadows, create the appropriate projections as needed.

• delete all of the above for any node Ports which were previously, but are no longer, classified as INPUT/OUTPUT

_get_nested_node_CIM_port(node, node_port, role)

Check for node in nested Composition Return relevant port of relevant CIM if found and nested Composition in which it was found, else (None, None)

Takes as input a specification for a projection to a parameter port that is nested n-levels below its sender, instantiates and activates ports and projections on intermediary pcims, and returns a new projection specification from the original sender to the relevant input port of the pcim of the Composition located in the same level of nesting.

Calls add_projection for each Projection in the projections list. Each Projection must have its sender and receiver already specified. If an item in the list is a list of projections, called recursively on that list.

Parameters

projections (list of Projections) – list of Projections to be added to the Composition

If projection is not specified, create a default MappingProjection using sender and receiver.

If projection is specified:

• if projection has already been instantiated, and sender and receiver are also specified, they must match the sender and receiver of projection.

• if sender and receiver are specified and one or more Projections already exists between them: - if it is in the Composition:

• if there is only one, the request is ignored and the existing Projection is returned

• if there is more than one, an exception is raised as this should never be the case

• it is NOT in the Composition: - if there is only one, that Projection is used; - if there is more than one, the last in the list (presumably the most recent) is used; in either case, processing continues, to activate it for the Composition, construct any “shadow” projections that may be specified, and assign feedback if specified,

• if the status of projection is deferred_init:

• if its sender and/or receiver attributes are not specified, then sender and/or receiver are used.

• if sender and/or receiver attributes are specified, they must match sender and/or receiver if those have also been specified.

• if a Projection between the specified sender and receiver does not already exist, it is initialized; if it does already exist, the request to add it is ignored, however requests to shadow it and/or mark it as a feedback Projection are implemented (in case it has not already been done for the existing Projection).

Note

If projection is an instantiated Projection (i.e., not in deferred_init) and one already exists between its sender and receiver a warning is generated and the request is ignored.

Parameters
• sender (Mechanism, Composition, or OutputPort) – the sender of projection.

• projection (Projection, matrix) – the projection to add.

• feedback (bool or FEEDBACK : False) – if False, the Projection is never designated as a feedback Projection, even if that may have been the default behavior (e.g., for a ControlProjection that forms a loop; if True or FEEDBACK, and the Projection is in a loop, it is always designated as a feedback Projection, and used to break" the cycle.

Returns

Return type

Projection

_check_for_projection_assignments(context=None)

Check that all Projections and Ports with require_projection_in_composition attribute are configured.

Validate that all InputPorts with require_projection_in_composition == True have an afferent Projection. Validate that all OuputStates with require_projection_in_composition == True have an efferent Projection. Validate that all Projections have senders and receivers.

get_feedback_status(projection)

Return True if projection is designated as a feedback Projection in the Composition, else False.

Check for Projection with same sender and receiver If in_composition is True, return only Projections found in the current Composition If in_composition is False, return only Projections that are found outside the current Composition

Return Projection or list of Projections that satisfies the conditions, else False

_check_for_unnecessary_feedback_projections()

Warn if there exist projections in the graph that the user labeled as EdgeType.FEEDBACK (True) but are not in a cycle

Add an existing Pathway to the Composition

Parameters

pathway (the Pathway to be added) –

Add sequence of Mechanisms and/or Compositions with intercolated Projections.

A MappingProjection is created for each contiguous pair of Mechanisms and/or Compositions in the pathway argument, from the primary OutputPort of the first one to the primary InputPort of the second.

Tuples (Mechanism, NodeRoles) can be used to assign required_roles to Mechanisms.

Note that any specifications of the monitor_for_control argument of a constructor for a ControlMechanism or the monitor argument specified in the constructor for an ObjectiveMechanism in the objective_mechanism argument of a ControlMechanism supercede any MappingProjections that would otherwise be created for them when specified in the pathway argument of add_linear_processing_pathway.

Parameters
Returns

Return type

Pathway

Parameters

pathways (Pathway or list[Pathway]) – specifies one or more Pathways to add to the Composition (see Pathway Specification).

Returns

List of Pathways added to the Composition.

Return type

list[Pathway]

Implement learning pathway (including necessary learning components.

Generic method for implementing a learning pathway. Calls add_linear_processing_pathway to implement the processing components including, if necessary, the MappingProjections between Mechanisms. All of the MappingProjections (whether specified or created) are subject to learning (and are assigned as the learned_projection attribute of the LearningMechanisms created for the pathway.

If learning_function is a sublcass of LearningFunction, a class-specific learning method is called. Some may allow the error_function to be specified, in which case it must be compatible with the class of LearningFunction specified.

If learning_function is a custom function, it is assigned to all of the LearningMechanisms created for the MappingProjections in the pathway. A ComparatorMechanism is created to compute the error for the pathway, and assigned the function specified in error_function, which must be compatible with learning_function.

See Learning in a Composition for a more detailed description of how learning is implemented in a Composition, including the learning components that are created, as well as other learning methods that can be used to implement specific algorithms.

The learning components created are placed in a dict the following entries:

OUTPUT_MECHANISM: ProcessingMechanism (assigned to output TARGET_MECHANISM: ProcessingMechanism (assigned to target OBJECTIVE_MECHANISM: ComparatorMechanism (assigned to learning_objective LEARNING_MECHANISMS: Learning Mechanism or list[Learning Mechanism] LEARNING_FUNCTION: LearningFunction used by all LEARNING_MECHSNISMS in the Pathway LEARNED_PROJECTIONS: Projection or list[Projections]

that is assigned to the learning_components attribute of the Pathway returned.

Parameters
Returns

learning Pathway <Composition_Learning_Pathway> added to the Composition.

Return type

Pathway

Convenience method that calls add_linear_learning_pathway with **learning_function**=Reinforcement

Parameters
• pathway (List) – list containing either [Node1, Node2] or [Node1, MappingProjection, Node2]. If a projection is specified, that projection is the learned projection. Otherwise, a default MappingProjection is automatically generated for the learned projection.

• learning_rate (float : default 0.05) – specifies the learning_rate used for the ReinforcementLearning function of the Learning Mechanism in the pathway.

• error_function (function : default LinearCombination) – specifies the function assigned to ComparatorMechanism used to compute the error from the target and the output (value) of the TARGET Mechanism in the pathway).

• learning_update (Optional[bool|ONLINE|AFTER] : default AFTER) – specifies when the matrix parameter of the learned_projection is updated in each TRIAL when the Composition executes; it is assigned as the default value for the learning_enabled attribute of the LearningMechanism in the pathway, and its LearningProjection (see learning_enabled for meaning of values).

• name (str :) – species the name used for Pathway; supercedes name of Pathway object if it is has one.

Returns

Reinforcement learning Pathway <Composition_Learning_Pathway> added to the Composition.

Return type

Pathway

Convenience method that calls add_linear_learning_pathway with **learning_function**=TDLearning

Parameters
• pathway (List) – list containing either [Node1, Node2] or [Node1, MappingProjection, Node2]. If a projection is specified, that projection is the learned projection. Otherwise, a default MappingProjection is automatically generated for the learned projection.

• learning_rate (float : default 0.05) – specifies the learning_rate used for the TDLearning function of the Learning Mechanism in the pathway.

• error_function (function : default LinearCombination) – specifies the function assigned to ComparatorMechanism used to compute the error from the target and the output (value) of the TARGET Mechanism in the pathway).

• learning_update (Optional[bool|ONLINE|AFTER] : default AFTER) – specifies when the matrix parameter of the learned_projection is updated in each TRIAL when the Composition executes; it is assigned as the default value for the learning_enabled attribute of the LearningMechanism in the pathway, and its LearningProjection (see learning_enabled for meaning of values).

• name (str :) – species the name used for Pathway; supercedes name of Pathway object if it is has one.

Returns

TD Reinforcement learning Pathway <Composition_Learning_Pathway> added to the Composition.

Return type

Pathway

add_backpropagation_learning_pathway(pathway, learning_rate=0.05, error_function=None, loss_function='MSE', learning_update='after', name=None)

Convenience method that calls add_linear_learning_pathway with **learning_function**=Backpropagation

Parameters
Returns

BackPropagation learning Pathway <Composition_Learning_Pathway> added to the Composition.

Return type

Pathway

Creates TARGET_MECHANISM, ComparatorMechanism and Learning Mechanism for RL and TD learning

Construct MappingProjections among learning components for pathway

_create_learning_projection(learning_mechanism, learned_projection)

Construct LearningProjections from LearningMechanisms to learned_projections in a learning pathway

infer_backpropagation_learning_pathways()

Convenience method that automatically creates backpropapagation learning pathways for every Input Node –> Output Node pathway

_create_terminal_backprop_learning_components(input_source, output_source, error_function, loss_function, learned_projection, learning_rate, learning_update, context)

Create ComparatorMechanism, LearningMechanism and LearningProjection for Component in learning Pathway

Add an ControlMechanism as the controller of the Composition.

This gives the ControlMechanism access to the Composition’s evaluate method. This allows subclasses of ControlMechanism that can use this (such as OptimizationControlMechanism) to execute “simulations” of the Composition (that is, executions in an execution context separate from the one used by the execution method called by the user) to evaluate the influence of parameters on performance.

It also assigns a ControlSignal for any Parameter of a Mechanism specified for control, and a ControlProjection to its correponding ParameterPort.

The ControlMechanism is assigned the NodeRole CONTROLLER.

_get_control_signals_for_composition()

Return list of ControlSignals specified by Nodes in the Composition

Generate list of ControlSignal specifications from ParameterPorts of Mechanisms specified for control. The specifications can be:

ControlProjections (with deferred_init()) # FIX: 9/14/19 - THIS SHOULD ALREADY HAVE BEEN PARSED INTO ControlProjection WITH DEFFERRED_INIT: # OTHERWISE, NEED TO ADD HANDLING OF IT BELOW ControlSignals (e.g., in a 2-item tuple specification for the parameter); CONTROL keyword Note:

The initialization of the ControlProjection and, if specified, the ControlSignal are completed in the call to controller_instantiate_control_signal() in add_controller.

Mechanism can be in the Composition itself, or in a nested Composition that does not have its own controller.

_check_projection_initialization_status(context=None)

Checks initialization status of controller (if applicable) and any projections or ports

evaluate(predicted_input=None, control_allocation=None, num_simulation_trials=None, runtime_params=None, base_context=<psyneulink.core.globals.context.Context object>, context=None, execution_mode=False, return_results=False, block_simulate=False)

Runs a simulation of the Composition, with the specified control_allocation, excluding its controller in order to return the net_outcome of the Composition, according to its controller under that control_allocation. All values are reset to pre-simulation values at the end of the simulation.

If block_simulate is set to True, the controller will attempt to use the entire input set provided to the run method of the Composition as input for the simulated call to run. If it is not, the controller will use the inputs slated for its next or previous execution, depending on whether the controller_mode of the Composition is set to before or after, respectively.

Note

Block simulation can not be used if the Composition’s stimuli were specified as a generator. If block_simulate is set to True and the input type for the Composition was a generator, block simulation will be disabled for the current execution of evaluate.

_infer_target_nodes(targets)

Maps targets onto target mechanisms (as needed by learning)

Returns

Dict mapping TargetMechanisms -> target values

Return type

dict

_parse_learning_spec(inputs, targets)

Converts learning inputs and targets to a standardized form

Returns

• dict – Dict mapping mechanisms to values (with TargetMechanisms inferred from output nodes if needed)

• int – Number of input sets in dict for each input node in the Composition

_parse_generator_function(inputs)

Instantiates and parses generator from generator function

Returns

• generator – Generator instance that will be used to yield inputs

• int – a large int (sys.maxsize), used in place of the number of input sets, since it is impossible to determine a priori how many times a generator will yield

_parse_generator(inputs)
Returns

• generator – Generator instance that will be used to yield inputs

• int – a large int (sys.maxsize), used in place of the number of input sets, since it is impossible to determine a priori how many times a generator will yield

_parse_list(inputs)
Validates that conditions are met to use a list as input, i.e. that there is only one input node. If so, convert

list to input dict and parse

Returns

• dict – Parsed and standardized input dict

• int – Number of input sets in dict for each input node in the Composition

_parse_string(inputs)
Validates that conditions are met to use a string as input, i.e. that there is only one input node and that node’s default

input port has a label matching the provided string. If so, convert the string to an input dict and parse

Returns

• dict – Parsed and standardized input dict

• int – Number of input sets in dict for each input node in the Composition

_parse_function(inputs)
Returns

• function – Function that will be used to yield inputs

• int – Functions must always return 1 trial of input per call, so this always returns 1

_validate_single_input(node, input)
validates a single input for a single node. if the input is specified without an outer list (i.e.

Composition.run(inputs = [1, 1]) instead of Composition.run(inputs = [[1], [1]]), add an extra dimension to the input

Returns

The input, with an added dimension if necessary, if the input is valid. None if the input is not valid.

Return type

None or np.ndarray or list

_validate_input_shapes(inputs)

Validates that all inputs provided in input dict are valid

Returns

The input dict, with shapes corrected if necessary.

Return type

dict

_flatten_nested_dicts(inputs)
Converts inputs provided in the form of a dict for a nested Composition to a list corresponding to the

Composition’s input CIM ports

Returns

The input dict, with nested dicts corresponding to nested Compositions converted to lists

Return type

dict

_parse_labels(inputs, mech=None)
Traverse input dict and replace any inputs that are in the form of their input or output label representations

to their numeric representations

Returns

The input dict, with inputs in the form of their label representations replaced by their numeric representations

Return type

dict

_parse_dict(inputs)
Validates and parses a dict provided as input to a Composition into a standardized form to be used throughout

its execution

Returns

• dict – Parsed and standardized input dict

• int – Number of input sets in dict for each input node in the Composition

_validate_input_dict_node_roles(inputs)
Validates that all nodes included in input dict are input nodes. Additionally, if any input nodes are not

included, adds them to the input dict using their default values as entries

Returns

The input dict, with added entries for any input nodes for which input was not provided

Return type

dict

_parse_run_inputs(inputs)

Takes user-provided input for entire run and parses it according to its type

Returns

• Parsed input dict

• The number of inputs sets included in the input

_parse_trial_inputs(inputs, trial_num)

Extracts inputs for a single trial and parses it in accordance with its type

Returns

Input dict parsed for a single trial of a Composition’s execution

Return type

dict

_validate_execution_inputs(inputs)

Validates and returns the formatted input dict for a single execution

Returns

Input dict parsed for a single trial of a Composition’s execution

Return type

dict

run(inputs=None, num_trials=None, initialize_cycle_values=None, reset_stateful_functions_to=None, reset_stateful_functions_when=<psyneulink.core.scheduling.condition.Never object>, skip_initialization=False, clamp_input='soft_clamp', runtime_params=None, call_before_time_step=None, call_after_time_step=None, call_before_pass=None, call_after_pass=None, call_before_trial=None, call_after_trial=None, termination_processing=None, skip_analyze_graph=False, animate=False, log=False, scheduler=None, bin_execute=False, context=None, base_context=<psyneulink.core.globals.context.Context object>)

Pass inputs to Composition, then execute sets of nodes that are eligible to run until termination conditions are met.

See Executing a Composition for details of formatting input specifications. Use animate to generate a gif of the execution sequence.

Parameters
• inputs (Dict{INPUT Node : list}, function or generator : default None) – specifies the inputs to each INPUT Node of the Composition in each TRIAL executed during the run; see Input formats (including targets for learning) for additional information about format. If inputs is not specified, the default_variable for each INPUT Node is used as its input on TRIAL

• num_trials (int : default 1) – typically, the composition will infer the number of trials from the length of its input specification. To reuse the same inputs across many trials, you may specify an input dictionary with lists of length 1, or use default inputs, and select a number of trials with num_trials.

• initialize_cycle_values (Dict { Node: Node Value } : default None) – sets the value of specified Nodes before the start of the run. All specified Nodes must be in a cycle (i.e., designated with with NodeRole CYCLE; otherwise, a warning is issued and the specification is ignored). If a Node in a cycle is not specified, it is assigned its default values when initialized (see Cycles and Feedback additional details).

• reset_stateful_functions_to (Dict { Node : Object | iterable [Object] } : default None) – object or iterable of objects to be passed as arguments to nodes’ reset methods when their respective reset_stateful_function_when conditions are met. These are used to seed the stateful attributes of Mechanisms that have stateful functions. If a node’s reset_stateful_function_when condition is set to Never, but they are listed in the reset_stateful_functions_to dict, then they will be reset once at the beginning of the run, using the provided values. For a more in depth explanation of this argument, see Resetting Parameters of StatefulFunctions.

• reset_stateful_functions_when (Dict { Node: Condition } | Condition : default Never()) – if type is dict, sets the reset_stateful_function_when attribute for each key Node to its corresponding value Condition. if type is Condition, sets the reset_stateful_function_when attribute for all nodes in the Composition that currently have their reset_stateful_function_when conditions set to Never. in either case, the specified Conditions persist only for the duration of the run, after which the nodes’ reset_stateful_functions_when attributes are returned to their previous Conditions. For a more in depth explanation of this argument, see Resetting Parameters of StatefulFunctions.

• skip_initialization (bool : default False) –

• clamp_input (enum.Enum[SOFT_CLAMP|HARD_CLAMP|PULSE_CLAMP|NO_CLAMP] : default SOFT_CLAMP) – specifies how inputs are handled for the Composition’s INPUT Nodes.

• runtime_params (Dict[Node: Dict[Parameter: Tuple(Value, Condition)]] : default None) – nested dictionary of (value, Condition) tuples for parameters of Nodes (Mechanisms or Compositions of the Composition; specifies alternate parameter values to be used only during this RUN when the specified Condition is met (see Runtime Parameters for additional informaton).

• call_before_time_step (callable : default None) – specifies fuction to call before each TIME_STEP is executed.

• call_after_time_step (callable : default None) – specifies fuction to call after each TIME_STEP is executed.

• call_before_pass (callable : default None) – specifies fuction to call before each PASS is executed.

• call_after_pass (callable : default None) – specifies fuction to call after each PASS is executed.

• call_before_trial (callable : default None) – specifies fuction to call before each TRIAL is executed.

• call_after_trial (callable : default None) – specifies fuction to call after each TRIAL is executed.

• termination_processing

specifies Condition under which execution of the run will occur.

COMMMENT:

BETTER DESCRIPTION NEEDED

• animate (dict or bool : default False) –

specifies use of the show_graph method to generate a gif movie showing the sequence of Components executed in a run (see example). A dict can be specified containing options to pass to the show_graph method; each key must be a legal argument for the show_graph method, and its value a specification for that argument. The entries listed below can also be included in the dict to specify parameters of the animation. If the animate argument is specified simply as True, defaults are used for all arguments of show_graph and the options below:

• UNIT: EXECUTION_SET or COMPONENT (default=EXECUTION_SET) – specifies which Components to treat as active in each call to show_graph. COMPONENT generates an image for the execution of each Component. EXECUTION_SET generates an image for each execution_set, showing all of the Components in that set as active.

• DURATION: float (default=0.75) – specifies the duration (in seconds) of each image in the movie.

• NUM_RUNS: int (default=1) – specifies the number of runs to animate; by default, this is 1. If the number specified is less than the total number of runs executed, only the number specified are animated; if it is greater than the number of runs being executed, only the number being run are animated.

• NUM_TRIALS: int (default=1) – specifies the number of trials to animate; by default, this is 1. If the number specified is less than the total number of trials being run, only the number specified are animated; if it is greater than the number of trials being run, only the number being run are animated.

• MOVIE_DIR: str (default=project root dir) – specifies the directdory to be used for the movie file; by default a subdirectory of <root_dir>/show_graph_OUTPUT/GIFS is created using the name of the Composition, and the gif files are stored there.

• MOVIE_NAME: str (default=name + ‘movie’) – specifies the name to be used for the movie file; it is automatically appended with ‘.gif’.

• SAVE_IMAGES: bool (default=False) – specifies whether to save each of the images used to construct the animation in separate gif files, in addition to the file containing the animation.

• SHOW: bool (default=False) – specifies whether to show the animation after it is constructed, using the OS’s default viewer.

• log (bool, LogCondition : default False) –

Sets the log_condition for every primary node and projection in the Composition, if it is not already set.

Note

as when setting the log_condition directly, a value of True will correspond to the EXECUTION LogCondition.

• scheduler (Scheduler : default None) – the scheduler object that owns the conditions that will instruct the execution of the Composition. If not specified, the Composition will use its automatically generated scheduler.

• bin_execute (bool or enum.Enum[LLVM|LLVMexec|LLVMRun|Python|PTXExec|PTXRun] : default Python) – specifies whether to run using the Python interpreter or a compiled mode. False is the same as Python; True tries LLVM compilation modes, in order of power, progressively reverting to less powerful modes (in the order of the options listed), and to Python if no compilation mode succeeds (see Compilation for explanation of modes). PTX modes are used for CUDA compilation.

• context (execution_id : default default_execution_id) – context in which the Composition will be executed; set to self.default_execution_id ifunspecified.

• base_context (execution_id : Context(execution_id=None)) – the context corresponding to the execution context from which this execution will be initialized, if values currently do not exist for context

Returns

2d list of values of OUTPUT Nodes at end of last trial – each item in the list is the output_values for an OUTPUT Node of the Composition, listed in the order listed in get_nodes_by_role(NodeRole.OUTPUT).

Note

The results attribute of the Compositon contains a list of the outputs for all trials.

Return type

list[list]

learn(inputs, targets=None, num_trials=None, epochs=1, minibatch_size=1, patience=None, min_delta=0, context=None, bin_execute=False, randomize_minibatches=False, call_before_minibatch=None, call_after_minibatch=None, *args, **kwargs)

Runs the composition in learning mode - that is, any components with disable_learning False will be executed in learning mode. See Learning in a Composition for details.

Parameters
• inputs ({Node:list }) –

a dictionary containing a key-value pair for each Node (Mechanism or Composition) in the composition that receives inputs from the user. There are several equally valid ways that this dict can be structured:

1. For each pair, the key is the and the value is an input, the shape of which must match the Node’s default variable. This is identical to the input dict in the run method (see Input Dictionary for additional details).

2. A dict with keys ‘inputs’, ‘targets’, and ‘epochs’. The inputs key stores a dict that is the same same structure as input specification (1) of learn. The targets and epochs keys should contain values of the same shape as targets and epochs.

• targets ({Node:list }) – a dictionary containing a key-value pair for each Node in the Composition that receives target values as input to the Composition for training learning pathways. The key of each entry can be either the TARGET_MECHANISM for a learning pathway or the final Node in that Pathway, and the value is the target value used for that Node on each trial (see target inputs for additional details concerning the formatting of targets).

• num_trials (int (default=None)) – typically, the composition will infer the number of trials from the length of its input specification. To reuse the same inputs across many trials, you may specify an input dictionary with lists of length 1, or use default inputs, and select a number of trials with num_trials.

• epochs (int (default=1)) – specifies the number of training epochs (that is, repetitions of the batched input set) to run with

• minibatch_size (int (default=1)) – specifies the size of the minibatches to use. The input trials will be batched and ran, after which learning mechanisms with learning mode TRIAL will update weights

• randomize_minibatch (bool (default=False)) – specifies whether the order of the input trials should be randomized on each epoch

• patience (int or None (default=None)) – used for early stopping of training; If a model has more than patience bad consecutive epochs, then learn will prematurely return. A bad epoch is determined by the min_delta value

• min_delta (float (default=0)) – the minimum reduction in average loss that an epoch must provide in order to qualify as a ‘good’ epoch; Any reduction less than this value is considered to be a bad epoch. Used for early stopping of training, in combination with patience.

• scheduler (Scheduler) – the scheduler object that owns the conditions that will instruct the execution of the Composition If not specified, the Composition will use its automatically generated scheduler.

• context (Optional[optional]) – context will be set to self.default_execution_id if unspecified

• call_before_minibatch (callable) – called before each minibatch is executed

• call_after_minibatch (callable) – called after each minibatch is executed

Returns

the results of the final epoch of training

Return type

list

execute(inputs=None, scheduler=None, termination_processing=None, call_before_time_step=None, call_before_pass=None, call_after_time_step=None, call_after_pass=None, reset_stateful_functions_to=None, context=None, base_context=<psyneulink.core.globals.context.Context object>, clamp_input='soft_clamp', runtime_params=None, skip_initialization=False, bin_execute=False)

Passes inputs to any Nodes receiving inputs directly from the user (via the “inputs” argument) then coordinates with the Scheduler to execute sets of Nodes that are eligible to execute until termination conditions are met.

Parameters
• inputs ({ Node: list } : default None) – a dictionary containing a key-value pair for each Node in the Composition that receives inputs from the user. For each pair, the key is the Node (a Mechanism or Composition) and the value is an input, the shape of which must match the Node’s default variable. If inputs is not specified, the default_variable for each INPUT Node is used as its input (see Input Formats for additional details).

• clamp_input (SOFT_CLAMP : default SOFT_CLAMP) –

• runtime_params (Dict[Node: Dict[Parameter: Tuple(Value, Condition)]] : default None) – specifies alternate parameter values to be used only during this EXECUTION when the specified Condition is met (see Runtime Parameters for more details and examples of valid dictionaries).

• skip_initialization (: default False) –

• scheduler (Scheduler : default None) – the scheduler object that owns the conditions that will instruct the execution of the Composition If not specified, the Composition will use its automatically generated scheduler.

• context (execution_id : default default_execution_id) – execution context in which the Composition will be executed.

• base_context (execution_id : Context(execution_id=None)) – the context corresponding to the execution context from which this execution will be initialized, if values currently do not exist for context.

• call_before_time_step (callable : default None) – called before each TIME_STEP is executed passed the current context (but it is not necessary for your callable to take).

• call_after_time_step (callable : default None) – called after each TIME_STEP is executed passed the current context (but it is not necessary for your callable to take).

• call_before_pass (callable : default None) – called before each PASS is executed passed the current context (but it is not necessary for your callable to take).

• call_after_pass (callable : default None) – called after each PASS is executed passed the current context (but it is not necessary for your callable to take).

• bin_execute (bool or enum.Enum[LLVM|LLVMexec|Python|PTXExec] : default Python) – specifies whether to run using the Python interpreter or a compiled mode. see bin_execute argument of run method for additional details.

Returns

output value of the final Mechanism executed in the Composition

Return type

various

reset(values=None, include_unspecified_nodes=True, context=NotImplemented)

If the component’s execute method involves execution of an IntegratorFunction Function, this method effectively begins the function’s accumulation over again at the specified value, and may update related values on the component, depending on the component type. Otherwise, it simply reassigns the Component’s value based on its default_variable.

initialize(values=None, include_unspecified_nodes=True, context=None)

Initializes the values of nodes within cycles. If include_unspecified_nodes is True and a value is provided for a given node, the node will be initialized to that value. If include_unspecified_nodes is True and a value is not provided, the node will be initialized to its default value. If include_unspecified_nodes is False, then all nodes must have corresponding initialization values. The DEFAULT keyword can be used in lieu of a numerical value to reset a node’s value to its default.

If a context is not provided, the most recent context under which the Composition has executed will be used.

Parameters
• values (Dict { Node: Node Value }) – A dictionary contaning key-value pairs of Nodes and initialization values. Nodes within cycles that are not included in this dict will be initialized to their default values.

• include_unspecified_nodes (bool) – Specifies whether all nodes within cycles should be initialized or only ones specified in the provided values dictionary.

• context (Context) – The context under which the nodes should be initialized. context will be set to self.most_recent_execution_context if one is not specified.

disable_all_history()

When run, disables history tracking for all Parameters of all Components used in the Composition

_is_learning(context)

Returns true if the composition can learn in the given context

_build_variable_for_input_CIM(inputs)

Assign values from input dictionary to the InputPorts of the Input CIM, then execute the Input CIM

_assign_execution_ids(context=None)

assigns the same execution id to each Node in the composition’s processing graph as well as the CIMs. he execution id is either specified in the user’s call to run(), or from the Composition’s default_execution_id

_parse_runtime_params_conditions(runtime_params)

Validate runtime_params and assign Always() for any params that don’t have a Condition already specified. Recursively process subdicts (Port- or Project-specific dictionaries of params).

_get_satisfied_runtime_param_values(runtime_params, scheduler, context)

Return dict with values for all runtime_params the Conditions of which are currently satisfied. Recursively parse nested dictionaries for which Condition on dict is satisfied.

property input_ports

Returns all InputPorts that belong to the Input CompositionInterfaceMechanism

property input_port

Returns the index 0 InputPort that belongs to the Input CompositionInterfaceMechanism

property input_values

Returns values of all InputPorts that belong to the Input CompositionInterfaceMechanism

property output_ports

Returns all OutputPorts that belong to the Output CompositionInterfaceMechanism

property output_values

Returns values of all OutputPorts that belong to the Output CompositionInterfaceMechanism in the most recently executed context

property external_input_ports

Returns all external InputPorts that belong to the Input CompositionInterfaceMechanism

property external_input_values

Returns values of all external InputPorts that belong to the Input CompositionInterfaceMechanism

property default_external_input_values

Returns the default values of all external InputPorts that belong to the Input CompositionInterfaceMechanism

property stateful_nodes

List of all nodes in the Composition that are currently marked as stateful. For Mechanisms, statefulness is determined by checking whether node.has_initializers is True. For Compositions, statefulness is determined by checking whether any of its Nodes are stateful.

Returns

all stateful nodes in the Composition

Return type

List[Node]

property output_port

Returns the index 0 OutputPort that belongs to the Output CompositionInterfaceMechanism

property stateful_parameters

A list of all of this object’s parameters whose values may change during runtime

property _dependent_components

Returns a set of Components that will be executed if this Component is executed

Roles assigned to Nodes of a Composition.

ORIGIN

A Node that does not receive any Projections from any other Nodes within its own Composition, though if it is in a nested Composition it may receive Projections from the outer Composition. Execution of a Composition always begins with an ORIGIN Node. A Composition may have many ORIGIN Nodes. This role cannot be modified programmatically.

INPUT

A Node that receives input from outside its Composition, either from the Composition’s run method or, if it is in a nested Composition, from the outer outer Composition. By default, the ORIGIN Nodes of a Composition are also its INPUT Nodes; however this can be modified by assigning specified NodeRoles to Nodes. A Composition can have many INPUT Nodes.

SINGLETON

A Node that is both an ORIGIN and a TERMINAL. This role cannot be modified programmatically.

INTERNAL

A Node that is neither ORIGIN nor TERMINAL. This role cannot be modified programmatically.

CYCLE

A Node that belongs to a cycle. This role cannot be modified programmatically.

FEEDBACK_SENDER

A Node with one or more efferent Projections designated as feedback in the Composition. This means that the Node executes last in the sequence of Nodes that would otherwise form a cycle. This role cannot be modified directly, but is modified if the feedback status of the Projection is explicitly specified.

A Node with one or more afferent Projections designated as feedback in the Composition. This means that the Node executes first in the sequence of Nodes that would otherwise form a cycle. This role cannot be modified directly, but is modified if the feedback status of the Projection is explicitly specified.

CONTROL_OBJECTIVE

A Node that is an ObjectiveMechanism associated with a ControlMechanism other than the Composition’s controller (if it has one).

CONTROLLER

A Node that is the controller of a Composition. This role cannot be modified programmatically.

CONTROLLER_OBJECTIVE

A Node that is an ObjectiveMechanism associated with a Composition’s controller.

LEARNING

A Node that is only executed when learning is enabled; if it is not also assigned TARGET or LEARNING_OBJECTIVE, then it is a Learning Mechanism. This role can, but generally should not be modified programmatically.

TARGET

A Node that receives the target for a learning pathway specifying the desired output of the OUTPUT_MECHANISM for that pathway (see TARGET_MECHANISM). This role can, but generally should not be modified programmatically.

LEARNING_OBJECTIVE

A Node that is the ObjectiveMechanism of a learning Pathway; usually a ComparatorMechanism (see OBJECTIVE_MECHANISM). This role can, but generally should not be modified programmatically.

OUTPUT

A Node the output_values of which are included in the Composition’s results attribute. By default, the TERMINAL Nodes of a Composition are also its OUTPUT Nodes; however this can be modified by assigning specified NodeRoles to Nodes. A Composition can have many OUTPUT Nodes.

TERMINAL

A Node that does not send any Projections to any other Nodes within its own Composition, though if it is in a nested Composition it may send Projections to the outer Composition. A Composition may have many TERMINAL Nodes. The ObjectiveMechanism associated with the Composition’s controller (assigned the role CONTROLLER_OBJECTIVE) cannot be a TERMINAL Node of a Composition. Execution of a Composition itself always ends with a TERMINAL Node, although the controller and its associated ObjectiveMechanism may execute after that; some TERMINAL Nodes may also execute earlier (i.e., if they belong to a Pathway that is shorter than the longest one in the Composition). This role cannot be modified programmatically.