def test_redundant_paths_spinn7_via_router_require_turn(): the_machine = machine.Machine('spinn-7', type="spinn4") src_vertex_constraints = lib_map.VertexConstraints(x=0, y=0) src_vrt = graph.Vertex(1,models.IF_curr_exp, constraints=src_vertex_constraints) src_sub_vert = graph.Subvertex(src_vrt, 0,1) dest_vertex_constraints = lib_map.VertexConstraints(x=2, y=3) dest_vrt = graph.Vertex(1,models.IF_curr_exp, constraints=dest_vertex_constraints) dest_sub_vert = graph.Subvertex(dest_vrt, 0,1) dest_sub_vert2 = graph.Subvertex(dest_vrt, 0,1) edge = graph.Edge(None, src_vrt, dest_vrt) sbedge = graph.Subedge(edge, src_sub_vert, dest_sub_vert) sbedge2 = graph.Subedge(edge, src_sub_vert, dest_sub_vert2) dao_object = dao #place vertexes in correct cores placements = Placer.place_raw(the_machine, [src_sub_vert, dest_sub_vert, dest_sub_vert2]) dao.placements = placements routings = dijkstra_routing.DijkstraRouting.\ route_raw(the_machine, [src_sub_vert, dest_sub_vert, dest_sub_vert2]) inconsistant_routings, redundant_paths = \ Router.check_for_inconsistant_routings(the_machine) assert(len(redundant_paths) > 0) assert(len(inconsistant_routings) == 0) Router.redundant_path_removal(redundant_paths, the_machine) inconsistant_routings, redundant_paths = \ Router.check_for_inconsistant_routings(the_machine) assert(len(redundant_paths) == 0) assert(len(inconsistant_routings) == 0)
def setUp(self): # Create a machine with a vertex mapped to each core. self._init_machine_and_vertexes(1.0) # Create a connection to all devices for v1 in self.vertices: for v2 in self.vertices: graph.Edge(None, v1, v2) # Finish off self._partition_place_and_route()
def setUp(self): # Create a machine with a vertex mapped to each core. self._init_machine_and_vertexes(1.0) # Create a circular connectivity scheme for v1, v2 in zip(self.vertices, self.vertices[1:] + [self.vertices[0]]): graph.Edge(None, v1, v2) # Finish off self._partition_place_and_route()
def test_partition_multiple_productions_with_multiple_subvertices_and_multiple_subedges( self): """ Calculates max atoms per vertex based on a vertex model and then it creates 48 pre vertices and 48 pro vertices. This test checks if the subvertices are an instance of graph.Subvertex, subedges are an instance of graph.SubEdge if total number of subvertices (is i+j+2)*48 and subedges is (i+1)*(j+1)*48*48. """ # Specify a SpiNNaker machine machine = lib_machine.Machine('test', 1, 1, 'wrapped') # Calculate the max atoms per core # The following code has been taken from core.mapper.partition_raw requirements = pynn.IF_curr_exp.get_requirements_per_atom() resources = machine.get_resources_per_processor() atoms = resources / requirements print "Long Test: (test_partition_multiple_productions_with_multiple_subvertices_and_multiple_subedges)" for i in range(16): # i is the number of subvertices of a prev vertex print " progress: set", i + 1, "of 16" for j in range( 16): # j is the number of subvertices of a pro vertex preVertices = [] proVertices = [] for k in range(48): # k is the number of vertices preVertices.append( graph.Vertex(atoms * (i + 1), pynn.IF_curr_exp)) proVertices.append( graph.Vertex(atoms * (j + 1), pynn.IF_curr_exp)) for k1 in range(48): for k2 in range(48): edges = graph.Edge(None, preVertices[k1], proVertices[k2]) max_atoms_per_core = dict() subvertices, subedges = \ basic_partitioner.BasicPartitioner.partition_raw(machine, preVertices + proVertices, max_atoms_per_core) # subvertices should be an instance of the Subvertex class for subvertex in subvertices: self.assertIsInstance(subvertex, graph.Subvertex) # subedges should be an instance of the Subvedge class for subedge in subedges: self.assertIsInstance(subedge, graph.Subedge) # subvertices should be (i+1+j+1)*48 self.assertEqual(len(subvertices), (i + j + 2) * 48) # subedges should be number of preSubvertices times number of proSubvertices self.assertEqual(len(subedges), (i + 1) * (j + 1) * 48 * 48)
def __init__(self, size, cellclass, cellparams, structure=None, label=None): """ Instantiates a :py:object:`Population`. """ global controller, multi_cast_vertex # Raise an exception if the Pop. attempts to employ spatial structure if structure: raise Exception( "Spatial structure is unsupported for Populations.") # Create a graph vertex for the population and add it to PACMAN self.vertex = cellclass(size, label=label, **cellparams) #check if the vertex is a cmd sender, if so store for future if self.vertex.requires_multi_cast_source(): if multi_cast_vertex is None: multi_cast_vertex = MultiCastSource() controller.add_vertex(multi_cast_vertex) edge = graph.Edge(multi_cast_vertex, self.vertex) controller.add_edge(edge) self.parameters = PyNNParametersSurrogate(self.vertex) controller.add_vertex(self.vertex) #add any dependant edges and verts if needed dependant_verts, dependant_edges = \ self.vertex.get_dependant_vertexes_edges() if dependant_verts is not None: for dependant_vert in dependant_verts: controller.add_vertex(dependant_vert) if dependant_edges is not None: for dependant_edge in dependant_edges: controller.add_edge(dependant_edge) #initlise common stuff self.size = size self.recordSpikeFile = None self.recordVFile = None self.recordGSynFile = None
def test_redundant_paths_spinn7_via_router_same_chip(): the_machine = machine.Machine('spinn-7', type="spinn4") src_vertex_constraints = lib_map.VertexConstraints(x=0, y=0, p=2) src_vrt = graph.Vertex(1, models.IF_curr_exp, constraints=src_vertex_constraints) src_sub_vert = graph.Subvertex(src_vrt, 0,1) dest_vertex_constraints = lib_map.VertexConstraints(x=0, y=0, p=5) dest_vrt = graph.Vertex(1, models.IF_curr_exp, constraints=dest_vertex_constraints) dest_sub_vert = graph.Subvertex(dest_vrt, 0,1) dest_sub_vert2 = graph.Subvertex(dest_vrt, 0,1) dest_vertex_constraints2 = lib_map.VertexConstraints(x=0, y=0, p=6) dest_vrt2 = graph.Vertex(1, models.IF_curr_exp, constraints=dest_vertex_constraints2) dest_sub_vert2 = graph.Subvertex(dest_vrt2, 0, 1) edge = graph.Edge(None, src_vrt, dest_vrt) sbedge = graph.Subedge(edge, src_sub_vert, dest_sub_vert) sbedge2 = graph.Subedge(edge, src_sub_vert, dest_sub_vert2) dao_object = dao #place vertexes in correct cores placements = Placer.place_raw(the_machine, [src_sub_vert, dest_sub_vert, dest_sub_vert2]) dao.placements = placements routings = dijkstra_routing.\ DijkstraRouting.route_raw(the_machine, [src_sub_vert, dest_sub_vert, dest_sub_vert2]) inconsistant_routings, redundant_paths = \ Router.check_for_inconsistant_routings(the_machine) assert(len(redundant_paths) > 0) assert(len(inconsistant_routings) == 0) #print "entry {} and entry {}".format(redundant_paths[0][2].route, redundant_paths[0][3].route) Router.redundant_path_removal(redundant_paths, the_machine) inconsistant_routings, redundant_paths = \ Router.check_for_inconsistant_routings(the_machine) assert(len(redundant_paths) == 0) assert(len(inconsistant_routings) == 0) for key in the_machine.chips[0][0].router.cam.keys(): entry_list = the_machine.chips[0][0].router.cam.get(key) assert(len(entry_list) == 1) #print "entry is {}".format(entry_list[0].route) assert(entry_list[0].route == 6144)
def record(self, to_file=None, focus=None, visualiser_mode=visualiser_modes.RASTER, visualiser_2d_dimension=None, visualiser_raster_seperate=None, visualiser_no_colours=None, visualiser_average_period_tics=None, visualiser_longer_period_tics=None, visualiser_update_screen_in_tics=None, visualiser_reset_counters=None, visualiser_reset_counter_period=None, stream=True): """ Record spikes from all cells in the Population. A flag is set for this population that is passed to the simulation, triggering spike time recording. """ record_attr = getattr(self.vertex, "record", None) if ((record_attr == None) or not callable(record_attr)): raise Exception("Vertex does not support recording of spikes") # Tell the vertex to record spikes self.vertex.record() self.recordSpikeFile = to_file if stream: self.vertex.setup_visualizer( focus=focus, visualiser_mode=visualiser_mode, visualiser_2d_dimension=visualiser_2d_dimension, visualiser_raster_seperate=visualiser_raster_seperate, visualiser_no_colours=visualiser_no_colours, visualiser_average_period_tics=visualiser_average_period_tics, visualiser_longer_period_tics=visualiser_longer_period_tics, visualiser_update_screen_in_tics= visualiser_update_screen_in_tics, visualiser_reset_counters=visualiser_reset_counters, visualiser_reset_counter_period=visualiser_reset_counter_period ) # If the monitor is enabled, add an edge to the monitor global appMonitorVertex if appMonitorVertex != None: controller.add_edge(graph.Edge(self.vertex, appMonitorVertex))
def test_partition_production_with_multiple_subvertices_and_multiple_subedges( self): """ Calculates max atoms per vertex based on a vertex model and then it creates two vertices. Vertex2 has a multiple of max atoms per core controlled by i while the size of vertex1 stays fixed to max atoms per core. This test checks if the subvertices are an instance of graph.Subvertex, subedges are an instance of graph.SubEdge if total number of subvertices is n+2 and subedges is n+1. """ # Specify a SpiNNaker machine machine = lib_machine.Machine('test', 1, 1, 'unwrapped') # Calculate the max atoms per core # The following code has been taken from core.mapper.partition_raw requirements = pynn.IF_curr_exp.get_requirements_per_atom() resources = machine.get_resources_per_processor() atoms = resources / requirements for i in range(16): for j in range(16): vertex1 = graph.Vertex(atoms * (i + 1), pynn.IF_curr_exp) vertex2 = graph.Vertex(atoms * (j + 1), pynn.IF_curr_exp) # Generate a self projected edge edge = graph.Edge(None, vertex1, vertex2) max_atoms_per_core = dict() subvertices1, subedges1 = basic_partitioner.BasicPartitioner.partition_raw( machine, [vertex1, vertex2], max_atoms_per_core) # subvertices should be an instance of the Subvertex class for subvertex in subvertices1: self.assertIsInstance(subvertex, graph.Subvertex) # subedges should be an instance of the Subvedge class for subedge in subedges1: self.assertIsInstance(subedge, graph.Subedge) # subvertices should be 1 self.assertEqual(len(subvertices1), i + j + 2) # subedges should be squared the number of subvertices self.assertEqual(len(subedges1), (i + 1) * (j + 1))
def test_partition_production_with_multiple_subvertices_and_self_projected_subedges( self): """ Calculates max atoms per vertex based on the vertex model and then it creates a vertex with n multiples of max atoms and adds an edge which projects back to itself. This test checks if the subvertices are an instance of graph.Subvertex, subedges are an instance of graph.SubEdge if total number of subvertices and subedges is 1. """ # Specify a SpiNNaker machine machine = lib_machine.Machine('test', 1, 1, 'unwrapped') # Calculate the max atoms per core # The following code has been taken from core.mapper.partition_raw requirements = pynn.IF_curr_exp.get_requirements_per_atom() resources = machine.get_resources_per_processor() atoms = resources / requirements for i in range(16): vertex1 = graph.Vertex(atoms * (i + 1), pynn.IF_curr_exp) # Generate a self projected edge edge = graph.Edge(None, vertex1, vertex1) max_atoms_per_core = dict() subvertices, subedges = basic_partitioner.BasicPartitioner.partition_raw( machine, [vertex1], max_atoms_per_core) # subvertices should be an instance of the Subvertex class for subvertex in subvertices: self.assertIsInstance(subvertex, graph.Subvertex) # subedges should be an instance of the Subvedge class for subedge in subedges: self.assertIsInstance(subedge, graph.Subedge) # subvertices are equal to the number of i+1 self.assertEqual(len(subvertices), (i + 1)) # subedges should be squared the number of subvertices self.assertEqual(len(subedges), (i + 1)**2)
def test_partition_production_with_self_projected_edge(self): """ Calculates max atoms per vertex based on the vertex model and then it creates a vertex and adds an edge which projects back to itself. This test checks if the subvertices are an instance of graph.Subvertex, subedges are an instance of graph.SubEdge if total number of subvertices and subedges is 1. """ # Specify a SpiNNaker machine machine = lib_machine.Machine('test', 1, 1, 'unwrapped') # Calculate the max atoms per core # The following code has been taken from core.mapper.partition_raw requirements = pynn.IF_curr_exp.get_requirements_per_atom() resources = machine.get_resources_per_processor() atoms = resources / requirements vertex1 = graph.Vertex(atoms, pynn.IF_curr_exp) pdb.set_trace edge = graph.Edge(None, vertex1, vertex1) max_atoms_per_core = dict() subvertices, subedges = basic_partitioner.BasicPartitioner.partition_raw( machine, [vertex1], max_atoms_per_core) # subvertices should be an instance of the Subvertex class for subvertex in subvertices: self.assertIsInstance(subvertex, graph.Subvertex) # subedges should be an instance of the Subvedge class for subedge in subedges: self.assertIsInstance(subedge, graph.Subedge) # subvertices should have only two vertices since all atoms fit in two # cores self.assertEqual(len(subvertices), 1) # subedges should be zero self.assertEqual(len(subedges), 1)
def stream(self): # If the monitor is enabled, add an edge to the monitor global appMonitorVertex self.vertex.setup_visualizer(visualiser_mode=visualiser_modes.RASTER) if appMonitorVertex != None: controller.add_edge(graph.Edge(self.vertex, appMonitorVertex))
def try_creating_route(source, dests, machine_id): ''' create vertexes subverts and placements, run routing, and start backward chasing ''' the_machine = None #initilise machine description = machines.machines[machine_id] the_machine = machine.Machine(**description) subedges = dict() sub_verts = list() src_vertex_constraints = lib_map.VertexConstraints(x=source[0], y=source[1], p=source[2]) src_vrt = models.IF_curr_exp(1, constraints=src_vertex_constraints) src_sub_vert = graph.Subvertex(src_vrt, 0, 1, 0) sub_verts.append(src_sub_vert) #place vertexes in correct cores placement_chip = the_machine.get_chip( src_sub_vert.vertex.constraints.x, src_sub_vert.vertex.constraints.y) placement_processor = placement_chip.get_processor( src_sub_vert.vertex.constraints.p) placement = lib_map.Placement(src_sub_vert, placement_processor) src_sub_vert.placement = placement #add subvert and edge for each destination vertex dest_subverts = list() for dest in dests: dest_vertex_constraints = lib_map.VertexConstraints(x=dest[0], y=dest[1], p=dest[2]) dest_vrt = models.IF_curr_exp(1, constraints=dest_vertex_constraints) dest_sub_vert = graph.Subvertex(dest_vrt, 0, 1, 0) edge = graph.Edge(src_vrt, dest_vrt) sbedge = graph.Subedge(edge, src_sub_vert, dest_sub_vert) #give its routing key and mask key, mask = src_sub_vert.vertex.generate_routing_info(sbedge) sbedge.key = key sbedge.mask = mask sbedge.key_mask_combo = key & mask subedges[dest_sub_vert] = sbedge sub_verts.append(dest_sub_vert) dest_subverts.append(dest_sub_vert) #place vertexes in correct cores placement_chip = the_machine.get_chip( dest_sub_vert.vertex.constraints.x, dest_sub_vert.vertex.constraints.y) placement_processor = placement_chip.get_processor( dest_sub_vert.vertex.constraints.p) placement = lib_map.Placement(dest_sub_vert, placement_processor) dest_sub_vert.placement = placement fails = list() #try to route between the verts try: dijkstra_routing.DijkstraRouting.route_raw(the_machine, sub_verts) return src_sub_vert, dest_subverts, machine, subedges, None except Exception as e: print traceback.print_exc(e) return src_sub_vert, dest_subverts, machine, subedges, \ fails.append([src_sub_vert, dests, "failed to generate a route"])
def test_routing_simple(self): #print "test_routing simple" the_machine = machine.Machine('host', type="spinn4") src_vrt = graph.Vertex(1, None) src_vrt.model = models.IF_curr_exp dst_vrt = graph.Vertex(1, None) dst_vrt.model = models.IF_curr_exp edge = graph.Edge(src_vrt, dst_vrt) src_sbvrt = graph.Subvertex(src_vrt, 0, 0, None) dst_sbvrt = graph.Subvertex(dst_vrt, 0, 0, None) sbedge = graph.Subedge(edge, src_sbvrt, dst_sbvrt) radial_placer = radial_placer.RadialPlacer(None) radial_placer.RadialPlacer.place_raw(the_machine, [src_sbvrt, dst_sbvrt]) dijkstra_routing.DijkstraRouting.route_raw(the_machine, [src_sbvrt, dst_sbvrt]) #the machine object now contains all the routes #now I need to test that the routes are correct #(i.e. from a single source they go to the correct destination(s)) out_sbedges_lst = src_sbvrt.out_subedges #the routing key dictionary associates to a routing key the list of #destinations rt_key_list = dict() for i in range(len(out_sbedges_lst)): #for each subvertex and for each subedge key and mask are retrieved key, mask = src_sbvrt.vertex.model.generate_routing_info( out_sbedges_lst[i]) #then the destination of the subedge is retrieved dst = out_sbedges_lst[ i].postsubvertex.placement.processor.get_coordinates() #and it is added to the appropriate list #then all the destinations are merged in the list rt_key_list if key in rt_key_list: #if the routing key for the subedge is already in the rt_key_list #then append the destination to the list of the destinations #extracted from the graph if dst not in rt_key_list[key]: rt_key_list[key].append(dst) else: #if the routing key was not present in the lsit of already known #routing keys, then append it with the new destination rt_key_list.update({key: [dst]}) #rt_key list at this point is a dictionary of elements; each of these #elements contains a list where the elements are destinations #{'key1':[dst1, dst2, ...], 'key2':[dst3, dst4, ...], ...} for i in range(len(rt_key_list.keys())): #retrieve the list of desired destinations from rt_key_list key = rt_key_list.keys()[i] desired_dsts = rt_key_list[key] #sort destinations desired_dsts.sort() #get from the binaries of the routing tables the destination core(s) #for a specific routing key starting from a particular chip test = TestRoutes(the_machine, src_sbvrt, key) test.TraceRoute() dsts = test.dsts dsts.sort() #dsts contains the list of processors to which the routing key is #addresses. this list must be equal to the desired destination(s) #extracted from the graph #test desired_dsts and dsts. if not equal, the routing made a mess! #print "desired_dsts: ", desired_dsts #print "dsts: ",dsts self.assertEqual(dsts, desired_dsts)
def test_routing(self): the_machine = machine.Machine('host', type="spinn4") machine_size = len(the_machine.processors) vertexes = list() for i in xrange(machine_size): v = graph.Vertex(1, None) v.model = models.IF_curr_exp vertexes.append(v) number_of_projections = machine_size * machine_size * test_connectivity_percentage src_vertexes = random.sample( xrange(machine_size), int(math.ceil(math.sqrt(number_of_projections)))) dst_vertexes = random.sample( xrange(machine_size), int(math.floor(math.sqrt(number_of_projections)))) src_vertexes.sort() dst_vertexes.sort() # print "test_routing: total number of projections:", number_of_projections # print "test_routing: source vertexes", src_vertexes # print "test_routing: destination vertexes:", dst_vertexes # print "test_routing: number of projections:", len(src_vertexes) * len(dst_vertexes) edges = list() for i in xrange(len(src_vertexes)): for j in xrange(len(dst_vertexes)): src = vertexes[src_vertexes[i]] dst = vertexes[src_vertexes[j]] edges.append(graph.Edge(src, dst)) subvertexes = list() for i in xrange(machine_size): subvertexes.append(graph.Subvertex(vertexes[i], 0, 0, None)) sb_edges = list() for i in xrange(len(edges)): pre = edges[i].prevertex.subvertices[0] post = edges[i].postvertex.subvertices[0] sb_edges.append(graph.Subedge(edges[i], pre, post)) radial_placer.RadialPlacer.place_raw(the_machine, subvertexes) dijkstra_routing.DijkstraRouting.route_raw(the_machine, subvertexes) #the machine object now contains all the routes #now I need to test that the routes are correct #(i.e. from a single source they go to the correct destination(s)) for k in xrange(len(src_vertexes)): #take the list of the outgoing edges from each of the subvertexes src_sbvrt = subvertexes[src_vertexes[k]] out_sbedges_lst = src_sbvrt.out_subedges #the routing key dictionary associates to a routing key the list of #destinations rt_key_list = dict() for i in range(len(out_sbedges_lst)): #for each subvertex and for each subedge key and mask are retrieved key, mask = src_sbvrt.vertex.model.generate_routing_info( out_sbedges_lst[i]) #then the destination of the subedge is retrieved dst = out_sbedges_lst[ i].postsubvertex.placement.processor.get_coordinates() #and it is added to the appropriate list #then all the destinations are merged in the list rt_key_list if key in rt_key_list: #if the routing key for the subedge is already in the rt_key_list #then append the destination to the list of the destinations #extracted from the graph if dst not in rt_key_list[key]: rt_key_list[key].append(dst) else: #if the routing key was not present in the lsit of already known #routing keys, then append it with the new destination rt_key_list.update({key: [dst]}) #rt_key list at this point is a dictionary of elements; each of these #elements contains a list where the elements are destinations #{'key1':[dst1, dst2, ...], 'key2':[dst3, dst4, ...], ...} for i in range(len(rt_key_list.keys())): #retrieve the list of desired destinations from rt_key_list key = rt_key_list.keys()[i] desired_dsts = rt_key_list[key] #sort destinations desired_dsts.sort() #print "Desired destinations:", desired_dsts #get from the binaries of the routing tables the destination core(s) #for a specific routing key starting from a particular chip test = TestRoutes(the_machine, src_sbvrt, key) test.TraceRoute() dsts = test.dsts dsts.sort() #print "Actual destinations:", dsts #dsts contains the list of processors to which the routing key is #addresses. this list must be equal to the desired destination(s) #extracted from the graph #test desired_dsts and dsts. if not equal, the routing made a mess! self.assertEqual(dsts, desired_dsts)