lava.magma.core.process

lava.magma.core.process.connection

Inheritance diagram of lava.magma.core.process.connection
class lava.magma.core.process.connection.LearningConnectionProcess(shape=(1, 1), learning_rule=None, **kwargs)

Bases: AbstractProcess

Base class for connection Processes.

This base class holds all necessary Vars, Ports and functionality for online learning in fixed and floating point simulations.

s_in_bap

Input port to receive back-propagating action potentials (BAP)

Type

InPort

x0

Conditional for pre-synaptic spike times (is 1 if pre-synaptic neurons spiked in this time-step).

Type

Var

tx

Within-epoch spike times of pre-synaptic neurons.

Type

Var

x1

First pre-synaptic trace.

Type

Var

x2

Second pre-synaptic trace.

Type

Var

y0

Conditional for post-synaptic spike times (is 1 if post-synaptic neurons spiked in this time-step).

Type

Var

ty

Within-epoch spike times of post-synaptic neurons.

Type

Var

y1

First post-synaptic trace.

Type

Var

y2

Second post-synaptic trace.

Type

Var

y3

Third post-synaptic trace.

Type

Var

tag_1

Tag synaptic variable

Type

Var

tag_2

Delay synaptic variable

Type

Var

Parameters
  • shape (tuple, ndarray) – Shape of the connection in format (post, pre) order.

  • learning_rule (LoihiLearningRule) – Learning rule which determines the parameters for online learning.

lava.magma.core.process.interfaces

Inheritance diagram of lava.magma.core.process.interfaces
class lava.magma.core.process.interfaces.AbstractProcessMember(shape)

Bases: ABC

A member of a process has a reference to its parent process, a name and a shape because it is generally tensor-valued.

property name: str

Returns name of ProcessMember.

Return type

str

property process: AbstractProcess

Returns parent process of ProcessMember.

Return type

AbstractProcess

property size: int

Returns the size of the tensor-valued ProcessMember which is the product of all elements of its shape.

Return type

int

class lava.magma.core.process.interfaces.IdGeneratorSingleton

Bases: ABC

A singleton class that generates globally unique ids to distinguish other unique objects.

get_next_id()

Returns next id.

Return type

int

classmethod reset_singleton()

Resets singleton.

lava.magma.core.process.message_interface_enum

Inheritance diagram of lava.magma.core.process.message_interface_enum
class lava.magma.core.process.message_interface_enum.ActorType(value)

Bases: IntEnum

An enumeration.

MultiProcessing = 0

lava.magma.core.process.neuron

Inheritance diagram of lava.magma.core.process.neuron
class lava.magma.core.process.neuron.LearningNeuronProcess(shape, learning_rule, *args, **kwargs)

Bases: object

Base class for plastic neuron processes.

This base class holds all necessary Vars, Ports and functionality for online learning in fixed and floating point simulations.

Parameters
  • shape (tuple:) – Shape of the neuron process.

  • learning_rule (LoihiLearningRule) – Learning rule which determines the parameters for online learning.

lava.magma.core.process.process

Inheritance diagram of lava.magma.core.process.process
class lava.magma.core.process.process.AbstractProcess(**proc_params)

Bases: object

The notion of a Process is inspired by the Communicating Sequential Process paradigm for distributed, parallel, and asynchronous programming.

A Process represents the fundamental computational unit of the Lava framework. Processes are independent from each other in that they primarily operate on their own local memory while communication with other Processes happens via message passing through channels at runtime. This makes parallel processing safe against side effects from shared-memory interaction. Nevertheless, shared-memory interaction between Processes is also supported. Lava Processes are built for executing on a distributed and heterogeneous hardware platform consisting of different compute resources. Compute resources can be conventional CPUs, GPUs, embedded CPUs, or neuromorphic cores.

