Skip to main content

Types of SST elements

In SST, Elements are individual building blocks that make up not only simulated systems, but can also add functionality to SST-Core. Elements are dynamically loaded at runtime for highly customized simulations.

Simulation Elements

These are types of Elements typically used to model systems in simulation.

Component

The fundamental simulation element is the Component. A Component is a model of a particular piece of the simulated system. Parallel simulations partition the simulated system at the Component level. For example, a Component might model router, a cache, or a processor core. Components may only interact with other Components via SST Events. Internally, a Component is for the most part, free to operate as it chooses.

SubComponent

SubComponents can be dynamically loaded into a Component or another SubComponent to provide modular flexibility within Components. For example, a router Component might load a SubComponent to manage arbitration. Other than always belonging to a Component, SubComponents are similar to Components with a nearly identical API (e.g., support for Clocks, Statistics, etc.). Because SubComponents are part of a Component, they may interact with the Component and other SubComponents in the same Component tree via function calls and shared state.

SST supports two flavors of SubComponent: user-defined and anonymous. User-defined SubComponents are declared explicitly in an SST input file, similar to the way Components are. As a result, user-defined SubComponents can provide their own ports and connect to other components via SST Links. Anonymous SubComponents on the other hand, are loaded internally by a (Sub)Component. Any user-level control of an anonymous SubComponent is done through parameters to the loading component. Anonymous SubComponents are not visible to the SST graph builder and so they cannot have their own ports into the SST graph. They can however, use ports that belong to their parent component.

ComponentExtension

A ComponentExtension is loaded into a Component or SubComponent. It is used to statically break up the functionality of a Component into multiple classes while allowing all classes equal access to the SST Component APIs. It is not neccessary for every class belonging to a Component to be a ComponentExtension, however it can be useful if the class needs access to Statistics, register its own Clocks, etc. Thus, in contrast to SubComponents which provide runtime flexibility, ComponentExtensions support code organization. For example, if your Component is a multi-core CPU, it may be more maintainable to model each individual core in a ComponentExtension. Each core may load its own clock, manage its own events, etc., as part of the larger multi-core Component.

Module

A Module is similar to a SubComponent but it has almost no available SST API. Think of it as a very lightweight subcomponent. Modules are used for small pieces of functionality such as providing a mechanism for dynamically loading a hashing algorithm. They cannot register Clocks, send Events, query SST for simulated time, register Statistics, etc.

PortModule

A PortModule is like a SubComponent but instead of loading into a Component, it loads onto a port. The PortModule is invoked automatically whenever an SST Event is sent or received through a port. PortModules can monitor, modify, and even delete Events.

Deciding which element type to use

Deciding how to map a simulated system into a graph of Components, SubComponents, and other elements requires considering the performance tradeoffs of each and deciding what makes sense for the system to be simulated. Consider the following:

  1. Partitioning parallel simulations is done at Component granularity.
  2. Components may only interact with other Components by sending Events.
  3. SubComponents have almost the same memory overhead as a Component. If SST APIs are not needed and memory footprint is a concern, consider using a Module.
  4. Loading a PortModule onto the send side of a link (i.e., monitoring outgoing Events) causes known performance degradations. Consider monitoring Events from the receive side of a link or from within a (Sub)Component instead.
  5. If Components are too large, SST may not be able to sufficiently parallelize. If Components are too small, the overhead of interacting via Events may become too high.
  6. Events sent between Component trees always incur simulated latency. Zero-latency exchanges can only be done within a Component tree.

SST-Core Elements

SST-Core also uses Elements to enable runtime flexibility and extensibility for certain functionality. While SST-Core provides a set of default elements for each type, Element libraries can augment these by providing their own and having SST-Core load them at runtime. The set of available SST-Core elements provided with SST can be viewed using $sst-info sst.

Partitioner

Partitioners are used by SST to partition the simulation graph into ranks and/or threads. Built-in partitioners include linear, round-robin, serial, a simple partitioning scheme that cuts on high-latency links, and a self-partitioner which allows the SST input file to specify partitioning.

Statistic

A Statistic object collects information given to it. Built-in types include accumulator, unique count, and histogram. New types can be registered to allow custom data collection.

StatisticOutput

A StatisticOutput object iterates over the list of statistics registered to it and generates an output. Built-in output types include text file, console/stdout, CSV, JSON, and HDF5. Additional StatisticOutput types can be registered to provide statistics in the preferred format.

ProfileTool

SST has a generic "AttachPoint" concept which is a place in SST-Core where certain types of elements may attach for the purpose of profiling or modifying simulation. A ProfileTool is one such element type (along with PortModules and WatchPoints) and it attaches to ProfilePoints or AttachPoints designed for profiling. ProfilePoints for clock handlers, event handlers, and sync operations are available and Components may also expose their own. A ProfileTool attaches to one of these points and is called each time the handler or sync operation is executed. A ProfileTool could measure time spent in SST synchronization for example, or count how many times a handler is invoked.

RealTimeAction

RealTimeActions are actions that can be attached to signal handlers as well as invoked at a regular real (wall) time interval. Elements can provide custom RealTimeActions to do things like introspect simulation state and trigger checkpoints. See Signal Handling for more information.

InteractiveConsole

An InteractiveConsole is an API allowing an external "console" to stop simulation and introspect state. Consoles register with WatchPoints which are specific places in an SST simulation where they are to be triggered. A WatchPoint is a variable together with a condition for triggering entry into an InteractiveConsole. The InteractiveConsole API is new and evolving with an intention to stabilize it before SST 16.0.

Creating custom elements

To create a custom element, define a class that inherits from the element API and declare the appropriate ELI (Element Library Info) macros. Compile your element(s) into a dynamic library and register the library with SST-core using sst-register.

Using custom elements

Anywhere an SST element type is used (lib.elementname), a custom type can be substituted. For example, SST input/configuration files often contain Components, SubComponents, Statistics, PortModules, and StatisticOutputs. Components directly load anonymous SubComponents and Modules by type. And several SST command line options accept an element type to do things like attach ProfileTools, InteractiveConsoles, and RealTimeActions.