def _load_executables(routing_tables, compressor_app_id, txrx, machine): """ Loads the router compressor onto the chips. :param routing_tables: the router tables needed to be compressed :param compressor_app_id: the app ID of the compressor compressor :param txrx: the spinnman interface :param machine: the SpiNNaker machine representation :return:\ the executable targets that represent all cores/chips which have\ active routing tables """ # build core subsets core_subsets = CoreSubsets() for routing_table in routing_tables: # get the first none monitor core chip = machine.get_chip_at(routing_table.x, routing_table.y) processor = chip.get_first_none_monitor_processor() # add to the core subsets core_subsets.add_processor( routing_table.x, routing_table.y, processor.processor_id) # build executable targets executable_targets = ExecutableTargets() executable_targets.add_subsets(_BINARY_PATH, core_subsets) txrx.execute_application(executable_targets, compressor_app_id) return executable_targets
def _load_executables(self): """ Loads the router compressor onto the chips. :return: the executable targets that represent all cores/chips which have active routing tables :rtype: ExecutableTargets """ # build core subsets core_subsets = CoreSubsets() for routing_table in self._routing_tables: # get the first none monitor core chip = self._machine.get_chip_at(routing_table.x, routing_table.y) processor = chip.get_first_none_monitor_processor() # add to the core subsets core_subsets.add_processor( routing_table.x, routing_table.y, processor.processor_id) # build executable targets executable_targets = ExecutableTargets() executable_targets.add_subsets(self._binary_path, core_subsets, ExecutableType.SYSTEM) return executable_targets
def _load_executables(routing_tables, compressor_app_id, txrx, machine): """ Loads the router compressor onto the chips. :param routing_tables: the router tables needed to be compressed :param compressor_app_id: the app ID of the compressor compressor :param txrx: the spinnman interface :param machine: the SpiNNaker machine representation :return:\ the executable targets that represent all cores/chips which have\ active routing tables """ # build core subsets core_subsets = CoreSubsets() for routing_table in routing_tables: # get the first none monitor core chip = machine.get_chip_at(routing_table.x, routing_table.y) processor = chip.get_first_none_monitor_processor() # add to the core subsets core_subsets.add_processor( routing_table.x, routing_table.y, processor.processor_id) # build executable targets executable_targets = ExecutableTargets() executable_targets.add_subsets(_BINARY_PATH, core_subsets) txrx.execute_application(executable_targets, compressor_app_id) return executable_targets
def convert_string_into_chip_and_core_subset(cores): """ Translate a string list of cores into a core subset :param cores:\ string representing down cores formatted as x,y,p[:x,y,p]* :type cores: str or None """ ignored_cores = CoreSubsets() if cores is not None and cores != "None": for downed_core in cores.split(":"): x, y, processor_id = downed_core.split(",") ignored_cores.add_processor(int(x), int(y), int(processor_id)) return ignored_cores
def convert_vertices_to_core_subset(vertices, placements): """ Converts vertices into core subsets. :param extra_monitor_cores_to_set:\ the vertices to convert to core subsets :param placements: the placements object :return: the CoreSubSets of the vertices """ core_subsets = CoreSubsets() for vertex in vertices: placement = placements.get_placement_of_vertex(vertex) core_subsets.add_processor(placement.x, placement.y, placement.p) return core_subsets
def convert_vertices_to_core_subset(vertices, placements): """ Converts vertices into core subsets. :param extra_monitor_cores_to_set:\ the vertices to convert to core subsets :param placements: the placements object :return: the CoreSubSets of the vertices """ core_subsets = CoreSubsets() for vertex in vertices: placement = placements.get_placement_of_vertex(vertex) core_subsets.add_processor(placement.x, placement.y, placement.p) return core_subsets
def convert_string_into_chip_and_core_subset(cores): """ Translate a string list of cores into a core subset :param cores:\ string representing down cores formatted as x,y,p[:x,y,p]* :type cores: str or None """ ignored_cores = CoreSubsets() if cores is not None and cores != "None": for downed_core in cores.split(":"): x, y, processor_id = downed_core.split(",") ignored_cores.add_processor(int(x), int(y), int(processor_id)) return ignored_cores
def get_cores_in_state(self, core_subsets, states): with self._lock: cores_in_state = CoreSubsets() core_states = self._core_states[self._current_state] for core_subset in core_subsets: x = core_subset.x y = core_subset.y for p in core_subset.processor_ids: if (x, y, p) in core_states: if hasattr(states, "__iter__"): if core_states[x, y, p] in states: cores_in_state.add_processor(x, y, p) elif core_states[x, y, p] == states: cores_in_state.add_processor(x, y, p) return cores_in_state
def _convert_vertices_to_core_subset(extra_monitor_cores, placements): """ Convert vertices into the subset of cores where they've been\ placed. :param iterable(ExtraMonitorSupportMachineVertex) extra_monitor_cores: the vertices to convert to core subsets :param ~.Placements placements: the placements object :return: where the vertices have been placed :rtype: ~.CoreSubsets """ core_subsets = CoreSubsets() for vertex in extra_monitor_cores: if not isinstance(vertex, ExtraMonitorSupportMachineVertex): raise Exception( "can only use ExtraMonitorSupportMachineVertex to set " "the router time out") placement = placements.get_placement_of_vertex(vertex) core_subsets.add_processor(placement.x, placement.y, placement.p) return core_subsets
def _load_data_specs(self, txrx, dsg_targets, app_id, write_report): # pylint: disable=too-many-locals # create a progress bar for end users progress = ProgressBar(dsg_targets, "Loading data specifications") dse_app_id = txrx.app_id_tracker.get_new_id() core_subset = CoreSubsets() for (x, y, p, label) in progress.over(dsg_targets): core_subset.add_processor(x, y, p) file_path = dsg_targets[x, y, p, label] file_size = os.path.getsize(file_path) # data spec file is written at specific address (file_data_addr); # this is encapsulated in a structure with four fields: # # 1 - data specification base address # 2 - data specification file size # 3 - future application ID # 4 - store data for memory map report (True / False) # # If the memory map report is going to be produced, the # address of the structure is returned in user1 dse_data_struct = txrx.malloc_sdram(x, y, DSE_DATA_STRUCT_SIZE, dse_app_id) file_data_addr = txrx.malloc_sdram(x, y, file_size, dse_app_id) txrx.write_memory( x, y, dse_data_struct, _FOUR_WORDS.pack(file_data_addr, file_size, app_id, write_report)) txrx.write_memory(x, y, file_data_addr, file_path, is_filename=True) write_address_to_user0(txrx, x, y, p, dse_data_struct) return dse_app_id, core_subset
def _convert_vertices_to_core_subset(extra_monitor_cores, placements): """ Convert vertices into the subset of cores where they've been\ placed. :param extra_monitor_cores: \ the vertices to convert to core subsets :type extra_monitor_cores: \ iterable(:py:class:`ExtraMonitorSupportMachineVertex`) :param placements: the placements object :type placements: :py:class:`~pacman.model.placements.Placements` :return: where the vertices have been placed :rtype: :py:class:`~spinn_machine.CoreSubsets` """ core_subsets = CoreSubsets() for vertex in extra_monitor_cores: if not isinstance(vertex, ExtraMonitorSupportMachineVertex): raise Exception( "can only use ExtraMonitorSupportMachineVertex to set " "the router time out") placement = placements.get_placement_of_vertex(vertex) core_subsets.add_processor(placement.x, placement.y, placement.p) return core_subsets
def test_app_finisher(): finisher = ApplicationFinisher() core_subsets = CoreSubsets() core_subsets.add_processor(0, 0, 1) core_subsets.add_processor(1, 1, 2) core_states = [{ (0, 0, 1): CPUState.RUNNING, (1, 1, 2): CPUState.RUNNING }, { (0, 0, 1): CPUState.RUNNING, (1, 1, 2): CPUState.FINISHED }, { (0, 0, 1): CPUState.FINISHED, (1, 1, 2): CPUState.FINISHED }] executable_types = {ExecutableType.USES_SIMULATION_INTERFACE: core_subsets} txrx = _MockTransceiver(core_states, 0.5) finisher.__call__(30, txrx, executable_types) # First round called twice as 2 running + # second round called once as 1 running assert txrx.sdp_send_count == 3
def _load_executables(self, routing_tables, compressor_app_id, transceiver, machine): """ loads the router compressor onto the chips. :param routing_tables: the router tables needed to be compressed :param compressor_app_id: the app id of the compressor compressor :param transceiver: the spinnman interface :param machine: the spinnaker machine representation :return:\ the executable targets that represent all cores/chips which have\ active routing tables """ # build core subsets core_subsets = CoreSubsets() for routing_table in routing_tables: # get the first none monitor core chip = machine.get_chip_at(routing_table.x, routing_table.y) processor = chip.get_first_none_monitor_processor() # add to the core subsets core_subsets.add_processor(routing_table.x, routing_table.y, processor.processor_id) # build binary path binary_path = os.path.join( os.path.dirname(on_chip_router_table_compression.__file__), "rt_minimise.aplx") # build executable targets executable_targets = ExecutableTargets() executable_targets.add_subsets(binary_path, core_subsets) transceiver.execute_application(executable_targets, compressor_app_id) return executable_targets
def spinnaker_based_data_specification_execution(self, write_memory_map_report, dsg_targets, transceiver, app_id): """ :param write_memory_map_report: :param dsg_targets: :param transceiver: :param app_id: :return: True :rtype: bool """ # create a progress bar for end users progress = ProgressBar(dsg_targets, "Loading data specifications") dse_app_id = transceiver.app_id_tracker.get_new_id() core_subset = CoreSubsets() for (x, y, p, label) in progress.over(dsg_targets): core_subset.add_processor(x, y, p) dse_data_struct_address = transceiver.malloc_sdram( x, y, DSE_DATA_STRUCT_SIZE, dse_app_id) data_spec_file_path = dsg_targets[x, y, p, label] data_spec_file_size = os.path.getsize(data_spec_file_path) base_address = transceiver.malloc_sdram(x, y, data_spec_file_size, dse_app_id) dse_data_struct_data = struct.pack("<4I", base_address, data_spec_file_size, app_id, write_memory_map_report) transceiver.write_memory(x, y, dse_data_struct_address, dse_data_struct_data, len(dse_data_struct_data)) transceiver.write_memory(x, y, base_address, data_spec_file_path, is_filename=True) # data spec file is written at specific address (base_address) # this is encapsulated in a structure with four fields: # 1 - data specification base address # 2 - data specification file size # 3 - future application ID # 4 - store data for memory map report (True / False) # If the memory map report is going to be produced, the # address of the structure is returned in user1 user_0_address = transceiver.\ get_user_0_register_address_from_core(x, y, p) transceiver.write_memory(x, y, user_0_address, dse_data_struct_address, 4) # Execute the DSE on all the cores logger.info("Loading the Data Specification Executor") dse_exec = os.path.join(os.path.dirname(data_spec_sender), 'data_specification_executor.aplx') transceiver.execute_flood(core_subset, dse_exec, app_id, is_filename=True) logger.info( "Waiting for On-chip Data Specification Executor to complete") transceiver.wait_for_cores_to_be_in_state(core_subset, app_id, [CPUState.FINISHED]) transceiver.stop_application(dse_app_id) transceiver.app_id_tracker.free_id(dse_app_id) logger.info("On-chip Data Specification Executor completed") return True
def _generate_core_subsets( self, routing_tables, executable_finder, machine, progress_bar, system_executable_targets): """ generates the core subsets for the binaries :param ~.MulticastRoutingTables routing_tables: the routing tables :param ~.ExecutableFinder executable_finder: the executable path finder :param ~.Machine machine: the spinn machine instance :param ~.ProgressBar progress_bar: progress bar :param ExecutableTargets system_executable_targets: the executables targets to cores :return: (targets, sorter path, and compressor path) :rtype: tuple(ExecutableTargets, str, str) """ bit_field_sorter_cores = CoreSubsets() bit_field_compressor_cores = CoreSubsets() _, cores = LoadExecutableImages.filter_targets( system_executable_targets, lambda ty: ty is ExecutableType.SYSTEM) for routing_table in progress_bar.over(routing_tables, False): # add 1 core to the sorter, and the rest to compressors sorter = None for processor in machine.get_chip_at( routing_table.x, routing_table.y).processors: if (not processor.is_monitor and not cores.all_core_subsets.is_core( routing_table.x, routing_table.y, processor.processor_id)): if sorter is None: sorter = processor bit_field_sorter_cores.add_processor( routing_table.x, routing_table.y, processor.processor_id) else: bit_field_compressor_cores.add_processor( routing_table.x, routing_table.y, processor.processor_id) # convert core subsets into executable targets executable_targets = ExecutableTargets() # bit field executable paths bit_field_sorter_executable_path = \ executable_finder.get_executable_path( self._BIT_FIELD_SORTER_AND_SEARCH_EXECUTOR_APLX) bit_field_compressor_executable_path = \ executable_finder.get_executable_path(self.compressor_aplx) # add the sets executable_targets.add_subsets( binary=bit_field_sorter_executable_path, subsets=bit_field_sorter_cores, executable_type=ExecutableType.SYSTEM) executable_targets.add_subsets( binary=bit_field_compressor_executable_path, subsets=bit_field_compressor_cores, executable_type=ExecutableType.SYSTEM) return (executable_targets, bit_field_sorter_executable_path, bit_field_compressor_executable_path)
DiagnosticFilterDestination, DiagnosticFilterPacketType) from spinnman.constants import ROUTER_REGISTER_REGISTERS from board_test_configuration import BoardTestConfiguration logging.basicConfig(level=logging.INFO) logging.getLogger("spinnman.transceiver").setLevel(logging.DEBUG) board_config = BoardTestConfiguration() board_config.set_up_remote_board() n_cores = 20 core_subsets = CoreSubsets(core_subsets=[CoreSubset(0, 0, range(1, 11)), CoreSubset(1, 1, range(1, 11))]) down_cores = CoreSubsets() down_cores.add_processor(0, 0, 5) down_chips = CoreSubsets(core_subsets=[CoreSubset(0, 1, [])]) def print_enums(name, enum_list): string = "" for enum_value in enum_list: string += enum_value.name + "; " print(name, string) def print_word_as_binary(name, word, start=0, end=32, fields=None): start_fields = set() end_fields = set() if fields is not None: for field in fields:
def test_add_processor_duplicate_processor_different_chip(self): proc_list = [0, 1, 2, 3, 5, 8, 13] cs = CoreSubset(0, 0, proc_list) css = CoreSubsets([cs]) css.add_processor(0, 1, 0)
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) 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) 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 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]) 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] 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() 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 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 parameter = "x:{} y:{} p:{}".format(chip_x, chip_y, chip_p) problem = "Already associated with a different binary" raise SpinnmanInvalidParameterException(parameter, binary, problem)
class ExecutableTargets(object): """ Encapsulate the binaries and cores on which to execute them. """ __slots__ = [ "_all_core_subsets", "_targets", "_total_processors"] def __init__(self): self._targets = dict() self._total_processors = 0 self._all_core_subsets = CoreSubsets() def add_subsets(self, binary, subsets): """ Add core subsets to a binary :param binary: the path to the binary needed to be executed :param subsets: \ the subset of cores that the binary needs to be loaded on :return: """ for subset in subsets.core_subsets: for p in subset.processor_ids: self.add_processor(binary, subset.x, subset.y, p) def add_processor(self, binary, chip_x, chip_y, chip_p): """ Add a processor to the executable targets :param binary: the binary path for executable :param chip_x: the coordinate on the machine in terms of x for the chip :param chip_y: the coordinate on the machine in terms of y for the chip :param chip_p: the processor ID to place this executable on :return: """ if self.known(binary, chip_x, chip_y, chip_p): return if binary not in self._targets: self._targets[binary] = CoreSubsets() 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 def get_cores_for_binary(self, binary): """ Get the cores that a binary is to run on :param binary: The binary to find the cores for """ return self._targets.get(binary) @property def binaries(self): """ The binaries of the executables """ return self._targets.keys() @property def total_processors(self): """ The total number of cores to be loaded """ return self._total_processors @property def all_core_subsets(self): """ All the core subsets for all the binaries """ return self._all_core_subsets def known(self, binary, chip_x, chip_y, chip_p): if self._all_core_subsets.is_core(chip_x, chip_y, chip_p): # 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 parameter = "x:{} y:{} p:{}".format(chip_x, chip_y, chip_p) problem = "Already associated with a different binary" raise SpinnmanInvalidParameterException(parameter, binary, problem) else: return False
def test_add_processor_duplicate_processor_different_chip(self): proc_list = [0, 1, 2, 3, 5, 8, 13] cs = CoreSubset(0, 0, proc_list) css = CoreSubsets([cs]) css.add_processor(0, 1, 0)