Lava Processes consist of the following key components:

  1. State: A Lava Process has internal state that is realized through Lava Vars (variables). Vars can be initialized by the user and are mutable during execution either as a result of Process code or user interaction.

  2. Ports: Lava Processes communicate with their environment or other Processes solely via messages. Messages are sent between ports via channels. Processes may have one or more input, output, or reference ports.

    • OutPorts can only be connected to one or more InPorts and communication is uni-directional.

    • InPorts can receive inputs from one or more OutPorts.

    • RefPorts can be connected to Vars of remote Processes and allow the Process with the RefPort to access another Process’ internal state directly and bi-directionally. This type of shared-memory interaction is potentially unsafe and should be used with caution!

  3. API: A Lava Process can expose a public API to configure it or interact with it at setup or during execution interactively. In general, the public state Vars can be considered part of a Process’ API.

Crucially, the behavior of a Process is not specified by the Process itself but by separate ProcessModels that implement the behavior of a Process at different levels of abstraction, in different programming languages, and for different compute resources, such as CPUs or neuromorphic cores. A single Process can support multiple ProcessModels of the same type or of different types. Please refer to the documentation of AbstractProcessModel for more details.

Developers creating new Processes need to inherit from the AbstractProcess interface. Any internal Vars or Ports must be initialized within its init method:

>>> class NewProcess(AbstractProcess):
>>>     def __init__(self, shape, name):
>>>         super().__init__(shape=shape, name=name)
>>>         self.var1 = Var(shape=shape)
>>>         self.in_port1 = InPort(shape=shape)
>>>         self.out_port1 = OutPort(shape=shape)
>>>         ...

Vars should only be used for dynamic state parameters that play a role in the behavioral model of the Process or for static configuration parameters that affect the behavior of the Process (e.g., the membrane potential of a LIF neuron). Meta parameters that are only needed for communicating information between the Process and its ProcessModels (e.g., shape) should not become a Var. They should be passed to the Process as keyword arguments and then need to be passed to the __init__ method of AbstractProcess, as is done with ‘shape’ and ‘name’ in the example above. All such keyword arguments are stored in the member ‘proc_params’, which is passed on to all ProcessModels of the Process.

Vars can be initialized with user-provided values and Processes can be connected to other Processes via their ports: ` p1 = NewProcess(<in_args>) p2 = NewProcess(<in_args>) p1.out_port1.connect(p2.in_port1) ` For more information on connecting Processes, see the documentation of InPort, OutPort, and RefPort.

Once a concrete Process has been created and connected with other Processes it needs to be compiled before it is ready for execution. A Process is compiled by the Lava Compiler while execution is controlled by the Lava Runtime. While the Lava Compiler and Runtime can be created manually to compile and run a Process, the AbstractProcess interface provides short-hand methods to compile and run a Process without interacting with the compiler or runtime directly. In particular running an uncompiled Process will compile a Process automatically. Since all Processes created in a session usually form a system, calling ‘compile(..)’ or ‘run(..)’ on any of them compiles and runs all of them automatically.

At compile time, the user must provide the Lava Compiler with a specific instance of a RunConfig class. A RunConfig class represents a set of rules that allows the compiler to select one and only one ProcessModel of a specific Process to be compiled for execution with specific compute resources. See the documentation on RunConfigs for more information how to create and customize such RunConfigs.

Finally, in order to run a Process, a RunCondition must be provided. A RunCondition such as ‘RunSteps’ or ‘RunContinuous’ specifies until when a Process should be executed.

Since Processes generally run asynchronously and in parallel, the execution of a set of Processes can either be paused or stopped by calling the corresponding ‘pause()’ or ‘stop()’ methods.

In order to save time setting up Processes for future use, Processes can also be saved and reloaded from disk.

Parameters
  • proc_params – Any keyword arguments that get passed from child Processes will be stored in the AbstractProcess member ‘proc_params’ and passed to all ProcessModels. ‘proc_params’ can be further added to or modified in order to pass parameters to ProcessModels that are not represented by dynamic state variables (Vars) of the Process.

  • name (str, optional) – Name of the Process. Default is ‘Process_ID’, where ID is an integer value that is determined automatically.

  • log_config (LogConfig, optional) – Configuration options for logging.

