Core API Reference (sanafe)

This page contains the core API documentation for SANA-FE.

Quickstart

import sanafe

# Examples of architectures and applications
example_arch, example_snn = sanafe.load_example()
loihi_arch = sanafe.load_loihi()  # Intel's Loihi 1 chip
truenorth_arch = sanafe.load_truenorth()  # IBM's TrueNorth chip

# Introspecting architectural features
print(example_arch)
print(example_arch.tiles)
print(example_arch.cores())
print(example_arch.tiles[0].cores)
print(example_arch.tiles[1].cores[0].pipeline_hw)

# Introspecting SNN features
print(example_snn)
print(example_snn.groups)
print(example_snn.groups["out"].neurons)

# Creating a SNN programmatically via the SANA-FE API
python_snn = sanafe.Network()
python_snn.create_neuron_group("foo", 2)
python_snn.create_neuron_group("bar", 3, model_attributes={"bias": 0})
src, dst = python_snn.groups["foo"][0], python_snn.groups["bar"][1]
src.connect_to_neuron(dst, {"weight": 2.5})
# Attributes can be set, using either a small subset of simulator built-in
#  attributes (e.g. log_spikes), or arbitrary model-defined attributes.
python_snn.groups["bar"].neurons[0].set_attributes(
    log_spikes=True, model_attributes={"bias": 0.5})

# Mapping neurons to h/w
for n in python_snn.groups["foo"]:
    n.map_to_core(example_arch.tiles[0].cores[0])
for n in python_snn.groups["bar"]:
    n.map_to_core(example_arch.tiles[0].cores[1])
# Neurons and edges can be mapped to specific h/w pipeline units. Unit names
#  much match exactly with the corresponding pipeline unit in the
#  architecture. If not provided, SANA-FE defaults by mapping to the first
#  defined synapse/dendrite/soma unit.
python_snn.groups["foo"].neurons[0].set_attributes(soma_hw_name="demo_soma_alt")
python_snn.groups["foo"].neurons[1].set_attributes(soma_hw_name="demo_input[1]")

# Creating a spiking chip for simulation based on a provided arch and SNN
chip = sanafe.SpikingChip(example_arch)
chip.load(example_snn)
chip.load(python_snn)  # Reprogram with a new SNN
import json
# Get a complete view and specification of the chip hardware, including all
#  its pipeline h/w and supported attributes
print(json.dumps(chip.describe(), indent=1))

# Running and dynamically controlling a simulation
results = chip.sim(2)
print(results)
# SANA-FE supports multiple ways of providing trace output, including as a
#  Python object, default generated CSV files, or via file handles
with open("message_file.csv", "w") as message_handle:
    chip.sim(3, spike_trace=True,
            potential_trace="potential_file.csv",
            message_trace=message_handle,
            processing_threads=2,
            scheduler_threads=1)
chip.reset()
# Mapped neurons can also be reprogrammed on the fly e.g., for dynamic inputs
mapped_input_neurons = chip.mapped_neuron_groups["foo"]
mapped_input_neurons[0].set_attributes(model_attributes={"rate": 0.5})
chip.sim(1)

Core Classes

SpikingChip

class sanafe.SpikingChip

Bases: pybind11_object

Simulated spiking chip executing a mapped SNN.

SpikingChip combines an Architecture with a mapped Network to provide functional simulation with detailed energy and performance analysis. You create a SpikingChip from an abstract Architecture object, and then load your mapped Network application. Finally, you simulate the chip for one or more steps, optionally with trace outputs.

Example

>>> chip = sanafe.SpikingChip(arch)
>>> chip.load(network)
>>> results = chip.sim(timesteps=100)
__init__(self: sanafecpp.SpikingChip, arch: sanafecpp.Architecture) None
describe(self: sanafecpp.SpikingChip) dict

Enumerate the full chip structure – every tile, core, pipeline unit, and the attributes each unit supports – as a nested dictionary.

get_power(self: sanafecpp.SpikingChip) float

Calculate average power consumption based on simulation results.

Returns:

Average power in Watts (total_energy / sim_time)

