# Port¶

Subclasses

## Overview¶

A Port provides an interface to one or more Projections, and receives the value(s) provided by them. The value of a Port can be modulated by a ModulatoryProjection. There are three primary types of Ports (InputPorts, ParameterPorts and OutputPorts) as well as one subtype (ModulatorySignal, used to send ModulatoryProjections), as summarized in the table below:

Port Types and Associated Projection Types

Port Type

Owner

Description

Modulated by

Specification

InputPort

Mechanism

InputPort constructor; Mechanism constructor or its add_ports method

ParameterPort

represents parameter value for a Component or its function

Implicitly whenever a parameter value is specified

OutputPort

Mechanism

provides output to MappingProjection

OutputPort constructor; Mechanism constructor or its add_ports method

ModulatorySignal

ModulatoryMechanism

provides value for ModulatoryProjection

ModulatoryMechanism constructor; tuple in Port or parameter specification

## Creating a Port¶

In general, Ports are created automatically by the objects to which they belong (their owner), or by specifying the Port in the constructor for its owner. For example, unless otherwise specified, when a Mechanism is created it creates a default InputPort and OutputPort for itself, and whenever any Component is created, it automatically creates a ParameterPort for each of its configurable parameters and those of its function. Ports are also created in response to explicit specifications. For example, InputPorts and OutputPorts can be specified in the constructor for a Mechanism (see Specifying Ports); and ParameterPorts are specified in effect when the value of a parameter for any Component or its function is specified in the constructor for that Component or function. InputPorts and OutputPorts (but not ParameterPorts) can also be created directly using their constructors, and then assigned to a Mechanism using the Mechanism’s add_ports method; however, this should be done with caution as the Port must be compatible with other attributes of its owner (such as its OutputPorts) and its function (for example, see note regarding InputPorts). Parameter Ports cannot on their own; they are always and only created when the Component to which a parameter belongs is created.

### Specifying a Port¶

A Port can be specified using any of the following:

• existing Port object;

• name of a Port subclass (InputPort, ParameterPort, or OutputPort) – creates a default Port of the specified type, using a default value for the Port that is determined by the context in which it is specified.

• value – creates a default Port using the specified value as its default value.

• Port specification dictionary – can use the following: KEY:<value> entries, in addition to those specific to the Port’s type (see documentation for each Port type):

• PORT_TYPE:<Port type>

specifies type of Port to create (necessary if it cannot be determined from the context of the other entries or in which it is being created).

• NAME:<str>

the string is used as the name of the Port.

• VALUE:<value>

the value is used as the default value of the Port.

A Port specification dictionary can also be used to specify one or more Projections used to modify the value of the Port. The type of Projection(s) created depend on the type of Port specified and context of the specification (see examples). This can be done using any of the following entries, each of which can contain any of the forms used to specify a Projection:

• MECHANISM:Mechanism

this can be used to specify one or more Projections to or from the specified Mechanism. If the entry appears without any accompanying Port specification entries (see below), the Projection is assumed to be a MappingProjection to the Mechanism’s primary InputPort or from its primary OutputPort, depending upon the type of Mechanism and context of specification. It can also be accompanied by one or more Port specification entries described below, to create one or more Projections to/from those specific Ports (see examples).

• <PORTS_KEYWORD>:List[<str or Port.name>,…]

this must accompany a MECHANISM entry (described above), and is used to specify its Port(s) by name. Each entry must use one of the following keywords as its key, and there can be no more than one of each:

• INPUT_PORTS

• OUTPUT_PORTS

• PARAMETER_PORTS

• LEARNING_SIGNAL

• CONTROL_SIGNAL

• GATING_SIGNAL.

Each entry must contain a list Ports of the specified type, all of which belong to the Mechanism specified in the MECHANISM entry; each item in the list must be the name of one the Mechanism’s Ports, or a ProjectionTuple the first item of which is the name of a Port. The types of Ports that can be specified in this manner depends on the type of the Mechanism and context of the specification (see examples).

