Source code for spinn_front_end_common.interface.interface_functions.graph_data_specification_writer

from collections import defaultdict

from spinn_utilities.progress_bar import ProgressBar

from data_specification.utility_calls \
    import get_data_spec_and_file_writer_filename

from spinn_front_end_common.abstract_models import \
    AbstractGeneratesDataSpecification
from spinn_front_end_common.utilities.exceptions import ConfigurationException


[docs]class GraphDataSpecificationWriter(object): """ Executes data specification generation """ __slots__ = ( # Dict of sdram usage by chip coordinates "_sdram_usage", # Dict of list of region sizes by vertex "_region_sizes", # Dict of list of vertices by chip coordinates "_vertices_by_chip" ) def __init__(self): self._sdram_usage = defaultdict(lambda: 0) self._region_sizes = dict() self._vertices_by_chip = defaultdict(list) def __call__( self, placements, hostname, report_default_directory, write_text_specs, app_data_runtime_folder, machine, graph_mapper=None): """ :param placements: placements of machine graph to cores :param hostname: spinnaker machine name :param report_default_directory: the location where reports are stored :param write_text_specs:\ True if the textual version of the specification is to be written :param app_data_runtime_folder:\ Folder where data specifications should be written to :param machine: the python representation of the spinnaker machine :param graph_mapper:\ the mapping between application and machine graph :return: dsg targets (map of placement tuple and filename) """ # iterate though vertices and call generate_data_spec for each # vertex dsg_targets = dict() progress = ProgressBar( placements.n_placements, "Generating data specifications") for placement in progress.over(placements.placements): # Try to generate the data spec for the placement generated = self._generate_data_spec_for_vertices( placement, placement.vertex, dsg_targets, hostname, report_default_directory, write_text_specs, app_data_runtime_folder, machine) # If the spec wasn't generated directly, and there is an # application vertex, try with that if not generated and graph_mapper is not None: associated_vertex = graph_mapper.get_application_vertex( placement.vertex) self._generate_data_spec_for_vertices( placement, associated_vertex, dsg_targets, hostname, report_default_directory, write_text_specs, app_data_runtime_folder, machine) return dsg_targets def _generate_data_spec_for_vertices( self, placement, vertex, dsg_targets, hostname, report_default_directory, write_text_specs, app_data_runtime_folder, machine): """ :param placement: placement of machine graph to cores :param vertex: the specific vertex to write dsg for. :param hostname: spinnaker machine name :param report_default_directory: the location where reports are stored :param write_text_specs:\ True if the textual version of the specification is to be written :param app_data_runtime_folder: \ Folder where data specifications should be written to :param machine: the python representation of the spinnaker machine :return: True if the vertex was data specable, False otherwise """ # if the vertex can generate a DSG, call it if not isinstance(vertex, AbstractGeneratesDataSpecification): return False # build the writers for the reports and data data_writer_filename, spec = get_data_spec_and_file_writer_filename( placement.x, placement.y, placement.p, hostname, report_default_directory, write_text_specs, app_data_runtime_folder) # link dsg file to vertex dsg_targets[placement.x, placement.y, placement.p] = \ data_writer_filename # generate the dsg file vertex.generate_data_specification(spec, placement) # Check the memory usage self._region_sizes[placement.vertex] = spec.region_sizes self._vertices_by_chip[placement.x, placement.y].append( placement.vertex) self._sdram_usage[placement.x, placement.y] += sum( spec.region_sizes) if (self._sdram_usage[placement.x, placement.y] <= machine.get_chip_at(placement.x, placement.y).sdram.size): return True # creating the error message which contains the memory usage of # what each core within the chip uses and its original # estimate. memory_usage = "\n".join(( " {}: {} (total={}, estimated={})".format( vert, self._region_sizes[vert], sum(self._region_sizes[vert]), vert.resources_required.sdram.get_value()) for vert in self._vertices_by_chip[placement.x, placement.y])) raise ConfigurationException( "Too much SDRAM has been used on {}, {}. Vertices and" " their usage on that chip is as follows:\n{}".format( placement.x, placement.y, memory_usage))