Return type:

float

load(self: sanafecpp.SpikingChip, net: sanafecpp.Network, overwrite: bool = True) None

Map a neural network onto this chip’s hardware architecture.

Parameters:
  • network (Network) – Spiking network to map onto hardware

  • overwrite (bool, optional) – Overwrite programmed spiking network. Default is True.

Raises:

HardwareMappingError – If the network cannot be mapped to the architecture. This may occur if a neuron was never assigned to a core, if a required hardware unit (soma, synapse, or dendrite) is not supported by the target architecture, or if a model attribute is incompatible with the specified hardware. The exception message describes which mapping constraint was violated.

property mapped_neuron_groups
reset(self: sanafecpp.SpikingChip) None

Reset all neuron states and hardware buffers to initial conditions.

sim(self: sanafecpp.SpikingChip, timesteps: SupportsInt | SupportsIndex = 1, timing_model: str = 'detailed', processing_threads: SupportsInt | SupportsIndex = 0, scheduler_threads: SupportsInt | SupportsIndex = 0, spike_trace: object = None, potential_trace: object = None, neuron_trace: object = None, perf_trace: object = None, message_trace: object = None, write_trace_headers: bool = True) dict

Execute neuromorphic simulation for specified timesteps.

Parameters:
  • timesteps (int, optional) – Number of simulation timesteps

  • timing_model (str, optional) – Timing model (“simple”, “detailed”, “cycle”). Default is “detailed”.

  • processing_threads (int, optional) – Number of processing threads. Default is 0 (automatically detect threads).

  • scheduler_threads (int, optional) – Number of scheduler threads. Default is 0 (run in main thread).

  • spike_trace (object, optional) – Spike trace output (file, string, True, or None). Default is None.

  • potential_trace (object, optional) – Potential trace output (file, string, True, or None). Default is None.

  • neuron_trace (object, optional) – Neuron state trace output (file, string, True, or None). Default is None.

  • perf_trace (object, optional) – Performance metrics trace output (file, string, True, or None). Default is None.

  • message_trace (object, optional) – Message trace output (file, string, True, or None). Default is None.

  • write_trace_headers (bool, optional) – Write CSV headers to trace files. Default is True.

Returns:

Simulation results including energy, timing, and trace data.
  • timesteps_executed (int): Number of timesteps simulated.

  • energy (float): Energy breakdown by component.

  • sim_time (float): Simulated hardware time (seconds).

  • spikes (int): Total spike count.

  • spike_trace (list[list[NeuronAddress]]): A list of length <timesteps_executed> where each element is a list of the spiking MappedNeuron objects (if enabled).

  • potential_trace (list[list[float]]): A 2D array of probed neuron potentials (if enabled).

  • neuron_trace (dict[str, list[list]]): A dictionary of neuron traces, where each entry is a 2D array, i.e., a list of length <timesteps_executed> which elements are a list of per-neuron values (if enabled).

  • perf_trace (dict[str, list]): A dict of H/W performance metrics indexed by statistic name and containing lists of length <timesteps_executed> (if enabled).

  • message_trace (list[list[dict]]): A list of length <timesteps_executed>, where each time-step has a list of dictionaries, one per message (if enabled).

Return type:

dict

Example

>>> results = chip.sim(timesteps=1000, spike_trace=True, perf_trace=True)
>>> print(f"Total energy: {results['energy']['total']:.2e} J")
>>> print(f"Spike count: {results['spikes']}")
class sanafe.MappedNeuron

Bases: pybind11_object

A spiking neuron that has been mapped to neuromorphic hardware.

Once a Neuron object is mapped to hardware, it becomes a MappedNeuron. This means it has been mapped to a specific core within a network tile, and is assigned to specific hardware units. MappedNeuron objects can be used to access the state of a neuron during simulation or passing additional attributes, e.g., to change an attribute mid-simulation.

__init__(*args, **kwargs)
set_attributes(self: sanafecpp.MappedNeuron, model_attributes: dict = {}, soma_attributes: dict = {}, dendrite_attributes: dict = {}, log_spikes: bool | None = None) None