• Port, Mechanism, or list of these – creates a default Port with Projection(s) to/from the specified Ports; the type of Port being created determines the type and directionality of the Projection(s) and, if Mechanism(s) are specified, which of their primary Ports are used (see Port subclasses for specifics).

• Tuple specifications – these are convenience formats that can be used to compactly specify a Port by specifying other Components with which it should be connected by Projection(s). Different Ports support different forms, but all support the following two forms:

• 2-item tuple: (<Port name or list of Port names>, <Mechanism>) – 1st item is the name of a Port or list of them, and the 2nd item is the Mechanism to which they belong; a Projection is created to or from each of the Ports specified. The type of Projection depends on the type of Port being created, and the type of Ports specified in the tuple (see Sender, Receiver and Attribute Assignments for Projection Types). For example, if the Port being created is an InputPort, and the Ports specified in the tuple are OutputPorts, then MappingProjections are used; if ModulatorySignals are specified, then the corresponding type of ModulatoryProjections are created. See Port subclasses for additional details and compatibility requirements.

• ProjectionTuple – a 4-item tuple that specifies one or more Projections to or from other Port(s), along with a weight and/or exponent for each.

### Projections¶

When a Port is created, it can be assigned one or more Projections, in either the projections argument of its constructor, or a PROJECTIONS entry of a Port specification dictionary (or a dictionary assigned to the params argument of the Port’s constructor). The following types of Projections can be specified for each type of Port:

Projections must be specified in a list. Each entry must be either a specification for a projection, or for a sender or receiver of one, in which case the appropriate type of Projection is created. A sender or receiver can be specified as a Port or a Mechanism. If a Mechanism is specified, its primary InputPort or OutputPort is used, as appropriate. When a sender or receiver is used to specify the Projection, the type of Projection created is inferred from the Port and the type of sender or receiver specified, as illustrated in the examples below. Note that the Port must be assigned to an owner in order to be functional, irrespective of whether any Projections have been assigned to it.

### Deferred Initialization¶

