Skip to content

spinnaker2.configuration

Example:

from spinnaker2.configuration import PEConfig, ExperimentConfig, MemoryRegion, Experiment
from spinnaker2.coordinates import ByteAddr, WordAddr, PE
import spinnaker2.hardware

pe = PE(1,1,0)
pe_cfg = PEConfig(pe, "test_app", "path/to/test/binaries/s2app_arm.mem")
pe_cfg.add_mem_data_to_send(ByteAddr(0x10000).to_WordAddr(), [10,20,30])
pe_cfg.add_mem_region_to_read("my_result", MemoryRegion(ByteAddr(0x10000).to_WordAddr(), 1))

exp_config = ExperimentConfig(duration_in_s=1.0)
exp_config.add(pe_config)

experiment = Experiment(exp_config, spinnaker2.hardware._experiment_app_path_s2_chip())
cmd_opts = ['-e', "192.168.1.59"]
experiment.run(cmd_opts)

my_result = experiment.get_result(pe, "my_result")

Classes:

Experiment

Bases: ExperimentResult

Runs experiment on SpiNNaker2 chip and stores results.

Parameters:

Name Type Description Default
config ExperimentConfig

experiment configuration

required
app_path str

path to experiment runner executable

required
Source code in src/spinnaker2/configuration.py
class Experiment(ExperimentResult):
    """Runs experiment on SpiNNaker2 chip and stores results.

    Args:
        config (ExperimentConfig): experiment configuration
        app_path (str): path to experiment runner executable
    """

    def __init__(self, experiment_config, app_path):
        """init experiment.

        Args:
            experiment_config (ExperimentConfig): experiment configuration
            app_path (str): path to experiment runner executable
        """
        super().__init__()
        self.config = experiment_config
        self.app_path = app_path

    def run(self, cmd_opts=[]):
        """run experiment on SpiNNaker2 hardware.

        Args:
            cmd_opts (list of strings): command line options for the experiment runner
        """
        # TODO: make handling of additional command line parameters flexible
        spec_file = "spec.json"
        self.config.dump_spec(json_file=spec_file)

        # Run experiment
        cmd = [self.app_path] + cmd_opts
        subprocess.run(cmd, check=True)  # noqa S603

        result_file = "results.json"
        with open(result_file, "r") as f:
            self.results = json.load(f)

__init__(experiment_config, app_path)

init experiment.

Parameters:

Name Type Description Default
experiment_config ExperimentConfig

experiment configuration

required
app_path str

path to experiment runner executable

required
Source code in src/spinnaker2/configuration.py
def __init__(self, experiment_config, app_path):
    """init experiment.

    Args:
        experiment_config (ExperimentConfig): experiment configuration
        app_path (str): path to experiment runner executable
    """
    super().__init__()
    self.config = experiment_config
    self.app_path = app_path

run(cmd_opts=[])

run experiment on SpiNNaker2 hardware.

Parameters:

Name Type Description Default
cmd_opts list of strings

command line options for the experiment runner

[]
Source code in src/spinnaker2/configuration.py
def run(self, cmd_opts=[]):
    """run experiment on SpiNNaker2 hardware.

    Args:
        cmd_opts (list of strings): command line options for the experiment runner
    """
    # TODO: make handling of additional command line parameters flexible
    spec_file = "spec.json"
    self.config.dump_spec(json_file=spec_file)

    # Run experiment
    cmd = [self.app_path] + cmd_opts
    subprocess.run(cmd, check=True)  # noqa S603

    result_file = "results.json"
    with open(result_file, "r") as f:
        self.results = json.load(f)

ExperimentConfig

Bases: object

Configuration of experiment on a SpiNNaker2 chip.

This class provides a container for the experiment specification for one SpiNNakere2 chip. Besides the configuration of used PEs it contains the runtime and the synchronous_start flag.

Attributes:

Name Type Description
runtime_in_s

experiment runtime in seconds

synchronous_start bool

start all PEs synchronously via feedthrough interrupt. Default: False

pe_configs

list of PEConfigs