Configure neuron-specific attributes after mapping to hardware.

Parameters:
  • log_spikes (bool, optional) – Enable spike logging for this neuron. Default is False.

  • model_attributes (dict, optional) – General model parameters. Default is None.

  • soma_attributes (dict, optional) – Soma-specific model parameters. Default is None.

  • dendrite_attributes (dict, optional) – Dendrite-specific model parameters. Default is None.

Raises:

HardwareMappingError – If the model attribute is incompatible with the specified hardware.

Architecture

class sanafe.Architecture

Bases: pybind11_object

Hardware architecture specification defining tiles, cores, and NoC topology.

Architecture describes the target neuromorphic hardware platform including processing cores, network-on-chip parameters, and power/timing models.

Example

>>> arch = sanafe.Architecture("MyChip", noc_config)
>>> tile = arch.create_tile("tile_0", energy_north_hop=1e-12)
>>> core = arch.create_core("core_0", tile.id)
__init__(self: sanafecpp.Architecture, arg0: str, arg1: sanafe::NetworkOnChipConfiguration) None
cores(self: sanafecpp.Architecture) list[sanafe::CoreConfiguration]
property tiles
class sanafe.Tile

Bases: pybind11_object

__init__(self: sanafecpp.Tile, name: str, id: SupportsInt | SupportsIndex, energy_north_hop: SupportsFloat | SupportsIndex = 0.0, latency_north_hop: SupportsFloat | SupportsIndex = 0.0, energy_east_hop: SupportsFloat | SupportsIndex = 0.0, latency_east_hop: SupportsFloat | SupportsIndex = 0.0, energy_south_hop: SupportsFloat | SupportsIndex = 0.0, latency_south_hop: SupportsFloat | SupportsIndex = 0.0, energy_west_hop: SupportsFloat | SupportsIndex = 0.0, latency_west_hop: SupportsFloat | SupportsIndex = 0.0, log_energy: bool = False) None
property cores
property id
property name
class sanafe.Core

Bases: pybind11_object

__init__(self: sanafecpp.Core, name: str, parent_tile_id: SupportsInt | SupportsIndex, offset_within_tile: SupportsInt | SupportsIndex, core_id: SupportsInt | SupportsIndex, buffer_position: str = <BufferPosition.buffer_before_soma_unit: 2>, buffer_inside_unit: bool = False, max_neurons_supported: SupportsInt | SupportsIndex = 1024, log_energy: bool = False) None
property axon_in
property axon_out
property name
property pipeline_hw
class sanafe.PipelineUnit

Bases: pybind11_object

__init__(*args, **kwargs)
property implements_dendrite
property implements_soma
property implements_synapse
property model_info
property name
class sanafe.ModelInfo

Bases: pybind11_object

__init__(*args, **kwargs)
property log_energy
property log_latency
property model_attributes
property name
property plugin_library_path
property update_every_timestep
class sanafe.AxonInPowerMetrics

Bases: pybind11_object

__init__(*args, **kwargs)
property energy_message_in
property latency_message_in
class sanafe.AxonOutPowerMetrics

Bases: pybind11_object

__init__(*args, **kwargs)
property energy_message_out
property latency_message_out

Network

class sanafe.Network

Bases: pybind11_object

Spiking Neural Network (SNN) container representing neurons and their connections.

A Network represents the graph of neurons and synapses, independent of any hardware mapping. Use this to define your neural network (application) before mapping to a neuromorphic hardware architecture. SANA-FE allows you to associate arbitrary parameters with groups, neurons and edges, making it possible for you to pass model attributes as user input.

__init__(self: sanafecpp.Network) None
create_neuron_group(self: sanafecpp.Network, group_name: str, neuron_count: SupportsInt | SupportsIndex, model_attributes: dict = {}, default_synapse_hw_name: str = '', default_dendrite_hw_name: str = '', log_potential: bool = False, log_spikes: bool = False, soma_hw_name: str = '') sanafe::NeuronGroup

Create a new group of neurons with shared properties.