__del__()

On destruction, terminate Runtime automatically to free compute resources.

compile(run_cfg, compile_config=None)

Compiles this and any process connected to this process and returns the resulting Executable that can either be serialized or passed to Runtime.

Parameters
  • run_cfg (RunConfig) – Used by the compiler to select a ProcessModel for each Process.

  • compile_config (Dict[str, Any], optional) – Configuration options for the Compiler and SubCompilers.

Return type

Executable

property is_compiled

Returns True if process has been compiled.

is_sub_proc_of(proc)

Returns True, is this Process is a sub process of ‘proc’.

load(path)

Loads and de-serializes Process from disk.

property model: AbstractProcessModel

Return model

Return type

AbstractProcessModel

property model_class: Type[AbstractProcessModel]

Return model class

Return type

Type[AbstractProcessModel]

pause()

Pauses process execution while running in non-blocking mode.

register_sub_procs(procs)

Registers other processes as sub processes of this process.

run(condition, run_cfg=None, compile_config=None)

Executes this and any connected Processes that form a Process network. If any Process has not been compiled, it is automatically compiled before execution.

When RunConfig.blocking is True, the Processes are executed for as long as the RunCondition is satisfied. Otherwise, the method run() returns immediately while the Processes are executed. In this case, the methods wait(), pause(), and stop() can be used to interact with the Runtime:

  • wait() blocks execution for as long as the RunCondition is satisfied.

  • pause() pauses execution as soon as possible and returns control back to the user.

  • stop() terminates execution and releases control of all involved compute nodes.

If a run has been suspended by either pause() or a RunCondition being no longer satisfied, run() can be called again to resume execution from the current state.

Parameters
  • condition (AbstractRunCondition) – Specifies for how long to run the Process.

  • run_cfg (RunConfig, optional) – Used by the compiler to select a ProcessModel for each Process. Must be provided when Processes have to be compiled, can be omitted otherwise.

  • compile_config (Dict[str, Any], optional) – Configuration options for the Compiler and SubCompilers.

property runtime

Returns current Runtime or None if no Runtime exists.

save(path)

Serializes and saves Process in current stage to disk. Serialization at different levels will be possible: After partitioning, after mapping, …

stop()

Terminates process execution by releasing all allocated compute nodes.

validate_var_aliases()

Validates that any aliased Var is a member of a Process that is a strict sub-Process of this Var’s Process.

wait()

Waits until end of process execution or for as long as RunCondition is met by blocking execution at command line level.

class lava.magma.core.process.process.Collection(process, name)

Bases: object

Represents a collection of objects. Member objects can be accessed via dot-notation (SomeCollection.some_object_name). Collection also offers an iterator to iterate all member objects.

Parameters
  • process (AbstractProcess) – Parent Process that holds the Collection

  • name (str) – Name of the Collection

add_members(members)

Adds members to a Collection.

Parameters

members (Dict[str, mem_type]) – Dictionary of Collection members, where the key is the string name of the member and the value is the member.

has(obj)

Returns True if member is in collection.

Return type

bool

is_empty()

Returns True if Collection has no members.

Return type

bool

mem_type

alias of Union[InPort, OutPort, RefPort, VarPort, Var, AbstractProcess]

property member_names: List[str]

Returns the names of Collection members.

Return type

List[str]

property members: ty.List[mem_type]

Returns the members of the Collection.

Return type

ty.List[mem_type]

class lava.magma.core.process.process.LogConfig(file='', level=30, level_console=40, logs_to_file=False, format='%(asctime)s:%(levelname)s: %(name)s - %(message)s', date_format='%m/%d/%Y %I:%M:%S%p')

Bases: object

Configuration options for logging that can be passed into a Process.

