def _find_one_to_one_vertices(vertex, graph): """ Find vertices which have one to one connections with the given\ vertex, and where their constraints don't force them onto\ different chips. :param graph: the graph to look for other one to one vertices :param vertex: the vertex to use as a basis for one to one connections :return: set of one to one vertices """ # Virtual vertices can't be forced on other chips if isinstance(vertex, AbstractVirtualVertex): return [] found_vertices = set() vertices_seen = {vertex} # look for one to ones leaving this vertex outgoing = graph.get_edges_starting_at_vertex(vertex) vertices_to_try = [ edge.post_vertex for edge in outgoing if edge.post_vertex not in vertices_seen] while vertices_to_try: next_vertex = vertices_to_try.pop() if next_vertex not in vertices_seen and \ not isinstance(next_vertex, AbstractVirtualVertex): vertices_seen.add(next_vertex) edges = graph.get_edges_ending_at_vertex(next_vertex) if is_single(edges): found_vertices.add(next_vertex) outgoing = graph.get_edges_starting_at_vertex(next_vertex) vertices_to_try.extend([ edge.post_vertex for edge in outgoing if edge.post_vertex not in vertices_seen]) # look for one to ones entering this vertex incoming = graph.get_edges_ending_at_vertex(vertex) vertices_to_try = [ edge.pre_vertex for edge in incoming if edge.pre_vertex not in vertices_seen] while vertices_to_try: next_vertex = vertices_to_try.pop() if next_vertex not in vertices_seen: vertices_seen.add(next_vertex) edges = graph.get_edges_starting_at_vertex(next_vertex) if is_single(edges): found_vertices.add(next_vertex) incoming = graph.get_edges_ending_at_vertex(next_vertex) vertices_to_try.extend([ edge.pre_vertex for edge in incoming if edge.pre_vertex not in vertices_seen]) extra_vertices = get_vertices_on_same_chip(vertex, graph) for vertex in extra_vertices: found_vertices.add(vertex) return found_vertices
def generate_machine_data_specification( self, spec, placement, machine_graph, routing_info, iptags, reverse_iptags, machine_time_step, time_scale_factor, data_n_time_steps): # Generate the system data region for simulation .c requirements generate_system_data_region(spec, self.DATA_REGIONS.SYSTEM.value, self, machine_time_step, time_scale_factor) # reserve memory regions for every data region spec.reserve_memory_region( region=self.DATA_REGIONS.TRANSMISSIONS.value, size=self.TRANSMISSION_DATA_SIZE, label="inputs") spec.reserve_memory_region( region=self.DATA_REGIONS.POSITION.value, size=self.POSITION_DATA_SIZE, label="position" ) spec.reserve_memory_region( region=self.DATA_REGIONS.NEIGHBOUR_KEYS.value, size=self.NEIGHBOUR_KEYS_SIZE ) spec.reserve_memory_region( region=self.DATA_REGIONS.VELOCITY.value, size=self.VELOCITY_SIZE ) spec.reserve_memory_region( region=self.DATA_REGIONS.VERTEX_INDEX.value, size=self.VERTEX_INDEX_SIZE ) spec.reserve_memory_region( region=self.DATA_REGIONS.RESULTS.value, size=recording_utilities.get_recording_header_size(1)) # get recorded buffered regions sorted spec.switch_write_focus(self.DATA_REGIONS.RESULTS.value) spec.write_array(recording_utilities.get_recording_header_array( [self.RECORDING_ELEMENT_SIZE * data_n_time_steps])) # check got right number of keys and edges going into me partitions = \ machine_graph.get_outgoing_edge_partitions_starting_at_vertex(self) if not is_single(partitions): raise ConfigurationException( "Can only handle one type of partition.") # check for duplicates edges = list(machine_graph.get_edges_ending_at_vertex(self)) if len(edges) != 8: raise ConfigurationException( "I've not got the right number of connections. I have {} " "instead of 8".format( len(machine_graph.get_edges_ending_at_vertex(self)))) for edge in edges: if edge.pre_vertex == self: raise ConfigurationException( "I'm connected to myself, this is deemed an error" " please fix.") # write key needed to transmit with key = routing_info.get_first_key_from_pre_vertex( self, self.PARTITION_ID) spec.switch_write_focus( region=self.DATA_REGIONS.TRANSMISSIONS.value) spec.write_value(0 if key is None else 1) spec.write_value(0 if key is None else key) # write POSITION data spec.switch_write_focus( region=self.DATA_REGIONS.POSITION.value ) spec.write_value(int(self._x_position)) spec.write_value(int(self._y_position)) #write VERTEX_INDEX data. Mainly for add a random delay spec.switch_write_focus(region=self.DATA_REGIONS.VERTEX_INDEX.value) spec.write_value(machine_graph.vertices.index(self)) self.offset = generate_offset(placement.p) spec.write_value(self.offset) # write the neighbour keys and masks self._write_key_data(spec, routing_info, machine_graph) #write velocity data in two dimension, x and y spec.switch_write_focus(region=self.DATA_REGIONS.VELOCITY.value) spec.write_value(self.u_x, data_type=DataType.FLOAT_32) spec.write_value(self.u_y, data_type=DataType.FLOAT_32) # End-of-Spec: spec.end_specification()