def get_v(self, label, buffer_manager, region, state_region, placements, graph_mapper, partitionable_vertex): subvertices = \ graph_mapper.get_subvertices_from_vertex(partitionable_vertex) ms_per_tick = self._machine_time_step / 1000.0 data = list() missing_str = "" progress_bar = \ ProgressBar(len(subvertices), "Getting membrane voltage for {}".format(label)) for subvertex in subvertices: vertex_slice = graph_mapper.get_subvertex_slice(subvertex) placement = placements.get_placement_of_subvertex(subvertex) x = placement.x y = placement.y p = placement.p # for buffering output info is taken form the buffer manager neuron_param_region_data_pointer, missing_data =\ buffer_manager.get_data_for_vertex( placement, region, state_region) if missing_data: missing_str += "({}, {}, {}); ".format(x, y, p) record_raw = neuron_param_region_data_pointer.read_all() record_length = len(record_raw) n_rows = record_length / ((vertex_slice.n_atoms + 1) * 4) record = (numpy.asarray(record_raw, dtype="uint8"). view(dtype="<i4")).reshape((n_rows, (vertex_slice.n_atoms + 1))) split_record = numpy.array_split(record, [1, 1], 1) record_time = numpy.repeat( split_record[0] * float(ms_per_tick), vertex_slice.n_atoms, 1) record_ids = numpy.tile( numpy.arange(vertex_slice.lo_atom, vertex_slice.hi_atom + 1), len(record_time)).reshape((-1, vertex_slice.n_atoms)) record_membrane_potential = split_record[2] / 32767.0 part_data = numpy.dstack( [record_ids, record_time, record_membrane_potential]) part_data = numpy.reshape(part_data, [-1, 3]) data.append(part_data) progress_bar.update() progress_bar.end() if len(missing_str) > 0: logger.warn( "Population {} is missing membrane voltage data in region {}" " from the following cores: {}".format( label, region, missing_str)) data = numpy.vstack(data) order = numpy.lexsort((data[:, 1], data[:, 0])) result = data[order] return result
def get_spikes(self, label, buffer_manager, region, state_region, placements, graph_mapper, partitionable_vertex, base_key_function): results = list() missing_str = "" ms_per_tick = self._machine_time_step / 1000.0 subvertices = \ graph_mapper.get_subvertices_from_vertex(partitionable_vertex) progress_bar = ProgressBar(len(subvertices), "Getting spikes for {}".format(label)) for subvertex in subvertices: placement = placements.get_placement_of_subvertex(subvertex) subvertex_slice = graph_mapper.get_subvertex_slice(subvertex) x = placement.x y = placement.y p = placement.p # Read the spikes raw_spike_data, data_missing = \ buffer_manager.get_data_for_vertex( placement, region, state_region) if data_missing: missing_str += "({}, {}, {}); ".format(x, y, p) spike_data = str(raw_spike_data.read_all()) number_of_bytes_written = len(spike_data) offset = 0 while offset < number_of_bytes_written: eieio_header = EIEIODataHeader.from_bytestring( spike_data, offset) offset += eieio_header.size timestamp = eieio_header.payload_base * ms_per_tick timestamps = numpy.repeat([timestamp], eieio_header.count) keys = numpy.frombuffer( spike_data, dtype="<u4", count=eieio_header.count, offset=offset) neuron_ids = ((keys - base_key_function(subvertex)) + subvertex_slice.lo_atom) offset += eieio_header.count * 4 results.append(numpy.dstack((neuron_ids, timestamps))[0]) progress_bar.update() progress_bar.end() if len(missing_str) > 0: logger.warn( "Population {} is missing spike data in region {} from the" " following cores: {}".format(label, region, missing_str)) if len(results) != 0: result = numpy.vstack(results) result = result[numpy.lexsort((result[:, 1], result[:, 0]))] else: result = [] return result
def get_synaptic_list_from_machine(self, graph_mapper, partitioned_graph, placements, transceiver, routing_infos): """ Get synaptic data for all connections in this Projection from the\ machine. """ if self._stored_synaptic_data_from_machine is None: timer = None if conf.config.getboolean("Reports", "display_algorithm_timings"): timer = Timer() timer.start_timing() subedges = \ graph_mapper.get_partitioned_edges_from_partitionable_edge( self) if subedges is None: subedges = list() synaptic_list = copy.copy(self._synapse_list) synaptic_list_rows = synaptic_list.get_rows() progress_bar = ProgressBar( len(subedges), "Reading back synaptic matrix for edge between" " {} and {}".format(self._pre_vertex.label, self._post_vertex.label)) for subedge in subedges: n_rows = subedge.get_n_rows(graph_mapper) pre_vertex_slice = \ graph_mapper.get_subvertex_slice(subedge.pre_subvertex) post_vertex_slice = \ graph_mapper.get_subvertex_slice(subedge.post_subvertex) sub_edge_post_vertex = \ graph_mapper.get_vertex_from_subvertex( subedge.post_subvertex) rows = sub_edge_post_vertex.get_synaptic_list_from_machine( placements, transceiver, subedge.pre_subvertex, n_rows, subedge.post_subvertex, self._synapse_row_io, partitioned_graph, routing_infos, subedge.weight_scales).get_rows() for i in range(len(rows)): synaptic_list_rows[ i + pre_vertex_slice.lo_atom].set_slice_values( rows[i], vertex_slice=post_vertex_slice) progress_bar.update() progress_bar.end() self._stored_synaptic_data_from_machine = synaptic_list if conf.config.getboolean("Reports", "display_algorithm_timings"): logger.info("Time to read matrix: {}".format( timer.take_sample())) return self._stored_synaptic_data_from_machine
def _get_synaptic_data(self, as_list, data_to_get): post_vertex = self._projection_edge.post_vertex pre_vertex = self._projection_edge.pre_vertex # If in virtual board mode, the connection data should be set if self._virtual_connection_list is not None: post_vertex = self._projection_edge.post_vertex pre_vertex = self._projection_edge.pre_vertex return ConnectionHolder( data_to_get, as_list, pre_vertex.n_atoms, post_vertex.n_atoms, self._virtual_connection_list) connection_holder = ConnectionHolder( data_to_get, as_list, pre_vertex.n_atoms, post_vertex.n_atoms) # If we haven't run, add the holder to get connections, and return it if not self._spinnaker.has_ran: post_vertex.add_pre_run_connection_holder( connection_holder, self._projection_edge, self._synapse_information) return connection_holder # Otherwise, get the connections now graph_mapper = self._spinnaker.graph_mapper placements = self._spinnaker.placements transceiver = self._spinnaker.transceiver routing_infos = self._spinnaker.routing_infos partitioned_graph = self._spinnaker.partitioned_graph subedges = graph_mapper.get_partitioned_edges_from_partitionable_edge( self._projection_edge) progress = ProgressBar( len(subedges), "Getting {}s for projection between {} and {}".format( data_to_get, pre_vertex.label, post_vertex.label)) for subedge in subedges: placement = placements.get_placement_of_subvertex( subedge.post_subvertex) connections = post_vertex.get_connections_from_machine( transceiver, placement, subedge, graph_mapper, routing_infos, self._synapse_information, partitioned_graph) if connections is not None: connection_holder.add_connections(connections) progress.update() progress.end() connection_holder.finish() return connection_holder
def __call__( self, placements, graph_mapper, tags, executable_finder, partitioned_graph, partitionable_graph, routing_infos, hostname, report_default_directory, write_text_specs, app_data_runtime_folder): # Keep the results executable_targets = ExecutableTargets() dsg_targets = dict() # Keep delay extensions until the end delay_extension_placements = list() # create a progress bar for end users progress_bar = ProgressBar(len(list(placements.placements)), "Generating sPyNNaker data specifications") for placement in placements.placements: associated_vertex = graph_mapper.get_vertex_from_subvertex( placement.subvertex) if isinstance(associated_vertex, DelayExtensionVertex): delay_extension_placements.append( (placement, associated_vertex)) else: self._generate_data_spec_for_subvertices( placement, associated_vertex, executable_targets, dsg_targets, graph_mapper, tags, executable_finder, partitioned_graph, partitionable_graph, routing_infos, hostname, report_default_directory, write_text_specs, app_data_runtime_folder) progress_bar.update() for placement, associated_vertex in delay_extension_placements: self._generate_data_spec_for_subvertices( placement, associated_vertex, executable_targets, dsg_targets, graph_mapper, tags, executable_finder, partitioned_graph, partitionable_graph, routing_infos, hostname, report_default_directory, write_text_specs, app_data_runtime_folder) progress_bar.update() # finish the progress bar progress_bar.end() return {'executable_targets': executable_targets, 'dsg_targets': dsg_targets}
def __call__(self, subgraph, graph_mapper): """ :param subgraph: the subgraph whose edges are to be updated :param graph_mapper: the graph mapper between partitionable and \ partitioned graphs. """ # create progress bar progress_bar = ProgressBar( len(subgraph.subedges), "Updating edge weights") # start checking subedges to decide which ones need pruning.... for subedge in subgraph.subedges: if isinstance(subedge, AbstractWeightUpdatable): subedge.update_weight(graph_mapper) progress_bar.update() progress_bar.end() # return nothing return {'subgraph': subgraph}
def __call__(self, placements, machine, partitioned_graph, k=1, l=0, m=0, bw_per_route_entry=BW_PER_ROUTE_ENTRY, max_bw=MAX_BW): """ Find routes between the subedges with the allocated information, placed in the given places :param placements: The placements of the subedges :type placements:\ :py:class:`pacman.model.placements.placements.Placements` :param machine: The machine through which the routes are to be found :type machine: :py:class:`spinn_machine.machine.Machine` :param partitioned_graph: the partitioned_graph object :type partitioned_graph:\ :py:class:`pacman.partitioned_graph.partitioned_graph.PartitionedGraph` :return: The discovered routes :rtype:\ :py:class:`pacman.model.routing_tables.multicast_routing_tables.MulticastRoutingTables` :raise pacman.exceptions.PacmanRoutingException: If something\ goes wrong with the routing """ # set up basic data structures self._routing_paths = MulticastRoutingTableByPartition() self._k = k self._l = l self._m = m self._bw_per_route_entry = bw_per_route_entry self._max_bw = max_bw self._machine = machine nodes_info = self._initiate_node_info(machine) dijkstra_tables = self._initiate_dijkstra_tables(machine) self._update_all_weights(nodes_info, machine) # each subvertex represents a core in the board progress = ProgressBar(len(list(placements.placements)), "Creating routing entries") for placement in placements.placements: subvert = placement.subvertex out_going_sub_edges = \ partitioned_graph.outgoing_subedges_from_subvertex(subvert) out_going_sub_edges = filter( lambda edge: isinstance(edge, MultiCastPartitionedEdge), out_going_sub_edges) dest_chips = set() subedges_to_route = list() for subedge in out_going_sub_edges: destination_subvertex = subedge.post_subvertex destination_placement = placements.get_placement_of_subvertex( destination_subvertex) chip = machine.get_chip_at(destination_placement.x, destination_placement.y) dest_chips.add((chip.x, chip.y)) subedges_to_route.append(subedge) if len(dest_chips) != 0: self._update_all_weights(nodes_info, machine) self._reset_tables(dijkstra_tables) dijkstra_tables[(placement.x, placement.y)]["activated?"] = True dijkstra_tables[(placement.x, placement.y)]["lowest cost"] = 0 self._propagate_costs_until_reached_destinations( dijkstra_tables, nodes_info, dest_chips, placement.x, placement.y) for subedge in subedges_to_route: dest = subedge.post_subvertex dest_placement = placements.get_placement_of_subvertex(dest) self._retrace_back_to_source(dest_placement.x, dest_placement.y, dijkstra_tables, dest_placement.p, subedge, nodes_info, placement.p, partitioned_graph) progress.update() progress.end() return {'routing_paths': self._routing_paths}
def host_based_data_specification_execution( hostname, transceiver, write_text_specs, application_data_runtime_folder, machine, report_default_directory, app_id, dsg_targets): """ :param hostname: :param transceiver: :param write_text_specs: :param application_data_runtime_folder: :param machine: :param report_default_directory: :param app_id: :param dsg_targets: :return: """ processor_to_app_data_base_address = dict() # create a progress bar for end users progress_bar = ProgressBar( len(list(dsg_targets)), "Executing data specifications and loading data") for ((x, y, p), data_spec_file_path) in dsg_targets.iteritems(): # build specification reader data_spec_file_path = dsg_targets[x, y, p] data_spec_reader = FileDataReader(data_spec_file_path) # build application data writer app_data_file_path = \ AbstractDataSpecableVertex.get_application_data_file_path( x, y, p, hostname, application_data_runtime_folder) data_writer = FileDataWriter(app_data_file_path) # generate a file writer for DSE report (app pointer table) report_writer = None if write_text_specs: new_report_directory = os.path.join(report_default_directory, "data_spec_text_files") if not os.path.exists(new_report_directory): os.mkdir(new_report_directory) file_name = "{}_DSE_report_for_{}_{}_{}.txt".format( hostname, x, y, p) report_file_path = os.path.join(new_report_directory, file_name) report_writer = FileDataWriter(report_file_path) # maximum available memory # however system updates the memory available # independently, so the check on the space available actually # happens when memory is allocated chip = machine.get_chip_at(x, y) memory_available = chip.sdram.size # generate data spec executor host_based_data_spec_executor = DataSpecificationExecutor( data_spec_reader, data_writer, memory_available, report_writer) # run data spec executor try: # bytes_used_by_spec, bytes_written_by_spec = \ host_based_data_spec_executor.execute() except exceptions.DataSpecificationException as e: logger.error( "Error executing data specification for {}, {}, {}".format( x, y, p)) raise e bytes_used_by_spec = \ host_based_data_spec_executor.get_constructed_data_size() # allocate memory where the app data is going to be written # this raises an exception in case there is not enough # SDRAM to allocate start_address = transceiver.malloc_sdram(x, y, bytes_used_by_spec, app_id) # the base address address needs to be passed to the DSE to # generate the pointer table with absolute addresses host_based_data_spec_executor.write_dse_output_file(start_address) # close the application data file writer data_writer.close() # the data is written to memory file_reader = FileDataReader(app_data_file_path) app_data = file_reader.readall() bytes_written_by_spec = len(app_data) transceiver.write_memory(x, y, start_address, app_data) file_reader.close() # set user 0 register appropriately to the application data user_0_address = \ transceiver.get_user_0_register_address_from_core(x, y, p) start_address_encoded = \ buffer(struct.pack("<I", start_address)) transceiver.write_memory(x, y, user_0_address, start_address_encoded) # write information for the memory map report processor_to_app_data_base_address[x, y, p] = { 'start_address': start_address, 'memory_used': bytes_used_by_spec, 'memory_written': bytes_written_by_spec } # update the progress bar progress_bar.update() # close the progress bar progress_bar.end() return { 'processor_to_app_data_base_address': processor_to_app_data_base_address, 'LoadedApplicationDataToken': True }
def __call__(self, subgraph, n_keys_map, routing_tables): # check that this algorithm supports the constraints utility_calls.check_algorithm_can_support_constraints( constrained_vertices=subgraph.partitions, supported_constraints=[ KeyAllocatorFixedMaskConstraint, KeyAllocatorFixedKeyAndMaskConstraint, KeyAllocatorContiguousRangeContraint ], abstract_constraint_type=AbstractKeyAllocatorConstraint) # verify that no edge has more than 1 of a constraint ,and that # constraints are compatible routing_info_allocator_utilities.\ check_types_of_edge_constraint(subgraph) routing_infos = RoutingInfo() # Get the partitioned edges grouped by those that require the same key (fixed_key_groups, fixed_mask_groups, fixed_field_groups, flexi_field_groups, continuous_groups, none_continuous_groups) = \ routing_info_allocator_utilities.get_edge_groups(subgraph) # Even non-continuous keys will be continuous for group in none_continuous_groups: continuous_groups.add(group) # Go through the groups and allocate keys progress_bar = ProgressBar(len(subgraph.partitions), "Allocating routing keys") # allocate the groups that have fixed keys for group in fixed_key_groups: # fixed keys groups # Get any fixed keys and masks from the group and attempt to # allocate them fixed_mask = None fixed_key_and_mask_constraint = \ utility_calls.locate_constraints_of_type( group.constraints, KeyAllocatorFixedKeyAndMaskConstraint)[0] # attempt to allocate them self._allocate_fixed_keys_and_masks( fixed_key_and_mask_constraint.keys_and_masks, fixed_mask) # update the pacman data objects self._update_routing_objects( fixed_key_and_mask_constraint.keys_and_masks, routing_infos, group) continuous_groups.remove(group) progress_bar.update() for group in fixed_mask_groups: # fixed mask groups # get mask and fields if need be fixed_mask = utility_calls.locate_constraints_of_type( group.constraints, KeyAllocatorFixedMaskConstraint)[0].mask fields = None if group in fixed_field_groups: fields = utility_calls.locate_constraints_of_type( group.constraints, KeyAllocatorFixedFieldConstraint)[0].fields fixed_field_groups.remove(group) # try to allocate keys_and_masks = self._allocate_keys_and_masks( fixed_mask, fields, n_keys_map.n_keys_for_partition(group)) # update the pacman data objects self._update_routing_objects(keys_and_masks, routing_infos, group) continuous_groups.remove(group) progress_bar.update() for group in fixed_field_groups: fields = utility_calls.locate_constraints_of_type( group.constraints, KeyAllocatorFixedFieldConstraint)[0].fields # try to allocate keys_and_masks = self._allocate_keys_and_masks( None, fields, n_keys_map.n_keys_for_partition(group)) # update the pacman data objects self._update_routing_objects(keys_and_masks, routing_infos, group) continuous_groups.remove(group) progress_bar.update() if len(flexi_field_groups) != 0: raise exceptions.PacmanConfigurationException( "MallocBasedRoutingInfoAllocator does not support FlexiField") # Sort the rest of the groups, using the routing tables for guidance # Group partitions by those which share routes in any table partition_groups = OrderedDict() routers = reversed( sorted( routing_tables.get_routers(), key=lambda item: len( routing_tables.get_entries_for_router(item[0], item[1])))) for x, y in routers: # Find all partitions that share a route in this table partitions_by_route = defaultdict(OrderedSet) routing_table = routing_tables.get_entries_for_router(x, y) for partition, entry in routing_table.iteritems(): if partition in continuous_groups: entry_hash = sum([1 << i for i in entry.out_going_links]) entry_hash += sum( [1 << (i + 6) for i in entry.out_going_processors]) partitions_by_route[entry_hash].add(partition) for entry_hash, partitions in partitions_by_route.iteritems(): found_groups = list() for partition in partitions: if partition in partition_groups: found_groups.append(partition_groups[partition]) if len(found_groups) == 0: # If no group was found, create a new one for partition in partitions: partition_groups[partition] = partitions elif len(found_groups) == 1: # If a single other group was found, merge it for partition in partitions: found_groups[0].add(partition) partition_groups[partition] = found_groups[0] else: # Merge the groups new_group = partitions for group in found_groups: for partition in group: new_group.add(partition) for partition in new_group: partition_groups[partition] = new_group # Sort partitions by largest group continuous_groups = OrderedSet( tuple(group) for group in partition_groups.itervalues()) continuous_groups = reversed( sorted([group for group in continuous_groups], key=lambda group: len(group))) for group in continuous_groups: for partition in group: keys_and_masks = self._allocate_keys_and_masks( None, None, n_keys_map.n_keys_for_partition(partition)) # update the pacman data objects self._update_routing_objects(keys_and_masks, routing_infos, partition) progress_bar.update() progress_bar.end() return {'routing_infos': routing_infos}
def get_data(label, buffer_manager, region, placements, graph_mapper, application_vertex, machine_time_step, variable): """ method for reading a uint32 mapped to time and neuron ids from the SpiNNaker machine :param label: vertex label :param buffer_manager: the manager for buffered data :param region: the dsg region id used for this data :param placements: the placements object :param graph_mapper: the mapping between application and machine vertices :param application_vertex: :param machine_time_step: :param variable: :return: """ vertices = graph_mapper.get_machine_vertices(application_vertex) ms_per_tick = machine_time_step / 1000.0 data = list() missing_str = "" progress_bar = \ ProgressBar( len(vertices), "Getting {} for {}".format(variable, label)) for vertex in vertices: vertex_slice = graph_mapper.get_slice(vertex) placement = placements.get_placement_of_vertex(vertex) x = placement.x y = placement.y p = placement.p # for buffering output info is taken form the buffer manager neuron_param_region_data_pointer, missing_data = \ buffer_manager.get_data_for_vertex( placement, region) if missing_data: missing_str += "({}, {}, {}); ".format(x, y, p) record_raw = neuron_param_region_data_pointer.read_all() record_length = len(record_raw) n_rows = record_length / ((vertex_slice.n_atoms + 1) * 4) record = (numpy.asarray(record_raw, dtype="uint8").view(dtype="<i4")).reshape( (n_rows, (vertex_slice.n_atoms + 1))) split_record = numpy.array_split(record, [1, 1], 1) record_time = numpy.repeat(split_record[0] * float(ms_per_tick), vertex_slice.n_atoms, 1) record_ids = numpy.tile( numpy.arange(vertex_slice.lo_atom, vertex_slice.hi_atom + 1), len(record_time)).reshape((-1, vertex_slice.n_atoms)) record_membrane_potential = split_record[2] / 32767.0 part_data = numpy.dstack( [record_ids, record_time, record_membrane_potential]) part_data = numpy.reshape(part_data, [-1, 3]) data.append(part_data) progress_bar.update() progress_bar.end() if len(missing_str) > 0: logger.warn("Population {} is missing {} data in region {}" " from the following cores: {}".format( label, variable, region, missing_str)) data = numpy.vstack(data) order = numpy.lexsort((data[:, 1], data[:, 0])) result = data[order] return result
def __call__(self, subgraph, n_keys_map, graph_mapper=None): # check that this algorithm supports the constraints utility_calls.check_algorithm_can_support_constraints( constrained_vertices=subgraph.partitions, supported_constraints=[ KeyAllocatorFixedMaskConstraint, KeyAllocatorFixedKeyAndMaskConstraint, KeyAllocatorContiguousRangeContraint ], abstract_constraint_type=AbstractKeyAllocatorConstraint) # verify that no edge has more than 1 of a constraint ,and that # constraints are compatible routing_info_allocator_utilities.\ check_types_of_edge_constraint(subgraph) routing_infos = RoutingInfo() # Get the partitioned edges grouped by those that require the same key (fixed_key_groups, fixed_mask_groups, fixed_field_groups, flexi_field_groups, continuous_groups, none_continuous_groups) = \ routing_info_allocator_utilities.get_edge_groups(subgraph) # Even non-continuous keys will be continuous for group in none_continuous_groups: continuous_groups.add(group) # Go through the groups and allocate keys progress_bar = ProgressBar(len(subgraph.partitions), "Allocating routing keys") # allocate the groups that have fixed keys for group in fixed_key_groups: # fixed keys groups # Get any fixed keys and masks from the group and attempt to # allocate them fixed_mask = None fixed_key_and_mask_constraint = \ utility_calls.locate_constraints_of_type( group.constraints, KeyAllocatorFixedKeyAndMaskConstraint)[0] # attempt to allocate them self._allocate_fixed_keys_and_masks( fixed_key_and_mask_constraint.keys_and_masks, fixed_mask) # update the pacman data objects self._update_routing_objects( fixed_key_and_mask_constraint.keys_and_masks, routing_infos, group) continuous_groups.remove(group) progress_bar.update() for group in fixed_mask_groups: # fixed mask groups # get mask and fields if need be fixed_mask = utility_calls.locate_constraints_of_type( group.constraints, KeyAllocatorFixedMaskConstraint)[0].mask fields = None if group in fixed_field_groups: fields = utility_calls.locate_constraints_of_type( group.constraints, KeyAllocatorFixedFieldConstraint)[0].fields fixed_field_groups.remove(group) # try to allocate keys_and_masks = self._allocate_keys_and_masks( fixed_mask, fields, n_keys_map.n_keys_for_partition(group)) # update the pacman data objects self._update_routing_objects(keys_and_masks, routing_infos, group) continuous_groups.remove(group) progress_bar.update() for group in fixed_field_groups: fields = utility_calls.locate_constraints_of_type( group.constraints, KeyAllocatorFixedFieldConstraint)[0].fields # try to allocate keys_and_masks = self._allocate_keys_and_masks( None, fields, n_keys_map.n_keys_for_partition(group)) # update the pacman data objects self._update_routing_objects(keys_and_masks, routing_infos, group) continuous_groups.remove(group) progress_bar.update() if len(flexi_field_groups) != 0: raise exceptions.PacmanConfigurationException( "MallocBasedRoutingInfoAllocator does not support FlexiField") # If there is a graph, group by source vertex and sort by vertex slice # (lo_atom) if graph_mapper is not None: vertex_groups = defaultdict(list) for partition in continuous_groups: vertex = graph_mapper.get_vertex_from_subvertex( partition.edges[0].pre_subvertex) vertex_groups[vertex].append(partition) vertex_partitions = list() for vertex_group in vertex_groups.itervalues(): sorted_partitions = sorted( vertex_group, key=lambda part: graph_mapper.get_subvertex_slice( part.edges[0].pre_subvertex)) vertex_partitions.extend(sorted_partitions) continuous_groups = vertex_partitions for group in continuous_groups: keys_and_masks = self._allocate_keys_and_masks( None, None, n_keys_map.n_keys_for_partition(group)) # update the pacman data objects self._update_routing_objects(keys_and_masks, routing_infos, group) progress_bar.end() return {'routing_infos': routing_infos}
def __call__(self, partitioned_graph, placements, n_keys_map): """ Allocates routing information to the partitioned edges in a\ partitioned graph :param partitioned_graph: The partitioned graph to allocate the \ outing info for :type partitioned_graph:\ :py:class:`pacman.model.partitioned_graph.partitioned_graph.PartitionedGraph` :param placements: The placements of the subvertices :type placements:\ :py:class:`pacman.model.placements.placements.Placements` :param n_keys_map: A map between the partitioned edges and the number\ of keys required by the edges :type n_keys_map:\ :py:class:`pacman.model.routing_info.abstract_partitioned_edge_n_keys_map.AbstractPartitionedEdgeNKeysMap` :return: The routing information :rtype: :py:class:`pacman.model.routing_info.routing_info.RoutingInfo`, :py:class:`pacman.model.routing_tables.multicast_routing_table.MulticastRoutingTable :raise pacman.exceptions.PacmanRouteInfoAllocationException: If\ something goes wrong with the allocation """ # check that this algorithm supports the constraints put onto the # partitioned_edges supported_constraints = [KeyAllocatorContiguousRangeContraint] utility_calls.check_algorithm_can_support_constraints( constrained_vertices=partitioned_graph.partitions, supported_constraints=supported_constraints, abstract_constraint_type=AbstractKeyAllocatorConstraint) # take each subedge and create keys from its placement progress_bar = ProgressBar(len(partitioned_graph.subvertices), "Allocating routing keys") routing_infos = RoutingInfo() for subvert in partitioned_graph.subvertices: partitions = partitioned_graph.\ outgoing_edges_partitions_from_vertex(subvert) for partition in partitions.values(): n_keys = n_keys_map.n_keys_for_partition(partition) if n_keys > MAX_KEYS_SUPPORTED: raise PacmanRouteInfoAllocationException( "This routing info allocator can only support up to {}" " keys for any given subedge; cannot therefore" " allocate keys to {}, which is requesting {} keys". format(MAX_KEYS_SUPPORTED, partition, n_keys)) placement = placements.get_placement_of_subvertex(subvert) if placement is not None: key = self._get_key_from_placement(placement) keys_and_masks = list( [BaseKeyAndMask(base_key=key, mask=MASK)]) subedge_routing_info = PartitionRoutingInfo( keys_and_masks, partition) routing_infos.add_partition_info(subedge_routing_info) else: raise PacmanRouteInfoAllocationException( "This subvertex '{}' has no placement! this should " "never occur, please fix and try again.".format( subvert)) progress_bar.update() progress_bar.end() return {'routing_infos': routing_infos}
def __call__(self, placements, tags, partitioned_graph, routing_infos, hostname, report_default_directory, write_text_specs, app_data_runtime_folder, executable_finder): """ generates the dsg for the graph. :return: """ # iterate though subvertices and call generate_data_spec for each # vertex executable_targets = ExecutableTargets() dsg_targets = dict() # create a progress bar for end users progress_bar = ProgressBar(len(list(placements.placements)), "Generating data specifications") for placement in placements.placements: if isinstance(placement.subvertex, AbstractPartitionedDataSpecableVertex): ip_tags = tags.get_ip_tags_for_vertex(placement.subvertex) reverse_ip_tags = \ tags.get_reverse_ip_tags_for_vertex( placement.subvertex) file_path = placement.subvertex.generate_data_spec( placement, partitioned_graph, routing_infos, hostname, report_default_directory, ip_tags, reverse_ip_tags, write_text_specs, app_data_runtime_folder) # link dsg file to subvertex dsg_targets[placement.x, placement.y, placement.p] = file_path progress_bar.update() # Get name of binary from vertex binary_name = placement.subvertex.get_binary_file_name() # Attempt to find this within search paths binary_path = executable_finder.get_executable_path( binary_name) if binary_path is None: raise exceptions.ExecutableNotFoundException(binary_name) if not executable_targets.has_binary(binary_path): executable_targets.add_binary(binary_path) executable_targets.add_processor(binary_path, placement.x, placement.y, placement.p) elif isinstance(placement.subvertex, AbstractDataSpecableVertex): ip_tags = tags.get_ip_tags_for_vertex(placement.subvertex) reverse_ip_tags = \ tags.get_reverse_ip_tags_for_vertex( placement.subvertex) file_path = placement.subvertex.generate_data_spec( placement.subvertex, placement, partitioned_graph, None, routing_infos, hostname, None, report_default_directory, ip_tags, reverse_ip_tags, write_text_specs, app_data_runtime_folder) # link dsg file to subvertex mapping_key = \ placement.x, placement.y, placement.p, \ placement.subvertex.label dsg_targets[mapping_key] = file_path progress_bar.update() # Get name of binary from vertex binary_name = placement.subvertex.get_binary_file_name() # Attempt to find this within search paths binary_path = executable_finder.get_executable_path( binary_name) if binary_path is None: raise exceptions.ExecutableNotFoundException(binary_name) if not executable_targets.has_binary(binary_path): executable_targets.add_binary(binary_path) executable_targets.add_processor(binary_path, placement.x, placement.y, placement.p) else: progress_bar.update() # Get name of binary from vertex binary_name = placement.subvertex.get_binary_file_name() # Attempt to find this within search paths binary_path = executable_finder.get_executable_path( binary_name) if binary_path is None: raise exceptions.ExecutableNotFoundException(binary_name) if not executable_targets.has_binary(binary_path): executable_targets.add_binary(binary_path) executable_targets.add_processor(binary_path, placement.x, placement.y, placement.p) # finish the progress bar progress_bar.end() return { 'executable_targets': executable_targets, 'dsg_targets': dsg_targets }
def __call__(self, partitioned_graph, machine, placements): progress_bar = ProgressBar(8, "Routing") vertices_resources, nets, net_names = \ rig_converters.convert_to_rig_partitioned_graph( partitioned_graph) progress_bar.update() rig_machine = rig_converters.convert_to_rig_machine(machine) progress_bar.update() rig_constraints = rig_converters.create_rig_machine_constraints( machine) progress_bar.update() rig_constraints.extend( rig_converters.create_rig_partitioned_graph_constraints( partitioned_graph, rig_machine)) progress_bar.update() rig_placements, rig_allocations = \ rig_converters.convert_to_rig_placements(placements) progress_bar.update() rig_routes = route(vertices_resources, nets, rig_machine, rig_constraints, rig_placements, rig_allocations, "cores") rig_routes = { name: rig_routes[net] for net, name in net_names.iteritems() } progress_bar.update() placements = rig_converters.convert_from_rig_placements( rig_placements, rig_allocations, partitioned_graph) progress_bar.update() routes = rig_converters.convert_from_rig_routes( rig_routes, partitioned_graph) progress_bar.update() progress_bar.end() return {"routing_paths": routes}
def get_spikes( self, label, buffer_manager, region, placements, graph_mapper, application_vertex, machine_time_step): spike_times = list() spike_ids = list() ms_per_tick = machine_time_step / 1000.0 vertices = \ graph_mapper.get_machine_vertices(application_vertex) missing_str = "" progress_bar = ProgressBar(len(vertices), "Getting spikes for {}".format(label)) for vertex in vertices: placement = placements.get_placement_of_vertex(vertex) vertex_slice = graph_mapper.get_slice(vertex) x = placement.x y = placement.y p = placement.p lo_atom = vertex_slice.lo_atom # Read the spikes n_words = int(math.ceil(vertex_slice.n_atoms / 32.0)) n_bytes_per_block = n_words * 4 # for buffering output info is taken form the buffer manager neuron_param_region_data_pointer, data_missing = \ buffer_manager.get_data_for_vertex( placement, region) if data_missing: missing_str += "({}, {}, {}); ".format(x, y, p) raw_data = neuron_param_region_data_pointer.read_all() offset = 0 while offset < len(raw_data): ((time, n_blocks), offset) = ( struct.unpack_from("<II", raw_data, offset), offset + 8) (spike_data, offset) = (numpy.frombuffer( raw_data, dtype="uint8", count=n_bytes_per_block * n_blocks, offset=offset), offset + (n_bytes_per_block * n_blocks)) spikes = spike_data.view("<i4").byteswap().view("uint8") bits = numpy.fliplr(numpy.unpackbits(spikes).reshape( (-1, 32))).reshape((-1, n_bytes_per_block * 8)) indices = numpy.nonzero(bits)[1] times = numpy.repeat([time * ms_per_tick], len(indices)) indices = indices + lo_atom spike_ids.append(indices) spike_times.append(times) progress_bar.update() progress_bar.end() if len(missing_str) > 0: logger.warn( "Population {} is missing spike data in region {} from the" " following cores: {}".format(label, region, missing_str)) if len(spike_ids) > 0: spike_ids = numpy.hstack(spike_ids) spike_times = numpy.hstack(spike_times) result = numpy.dstack((spike_ids, spike_times))[0] return result[numpy.lexsort((spike_times, spike_ids))] return numpy.zeros((0, 2))
def run_model(data, n_chips=None, n_ihcan=0, fs=44100, resample_factor=1): # Set up the simulation g.setup(n_chips_required=n_chips, model_binary_module=model_binaries) # Get the number of cores available for use n_cores = 0 machine = g.machine() # Create a OME for each chip boards = dict() #changed to lists to ensure data is read back in the same order that verticies are instantiated ihcans = list() cf_index = 0 count = 0 for chip in machine.chips: if count >= n_chips: break else: boards[chip.x, chip.y] = chip.ip_address for j in range(n_ihcan): ihcan = IHCANVertex(data[j][:], fs, resample_factor) g.add_machine_vertex_instance(ihcan) # constrain placement to local chip ihcan.add_constraint(ChipAndCoreConstraint(chip.x, chip.y)) #ihcans[chip.x, chip.y,j] = ihcan ihcans.append(ihcan) count = count + 1 # Run the simulation g.run(None) # Wait for the application to finish txrx = g.transceiver() app_id = globals_variables.get_simulator()._app_id #logger.info("Running {} worker cores".format(n_workers)) logger.info("Waiting for application to finish...") running = txrx.get_core_state_count(app_id, CPUState.RUNNING) while running > 0: time.sleep(0.5) error = txrx.get_core_state_count(app_id, CPUState.RUN_TIME_EXCEPTION) watchdog = txrx.get_core_state_count(app_id, CPUState.WATCHDOG) if error > 0 or watchdog > 0: error_msg = "Some cores have failed ({} RTE, {} WDOG)".format( error, watchdog) raise Exception(error_msg) running = txrx.get_core_state_count(app_id, CPUState.RUNNING) # Get the data back samples = list() progress = ProgressBar(len(ihcans), "Reading results") for ihcan in ihcans: samples.append(ihcan.read_samples(g.buffer_manager())) progress.update() progress.end() samples = numpy.hstack(samples) # Close the machine g.stop() print "channels running: ", len(ihcans) / 5.0 print "output data: {} fibres with length {}".format( len(ihcans) * 2, len(samples)) #if(len(samples) != len(ihcans)*2*numpy.floor(len(data[0][0])/100)*100*(1.0/resample_factor)): if (len(samples) != len(ihcans) * 2 * numpy.floor(len(data[0][0]) / 96) * 96): #print "samples length {} isn't expected size {}".format(len(samples),len(ihcans)*2*numpy.floor(len(data[0][0])/100)*100*(1.0/resample_factor)) print "samples length {} isn't expected size {}".format( len(samples), len(ihcans) * 2 * numpy.floor(len(data[0][0]) / 96) * 96) return samples
def __call__(self, machine, file_path): """ :param machine: :param file_path: :return: """ progress_bar = ProgressBar( ((machine.max_chip_x + 1) * (machine.max_chip_y + 1)) + 2, "Converting to json machine") # write basic stuff json_dictory_rep = dict() json_dictory_rep['width'] = machine.max_chip_x + 1 json_dictory_rep['height'] = machine.max_chip_y + 1 json_dictory_rep['chip_resources'] = dict() json_dictory_rep['chip_resources']['cores'] = CHIP_HOMOGENIOUS_CORES json_dictory_rep['chip_resources']['sdram'] = CHIP_HOMOGENIOUS_SDRAM json_dictory_rep['chip_resources']['sram'] = CHIP_HOMOGENIOUS_SRAM json_dictory_rep['chip_resources']["router_entries"] = \ ROUTER_HOMOGENIOUS_ENTRIES json_dictory_rep['chip_resources']['tags'] = CHIP_HOMOGENIOUS_TAGS # handle exceptions json_dictory_rep['dead_chips'] = list() json_dictory_rep['dead_links'] = list() chip_resource_exceptions = defaultdict() # write dead chips for x_coord in range(0, machine.max_chip_x + 1): for y_coord in range(0, machine.max_chip_y + 1): if (not machine.is_chip_at(x_coord, y_coord) or machine.get_chip_at(x_coord, y_coord).virtual): json_dictory_rep['dead_chips'].append([x_coord, y_coord]) else: # write dead links for link_id in range(0, ROUTER_MAX_NUMBER_OF_LINKS): router = machine.get_chip_at(x_coord, y_coord).router if not router.is_link(link_id): json_dictory_rep['dead_links'].append([ x_coord, y_coord, "{}".format( constants.EDGES(link_id).name.lower()) ]) self._check_for_exceptions(json_dictory_rep, x_coord, y_coord, machine, chip_resource_exceptions) progress_bar.update() # convert dict into list chip_resouce_exceptions_list = [] for (chip_x, chip_y) in chip_resource_exceptions: chip_resouce_exceptions_list.append( [chip_x, chip_y, chip_resource_exceptions[(chip_x, chip_y)]]) progress_bar.update() # store exceptions into json form json_dictory_rep['chip_resource_exceptions'] = \ chip_resouce_exceptions_list # dump to json file file_to_write = open(file_path, "w") json.dump(json_dictory_rep, file_to_write) file_to_write.close() # validate the schema machine_schema_file_path = os.path.join( os.path.dirname(file_format_schemas.__file__), "machine.json") file_to_read = open(machine_schema_file_path, "r") machine_schema = json.load(file_to_read) jsonschema.validate(json_dictory_rep, machine_schema) # update and complete progress bar progress_bar.update() progress_bar.end() return {'file_machine': file_path}
def __call__(self, app_id, txrx, executable_targets, has_ran): if not has_ran: raise exceptions.ConfigurationException( "The ran token is not set correctly, please fix and try again") total_processors = executable_targets.total_processors all_core_subsets = executable_targets.all_core_subsets progress_bar = ProgressBar( total_processors, "Turning off all the cores within the simulation") # check that the right number of processors are in sync0 processors_finished = txrx.get_core_state_count( app_id, CPUState.FINISHED) finished_cores = processors_finished while processors_finished != total_processors: if processors_finished > finished_cores: progress_bar.update(finished_cores - processors_finished) finished_cores = processors_finished processors_rte = txrx.get_core_state_count( app_id, CPUState.RUN_TIME_EXCEPTION) processors_watchdogged = txrx.get_core_state_count( app_id, CPUState.WATCHDOG) if processors_rte > 0 or processors_watchdogged > 0: error_cores = helpful_functions.get_cores_in_state( all_core_subsets, {CPUState.RUN_TIME_EXCEPTION, CPUState.WATCHDOG}, txrx) fail_message = helpful_functions.get_core_status_string( error_cores) raise exceptions.ExecutableFailedToStopException( "{} of {} processors went into an error state when" " shutting down: {}".format( processors_rte + processors_watchdogged, total_processors, fail_message), helpful_functions.get_core_subsets(error_cores), True) successful_cores_finished = set( helpful_functions.get_cores_in_state(all_core_subsets, CPUState.FINISHED, txrx)) all_cores = set(all_core_subsets) unsuccessful_cores = all_cores - successful_cores_finished for core_subset in unsuccessful_cores: for processor in core_subset.processor_ids: byte_data = struct.pack( "<I", constants.SDP_RUNNING_MESSAGE_CODES. SDP_STOP_ID_CODE.value) txrx.send_sdp_message( SDPMessage(sdp_header=SDPHeader( flags=SDPFlag.REPLY_NOT_EXPECTED, destination_port=(constants.SDP_PORTS. RUNNING_COMMAND_SDP_PORT.value), destination_cpu=processor, destination_chip_x=core_subset.x, destination_chip_y=core_subset.y), data=byte_data)) processors_finished = txrx.get_core_state_count( app_id, CPUState.FINISHED) progress_bar.end()
def __init__( self, width=None, height=None, with_wrap_arounds=False, version=None, n_cpus_per_chip=18, with_monitors=True, sdram_per_chip=None): """ :param width: the width of the virtual machine in chips :type width: int :param height: the height of the virtual machine in chips :type height: int :param with_wrap_arounds: bool defining if wrap around links exist :type with_wrap_arounds: bool :param version: the version id of a board; if None, a machine is\ created with the correct dimensions, otherwise the machine\ will be a single board of the given version :type version: int :param n_cpus_per_chip: The number of CPUs to put on each chip :type n_cpus_per_chip: int :param with_monitors: True if CPU 0 should be marked as a monitor :type with_monitors: bool :param sdram_per_chip: The amount of SDRAM to give to each chip :type sdram_per_chip: int or None """ Machine.__init__(self, ()) if ((width is not None and width < 0) or (height is not None and height < 0)): raise exceptions.SpinnMachineInvalidParameterException( "width or height", "{} or {}".format(width, height), "Negative dimensions are not supported") if version is None and (width is None or height is None): raise exceptions.SpinnMachineInvalidParameterException( "version, width, height", "{}, {}, {}".format(version, width, height), "Either version must be specified, " "or width and height must both be specified") if version is not None and (version < 2 or version > 5): raise exceptions.SpinnMachineInvalidParameterException( "version", str(version), "Version must be between 2 and 5 inclusive or None") if ((version == 5 or version == 4) and with_wrap_arounds is not None and with_wrap_arounds): raise exceptions.SpinnMachineInvalidParameterException( "version and with_wrap_arounds", "{} and True".format(version), "A version {} board does not have wrap arounds; set " "version to None or with_wrap_arounds to None".format(version)) if (version == 2 or version == 3) and with_wrap_arounds is not None: raise exceptions.SpinnMachineInvalidParameterException( "version and with_wrap_arounds", "{} and {}".format(version, with_wrap_arounds), "A version {} board has complex wrap arounds; set " "version to None or with_wrap_arounds to None".format(version)) if ((version == 5 or version == 4) and ( (width is not None and width != 8) or (height is not None and height != 8))): raise exceptions.SpinnMachineInvalidParameterException( "version, width, height", "{}, {}, {}".format(version, width, height), "A version {} board has a width and height of 8; set " "version to None or width and height to None".format(version)) if ((version == 2 or version == 3) and ( (width is not None and width != 2) or (height is not None and height != 2))): raise exceptions.SpinnMachineInvalidParameterException( "version, width, height", "{}, {}, {}".format(version, width, height), "A version {} board has a width and height of 2; set " "version to None or width and height to None".format(version)) if version == 5 or version == 4: if width is None: width = 8 if height is None: height = 8 with_wrap_arounds = False if version == 2 or version == 3: if width is None: width = 2 if height is None: height = 2 with_wrap_arounds = True # if x and y are none, assume a 48 chip board logger.debug("width = {} and height = {}".format(width, height)) # calculate the chip ids which this machine is going to have chip_ids = list() for i in xrange(width): for j in xrange(height): coords = (i, j) if (version == 5 and width == 8 and height == 8 and coords in _48boardgaps): # a chip doesn't exist in this static position # on these boards, so nullify it pass else: chip_ids.append((i, j)) progress_bar = ProgressBar( width * height, "Generating a virtual machine") # Create the chips and their links for i in xrange(width): for j in xrange(height): coords = (i, j) if (version == 5 and width == 8 and height == 8 and coords in _48boardgaps): # a chip doesn't exist in this static position # on these boards, so nullify it pass else: processors = list() for processor_id in range(0, n_cpus_per_chip): processor = Processor(processor_id, 200000000) if processor_id == 0 and with_monitors: processor.is_monitor = True processors.append(processor) chip_links = self._calculate_links( i, j, width, height, with_wrap_arounds, version, chip_ids) chip_router = Router(chip_links, False) if sdram_per_chip is None: sdram = SDRAM() else: system_base_address = ( SDRAM.DEFAULT_BASE_ADDRESS + sdram_per_chip) sdram = SDRAM(system_base_address=system_base_address) chip = Chip(i, j, processors, chip_router, sdram, 0, 0, "127.0.0.1") self.add_chip(chip) progress_bar.update() progress_bar.end() processor_count = 0 for chip in self.chips: processor_count += len(list(chip.processors)) link_count = 0 for chip in self.chips: link_count += len(list(chip.router.links)) logger.debug( "Static Allocation Complete;" " {} calculated app cores and {} links!".format( processor_count, link_count))
def get_spikes(self, label, buffer_manager, region, state_region, placements, graph_mapper, partitionable_vertex): spike_times = list() spike_ids = list() ms_per_tick = self._machine_time_step / 1000.0 subvertices = \ graph_mapper.get_subvertices_from_vertex(partitionable_vertex) missing_str = "" progress_bar = ProgressBar(len(subvertices), "Getting spikes for {}".format(label)) for subvertex in subvertices: placement = placements.get_placement_of_subvertex(subvertex) subvertex_slice = graph_mapper.get_subvertex_slice(subvertex) x = placement.x y = placement.y p = placement.p lo_atom = subvertex_slice.lo_atom # Read the spikes n_words = int(math.ceil(subvertex_slice.n_atoms / 32.0)) n_bytes = n_words * 4 n_words_with_timestamp = n_words + 1 # for buffering output info is taken form the buffer manager neuron_param_region_data_pointer, data_missing = \ buffer_manager.get_data_for_vertex( placement, region, state_region) if data_missing: missing_str += "({}, {}, {}); ".format(x, y, p) record_raw = neuron_param_region_data_pointer.read_all() raw_data = (numpy.asarray(record_raw, dtype="uint8"). view(dtype="<i4")).reshape( [-1, n_words_with_timestamp]) split_record = numpy.array_split(raw_data, [1, 1], 1) record_time = split_record[0] * float(ms_per_tick) spikes = split_record[2].byteswap().view("uint8") bits = numpy.fliplr(numpy.unpackbits(spikes).reshape( (-1, 32))).reshape((-1, n_bytes * 8)) time_indices, indices = numpy.where(bits == 1) times = record_time[time_indices].reshape((-1)) indices = indices + lo_atom spike_ids.append(indices) spike_times.append(times) progress_bar.update() progress_bar.end() if len(missing_str) > 0: logger.warn( "Population {} is missing spike data in region {} from the" " following cores: {}".format(label, region, missing_str)) spike_ids = numpy.hstack(spike_ids) spike_times = numpy.hstack(spike_times) result = numpy.dstack((spike_ids, spike_times))[0] return result[numpy.lexsort((spike_times, spike_ids))]
def __call__(self, report_default_directory, dsg_targets, transceiver): """ :param report_default_directory: :param processor_to_app_data_base_address: :return: """ directory_name = os.path.join( report_default_directory, MEM_MAP_SUBDIR_NAME) if not os.path.exists(directory_name): os.makedirs(directory_name) progress_bar = ProgressBar(len(dsg_targets), "Writing memory map reports") for (x, y, p) in dsg_targets: file_name = os.path.join( directory_name, "memory_map_from_processor" "_{0:d}_{1:d}_{2:d}.txt".format(x, y, p)) output = None try: output = open(file_name, "w") except IOError: logger.error("Generate_placement_reports: Can't open file" " {} for writing.".format(file_name)) output.write("On chip data specification executor\n\n") report_data_address_pointer = transceiver.\ get_user_1_register_address_from_core(x, y, p) report_data_address_encoded = buffer(transceiver.read_memory( x, y, report_data_address_pointer, 4)) report_data_address = struct.unpack_from( "<I", report_data_address_encoded)[0] report_bytes = \ _MemoryChannelState.STRUCT_SIZE * constants.MAX_MEM_REGIONS mem_map_report_data = buffer(transceiver.read_memory( x, y, report_data_address, report_bytes)) offset = 0 for i in xrange(constants.MAX_MEM_REGIONS): region = _MemoryChannelState.from_bytestring( mem_map_report_data, offset) offset += _MemoryChannelState.STRUCT_SIZE if region.start_address == 0: output.write("Region {0:d}: Unused\n\n".format(i)) else: if region.unfilled: space_written = 0 else: space_written = region.written output.write( "Region {0:d}:\n\t" "start address: 0x{1:x}\n\t" "size: {2:d}\n\t" "unfilled: {3:s}\n\t" "write pointer: 0x{4:x}\n\t" "size currently written(based on the " "write pointer): {5:d}\n\n".format( i, region.start_address, region.size, region.unfilled_tf, region.write_pointer, space_written)) output.flush() output.close() progress_bar.update() progress_bar.end()
def __call__(self, machine, placements): """ see AbstractTagAllocatorAlgorithm.allocate_tags """ resource_tracker = ResourceTracker(machine) # Check that the algorithm can handle the constraints progress_bar = ProgressBar(placements.n_placements, "Allocating tags") placements_with_tags = list() for placement in placements.placements: utility_calls.check_algorithm_can_support_constraints( constrained_vertices=[placement.subvertex], supported_constraints=[ TagAllocatorRequireIptagConstraint, TagAllocatorRequireReverseIptagConstraint ], abstract_constraint_type=AbstractTagAllocatorConstraint) if len( utility_calls.locate_constraints_of_type( placement.subvertex.constraints, AbstractTagAllocatorConstraint)): placements_with_tags.append(placement) progress_bar.update() # Go through and allocate the tags tags = Tags() for placement in placements_with_tags: vertex = placement.subvertex # Get the constraint details for the tags (board_address, ip_tags, reverse_ip_tags) =\ utility_calls.get_ip_tag_info(vertex.constraints) # Allocate the tags, first-come, first-served, using the # fixed placement of the vertex, and the required resources chips = [(placement.x, placement.y)] resources = vertex.resources_required (_, _, _, returned_ip_tags, returned_reverse_ip_tags) = \ resource_tracker.allocate_resources( resources, chips, placement.p, board_address, ip_tags, reverse_ip_tags) # Put the allocated ip tag information into the tag object if returned_ip_tags is not None: for (tag_constraint, (board_address, tag)) in zip(ip_tags, returned_ip_tags): ip_tag = IPTag(board_address, tag, tag_constraint.ip_address, tag_constraint.port, tag_constraint.strip_sdp) tags.add_ip_tag(ip_tag, vertex) # Put the allocated reverse ip tag information into the tag object if returned_reverse_ip_tags is not None: for (tag_constraint, (board_address, tag)) in zip(reverse_ip_tags, returned_reverse_ip_tags): reverse_ip_tag = ReverseIPTag(board_address, tag, tag_constraint.port, placement.x, placement.y, placement.p, tag_constraint.sdp_port) tags.add_reverse_ip_tag(reverse_ip_tag, vertex) progress_bar.end() return {'tags': tags}
def get_spikes(self, label, buffer_manager, region, state_region, placements, graph_mapper, partitionable_vertex): spike_times = list() spike_ids = list() ms_per_tick = self._machine_time_step / 1000.0 subvertices = \ graph_mapper.get_subvertices_from_vertex(partitionable_vertex) missing_str = "" progress_bar = ProgressBar(len(subvertices), "Getting spikes for {}".format(label)) for subvertex in subvertices: placement = placements.get_placement_of_subvertex(subvertex) subvertex_slice = graph_mapper.get_subvertex_slice(subvertex) x = placement.x y = placement.y p = placement.p lo_atom = subvertex_slice.lo_atom # Read the spikes n_words = int(math.ceil(subvertex_slice.n_atoms / 32.0)) n_bytes_per_block = n_words * 4 # for buffering output info is taken form the buffer manager neuron_param_region_data_pointer, data_missing = \ buffer_manager.get_data_for_vertex( placement, region, state_region) if data_missing: missing_str += "({}, {}, {}); ".format(x, y, p) raw_data = neuron_param_region_data_pointer.read_all() offset = 0 while offset < len(raw_data): ((time, n_blocks), offset) = ( struct.unpack_from("<II", raw_data, offset), offset + 8) (spike_data, offset) = (numpy.frombuffer( raw_data, dtype="uint8", count=n_bytes_per_block * n_blocks, offset=offset), offset + (n_bytes_per_block * n_blocks)) spikes = spike_data.view("<i4").byteswap().view("uint8") bits = numpy.fliplr(numpy.unpackbits(spikes).reshape( (-1, 32))).reshape((-1, n_bytes_per_block * 8)) indices = numpy.nonzero(bits)[1] times = numpy.repeat([time * ms_per_tick], len(indices)) indices = indices + lo_atom spike_ids.append(indices) spike_times.append(times) progress_bar.update() progress_bar.end() if len(missing_str) > 0: logger.warn( "Population {} is missing spike data in region {} from the" " following cores: {}".format(label, region, missing_str)) spike_ids = numpy.hstack(spike_ids) spike_times = numpy.hstack(spike_times) result = numpy.dstack((spike_ids, spike_times))[0] return result[numpy.lexsort((spike_times, spike_ids))]
def __call__(self, graph, machine): """ Partition a partitionable_graph so that each subvertex will fit\ on a processor within the machine :param graph: The partitionable_graph to partition :type graph:\ :py:class:`pacman.model.graph.partitionable_graph.PartitionableGraph` :param machine: The machine with respect to which to partition the\ partitionable_graph :type machine: :py:class:`spinn_machine.machine.Machine` :return: A partitioned_graph of partitioned vertices and partitioned\ edges :rtype:\ :py:class:`pacman.model.partitioned_graph.partitioned_graph.PartitionedGraph` :raise pacman.exceptions.PacmanPartitionException: If something\ goes wrong with the partitioning """ utility_calls.check_algorithm_can_support_constraints( constrained_vertices=graph.vertices, abstract_constraint_type=AbstractPartitionerConstraint, supported_constraints=[PartitionerMaximumSizeConstraint, PartitionerSameSizeAsVertexConstraint]) # Load the vertices and create the subgraph to fill vertices = graph.vertices subgraph = PartitionedGraph( label="partitioned graph for {}".format(graph.label)) graph_mapper = GraphMapper(graph.label, subgraph.label) # sort out vertex's by constraints vertices = utility_calls.sort_objects_by_constraint_authority(vertices) # Set up the progress n_atoms = 0 for vertex in vertices: n_atoms += vertex.n_atoms progress_bar = ProgressBar(n_atoms, "Partitioning graph vertices") resource_tracker = ResourceTracker(machine) # Partition one vertex at a time for vertex in vertices: # check that the vertex hasn't already been partitioned subverts_from_vertex = \ graph_mapper.get_subvertices_from_vertex(vertex) # if not, partition if subverts_from_vertex is None: self._partition_vertex( vertex, subgraph, graph_mapper, resource_tracker, graph) progress_bar.update(vertex.n_atoms) progress_bar.end() partition_algorithm_utilities.generate_sub_edges( subgraph, graph_mapper, graph) results = dict() results['partitioned_graph'] = subgraph results['graph_mapper'] = graph_mapper results['nChips'] = len(resource_tracker.keys) return results