Source code in src/spinnaker2/configuration.py
class ExperimentConfig(object):
    """Configuration of experiment on a SpiNNaker2 chip.

    This class provides a container for the experiment specification for one
    SpiNNakere2 chip.
    Besides the configuration of used PEs it contains the runtime and the
    synchronous_start flag.

    Attributes:
        runtime_in_s: experiment runtime in seconds
        synchronous_start (bool): start all PEs synchronously via feedthrough
            interrupt. Default: False
        pe_configs: list of PEConfigs
    """

    def __init__(self, runtime_in_s):
        """init experiment configuration.

        Args:
            runtime_in_s: experiment runtime in seconds
        """
        self.runtime_in_s = runtime_in_s
        self.synchronous_start = False
        self.pe_configs = []

    def add(self, *configs):
        """add one or several PEConfig"""
        for config in configs:
            if isinstance(config, PEConfig):
                self.pe_configs.append(config)
            else:
                raise TypeError("Config other than PEConfig not supported yet")

    def dump_spec(self, json_file="spec.json"):
        """dump experiment specification to JSON file.

        Args:
            json_file (str): name of JSON file
        """
        spec = {
            "active_pes": [],
            "mem_files": [],
            "duration_in_s": self.runtime_in_s,
            "synchronous_start": self.synchronous_start,
            "mem_regions_to_read": {},
            "mem_data_to_send": [],
        }

        for pe_config in self.pe_configs:
            pe = pe_config.pe
            pe_str = "PE_{}_".format(pe.global_id())
            spec["active_pes"].append([pe.x, pe.y, pe.pe])
            spec["mem_files"].append(pe_config.mem_file)
            for name, region in pe_config.mem_regions_to_read.items():
                # add prefix to mem region name
                new_name = pe_str + name
                spec["mem_regions_to_read"][new_name] = [
                    global_word_address(pe.x, pe.y, pe.pe, region.word_addr.to_ByteAddr()),
                    region.word_count,
                ]

            for mem_data in pe_config.mem_data_to_send:
                spec["mem_data_to_send"].append([global_word_address(pe.x, pe.y, pe.pe, mem_data[0] << 2), mem_data[1]])

        with open(json_file, "w") as f:
            json.dump(spec, f, indent=2)

__init__(runtime_in_s)

init experiment configuration.

Parameters:

Name Type Description Default
runtime_in_s

experiment runtime in seconds

required
Source code in src/spinnaker2/configuration.py
def __init__(self, runtime_in_s):
    """init experiment configuration.

    Args:
        runtime_in_s: experiment runtime in seconds
    """
    self.runtime_in_s = runtime_in_s
    self.synchronous_start = False
    self.pe_configs = []

add(*configs)

add one or several PEConfig

Source code in src/spinnaker2/configuration.py
def add(self, *configs):
    """add one or several PEConfig"""
    for config in configs:
        if isinstance(config, PEConfig):
            self.pe_configs.append(config)
        else:
            raise TypeError("Config other than PEConfig not supported yet")

dump_spec(json_file='spec.json')

dump experiment specification to JSON file.

Parameters:

Name Type Description Default
json_file str

name of JSON file

'spec.json'
Source code in src/spinnaker2/configuration.py
def dump_spec(self, json_file="spec.json"):
    """dump experiment specification to JSON file.

    Args:
        json_file (str): name of JSON file
    """
    spec = {
        "active_pes": [],
        "mem_files": [],
        "duration_in_s": self.runtime_in_s,
        "synchronous_start": self.synchronous_start,
        "mem_regions_to_read": {},
        "mem_data_to_send": [],
    }

    for pe_config in self.pe_configs:
        pe = pe_config.pe
        pe_str = "PE_{}_".format(pe.global_id())
        spec["active_pes"].append([pe.x, pe.y, pe.pe])
        spec["mem_files"].append(pe_config.mem_file)
        for name, region in pe_config.mem_regions_to_read.items():
            # add prefix to mem region name
            new_name = pe_str + name
            spec["mem_regions_to_read"][new_name] = [
                global_word_address(pe.x, pe.y, pe.pe, region.word_addr.to_ByteAddr()),
                region.word_count,
            ]

        for mem_data in pe_config.mem_data_to_send:
            spec["mem_data_to_send"].append([global_word_address(pe.x, pe.y, pe.pe, mem_data[0] << 2), mem_data[1]])

    with open(json_file, "w") as f:
        json.dump(spec, f, indent=2)