If a Port is created on its own, and its owner Mechanism is specified, it is assigned to that Mechanism; if its owner not specified, then its initialization is deferred. Its initialization is completed automatically when it is assigned to an owner Mechanism using the owner’s add_ports method. If the Port is not assigned to an owner, it will not be functional (i.e., used during the execution of Mechanisms and/or Compositions, irrespective of whether it has any Projections assigned to it.

## Structure¶

### Owner¶

Every Port has an owner. For InputPorts and OutputPorts, the owner must be a Mechanism. For ParameterPorts it can be a Mechanism or a PathwayProjection. For ModulatorySignals, it must be a ModulatoryMechanism. When a Port is created as part of another Component, its owner is assigned automatically to that Component. It is also assigned automatically when the Port is assigned to a Mechanism using that Mechanism’s add_ports method. Otherwise, it must be specified explicitly in the owner argument of the constructor for the Port (in which case it is immediately assigned to the specified Mechanism). If the owner argument is not specified, the Port’s initialization is deferred until it has been assigned to an owner using the owner’s add_ports method.

### Projections¶

Every Port has attributes that lists the Projections it sends and/or receives. These depend on the type of Port, listed below (and shown in the table):

In addition to these attributes, all of the Projections sent and received by a Port are listed in its projections attribute.

### Variable, Function and Value¶

In addition, like all PsyNeuLink Components, it also has the three following core attributes:

### Modulation¶

Every type of Port has a mod_afferents attribute, that lists the ModulatoryProjections it receives. Each ModulatoryProjection comes from a ModulatorySignal that specifies how it should modulate the Port’s value when the Port is updated (see Modulation and ModulatorySignal_Anatomy_Figure). In most cases, a ModulatorySignal uses the Port’s function to modulate its value. The function of every Port assigns one of its parameters as its ADDITIVE_PARAM and another as its MULTIPLICATIVE_PARAM. The modulation attribute of a ModulatorySignal determines which of these to modify when the Port uses it function to calculate its value. However, the ModulatorySignal can also be configured to override the Port’s value (i.e., assign it directly), or to disable modulation, using either the keyword OVERRIDE or DSIABLE, respectively, to specify the value for its modulation attribute (see Modulation for a more detailed discussion).

## Execution¶

Ports cannot be executed. They are updated when the Component to which they belong is executed. InputPorts and ParameterPorts belonging to a Mechanism are updated before the Mechanism’s function is called. OutputPorts are updated after the Mechanism’s function is called. When a Port is updated, it executes any Projections that project to it (listed in its all_afferents attribute. It uses the values it receives from any PathWayProjections (listed in its path_afferents attribute) as the variable for its function. It then executes all of the ModulatoryProjections it receives. Different ModulatorySignals may call for different forms of modulation (see Modulation). Accordingly, it separately sums the values specified by any ModulatorySignals for the MULTIPLICATIVE_PARAM of its function, and similarly for the ADDITIVE_PARAM. It then applies the summed value for each to the corresponding parameter of its function. If any of the ModulatorySignals specifies OVERRIDE, then the value of that ModulatorySignal is used as the Port’s value. Finally, the Port calls its function to determine its value.

Note

The change in the value of a Port does not occur until the Mechanism to which the Port belongs is next executed; This conforms to a “lazy evaluation” protocol (see Lazy Evaluation for an explanation of “lazy” updating).

Examples

Usually, Ports are created automatically by the Mechanism to which they belong. For example, creating a TransferMechanism:

my_mech = pnl.TransferMechanism()


automatically creates an InputPort, ParameterPorts for its parameters, including the slope and intercept parameters of its Linear Function (its default function), and an OutputPort (named RESULT):

print(my_mech.input_ports)
> [(InputPort InputPort-0)]
print(my_mech.parameter_ports)
> [(ParameterPort intercept), (ParameterPort slope), (ParameterPort noise), (ParameterPort integration_rate)]
print(my_mech.output_ports)
> [(OutputPort RESULT)]


Using the input_ports argument of a Mechanism constructor.

When Ports are specified explicitly, it is usually in an argument of the constructor for the Mechanism to which they belong. For example, the following specifies that my_mech should have an InputPort named ‘MY INPUT:

my_mech = pnl.TransferMechanism(input_ports=['MY INPUT'])
print(my_mech.input_ports)
> [(InputPort 'MY INPUT')]


The InputPort was specified by a string (for its name) in the input_ports argument. It can also be specified in a variety of other ways, as described above and illustrated in the examples below. Note that when one or more Ports is specified in the argument of a Mechanism’s constructor, it replaces any defaults Ports created by the Mechanism when none are specified (see note.

For example, the following specifies the InputPort by a value to use as its default_variable attribute:

my_mech = pnl.TransferMechanism(input_ports=[[0,0])


The value is also used to format the InputPort’s value, as well as the first (and, in this case, only) item of the Mechanism’s variable (i.e., the one to which the InputPort is assigned), as show below:

print(my_mech.input_ports[0].variable)
> [0 0]
print (my_mech.input_port.value)
> [ 0.  0.]
print (my_mech.variable)
> [[0 0]]


Note that in the first print port, the InputPort was referenced as the first one in the input_ports attribute of my_mech; the second print port references it directly, as the primary InputPort of my_mech, using its input_port attribute (note the singular).

Multiple InputPorts

The input_ports argument can also be used to create more than one InputPort:

my_mech = pnl.TransferMechanism(input_ports=['MY FIRST INPUT', 'MY SECOND INPUT'])
print(my_mech.input_ports)
> [(InputPort MY FIRST INPUT), (InputPort MY SECOND INPUT)]


Here, the print statement uses the input_ports attribute, since there is now more than one InputPort. OutputPorts can be specified in a similar way, using the output_ports argument.

Note

Although InputPorts and OutputPorts can be specified in a Mechanism’s constructor, ParameterPorts cannot; those are created automatically when the Mechanism is created, for each of its user configurable parameters and those of its function. However, the value can be specified when the Mechanism is created, or its function is assigned, and can be accessed and subsequently modified, as described under ParameterPort_Specification>.

OutputPorts

The following example specifies two OutputPorts for my_mech, using its Standard OutputPorts:

my_mech = pnl.TransferMechanism(output_ports=['RESULT', 'MEAN'])


As with InputPorts, specification of OutputPorts in the output_ports argument suppresses the creation of any default OutputPorts that would have been created if no OutputPorts were specified (see note above). For example, TransferMechanisms create a RESULT OutputPort by default, that contains the result of their function. This default behavior is suppressed by any specifications in its output_ports argument. Therefore, to retain a RESULT OutputPort, it must be included in the output_ports argument along with any others that are specified, as in the example above. If the name of a specified OutputPort matches the name of a Standard OutputPort <OutputPort_Standard> for the type of Mechanism, then that is used (as is the case for both of the OutputPorts specified for the TransferMechanism in the example above); otherwise, a new OutputPort is created.

Port specification dictionary

Ports can be specified in greater detail using a Port specification dictionary. In the example below, this is used to specify the variable and name of an InputPort:

my_mech = pnl.TransferMechanism(input_ports=[{PORT_TYPE: InputPort,
NAME: 'MY INPUT',
VARIABLE: [0,0]})


The PORT_TYPE entry is included here for completeness, but is not actually needed when the Port specification dicationary is used in input_ports or output_ports argument of a Mechanism, since the Port’s type is clearly determined by the context of the specification; however, where that is not clear, then the PORT_TYPE entry must be included.

Projections

A Port specification dictionary can also be used to specify projections to or from the Port, also in a number of different ways. The most straightforward is to include them in a PROJECTIONS entry. For example, the following specifies that the InputPort of my_mech receive two Projections, one from source_mech_1 and another from source_mech_2, and that its OutputPort send one to destination_mech:

source_mech_1 = pnl.TransferMechanism(name='SOURCE_1')
source_mech_2 = pnl.TransferMechanism(name='SOURCE_2')
destination_mech = pnl.TransferMechanism(name='DEST')
my_mech = pnl.TransferMechanism(name='MY_MECH',
input_ports=[{pnl.NAME: 'MY INPUT',
pnl.PROJECTIONS:[source_mech_1, source_mech_2]}],
output_ports=[{pnl.NAME: 'RESULT',
pnl.PROJECTIONS:[destination_mech]}])

# Print names of the Projections:
for projection in my_mech.input_port.path_afferents:
print(projection.name)
> MappingProjection from SOURCE_1[RESULT] to MY_MECH[MY INPUT]
> MappingProjection from SOURCE_2[RESULT] to MY_MECH[MY INPUT]
for projection in my_mech.output_port.efferents:
print(projection.name)
> MappingProjection from MY_MECH[RESULT] to DEST[InputPort]


A PROJECTIONS entry can contain any of the forms used to specify a Projection. Here, Mechanisms are used, which creates Projections from the primary InputPort of source_mech, and to the primary OutputPort of destination_mech. Note that MappingProjections are created, since the Projections specified are between InputPorts and OutputPorts. Modulatory Projections can also be specified in a similar way. The following creates a Gating Mechanism, and specifies that the InputPort of my_mech should receive a GatingProjection from it:

my_gating_mech = pnl.GatingMechanism()
my_mech = pnl.TransferMechanism(name='MY_MECH',
input_ports=[{pnl.NAME: 'MY INPUT',
pnl.PROJECTIONS:[my_gating_mech]}])


Conversely, ModulatoryProjections can also be specified from a Mechanism to one or more Ports that it modulates. In the following example, a ControlMechanism is created that sends ControlProjections to the drift_rate and threshold ParameterPorts of a DDM Mechanism:

my_mech = pnl.DDM(name='MY DDM')
my_ctl_mech = pnl.ControlMechanism(control_signals=[{pnl.NAME: 'MY DDM DRIFT RATE AND THREHOLD CONTROL SIGNAL',
pnl.PROJECTIONS: [my_mech.parameter_ports[pnl.DRIFT_RATE],
my_mech.parameter_ports[pnl.THRESHOLD]]}])
# Print ControlSignals and their ControlProjections
for control_signal in my_ctl_mech.control_signals:
print(control_signal.name)
for control_projection in control_signal.efferents:
> MY DDM DRIFT RATE AND THREHOLD CONTROL SIGNAL
>     MY DDM: (ParameterPort drift_rate)
>     MY DDM: (ParameterPort threshold)


Note that a ControlMechanism uses a control_signals argument in place of an output_ports argument (since it uses ControlSignal for its OutputPorts. In the example above, both ControlProjections are assigned to a single ControlSignal. However, they could each be assigned to their own by specifying them in separate itesm of the control_signals argument:

my_mech = pnl.DDM(name='MY DDM')
my_ctl_mech = pnl.ControlMechanism(control_signals=[{pnl.NAME: 'DRIFT RATE CONTROL SIGNAL',
pnl.PROJECTIONS: [my_mech.parameter_ports[pnl.DRIFT_RATE]]},
{pnl.NAME: 'THRESHOLD RATE CONTROL SIGNAL',
pnl.PROJECTIONS: [my_mech.parameter_ports[pnl.THRESHOLD]]}])
# Print ControlSignals and their ControlProjections...
> DRIFT RATE CONTROL SIGNAL
>     MY DDM: (ParameterPort drift_rate)
> THRESHOLD RATE CONTROL SIGNAL
>     MY DDM: (ParameterPort threshold)


Specifying Projections in a Port specification dictionary affords flexibility – for example, naming the Port and/or specifying other attributes. However, if this is not necessary, the Projections can be used to specify Ports directly. For example, the following, which is much simpler, produces the same result as the previous example (sans the custom name; though as the printout below shows, the default names are usually pretty clear):

my_ctl_mech = pnl.ControlMechanism(control_signals=[my_mech.parameter_ports[pnl.DRIFT_RATE],
my_mech.parameter_ports[pnl.THRESHOLD]])
# Print ControlSignals and their ControlProjections...
> MY DDM drift_rate ControlSignal
>    MY DDM: (ParameterPort drift_rate)
> MY DDM threshold ControlSignal
>    MY DDM: (ParameterPort threshold)


Convenience formats

There are two convenience formats for specifying Ports and their Projections in a Port specification dictionary. The first is to use the name of the Port as the key for its entry, and then a list of , as in the following example:

source_mech_1 = pnl.TransferMechanism()
source_mech_2 = pnl.TransferMechanism()
destination_mech = pnl.TransferMechanism()
my_mech_C = pnl.TransferMechanism(input_ports=[{'MY INPUT':[source_mech_1, source_mech_2]}],
output_ports=[{'RESULT':[destination_mech]}])


This produces the same result as the first example under Port specification dictionary above, but it is simpler and easier to read.

The second convenience format is used to specify one or more Projections to/from the Ports of a single Mechanism by their name. It uses the keyword MECHANISM to specify the Mechanism, coupled with a Port-specific entry to specify Projections to its Ports. This can be useful when a Mechanism must send Projections to several Ports of another Mechanism, such as a ControlMechanism that sends ControlProjections to several parameters of a given Mechanism, as in the following example:

my_mech = pnl.DDM(name='MY DDM')
my_ctl_mech = pnl.ControlMechanism(control_signals=[{pnl.MECHANISM: my_mech,
pnl.PARAMETER_PORTS: [pnl.DRIFT_RATE, pnl.THRESHOLD]}])


This produces the same result as the earlier example of ControlProjections, once again in a simpler and easier to read form. However, it be used only to specify Projections for a Port to or from the Ports of a single Mechanism; Projections involving other Mechanisms must be assigned to other Ports.

Create and then assign a port

Finally, a Port can be created directly using its constructor, and then assigned to a Mechanism. The following creates an InputPort my_input_port with a MappingProjection to it from the primary OutputPort of mech_A and assigns it to mech_B:

mech_A = pnl.TransferMechanism()
my_input_port = pnl.InputPort(name='MY INPUTPORT',
projections=[mech_A])
mech_B = pnl.TransferMechanism(input_ports=[my_input_port])
print(mech_B.input_ports)
> [(InputPort MY INPUTPORT)]


The InputPort my_input_port could also have been assigned to mech_B in one of two other ways: by explicity adding it using mech_B's add_ports method:

mech_A = pnl.TransferMechanism()
my_input_port = pnl.InputPort(name='MY INPUTPORT',
projections=[mech_A])
mech_B = pnl.TransferMechanism()


or by constructing it after mech_B and assigning mech_B as its owner:

mech_A = pnl.TransferMechanism()
mech_B = pnl.TransferMechanism()
my_input_port = pnl.InputPort(name='MY INPUTPORT',
owner=mech_B,
projections=[mech_A])


Note that, in both cases, adding the InputPort to mech_B does not replace its the default InputPort generated when it was created, as shown by printing the input_ports for mech_B:

print(mech_B.input_ports)
> [(InputPort InputPort-0), (InputPort MY INPUTPORT)]
> [(InputPort InputPort-0), (InputPort MY INPUTPORT)]


As a consequence, my_input_port is not the primary InputPort for mech_B (i.e., input_ports[0]), but rather its second InputPort (input_ports[1]). This is differs from specifying the InputPort as part of the constructor for the Mechanism, which suppresses generation of the default InputPort, as in the first example above (see note).

## Class Reference¶

class psyneulink.core.components.ports.port.Port_Base(owner=None)

Base class for Port.

The arguments below can be used in the constructor for any subclass of Port. See Component for additional arguments and attributes.

Note

Port is an abstract class and should never be instantiated by a call to its constructor. It should be created by calling the constructor for a subclass, or by using any of the other methods for specifying a Port.

### PortRegistry¶

Used by .__init__.py to assign default Projection types to each Port subclass

Note

All Ports that belong to a given owner are registered in the owner’s _portRegistry, which maintains a dict for each Port type that it uses, a count for all instances of that type, and a dictionary of those instances; none of these are registered in the PortRegistry This. is so that the same name can be used for instances of a Port type by different owners without adding index suffixes for that name across owners, while still indexing multiple uses of the same base name within an owner

Parameters

owner (Mechanism : default None) – the Mechanism to which the Port belongs; if it is not specified or determinable from the context in which the Port is created, the Port’s initialization is deferred.

variable

the Port’s input, provided as the variable to its function.

Type

number, list or np.ndarray

owner

object to which the Port belongs (see Owner for additional details).

Type

Mechanism or Projection

base_value

value with which the Port was initialized.

Type

number, list or np.ndarray

all_afferents

list of all Projections received by the Port (i.e., for which it is a receiver.

Type

Optional[List[Projection]]

path_afferents

list of all PathwayProjections received by the Port (i.e., for which it is the receiver <Projection_Base.receiver> (note: only InputPorts have path_afferents; the list is empty for other types of Ports).

Type

Optional[List[Projection]]

mod_afferents

list of all ModulatoryProjections received by the Port.

Type

Optional[List[GatingProjection]]

projections

list of all of the Projections sent or received by the Port.

Type

List[Projection]

efferents

list of outgoing Projections from the Port (i.e., for which is a sender; note: only OutputPorts, and members of its ModulatoryProjection subclass (LearningProjection, ControlProjection and GatingProjection) have efferents; the list is empty for InputPorts and ParameterPorts.

Type

Optional[List[Projection]]

function

used to determine the Port’s value from the value of the Projection(s) it receives; the parameters that the TransferFunction identifies as ADDITIVE and MULTIPLICATIVE are subject to modulation by a ModulatorySignal.

Type

TransferFunction : default determined by type

value

current value of the Port.

Type

number, list or np.ndarray

name

the name of the Port. If the Port’s initialization has been deferred, it is assigned a temporary name (indicating its deferred initialization status) until initialization is completed, at which time it is assigned its designated name. If that is the name of an existing Port, it is appended with an indexed suffix, incremented for each Port with the same base name (see Naming). If the name is not specified in the name argument of its constructor, a default name is assigned by the subclass (see subclass for details).

Note

Unlike other PsyNeuLink Components, Ports names are “scoped” within a Mechanism, meaning that Ports with the same name are permitted in different Mechanisms. However, they are not permitted in the same Mechanism: Ports within a Mechanism with the same base name are appended an index in the order of their creation).

Type

str

full_name

the name of the Port with its owner if that is assigned: <owner.name>[<self.name>] if owner is not None; otherwise same as name.

Type

str

prefs

the PreferenceSet for the Port; 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

_handle_size(size, variable)

Overwrites the parent method in Component.py, because the variable of a Port is generally 1D, rather than 2D as in the case of Mechanisms

_validate_variable(variable, context=None)

Validate variable and return validated variable

Sets self.base_value = self.value = variable Insures that it is a number of list or tuple of numbers

This overrides the class method, to perform more detailed type checking See explanation in class method. Note: this method (or the class version) is called only if the parameter_validation attribute is True

_validate_params(request_set, target_set=None, context=None)

validate projection specification(s)

Call super (Component._validate_params() Validate following params:

• PROJECTIONS: <entry or list of entries>; each entry must be one of the following:
• Projection object

• Projection class

• specification dict, with the following entries:
• PROJECTION_TYPE:<Projection class> - must be a subclass of Projection

• PROJECTION_PARAMS:<dict> - must be dict of params for PROJECTION_TYPE

# IMPLEMENTATION NOTE: TBI - When learning projection is implemented # + FUNCTION_PARAMS: <dict>, every entry of which must be one of the following: # ParameterPort, projection, 2-item tuple or value

_instantiate_function(function, function_params=None, context=None)

Instantiate function defined in <subclass>.function or <subclass>.function

Instantiate params[FUNCTION] if present, and assign it to self.function

If params[FUNCTION] is present and valid,

it is assigned as the function’s execute method, overriding any direct implementation of self.function

If FUNCTION IS in params:
• if it is a Function object, it is simply assigned to self.function;

• if it is a Function class reference:

it is instantiated using self.defaults.variable and, if present, params[FUNCTION_PARAMS]

If FUNCTION IS NOT in params:
• if self.function IS implemented, it is assigned to params[FUNCTION]

• if self.function IS NOT implemented: program error (should have been caught in _validate_function)

Upon successful completion:
• self._function === self.function

• self.execute should always return the output of self.function in the first item of its output array;

this is done by Function.execute; any subclass override should do the same, so that…

• value is value[0] returned by self.execute

_instantiate_projections(projections, context=None)

Implement any Projection(s) to/from Port specified in PROJECTIONS entry of params arg

Must be implemented by subclasss, to handle interpretation of projection specification(s) in a class-appropriate manner:

PathwayProjections:

InputPort: _instantiate_projections_to_port (.path_afferents) ParameterPort: disallowed OutputPort: _instantiate_projections_from_port (.efferents) ModulatorySignal: disallowed

ModulatoryProjections:

InputPort, OutputPort and ParameterPort: _instantiate_projections_to_port (mod_afferents) ModulatorySignal: _instantiate_projections_from_port (.efferents)

_instantiate_projections_to_port(projections, context=None)

Instantiate projections to a Port and assign them to self.path_afferents

Parses specifications in projection_list into ProjectionTuples

For projection_spec in ProjectionTuple:
• if it is a Projection specifiction dicionatry, instantiate it

• assign sender

• if deferred_init and sender is instantiated, complete initialization

• assign to path_afferents or mod_afferents

• if specs fail, instantiates a default Projection of type specified by self.projection_type

Notes

Calls _parse_connection_specs() to parse projection_list into a list of ProjectionTuples;

_parse_connection_specs, in turn, calls _parse_projection_spec for each spec in projection_list, which returns either a Projection object or Projection specification dictionary for each spec; that is placed in projection_spec entry of ProjectionTuple (Port, weight, exponent, projection_spec).

When the Projection is instantiated, it assigns itself to

its receiver’s .path_afferents attribute (in Projection_Base._instantiate_receiver) and its sender’s .efferents attribute (in Projection_Base._instantiate_sender); so, need to test for prior assignment to avoid duplicates.

_instantiate_projection_from_port(projection_spec, receiver=None, feedback=False, context=None)

Instantiate outgoing projection from a Port and assign it to self.efferents

Instantiate Projections specified in projection_list and, for each:
• insure its self.value is compatible with the projection’s function variable

• place it in self.efferents:

Notes

# LIST VERSION: # If receivers is not specified, they must be assigned to projection specs in projection_list # Calls _parse_connection_specs() to parse projection_list into a list of ProjectionTuples; # _parse_connection_specs, in turn, calls _parse_projection_spec for each spec in projection_list, # which returns either a Projection object or Projection specification dictionary for each spec; # that is placed in projection_spec entry of ProjectionTuple (Port, weight, exponent, projection_spec).

Calls _parse_connection_specs() to parse projection into a ProjectionTuple;

_parse_connection_specs, in turn, calls _parse_projection_spec for the projection_spec, which returns either a Projection object or Projection specification dictionary for the spec; that is placed in projection_spec entry of ProjectionTuple (Port, weight, exponent, projection_spec).

When the Projection is instantiated, it assigns itself to

its self.path_afferents or .mod_afferents attribute (in Projection_Base._instantiate_receiver) and its sender’s .efferents attribute (in Projection_Base._instantiate_sender); so, need to test for prior assignment to avoid duplicates.

Returns instantiated Projection

_remove_projection_from_port(projection, context=None)

Remove Projection entry from Port.efferents.

_remove_projection_to_port(projection, context=None)

If projection is in mod_afferents, remove that projection from self.mod_afferents. Else, Remove Projection entry from Port.path_afferents and reshape variable accordingly.

_parse_port_specific_specs(owner, port_dict, port_specific_spec)

Parse parameters in Port specification tuple specific to each subclass

Called by _parse_port_spec() port_dict contains standard args for Port constructor passed to _parse_port_spec port_specific_spec is either a:

• tuple containing a specification for the Port and/or Projections to/from it

• a dict containing port-specific parameters to be processed

Returns two values: - port_spec: specification for the Port;

• can be None (this is usually the case when port_specific_spec is a tuple specifying a Projection that will be used to specify the port)

• if a value is returned, that is used by _parse_port_spec in a recursive call to parse the specified value as the Port specification

• params: port-specific parameters that will be included in the PARAMS entry of the Port specification dict

_update(params=None, context=None)

Update each projection, combine them, and assign return result

Assign any runtime_params specified for Port, its function, and any of its afferent projections;
• assumes that type-specific sub-dicts have been created for each Projection type for which there are params

• and that specifications for individual Projections have been put in their own PROJECTION-SPECIFIC sub-dict

• specifications for individual Projections are removed from that as used (for check by Mechanism at end)

Call _update for each projection in self.path_afferents (passing specified params) Note: only update LearningSignals if context == LEARNING; otherwise, just get their value Call self.function (default: LinearCombination function) to combine their values Returns combined values of projections, modulated by any mod_afferents

_execute_afferent_projections(projection_params, context)

Execute all afferent Projections for Port

Returns

mod_params

Return type

dict or OVERRIDE

_get_modulated_param(mod_proj, receiver=None, context=None)

Return modulation specification from ModulatoryProjection, and name and value of param modulated.

_get_combined_mod_val(mod_param_name, values)

Combine the modulatory values received by ModulatoryProjections to mod_param_name Uses function specified by modulation_combination_function attribute of param, or MULTIPLICATIVE if not specified

abstract _get_variable_from_projections(context=None)

Return a variable to be used for self.execute when the variable passed in is None

property full_name

<owner.name>[<self.name>]

Type

Return name relative to owner as

static _get_port_function_value(*args, context=None, **kwargs)

Execute the function of a Port and return its value # FIX: CONSIDER INTEGRATING THIS INTO _EXECUTE FOR PORT?

This is a stub, that a Port subclass can override to treat its function in a Port-specific manner. Used primarily during validation, when the function may not have been fully instantiated yet (e.g., InputPort must sometimes embed its variable in a list– see InputPort._get_port_function_value).

property _dependent_components

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

exception psyneulink.core.components.ports.port.PortError(error_value)