The purpose of an InputPort is to receive and combine inputs to a Mechanism, allow them to be modified,
and provide them to the Mechanism’s function. An InputPort receives input to a Mechanism
provided by the Projections to that Mechanism from others in a Composition. If the InputPort belongs
to an ORIGIN Mechanism (see Role in Compositions), then it receives the input specified when that
Composition is run. The PathwayProjections received by an InputPort are listed in its
path_afferents, and its ModulatoryProjections in its
mod_afferents attribute. Its function combines the values received
from its PathWayProjections, modifies the combined value according to value(s) any ModulatoryProjections it receives,
and provides the result to the assigned item of its owner Mechanism’s variable and
input_values attributes (see below and Mechanism InputPorts
for additional details about the role of InputPorts in Mechanisms, and their assignment to the items of a Mechanism’s
variable attribute).
An InputPort can be created by calling its constructor, but in general this is not necessary as a Mechanism can usually automatically create the InputPort(s) it needs when it is created. For example, if the
Mechanism isbeing created within the pathway of a Process, its InputPort is created and assigned
as the receiver of a MappingProjection from the preceding Mechanism in the pathway. InputPorts can also be specified in the input_ports argument of a Mechanism’s constructor
(see below).
The variable of an InputPort can be specified using the variable or input_shapes arguments of
its constructor. It can also be specified using the projections argument, if neither variable nor input_shapes is
specified. The projections argument is used to specify Projections to the InputPort. If
neither the variable nor input_shapes arguments is specified, then the value of the Projections(s) or
their senders (all of which must be the same length) is used to determine the variable of the InputPort.
If an InputPort is created using its constructor, and a Mechanism is specified in the owner argument,
it is automatically assigned to that Mechanism. Note that its value (generally determined
by the size of its variable – see below) must
be compatible (in number and type of elements) with the item of its owner’s variable to
which it is assigned (see below and Mechanism).
If the owner argument is not specified, initialization is deferred.
An InputPort must be owned by a Mechanism. When InputPort is specified in the constructor for a
Mechanism (see below), it is automatically assigned to that Mechanism as its owner. If
the InputPort is created on its own, its owner can specified in the owner argument of its
constructor, in which case it is assigned to that Mechanism. If its owner argument is not specified, its
initialization is deferred until
the InputPort is assigned to a Mechanism using the Mechanism’s add_ports method.
Every Mechanism has at least one InputPort, referred to as its primary InputPort. If InputPorts are not
explicitly specified for a Mechanism, a primary InputPort is automatically created
and assigned to its input_port attribute (note the singular), and also to the first
entry of the Mechanism’s input_ports attribute (note the plural). The value of the primary InputPort is assigned as the first (and often only) item of the Mechanism’s
variable and input_values attributes.
Specifying InputPorts when a Mechanism is created¶
InputPorts can be specified for a Mechanism when it is created, in the input_ports argument of the
Mechanism’s constructor (see examples in Port), or in an INPUT_PORTS entry
of a parameter dictionary assigned to the constructor’s params argument. The latter takes precedence over the
former (that is, if an INPUT_PORTS entry is included in the parameter dictionary, any specified in the
input_ports argument are ignored).
Note
Assigning InputPorts to a Mechanism in its constructor replaces any that are automatically generated for
that Mechanism (i.e., those that it creates for itself by default). If any of those are needed, they must be
explicitly specified in the list assigned to the input_ports argument, or the INPUT_PORTS entry of the
parameter dictionary in the params argument. The number of InputPorts specified must also be equal to
the number of items in the Mechanism’s variable attribute.
Each InputPort specified in the input_ports argument of a Mechanism’s constructor must correspond to an item of
the Mechanism’s variable attribute (see Mechanism),
and the value of the InputPort must be compatible with that item (that is, have the same number
and type of elements). By default, this is also true of the InputPort’s variable attribute,
since the default function for an InputPort is a LinearCombination, the purpose of which
is to combine the inputs it receives and possibly modify the combined value (under the influence of any
ModulatoryProjections it receives), but not mutate its form. Therefore, under most
circumstances, both the variable of an InputPort and its value should
match the item of its owner’s variable to which the InputPort is assigned.
The format of an InputPort’s variable can be specified in a variety of ways. The most
straightforward is in the variable argument of its constructor. More commonly, however, it is determined by
the context in which it is being created, such as the specification for its owner Mechanism’s variable or for the InputPort in the Mechanism’s input_ports argument (see below and Mechanism InputPort specification
for details).
Adding InputPorts to a Mechanism after it is created¶
InputPorts can also be added to a Mechanism, either by creating the InputPort on its own, and specifying the
Mechanism in the InputPort’s owner argument, or by using the Mechanism’s add_ports
method (see examples in Port).
Note
Adding InputPorts does not replace any that the Mechanism generates by default; rather they are added to the
Mechanism, and appended to the list of InputPorts in its input_ports attribute.
Importantly, the Mechanism’s variable attribute is extended with items that
correspond to the value attribute of each added InputPort. This may affect the
relationship of the Mechanism’s variable to its function, as well as the number of its OutputPorts (see note).
If the name of an InputPort added to a Mechanism is the same as one that already exists, its name is suffixed with a
numerical index (incremented for each InputPort with that name; see Naming), and the InputPort is added to
the list (that is, it will not replace ones that already exist).
InputPorts can be specified in a variety of ways, that fall into three broad categories: specifying an InputPort
directly; use of a Port specification dictionary; or by specifying one or more Components that
should project to the InputPort. Each of these is described below:
Direct Specification of an InputPort
existing InputPort object or the name of one – If this is used to specify an InputPort in the
constructor for a Mechanism, its value must be compatible with the corresponding item of
the owner Mechanism’s variable (see Mechanism InputPort specification and InputPort variable: Compatibility and Constraints below). If the InputPort
belongs to another Mechanism, then an InputPort is created along with Projections(s) that shadow the inputs to the specified InputPort.
InputPort class, keywordINPUT_PORT, or a string – this creates a default InputPort; if used
to specify an InputPort in the constructor for a Mechanism, the item of the owner Mechanism’s variable to which the InputPort is assigned is used as the format for the InputPort`s
variable; otherwise, the default for the InputPort is used. If a string is specified,
it is used as the name of the InputPort (see example).
value – this creates a default InputPort using the specified value as the InputPort’s variable; if used to specify an InputPort in the constructor for a Mechanism, the format must be
compatible with the corresponding item of the owner Mechanism’s variable (see
Mechanism InputPort specification, example, and discussion below).
InputPort Specification Dictionary
InputPort specification dictionary – this can be used to specify the attributes of an InputPort, using
any of the entries that can be included in a Port specification dictionary (see
examples in Port). If the dictionary is used to specify an
InputPort in the constructor for a Mechanism, and it includes a VARIABLE and/or VALUE entry, the value
must be compatible with the item of the owner Mechanism’s variable to which the
InputPort is assigned (see Mechanism InputPort specification).
In addition to the standard entries of a Port specification dictionary, the dictionary
can also include either or both of the following entries specific to InputPorts:
WEIGHT:<number>
the value must be an integer or float, and is assigned as the value of the InputPort’s weight attribute (see weight and exponent);
this takes precedence over any specification in the weight argument of the InputPort’s constructor.
EXPONENT:<number>
the value must be an integer or float, and is assigned as the value of the InputPort’s exponent attribute (see weight and exponent);
this takes precedence over any specification in the exponent argument of the InputPort’s constructor.
Specification of an InputPort by Components that Project to It
An InputPort can also be specified by specifying one or more Ports, Mechanisms or Projections that should project
to it, as described below. Specifying an InputPort in this way creates both the InputPort and any of the
specified or implied Projection(s) to it (if they don’t already exist). MappingProjections
are assigned to the InputPort’s path_afferents attribute, while ControlProjections and GatingProjections to its mod_afferents
attribute. Any of the following can be used to specify an InputPort by the Components that projection to it (see
below for an explanation of the relationship between the value of
these Components and the InputPort’s variable):
OutputPort, GatingSignal, Mechanism, or list with any of these – creates an InputPort with Projection(s)
to it from the specified Port(s) or Mechanism(s). For each Mechanism specified, its primary OutputPort (or GatingSignal) is used.
Projection – any form of Projection specification can be
used; creates an InputPort and assigns it as the Projection’s receiver.
InputPort specification tuples – these are convenience formats that can be used to compactly specify an
InputPort and Projections to it any of the following ways:
2-item tuple:(<Port name or list of Port names>, <Mechanism>) – 1st item must be the name of an
OutputPort or ModulatorySignal, or a list of such names, and the 2nd item must be the Mechanism to
which they all belong. Projections of the relevant types are created for each of the specified Ports
(see Port 2-item tuple for additional details).
2-item tuple:(<value, Port specification, or list of Port specs>, <Projection specification>) –
this is a contracted form of the 4-item tuple described below;
3 or 4-item tuple:(<value, Port spec, or list of Port specs>, weight, exponent, Projection
specification) – this allows the specification of Port(s) that should project to the InputPort, together
with a specification of the InputPort’s weight and/or exponent
attributes of the InputPort, and (optionally) the Projection(s) to it. This can be used to compactly
specify a set of Ports that project the InputPort, while using the 4th item to determine its variable
(e.g., using the matrix of the Projection specification) and/or attributes of the Projection(s) to it. Each
tuple must have at least the following first three items (in the order listed), and can include the fourth:
value, Port specification, or list of Port specifications – specifies either the variable of the InputPort, or one or more Ports that should project to it. The Port
specification(s) can be a (Port name, Mechanism) tuple (see above), and/or include Mechanisms (in which
case their primary OutputPort is used. All of the Port specifications must be
consistent with (that is, their value must be compatible with the variable of) the Projection specified in the fourth item if that is included;
weight – must be an integer or a float; multiplies the value of the InputPort
before it is combined with others by the Mechanism’s function (see
ObjectiveMechanism for examples);
exponent – must be an integer or float; exponentiates the value of the
InputPort before it is combined with others by the ObjectiveMechanism’s function (see ObjectiveMechanism for examples);
Projection specification (optional) – specifies a Projection that
must be compatible with the Port specification(s) in the 1st item; if there is more than one Port
specified, and the Projection specification is used, all of the Ports
must be of the same type (i.e.,either OutputPorts or GatingSignals), and the Projection
Specification cannot be an instantiated Projection (since a
Projection cannot be assigned more than one sender).
InputPorts of Mechanisms to shadow – either of the following can be used to create InputPorts that
receive the same inputs as (“shadow”) the ones specified:
InputPort or [InputPort, …] – each InputPort must belong to an existing Mechanism; creates a new
InputPort for each one specified, along with Projections to it that parallel those of the one specified
(see below).
{SHADOW_INPUTS: <InputPort or Mechanism or [<InputPort or Mechanism>,…]>} – any InputPorts specified
must belong to an existing Mechanism; creates a new InputPort for each one specified, and for each of the
InputPorts belonging to any Mechanisms specified, along with Projections to them that parallel those of the
one(s) specified (see below).
For each InputPort specified, and all of the InputPorts belonging to any Mechanisms specified, a new InputPort
is created along with Projections to it that parallel those received by the corresponding InputPort in the list.
That is, for each InputPort specified, one is created that receives exactly the same inputs from the same senders as the ones specified (see examples below).
If an InputPort shadows another, its shadow_inputs attribute identifies the InputPort
that it shadows.
Note
Only InputPorts belonging to Mechanisms in the same Composition, or ones that are INPUTNodes of a nested can be specified for shadowing. Note also that
any Node that shadows an INPUTNode of the Composition to which it
belongs is itself also assigned the role of INPUT Node.
Hint
If an InputPort needs to be shadowed that belongs to a Mechanism in a nested that is
not an INPUTNode of that Composition, this can be accomplished in
one of two ways: 1) by assigning it INPUT as a required NodeRole where it is added to the nested Composition; and/or 2) by doing the
following: a) add a Mechanism to the nested Composition with an InputPort that shadows the one to be
shadowed; b) specify INPUT in the required_roles argument of the Composition’s
Composition.add_node method used to add that Mechanism to the Composition; c) use that Mechanism as the
InputPort specification for the shadowing InputPort.
Examples of InputPort Shadowing
Simple case of shadowing. The figure above shows a simple case in which ShadowingMech is configured
to shadow the input to ShadowedMech, as specified below:¶
Shadowing a nested Mechanism. This example shows a Composition in which the InputPort of
shadowing_mech is configured to shadow the input to mech in nested_comp. Accordingly
shadowing_mech receives a Projection from the same Port of outer_comp’s input_CIM as the input_CIM of nested_comp that projects to
mech. As a result, shadowing_mech will receive the same input as mech when outer_comp
is executed (as noted above, only the INPUTNodes of a nested Composition can be shadowed):¶
InputPort variable: Compatibility and Constraints¶
The variable of an InputPort must be compatible with the item of its owner Mechanism’s
variable to which it is assigned (see Mechanism).
This may have consequences that must be taken into account when specifying an InputPort by Components that project
to it. These depend on the context in which the specification is made,
and possibly the value of other specifications. These considerations and how they are handled are described below,
starting with constraints that are given the highest precedence:
default_variable argument for the Mechanism is also specified – the item of the variable to which the
InputPort is assigned is used to determine the InputPort’s variablemust. Any other specifications of the InputPort relevant to its variable
must be compatible with this (for example, specifying it by value or by a
MappingProjection or OutputPort that projects to it (see above).
More than one Component is specified with the same `value` format – that format is used to determine
the format of the InputPort’s variable.
More than one Component is specified with different `value` formats – the InputPort’s variable is determined by item of the default variable for
the class of its owner Mechanism.
A single Component is specified – its value is used to determine the format of the InputPort’s
variable; if the Component is a(n):
MappingProjection – can be specified by its class, an existing MappingProjection, or a matrix:
Existing MappingProjection – then its value determines the
InputPort’s variable.
Matrix specification – its receiver dimensionality determines the
format of the InputPort’s variable. For a standard 2d “weight” matrix (i.e., one that
maps a 1d array from its sender to a 1d array of its receiver), the receiver dimensionality is its outer dimension (axis 1, or its number of
columns). However, if the sender has more than one dimension, then the
dimensionality of the receiver (used for the InputPort’s variable) is the
dimensionality of the matrix minus the dimensionality of the sender’s value
(see matrixdimensionality).
OutputPort or ProcessingMechanism – the value of the OutputPort (if it is a
Mechanism, then its primary OutputPort) determines the format of the InputPort’s
variable, and a MappingProjection is created from the OutputPort to the InputPort
using an IDENTITY_MATRIX. If the InputPort’s variable is constrained (as in some
of the cases above), then a FULL_CONNECTIVITY_MATRIX is used which maps the shape of the OutputPort’s value to that of the InputPort’s variable.
GatingProjection, GatingSignal or GatingMechanism – any of these can be used to specify an InputPort;
their value does not need to be compatible with the InputPort’s variable, however
it does have to be compatible with the modulatory parameter of the InputPort’s
function.
Every InputPort is owned by a Mechanism. It can receive one or more MappingProjections from other Mechanisms or itself (e.g., RecurrentTransferMechanism), as well as from the
Composition to which its owner belongs (if it is the ORIGIN Mechanism for that Process or System). It has the
following attributes, that includes ones specific to, and that can be used to customize the InputPort:
mod_afferents – GatingProjections that project to the
InputPort, the value of which can modify the InputPort’s value
(see the descriptions of Modulation under ModulatorySignals and GatingSignals for additional details). If the InputPort receives more than one GatingProjection,
their values are combined before they are used to modify the value of InputPort.
variable – serves as the template for the value of the
Projections received by the InputPort: each must be compatible with (that is, match both the
number and type of elements of) the InputPort’s variable (see matrix
for additional details). In general, this must also be compatible with the item of the owner Mechanism’s variable to which the InputPort is assigned (see above and
Mechanism InputPort specification). The InputPort’s variable is composed of the concatenated values of its path_afferent Projections. If it has none, then the variable is either assigned
None or its default value, as determined by its default_input
setting.
function – combines the value of all of the path_afferentProjections received by the InputPort, and assigns the result to the
InputPort’s value attribute. The default function is LinearCombination that performs an
elementwise (Hadamard) sum of the afferent values. However, the parameters of the function
– and thus the value of the InputPort – can be modified by any GatingProjections received by the InputPort (listed in its mod_afferents attribute.
A custom function can also be specified, so long as it generates a result that is compatible with the item of the
Mechanism’s variable to which the InputPort is assigned.
weight and exponent – these can be used by the Mechanism to which the
InputPort belongs when that combines the values of its Ports (e.g., an ObjectiveMechanism
uses the weights and exponents assigned to its InputPorts to determine how the values it monitors are combined by
its function). The value of each must be an integer or float, and the default is 1 for both.
An InputPort cannot be executed directly. It is executed when the Mechanism to which it belongs is executed.
When this occurs, the InputPort executes any Projections it receives, calls its function to combine the values received from any MappingProjections it receives
(listed in its its path_afferents attribute) and modulate them in response to any
GatingProjections (listed in its mod_afferents attribute),
and then assigns the result to the InputPort’s value attribute. This, in turn, is assigned to
the item of the Mechanism’s variable and input_values
attributes corresponding to that InputPort (see Mechanism Variable and InputPorts
for additional details). If an InputPort does not have any path_afferentProjections,
by default its value is set to None which, when executed, generates an error; however, if its default_input attribute is DEFAULT_VARIABLE, then the default value for the
InputPort’s variable is used as its value (see default_input for
additional details).
reference_value (number, list or np.ndarray) – the value of the item of the owner Mechanism’s variable attribute to which
the InputPort is assigned; used as the template for the InputPort’s value attribute.
default_input (None or DEFAULT_VARIABLE : default None) – specifies value to use as variable if the InputPort has no path_afferentProjections. If None (the default), then None is returned; otherwise the default value for the InputPort’s variable is used (see default_input for additional details).
variable (number, list or np.ndarray) – specifies the shape of the InputPort’s variable, which may be used to define the
shape of the matrix parameter of the MappingProjection that projects to the
Inputport (see variable for additional details).
function (Function or method : default LinearCombination(operation=SUM)) – specifies the function applied to the variable. The default value combines the values of the Projections received by the InputPort. Any function
can be assigned, however: a) it must produce a result that has the same format (number and type of elements)
as the item of its owner Mechanism’s variable to which the InputPort has been
assigned; b) if it is not a TransformFunction, it may produce unpredictable results if the InputPort
receives more than one Projection (see function.
combine (SUM or PRODUCT : default None) – specifies the operation argument used by the default LinearCombination function, which determines how
the value of the InputPort’s projections are combined.
This is a convenience argument, that allows the operation to be specified without having to specify the
LinearCombination function; it assumes that LinearCombination (the default) is used as the InputPort’s function
– if it conflicts with a specification of function an error is generated.
the template for the value of each Projection that the InputPort receives,
each of which must match the format (number and types of elements) of the InputPort’s
variable. If neither the variable or input_shapes argument is specified, and
projections is specified, then variable is assigned the value of the Projection(s) or its sender.
determines the value used as variable if the InputPort has no path_afferentProjections. If None (the default), then None is used. This is the
default behavior, as it is useful for identifying “orphaned” InputPorts (i.e., ones that do not receive
any inputs) and the Mechanisms to which they belong, as an error is returned if an InputPort
is executed and its variable is assigned None. If default_input is assigned DEFAULT_VARIABLE, then the
default value for the InputPort’s variable is used as its value.
This is useful for assignment to a Mechanism that needs a constant (i.e., fixed value) as the input to its
function (such as a bias unit in an
AutodiffComposition).
Note
If default_input is assigned DEFAULT_VARIABLE, then its internal_only attribute is automatically assigned True. This is so that if the Mechanism
to which the InputPort belongs is assigned to a Composition, it is not treated as an INPUTNode of that Composition (and automatically assigned a Projection
from its input_CIM.
if it is a TransformFunction, it combines the values of
the PathwayProjections (e.g., MappingProjections) received by the
InputPort (listed in its path_afferents attribute), under the possible
influence of GatingProjections received by the InputPort (listed in its mod_afferents attribute). The result is assigned to the InputPort’s value
attribute. For example, the the default (LinearCombination with SUM as it operation) performs an
element-wise (Hadamard) sum of its Projection values, and assigns to value an array that is of the same length as each of the Projection values. If the InputPort receives only one Projection, then any other function can be
applied and it will generate a value that is the same length as the Projection’s value. However, if the InputPort receives more than one Projection and
uses a function other than a TransformFunction, a warning is generated and only the value of the first Projection listed in path_afferents
is used by the function, which may generate unexpected results when executing the Mechanism or Composition
to which it belongs.
the string label that represents the current value of the InputPort, according to the
owner mechanism’s input_labels_dict. If the current value
of the InputPort does not have a corresponding label, then the numeric value is returned.
determines whether input from a Composition must be specified for this
InputPort from a Composition’s execution method if the InputPort’s owner is an INPUTNode of that Composition; if True, external input is
not required or allowed.
the name of the InputPort; if it is not specified in the name argument of the constructor, a default is
assigned by the InputPortRegistry of the Mechanism to which the InputPort belongs. Note that some Mechanisms
automatically create one or more non-default InputPorts, that have pre-specified names. However, if any
InputPorts are specified in the input_ports argument of the Mechanism’s constructor, those replace those
InputPorts (see note), and standard naming conventions apply to the InputPorts specified, as well as any that are added to the Mechanism once it
is created (see note).
Check if projection is redundant with one in path_afferents of InputPort
Check for any instantiated projection in path_afferents with the same sender as projection
or one in deferred_init status with sender specification that is the same type as projection.
Returns redundant Projection if found, otherwise False.
If variable is None there are no active PathwayProjections in the Composition being run,
return None so that it is ignored in execute method (i.e., not combined with base_value)
Parse any InputPort-specific specifications, including SIZE, COMBINE, WEIGHTS and EXPONENTS
Get SIZE and/or COMBINE specification in if port_specific_spec is a dict
Get weights, exponents and/or any connections specified if port_specific_spec is a tuple
Tuple specification can be:
Put InputPort’s variable in a list if its function is LinearCombination and variable is >=2d
InputPort variable must be embedded in a list so that LinearCombination (its default function)
returns a variable that is >=2d intact (rather than as arrays to be combined);
this is normally done in port._update() (and in Port._instantiate-function), but that
can’t be called by _parse_port_spec since the InputPort itself may not yet have been instantiated.