Parameters:
  • group_name (str) – Unique identifier for this neuron group

  • neuron_count (int) – Number of neurons to create in this group

  • model_attributes (dict, optional) – Model parameters (e.g., threshold, bias). Default is None.

  • default_synapse_hw_name (str, optional) – Default synapse hardware unit name for neurons within the group. Hardware unit names much match exactly with their corresponding pipeline unit in the architecture description/object. Default is None (which means defaulting to the first defined pipeline unit).

  • default_dendrite_hw_name (str, optional) – Default dendrite hardware unit name. Default is None.

  • log_potential (bool, optional) – Enable membrane potential logging. Default is False.

  • log_spikes (bool, optional) – Enable spike event logging. Default is False.

  • soma_hw_name (str, optional) – Soma hardware implementation name. Default is None.

Returns:

The created neuron group

Return type:

NeuronGroup

Example

>>> group = net.create_neuron_group("layer1", 256,
...     model_attributes={"threshold": 1.0, "bias": 0.5})
property groups
save(self: sanafecpp.Network, path: os.PathLike | str | bytes, use_netlist_format: bool = False) None

Save network to file in YAML or legacy netlist format.

Parameters:
  • dest_group (NeuronGroup) – Target neuron group

  • attributes (dict) – Connection attributes with lists of values Length must equal source_neurons * dest_neurons

class sanafe.NeuronGroup

Bases: pybind11_object

Collection of neurons with shared configuration and connectivity patterns.

NeuronGroups represent groups of similar or related neurons, akin to ‘populations’, or ‘layers’ on neurons in other SNN frameworks. NeuronGroups provide efficient batch operations for creating connections and setting common neuron parameters. Individual neurons can be accessed via indexing and slicing.

__init__(*args, **kwargs)
connect_neurons_conv2d(self: sanafecpp.NeuronGroup, dest_group: sanafecpp.NeuronGroup, attributes: dict, input_width: SupportsInt | SupportsIndex, input_height: SupportsInt | SupportsIndex, input_channels: SupportsInt | SupportsIndex, kernel_width: SupportsInt | SupportsIndex, kernel_height: SupportsInt | SupportsIndex, kernel_count: SupportsInt | SupportsIndex = 1, stride_width: SupportsInt | SupportsIndex = 1, stride_height: SupportsInt | SupportsIndex = 1) None

Create 2D convolutional connections between neuron groups.

Implements CNN-style convolution with configurable kernel size, stride, and channel dimensions. Input neurons are interpreted as flattened 2D/3D arrays.

Parameters:
  • dest_group (NeuronGroup) – Output feature map neuron group

  • attributes (dict) – Filter weights and other connection parameters

  • input_width (int) – Width of input feature map

  • input_height (int) – Height of input feature map

  • input_channels (int) – Number of input channels

  • kernel_width (int) – Convolution kernel width

  • kernel_height (int) – Convolution kernel height

  • kernel_count (int, optional) – Number of output channels/filters. Default is 1.

  • stride_width (int, optional) – Horizontal stride. Default is 1.

  • stride_height (int, optional) – Vertical stride. Default is 1.

Example

>>> # 28x28x1 -> 26x26x32 convolution (3x3 kernels)
>>> src.connect_neurons_conv2d(dst, {"weight": filter_weights},
...     28, 28, 1, 3, 3, 32, 1, 1)
connect_neurons_dense(self: sanafecpp.NeuronGroup, arg0: sanafecpp.NeuronGroup, arg1: dict) None

Create fully-connected (dense) connections to destination group.

Connects every neuron in this group to every neuron in the destination group. Connection attributes are provided as flattened arrays.

Parameters:
  • dest_group (NeuronGroup) – Target neuron group

  • attributes (dict) – Connection attributes with lists of values

  • src_dest_id_pairs (list) – List of (source_idx, dest_idx) tuples

Example

>>> weights = [random.random() for _ in range(src.neurons * dst.neurons)]
>>> src.connect_neurons_dense(dst, {"weight": weights})
connect_neurons_sparse(self: sanafecpp.NeuronGroup, arg0: sanafecpp.NeuronGroup, arg1: dict, arg2: list) None