ExperimentResult

Bases: object

Container for results of SpiNNaker2 experiment.

Parameters:

Name Type Description Default
results dict

results from SpiNNaker2 experiments. Contains the mem_regions_to_read of the PEConfig.

required
Source code in src/spinnaker2/configuration.py
class ExperimentResult(object):
    """Container for results of SpiNNaker2 experiment.

    Args:
        results (dict): results from SpiNNaker2 experiments. Contains the
            mem_regions_to_read of the PEConfig.
    """

    def __init__(self):
        self.results = {}

    def get_result(self, pe, name):
        """get result of recorded memory region on PE.

        Returns the raw data of a memory region recorded after the experiment.

        Args:
            pe: PE coordinate
            name: name of memory region
        """
        pe_str = "PE_{}_".format(pe.global_id())
        return self.results[pe_str + name]

get_result(pe, name)

get result of recorded memory region on PE.

Returns the raw data of a memory region recorded after the experiment.

Parameters:

Name Type Description Default
pe

PE coordinate

required
name

name of memory region

required
Source code in src/spinnaker2/configuration.py
def get_result(self, pe, name):
    """get result of recorded memory region on PE.

    Returns the raw data of a memory region recorded after the experiment.

    Args:
        pe: PE coordinate
        name: name of memory region
    """
    pe_str = "PE_{}_".format(pe.global_id())
    return self.results[pe_str + name]

MemoryRegion

Bases: object

memory region on a SpiNNaker2 PE.

A memory region is defined by its start address and the number of 32-bit words.

Attributes:

Name Type Description
word_addr WordAddr

start address.

word_count int

size of memory region in 32-bit words

Source code in src/spinnaker2/configuration.py
class MemoryRegion(object):
    """memory region on a SpiNNaker2 PE.

    A memory region is defined by its start address and the number of 32-bit
    words.

    Attributes:
        word_addr (WordAddr): start address.
        word_count (int): size of memory region in 32-bit words

    """

    def __init__(self, word_addr: WordAddr, word_count: int):
        """Init MemoryRegion.

        Args:
            word_addr: start address.
            word_count: size of memory region in 32-bit words
        """
        assert isinstance(word_addr, WordAddr)
        self.word_addr = word_addr
        self.word_count = word_count

__init__(word_addr, word_count)

Init MemoryRegion.

Parameters:

Name Type Description Default
word_addr WordAddr

start address.

required
word_count int

size of memory region in 32-bit words

required
Source code in src/spinnaker2/configuration.py
def __init__(self, word_addr: WordAddr, word_count: int):
    """Init MemoryRegion.

    Args:
        word_addr: start address.
        word_count: size of memory region in 32-bit words
    """
    assert isinstance(word_addr, WordAddr)
    self.word_addr = word_addr
    self.word_count = word_count

PEConfig

Bases: object

Configuration of a SpiNNaker2 PE.

This class provides a container for the experiment specification related to one SpiNNaker2 processing element. It contains the mem-file, the input data blocks and the memory regions to read after the experiment as well as the coordinate of the PE.

Attributes:

Name Type Description
pe

PE coordinate

app_name

name of application to run on this PE.

mem_file str or None

path to mem-file with instruction memory.

mem_regions_to_read dict

memory regions to read from the PE after the experiment. The dict keys are unique names for the memory regions to ease the retrieval of the data after the experiment.

mem_data_to_send list

list of memory data blocks to send to the PE. Each block is defined by a start address (WordAddr) and a data array of 32-bit words (unsigned integer).