date_format: str = '%m/%d/%Y %I:%M:%S%p'
file: str = ''
format: str = '%(asctime)s:%(levelname)s: %(name)s - %(message)s'
level: int = 30
level_console: int = 40
logs_to_file: bool = False
class lava.magma.core.process.process.ProcessParameters(initial_parameters)

Bases: object

Wrapper around a dictionary that is used to pass parameters from a Process to its ProcessModels. The dictionary can be filled with an initial dictionary of parameters. Any further changes via the __setitem__ method may not overwrite existing values. To overwrite a value, use the method overwrite().

Parameters

initial_parameters (Dict[str, Any]) – Initial dictionary of parameters for a Process/ProcessModel.

get(key, default=None)
overwrite(key, value)

Sets a key-value pair without checking whether the key is already present in ProcessParameters.

Return type

None

class lava.magma.core.process.process.ProcessPostInitCaller

Bases: type

Metaclass for AbstractProcess that overwrites __call__() in order to call _post_init() initializer method after __init__() of any sub class is called.

class lava.magma.core.process.process.ProcessServer

Bases: IdGeneratorSingleton

ProcessServer singleton keeps track of all existing processes and issues new globally unique process ids.

instance: Optional[ProcessServer] = None
is_not_initialized: bool = True
property num_processes

Returns number of processes created so far.

register(process)

Registers a process with ProcessServer.

Return type

int

reset_server()

Resets the ProcessServer to initial state.

lava.magma.core.process.variable

Inheritance diagram of lava.magma.core.process.variable
class lava.magma.core.process.variable.Var(shape, init=0, shareable=True)

Bases: AbstractProcessMember

Represents a Lava variable. A Var implements the state of a Process and is part of its public user interface. Vars have the following properties:

  • Vars are numeric objects: Typically vars represent ints, float data types.

  • Vars are tensor-valued: In general Vars represent multiple numeric values not just scalar objects with a shape.

  • Vars can be initialized with numeric objects with a dimensionality equal or less than specified by its shape. The initial value will be broadcast to the shape of the Var at compile time.

  • Vars have a name: The Variable name will be assigned by the parent process of a Var.

  • Vars are mutable at runtime.

  • Vars are owned by a Process but shared-memory access by other Process is possible though should be used with caution.

How to enable interactive Var access?

>>> Executable ----------
>>>                     |
>>> Var -> Process -> Runtime -> RuntimeService -> ProcModel -> Var
  • Var can access Runtime via parent Process.

  • The compiler could have prepared the Executable with mapping information where each Var of a Process got mapped to. I.e. these can just be the former ExecVars. So the ExecVars are just stored inside the Executable.

  • Alternatively, the Executable stores a map from var_id -> ExecVar

alias(other_var)

Establishes an ‘alias’ relationship between this and ‘other_var’. The other Var must be a member of a strict sub processes of this Var’s parent process which might be instantiated within a SubProcessModel that implements this Var’s parent process. Both, this and ‘other_var’ must have the same ‘shape’ and be both ‘shareable’ or not.

:param : param other_var: The other Var that this Var is an alias for. :param Calls to Var.set: :type Calls to Var.set: ..) or Var.get( :param Var.:

get(idx=None)

Gets and returns value of Var. If this Var aliases another Var, then get() is delegated to aliased Var.

Return type

ndarray

property model

Return model.

set(value, idx=None)

Sets value of Var. If this Var aliases another Var, then set(..) is delegated to aliased Var.

validate_alias()

Validates that any aliased Var is a member of a Process that is a strict sub-Process of this Var’s Process.

class lava.magma.core.process.variable.VarServer

Bases: IdGeneratorSingleton

VarServer singleton keeps track of all existing Vars and issues new globally unique Var ids.

instance: Optional[VarServer] = None
is_not_initialized: bool = True
property num_vars

Returns number of vars created so far.

register(var)

Registers a Var with VarServer.

Return type

int

reset_server()

Resets the VarServer to initial state.