Create sparse connections using explicit source-destination pairs.

Parameters:
  • dest_group (NeuronGroup) – Target neuron group

  • attributes (dict) – Connection attributes with lists of values Length must equal source_neurons * dest_neurons

Example

>>> connections = [(0, 5), (1, 3), (2, 7)]
>>> weights = [0.5, 0.8, 0.3]
>>> src.connect_neurons_sparse(dst, {"weight": weights}, connections)
get_name(self: sanafecpp.NeuronGroup) str
property neurons
class sanafe.Neuron

Bases: pybind11_object

Individual spiking neuron with configurable hardware mapping and attributes.

Neurons maintain their own state, connections, and hardware assignments. Access via NeuronGroup indexing or iteration.

__init__(*args, **kwargs)
connect_to_neuron(self: sanafecpp.Neuron, dest_neuron: sanafecpp.Neuron, attributes: object = None) int

Create direct connection to another neuron.

Parameters:
  • dest_neuron (Neuron) – Target neuron

  • attributes (dict, optional) – Connection-specific parameters

Returns:

Connection index for later reference

Return type:

int

property edges_out
get_id(self: sanafecpp.Neuron) int
map_to_core(self: sanafecpp.Neuron, arg0: sanafe::CoreConfiguration) None

Assign this neuron to a specific hardware core.

Parameters:

core_configuration (Core) – Target core for neuron placement

set_attributes(self: sanafecpp.Neuron, soma_hw_name: str | None = None, default_synapse_hw_name: str | None = None, dendrite_hw_name: str | None = None, log_spikes: bool | None = None, log_potential: bool | None = None, model_attributes: dict = {}, soma_attributes: dict = {}, dendrite_attributes: dict = {}) None

Configure neuron-specific attributes and mapping to hardware.

Parameters:
  • soma_hw_name (str, optional) – Soma processing unit name. Default is None.

  • default_synapse_hw_name (str, optional) – Default synapse type. Default is None.

  • dendrite_hw_name (str, optional) – Dendrite processing unit name. Hardware unit names much match exactly with their corresponding pipeline unit in the architecture description/object. Default is None (which means defaulting to the first defined pipeline unit).

  • log_spikes (bool, optional) – Enable spike logging for this neuron. Default is False.

  • log_potential (bool, optional) – Enable potential logging for this neuron. Default is False.

  • model_attributes (dict, optional) – General model parameters. Default is None.

  • soma_attributes (dict, optional) – Soma-specific model parameters. Default is None.

  • dendrite_attributes (dict, optional) – Dendrite-specific model parameters. Default is None.

class sanafe.Connection

Bases: pybind11_object

__init__(*args, **kwargs)
property post_neuron
property pre_neuron
property synapse_attributes
property synapse_hw_name

Utility Functions

sanafe.load_arch(arg0: os.PathLike | str | bytes) sanafe::Architecture

Load hardware architecture from YAML configuration file.

An architecture is an abstract hardware configuration. To simulate this hardware, you must use the configuration to create one or more SpikingChip objects.

Parameters:

path (str) – Path to architecture YAML file

Returns:

Loaded architecture configuration

Return type:

Architecture

Example

>>> arch = sanafe.load_arch("loihi.yaml")
sanafe.load_net(path: os.PathLike | str | bytes, arch: sanafe::Architecture, use_netlist_format: bool = False) sanafe::SpikingNetwork

Load neural network from file (YAML or legacy netlist format).

Parameters:
  • path (str) – Path to network file

  • arch (Architecture) – Target architecture for validation

  • use_netlist_format (bool, optional) – Parse as legacy netlist format

Returns:

Loaded spiking neural network

Return type:

Network

Example

>>> net = sanafe.load_net("snn.yaml", arch)
sanafe.load_example()[source]

Load a bundled example architecture and SNN.

sanafe.load_loihi()[source]

Load the Loihi architecture file

sanafe.load_truenorth()[source]

Load the TrueNorth architecture file

sanafe.framework_attributes

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)

sanafe.model_attributes

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)