Source code in src/spinnaker2/configuration.py
class PEConfig(object):
    """Configuration of a SpiNNaker2 PE.

    This class provides a container for the experiment specification related to
    one SpiNNaker2 processing element.
    It contains the mem-file, the input data blocks and the memory regions to
    read after the experiment as well as the coordinate of the PE.

    Attributes:
        pe: PE coordinate
        app_name: name of application to run on this PE.
        mem_file (str or None): path to mem-file with instruction memory.
        mem_regions_to_read (dict): memory regions to read from the PE after
            the experiment. The dict keys are unique names for the memory
            regions to ease the retrieval of the data after the experiment.
        mem_data_to_send (list): list of memory data blocks to send to the PE.
            Each block is defined by a start address (WordAddr) and a data
            array of 32-bit words (unsigned integer).
    """

    def __init__(self, pe, app_name, mem_file=None):
        """init PE configuration.

        Args:
            pe: PE coordinate.
            app_name: name of application to run on this PE.
            mem_file (str or None): path to mem-file with instruction memory.
        """
        self.pe = pe
        self.app_name = app_name
        self.mem_file = mem_file
        self.mem_regions_to_read = {}
        self.mem_data_to_send = []

    def add_mem_region_to_read(self, name, mem_region):
        """
        add memory region to read.

        Args:
          name : name tag for the memory region (string)
          mem_region: MemoryRegion
        """
        self.mem_regions_to_read[name] = mem_region

    def add_mem_data_to_send(self, start_addr, data_array):
        """
        add memory data to send

        Args:
          start_addr: PE local word address to write
          data_array: list of 32-bit words representing 4 bytes each
        """
        self.mem_data_to_send.append([start_addr, data_array])

    def check_for_overlap_in_data_to_send(self):
        send_data_length_sorted = []
        for addr, data in self.mem_data_to_send:
            send_data_length_sorted.append([addr, len(data)])
        send_data_length_sorted.sort(key=lambda x: x[0])
        if len(send_data_length_sorted) < 2:
            return
        for this_entry, next_entry in zip(send_data_length_sorted[:-1], send_data_length_sorted[1:]):
            this_end_addr = this_entry[0] + this_entry[1]
            if this_end_addr > next_entry[0]:
                raise Exception(
                    f"Conflict in PEConfig of {self.pe}: data "
                    f"starting at {this_entry[0]} with size {this_entry[1]} "
                    f"overlaps with data starting at {next_entry[0]}"
                )

__init__(pe, app_name, mem_file=None)

init PE configuration.

Parameters:

Name Type Description Default
pe

PE coordinate.

required
app_name

name of application to run on this PE.

required
mem_file str or None

path to mem-file with instruction memory.

None
Source code in src/spinnaker2/configuration.py
def __init__(self, pe, app_name, mem_file=None):
    """init PE configuration.

    Args:
        pe: PE coordinate.
        app_name: name of application to run on this PE.
        mem_file (str or None): path to mem-file with instruction memory.
    """
    self.pe = pe
    self.app_name = app_name
    self.mem_file = mem_file
    self.mem_regions_to_read = {}
    self.mem_data_to_send = []

add_mem_data_to_send(start_addr, data_array)

add memory data to send

Parameters:

Name Type Description Default
start_addr

PE local word address to write

required
data_array

list of 32-bit words representing 4 bytes each

required
Source code in src/spinnaker2/configuration.py
def add_mem_data_to_send(self, start_addr, data_array):
    """
    add memory data to send

    Args:
      start_addr: PE local word address to write
      data_array: list of 32-bit words representing 4 bytes each
    """
    self.mem_data_to_send.append([start_addr, data_array])

add_mem_region_to_read(name, mem_region)

add memory region to read.

Parameters:

Name Type Description Default
name

name tag for the memory region (string)

required
mem_region

MemoryRegion

required
Source code in src/spinnaker2/configuration.py
def add_mem_region_to_read(self, name, mem_region):
    """
    add memory region to read.

    Args:
      name : name tag for the memory region (string)
      mem_region: MemoryRegion
    """
    self.mem_regions_to_read[name] = mem_region