Source code for spinnman.model.executable_targets

# Copyright (c) 2016 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 collections import defaultdict
from spinn_utilities.ordered_set import OrderedSet
from spinn_machine import CoreSubsets
from spinnman.exceptions import SpinnmanInvalidParameterException


[docs]class ExecutableTargets(object): """ Encapsulate the binaries and cores on which to execute them. """ __slots__ = [ "_all_core_subsets", "_targets", "_total_processors", "_binary_type_map"] def __init__(self): self._targets = dict() self._total_processors = 0 self._all_core_subsets = CoreSubsets() self._binary_type_map = defaultdict(OrderedSet)
[docs] def add_subsets(self, binary, subsets, executable_type=None): """ Add core subsets to a binary. :param str binary: the path to the binary needed to be executed :param ~spinn_machine.CoreSubsets subsets: the subset of cores that the binary needs to be loaded on :param ~spinn_front_end_common.utilities.utility_objs.ExecutableType \ executable_type: The type of this executable. ``None`` means don't record it. """ try: for subset in subsets.core_subsets: for p in subset.processor_ids: self.add_processor(binary, subset.x, subset.y, p) except AttributeError: if subsets is not None: raise if executable_type is not None: self._binary_type_map[executable_type].add(binary)
[docs] def add_processor( self, binary, chip_x, chip_y, chip_p, executable_type=None): """ Add a processor to the executable targets :param str binary: the binary path for executable :param int chip_x: the coordinate on the machine in terms of x for the chip :param int chip_y: the coordinate on the machine in terms of y for the chip :param int chip_p: the processor ID to place this executable on :param ~spinn_front_end_common.utilities.utility_objs.ExecutableType \ executable_type: the executable type for locating n cores of """ if self.known(binary, chip_x, chip_y, chip_p): return if binary not in self._targets: self._targets[binary] = CoreSubsets() if executable_type is not None: self._binary_type_map[executable_type].add(binary) self._targets[binary].add_processor(chip_x, chip_y, chip_p) self._all_core_subsets.add_processor(chip_x, chip_y, chip_p) self._total_processors += 1
[docs] def get_n_cores_for_executable_type(self, executable_type): """ Get the number of cores that the executable type is using. :param ~spinn_front_end_common.utilities.utility_objs.ExecutableType \ executable_type: the executable type for locating n cores of :return: the number of cores using this executable type :rtype: int """ return sum( len(self.get_cores_for_binary(aplx)) for aplx in self._binary_type_map[executable_type])
[docs] def get_binaries_of_executable_type(self, executable_type): """ Get the binaries of a given a executable type. :param ~spinn_front_end_common.utilities.utility_objs.ExecutableType \ executable_type: the executable type enum value :return: iterable of binaries with that executable type :rtype: iterable(str) """ return self._binary_type_map[executable_type]
[docs] def executable_types_in_binary_set(self): """ Get the executable types in the set of binaries. :return: iterable of the executable types in this binary set. :rtype: iterable(~spinn_front_end_common.utilities.utility_objs.ExecutableType) """ return self._binary_type_map.keys()
[docs] def get_cores_for_binary(self, binary): """ Get the cores that a binary is to run on. :param str binary: The binary to find the cores for """ return self._targets.get(binary)
@property def binaries(self): """ The binaries of the executables. :rtype: iterable(str) """ return self._targets.keys() @property def total_processors(self): """ The total number of cores to be loaded. :rtype: int """ return self._total_processors @property def all_core_subsets(self): """ All the core subsets for all the binaries. :rtype: ~spinn_machine.CoreSubsets """ return self._all_core_subsets
[docs] def known(self, binary, chip_x, chip_y, chip_p): """ :param str binary: :param int chip_x: :param int chip_y: :param int chip_p: :rtype: bool """ if not self._all_core_subsets.is_core(chip_x, chip_y, chip_p): return False # OK if and only if the chip is in this binary already if binary in self._targets: if self._targets[binary].is_core(chip_x, chip_y, chip_p): return True raise SpinnmanInvalidParameterException( f"x:{chip_x} y:{chip_y} p:{chip_p}", binary, "Already associated with a different binary")