Source code for spynnaker.pyNN.models.neuron.population_machine_common

# Copyright (c) 2017 The University of Manchester
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from typing import Mapping, NamedTuple, Sequence, cast, TYPE_CHECKING
from spinn_utilities.overrides import overrides
from spinnman.model.enums import ExecutableType
from pacman.model.graphs.machine import MachineVertex
from pacman.model.graphs.common import Slice
from pacman.model.resources import AbstractSDRAM
from pacman.model.placements import Placement

from spinn_front_end_common.interface.provenance import (
    ProvidesProvenanceDataFromMachineImpl)
from spinn_front_end_common.interface.buffer_management.buffer_models import (
    AbstractReceiveBuffersToHost)
from spinn_front_end_common.utilities.helpful_functions import (
    locate_memory_region_for_placement)
from spinn_front_end_common.interface.profiling.profile_utils import (
    get_profiling_data, reserve_profile_region, write_profile_region_data)
from spinn_front_end_common.abstract_models import AbstractHasAssociatedBinary
from spinn_front_end_common.interface.buffer_management\
    .recording_utilities import (
        get_recording_header_size, get_recording_header_array)
from spinn_front_end_common.interface.simulation.simulation_utilities import (
    get_simulation_header_array)
from spinn_front_end_common.interface.ds import DataSpecificationGenerator
from spinn_front_end_common.interface.profiling import (
    AbstractHasProfileData, ProfileData)
from spinn_front_end_common.utilities.constants import SIMULATION_N_BYTES
if TYPE_CHECKING:
    from .abstract_population_vertex import AbstractPopulationVertex


[docs] class CommonRegions(NamedTuple): """ Identifiers for common regions. """ #: System control region system: int #: Provenance collection region provenance: int #: Profiling data region profile: int #: Recording channels region recording: int
# pylint: disable=abstract-method
[docs] class PopulationMachineCommon( MachineVertex, ProvidesProvenanceDataFromMachineImpl, AbstractReceiveBuffersToHost, AbstractHasProfileData, AbstractHasAssociatedBinary): """ A common machine vertex for all population binaries. """ __slots__ = ( # Sdram used by the machine vertex "__sdram", # Regions to be used "__regions", # The total number of provenance items returned by this core "__n_provenance_items", # The profile tags to be decoded "__profile_tags", # The name of the binary to run on the core "__binary_file_name") def __init__( self, label: str, app_vertex: AbstractPopulationVertex, vertex_slice: Slice, sdram: AbstractSDRAM, regions: CommonRegions, n_provenance_items: int, profile_tags: Mapping[int, str], binary_file_name: str): """ :param str label: The label of the vertex :param AbstractPopulationVertex app_vertex: The associated application vertex :param ~pacman.model.graphs.common.Slice vertex_slice: The slice of the population that this implements :param ~pacman.model.resources.AbstractSDRAM sdram: The SDRAM used by the vertex :param .CommonRegions regions: The regions to be assigned :param int n_provenance_items: The number of additional provenance items to be read :param dict(int,str) profile_tags: A mapping of profile identifiers to names :param str binary_file_name: The name of the binary file """ super().__init__(label, app_vertex, vertex_slice) self.__sdram = sdram self.__regions = regions self.__n_provenance_items = n_provenance_items self.__profile_tags = profile_tags self.__binary_file_name = binary_file_name @property @overrides(MachineVertex.sdram_required) def sdram_required(self) -> AbstractSDRAM: return self.__sdram @property def _pop_vertex(self) -> AbstractPopulationVertex: return cast('AbstractPopulationVertex', self._app_vertex) @property @overrides(ProvidesProvenanceDataFromMachineImpl._provenance_region_id) def _provenance_region_id(self) -> int: return self.__regions.provenance @property @overrides(ProvidesProvenanceDataFromMachineImpl._n_additional_data_items) def _n_additional_data_items(self) -> int: return self.__n_provenance_items
[docs] @overrides(AbstractReceiveBuffersToHost.get_recording_region_base_address) def get_recording_region_base_address(self, placement: Placement) -> int: return locate_memory_region_for_placement( placement, self.__regions.recording)
[docs] @overrides(AbstractHasProfileData.get_profile_data) def get_profile_data(self, placement: Placement) -> ProfileData: return get_profiling_data( self.__regions.profile, self.__profile_tags, placement)
[docs] @overrides(AbstractHasAssociatedBinary.get_binary_start_type) def get_binary_start_type(self) -> ExecutableType: return ExecutableType.USES_SIMULATION_INTERFACE
def _write_common_data_spec( self, spec: DataSpecificationGenerator, rec_regions: Sequence[int]): """ Write the data specification for the common regions. :param ~data_specification.DataSpecificationGenerator spec: The data specification to write to :param list(int) rec_regions: A list of sizes of each recording region (including empty ones) """ # Write the setup region spec.reserve_memory_region( region=self.__regions.system, size=SIMULATION_N_BYTES, label='System') spec.switch_write_focus(self.__regions.system) spec.write_array(get_simulation_header_array(self.__binary_file_name)) # Reserve memory for provenance self.reserve_provenance_data_region(spec) # Write profile data reserve_profile_region( spec, self.__regions.profile, self._pop_vertex.n_profile_samples) write_profile_region_data( spec, self.__regions.profile, self._pop_vertex.n_profile_samples) # Set up for recording spec.reserve_memory_region( region=self.__regions.recording, size=get_recording_header_size(len(rec_regions)), label="Recording") spec.switch_write_focus(self.__regions.recording) spec.write_array(get_recording_header_array(rec_regions))
[docs] @overrides(AbstractHasAssociatedBinary.get_binary_file_name) def get_binary_file_name(self) -> str: return self.__binary_file_name
[docs] @overrides(MachineVertex.get_n_keys_for_partition) def get_n_keys_for_partition(self, partition_id: str) -> int: # Colour each time slot with up to 16 colours to allow for delays return self.vertex_slice.n_atoms * 16