def __call__(self, machine_graph, machine, plan_n_timesteps): """ Place a machine_graph so that each vertex is placed on a core :param machine_graph: The machine_graph to place :type machine_graph:\ :py:class:`pacman.model.graphs.machine.MachineGraph` :param machine:\ The machine with respect to which to partition the application\ graph :type machine: :py:class:`spinn_machine.Machine` :param plan_n_timesteps: number of timesteps to plan for :type plan_n_timesteps: int :return: A set of placements :rtype: :py:class:`pacman.model.placements.Placements` :raise pacman.exceptions.PacmanPlaceException: \ If something goes wrong with the placement """ # check that the algorithm can handle the constraints ResourceTracker.check_constraints(machine_graph.vertices) placements = Placements() vertices = sort_vertices_by_known_constraints(machine_graph.vertices) # Iterate over vertices and generate placements progress = ProgressBar(vertices, "Placing graph vertices") resource_tracker = ResourceTracker(machine, plan_n_timesteps) for vertex in progress.over(vertices): # Create and store a new placement anywhere on the board (x, y, p, _, _) = resource_tracker.allocate_constrained_resources( vertex.resources_required, vertex.constraints, None) placement = Placement(vertex, x, y, p) placements.add_placement(placement) return placements
def test_ner_route_default(): unittest_setup() graph = MachineGraph("Test") machine = virtual_machine(8, 8) placements = Placements() source_vertex = SimpleMachineVertex(None) graph.add_vertex(source_vertex) placements.add_placement(Placement(source_vertex, 0, 0, 1)) target_vertex = SimpleMachineVertex(None) graph.add_vertex(target_vertex) placements.add_placement(Placement(target_vertex, 0, 2, 1)) edge = MachineEdge(source_vertex, target_vertex) graph.add_edge(edge, "Test") partition = graph.get_outgoing_partition_for_edge(edge) routes = ner_route(graph, machine, placements) source_route = routes.get_entries_for_router(0, 0)[partition] assert (not source_route.defaultable) mid_route = routes.get_entries_for_router(0, 1)[partition] print(mid_route.incoming_link, mid_route.link_ids) assert (mid_route.defaultable) end_route = routes.get_entries_for_router(0, 2)[partition] assert (not end_route.defaultable)
def test_routing(self): graph = MachineGraph("Test") machine = VirtualMachine(2, 2) placements = Placements() vertices = list() for x in range(machine.max_chip_x + 1): for y in range(machine.max_chip_y + 1): chip = machine.get_chip_at(x, y) if chip is not None: for processor in chip.processors: if not processor.is_monitor: vertex = SimpleMachineVertex( resources=ResourceContainer()) graph.add_vertex(vertex) placements.add_placement( Placement(vertex, x, y, processor.processor_id)) vertices.append(vertex) for vertex in vertices: for vertex_to in vertices: if vertex != vertex_to: graph.add_edge(MachineEdge(vertex, vertex_to), "Test") router = BasicDijkstraRouting() routing_paths = router.__call__(placements, machine, graph) for vertex in vertices: vertices_reached = set() queue = deque() seen_entries = set() placement = placements.get_placement_of_vertex(vertex) partition = graph.get_outgoing_edge_partition_starting_at_vertex( vertex, "Test") entry = routing_paths.get_entry_on_coords_for_edge( partition, placement.x, placement.y) self.assertEqual(entry.incoming_processor, placement.p) queue.append((placement.x, placement.y)) while len(queue) > 0: x, y = queue.pop() entry = routing_paths.get_entry_on_coords_for_edge( partition, x, y) self.assertIsNotNone(entry) chip = machine.get_chip_at(x, y) for p in entry.out_going_processors: self.assertIsNotNone(chip.get_processor_with_id(p)) vertex_found = placements.get_vertex_on_processor(x, y, p) vertices_reached.add(vertex_found) seen_entries.add((x, y)) for link_id in entry.out_going_links: link = chip.router.get_link(link_id) self.assertIsNotNone(link) dest_x, dest_y = link.destination_x, link.destination_y if (dest_x, dest_y) not in seen_entries: queue.append((dest_x, dest_y)) for vertex_to in vertices: if vertex != vertex_to: self.assertIn(vertex_to, vertices_reached)
def __call__(self, machine_graph, machine): """ Place a machine_graph so that each vertex is placed on a core :param machine_graph: The machine_graph to place :type machine_graph:\ :py:class:`pacman.model.graphs.machine.MachineGraph` :return: A set of placements :rtype: :py:class:`pacman.model.placements.Placements` :raise pacman.exceptions.PacmanPlaceException: \ If something goes wrong with the placement """ # check that the algorithm can handle the constraints ResourceTracker.check_constraints(machine_graph.vertices) placements = Placements() vertices = sort_vertices_by_known_constraints(machine_graph.vertices) # Iterate over vertices and generate placements progress = ProgressBar(vertices, "Placing graph vertices") resource_tracker = ResourceTracker(machine) for vertex in progress.over(vertices): # Create and store a new placement anywhere on the board (x, y, p, _, _) = resource_tracker.allocate_constrained_resources( vertex.resources_required, vertex.constraints, None) placement = Placement(vertex, x, y, p) placements.add_placement(placement) return placements
def test_routing(self): graph = MachineGraph("Test") machine = VirtualMachine(2, 2) placements = Placements() vertices = list() for x in range(machine.max_chip_x + 1): for y in range(machine.max_chip_y + 1): chip = machine.get_chip_at(x, y) if chip is not None: for processor in chip.processors: if not processor.is_monitor: vertex = SimpleMachineVertex( resources=ResourceContainer()) graph.add_vertex(vertex) placements.add_placement(Placement( vertex, x, y, processor.processor_id)) vertices.append(vertex) for vertex in vertices: for vertex_to in vertices: if vertex != vertex_to: graph.add_edge(MachineEdge(vertex, vertex_to), "Test") router = BasicDijkstraRouting() routing_paths = router.__call__(placements, machine, graph) for vertex in vertices: vertices_reached = set() queue = deque() seen_entries = set() placement = placements.get_placement_of_vertex(vertex) partition = graph.get_outgoing_edge_partition_starting_at_vertex( vertex, "Test") entry = routing_paths.get_entry_on_coords_for_edge( partition, placement.x, placement.y) self.assertEqual(entry.incoming_processor, placement.p) queue.append((placement.x, placement.y)) while len(queue) > 0: x, y = queue.pop() entry = routing_paths.get_entry_on_coords_for_edge( partition, x, y) self.assertIsNotNone(entry) chip = machine.get_chip_at(x, y) for p in entry.processor_ids: self.assertIsNotNone(chip.get_processor_with_id(p)) vertex_found = placements.get_vertex_on_processor(x, y, p) vertices_reached.add(vertex_found) seen_entries.add((x, y)) for link_id in entry.link_ids: link = chip.router.get_link(link_id) self.assertIsNotNone(link) dest_x, dest_y = link.destination_x, link.destination_y if (dest_x, dest_y) not in seen_entries: queue.append((dest_x, dest_y)) for vertex_to in vertices: if vertex != vertex_to: self.assertIn(vertex_to, vertices_reached)
def test_routing(self): graph = MachineGraph("Test") set_config("Machine", "down_chips", "1,2:5,4:3,3") machine = virtual_machine(8, 8) placements = Placements() vertices = list() for chip in machine.chips: for processor in chip.processors: if not processor.is_monitor: vertex = SimpleMachineVertex(resources=ResourceContainer()) graph.add_vertex(vertex) placements.add_placement( Placement(vertex, chip.x, chip.y, processor.processor_id)) vertices.append(vertex) for vertex in vertices: graph.add_outgoing_edge_partition( MulticastEdgePartition(identifier="Test", pre_vertex=vertex)) for vertex_to in vertices: graph.add_edge(MachineEdge(vertex, vertex_to), "Test") routing_paths = ner_route_traffic_aware(graph, machine, placements) for vertex in vertices: vertices_reached = set() queue = deque() seen_entries = set() placement = placements.get_placement_of_vertex(vertex) partition = graph.get_outgoing_edge_partition_starting_at_vertex( vertex, "Test") entry = routing_paths.get_entry_on_coords_for_edge( partition, placement.x, placement.y) self.assertEqual(entry.incoming_processor, placement.p) queue.append((placement.x, placement.y)) while len(queue) > 0: x, y = queue.pop() entry = routing_paths.get_entry_on_coords_for_edge( partition, x, y) self.assertIsNotNone(entry) chip = machine.get_chip_at(x, y) for p in entry.processor_ids: self.assertIsNotNone(chip.get_processor_with_id(p)) vertex_found = placements.get_vertex_on_processor(x, y, p) vertices_reached.add(vertex_found) seen_entries.add((x, y)) for link_id in entry.link_ids: link = chip.router.get_link(link_id) self.assertIsNotNone(link) dest_x, dest_y = link.destination_x, link.destination_y if (dest_x, dest_y) not in seen_entries: queue.append((dest_x, dest_y)) for vertex_to in vertices: self.assertIn(vertex_to, vertices_reached)
def convert_from_rig_placements( rig_placements, rig_allocations, machine_graph): placements = Placements() for vertex in rig_placements: if isinstance(vertex, AbstractVirtualVertex): placements.add_placement(Placement( vertex, vertex.virtual_chip_x, vertex.virtual_chip_y, None)) else: x, y = rig_placements[vertex] p = rig_allocations[vertex]["cores"].start placements.add_placement(Placement(vertex, x, y, p)) return placements
def convert_from_rig_placements(rig_placements, rig_allocations, machine_graph): placements = Placements() for vertex in rig_placements: if isinstance(vertex, AbstractVirtualVertex): placements.add_placement( Placement(vertex, vertex.virtual_chip_x, vertex.virtual_chip_y, None)) else: x, y = rig_placements[vertex] p = rig_allocations[vertex]["cores"].start placements.add_placement(Placement(vertex, x, y, p)) return placements
def __call__(self, extended_machine, placements, allocations, constraints, vertex_by_id): """ :param placements: :param allocations: :param extended_machine: :param constraints: """ # load the json files file_placements, core_allocations, constraints = \ self._load_json_files(placements, allocations, constraints) # validate the json files against the schemas self._validate_file_read_data(file_placements, core_allocations, constraints) memory_placements = Placements() # process placements for vertex_id in file_placements: if str(vertex_id) not in vertex_by_id: if text_type(vertex_id) not in core_allocations: raise PacmanConfigurationException( "I don't recognise this pattern of constraints for" " a vertex which does not have a placement") else: raise PacmanConfigurationException( "Failed to locate the vertex in the " "graph with id {}".format(vertex_id)) if text_type(vertex_id) in core_allocations: memory_placements.add_placement( Placement(x=file_placements[vertex_id][0], y=file_placements[vertex_id][1], p=core_allocations[vertex_id][0], vertex=vertex_by_id[str(vertex_id)])) else: # virtual chip or tag chip external_device_constraints = \ self._valid_constraints_for_external_device( self._locate_constraints(vertex_id, constraints)) if external_device_constraints: placements.add( self._make_virtual_placement( extended_machine, vertex_by_id[str(vertex_id)], external_device_constraints)) # return the file format return memory_placements
def __call__(self, extended_machine, placements, allocations, constraints, vertex_by_id): """ :param placements: :param allocations: :param extended_machine: :param constraints: """ # load the json files file_placements, core_allocations, constraints = \ self._load_json_files(placements, allocations, constraints) # validate the json files against the schemas self._validate_file_read_data( file_placements, core_allocations, constraints) memory_placements = Placements() # process placements for vertex_id in file_placements: if str(vertex_id) not in vertex_by_id: if text_type(vertex_id) not in core_allocations: raise PacmanConfigurationException( "I don't recognise this pattern of constraints for" " a vertex which does not have a placement") else: raise PacmanConfigurationException( "Failed to locate the vertex in the " "graph with id {}".format(vertex_id)) if text_type(vertex_id) in core_allocations: memory_placements.add_placement(Placement( x=file_placements[vertex_id][0], y=file_placements[vertex_id][1], p=core_allocations[vertex_id][0], vertex=vertex_by_id[str(vertex_id)])) else: # virtual chip or tag chip external_device_constraints = \ self._valid_constraints_for_external_device( self._locate_constraints(vertex_id, constraints)) if external_device_constraints: placements.add(self._make_virtual_placement( extended_machine, vertex_by_id[str(vertex_id)], external_device_constraints)) # return the file format return memory_placements
def test_memory_io(): vertex = MyVertex() graph = MachineGraph("Test") graph.add_vertex(vertex) placements = Placements() placements.add_placement(Placement(vertex, 0, 0, 1)) transceiver = _MockTransceiver() temp = tempfile.mkdtemp() print("ApplicationDataFolder = {}".format(temp)) inputs = { "MemoryTransceiver": transceiver, "MemoryMachineGraph": graph, "MemoryPlacements": placements, "IPAddress": "testing", "ApplicationDataFolder": temp, "APPID": 30 } algorithms = ["WriteMemoryIOData"] executor = PACMANAlgorithmExecutor( algorithms, [], inputs, [], [], [], xml_paths=get_front_end_common_pacman_xml_paths()) executor.execute_mapping() assert(vertex._test_tag == vertex._tag)
def _do_allocation(self, vertices, machine, same_chip_vertex_groups, machine_graph): placements = Placements() # Iterate over vertices and generate placements progress = ProgressBar(machine_graph.n_vertices, "Placing graph vertices") resource_tracker = ResourceTracker( machine, self._generate_radial_chips(machine)) all_vertices_placed = set() # iterate over vertices for vertex_list in vertices: # if too many one to ones to fit on a chip, allocate individually if len(vertex_list) > machine.maximum_user_cores_on_chip: for vertex in progress.over(vertex_list, False): self._allocate_individual(vertex, placements, resource_tracker, same_chip_vertex_groups, all_vertices_placed) continue allocations = self._get_allocations(resource_tracker, vertex_list) if allocations is not None: # allocate cores to vertices for vertex, (x, y, p, _, _) in progress.over(zip(vertex_list, allocations), False): placements.add_placement(Placement(vertex, x, y, p)) else: # Something went wrong, try to allocate each individually for vertex in progress.over(vertex_list, False): self._allocate_individual(vertex, placements, resource_tracker, same_chip_vertex_groups, all_vertices_placed) progress.end() return placements
def test_memory_io(): vertex = MyVertex() graph = MachineGraph("Test") graph.add_vertex(vertex) placements = Placements() placements.add_placement(Placement(vertex, 0, 0, 1)) transceiver = _MockTransceiver() temp = tempfile.mkdtemp() print("ApplicationDataFolder = {}".format(temp)) inputs = { "MemoryTransceiver": transceiver, "MemoryMachineGraph": graph, "MemoryPlacements": placements, "IPAddress": "testing", "ReportFolder": temp, "APPID": 30 } algorithms = ["WriteMemoryIOData"] executor = PACMANAlgorithmExecutor( algorithms, [], inputs, [], [], [], xml_paths=get_front_end_common_pacman_xml_paths()) executor.execute_mapping() assert (vertex._test_tag == vertex._tag)
def _do_allocation( self, one_to_one_groups, same_chip_vertex_groups, machine, plan_n_timesteps, machine_graph, progress): """ :param list(set(MachineVertex)) one_to_one_groups: Groups of vertexes that would be nice on same chip :param same_chip_vertex_groups: Mapping of Vertex to the Vertex that must be on the same Chip :type same_chip_vertex_groups: dict(MachineVertex, collection(MachineVertex)) :param ~spinn_machine.Machine machine: The machine with respect to which to partition the application graph :param int plan_n_timesteps: number of timesteps to plan for :param MachineGraph machine_graph: The machine_graph to place :param ~spinn_utilities.progress_bar.ProgressBar progress: :rtype: Placements """ placements = Placements() resource_tracker = ResourceTracker( machine, plan_n_timesteps, self._generate_radial_chips(machine)) all_vertices_placed = set() # RadialPlacementFromChipConstraint won't work here for vertex in machine_graph.vertices: for constraint in vertex.constraints: if isinstance(constraint, RadialPlacementFromChipConstraint): raise PacmanPlaceException( "A RadialPlacementFromChipConstraint will not work " "with the OneToOnePlacer algorithm; use the " "RadialPlacer algorithm instead") # Find and place vertices with hard constraints for vertex in machine_graph.vertices: if isinstance(vertex, AbstractVirtual): virtual_p = 0 while placements.is_processor_occupied( vertex.virtual_chip_x, vertex.virtual_chip_y, virtual_p): virtual_p += 1 placements.add_placement(Placement( vertex, vertex.virtual_chip_x, vertex.virtual_chip_y, virtual_p)) all_vertices_placed.add(vertex) elif locate_constraints_of_type( vertex.constraints, ChipAndCoreConstraint): self._allocate_same_chip_as_group( vertex, placements, resource_tracker, same_chip_vertex_groups, all_vertices_placed, progress, machine_graph) for grouped_vertices in one_to_one_groups: # Get unallocated vertices and placements of allocated vertices unallocated = list() chips = list() for vert in grouped_vertices: if vert in all_vertices_placed: placement = placements.get_placement_of_vertex(vert) chips.append((placement.x, placement.y)) else: unallocated.append(vert) if not chips: chips = None if 0 < len(unallocated) <=\ resource_tracker.get_maximum_cores_available_on_a_chip(): # Try to allocate all vertices to the same chip self._allocate_one_to_one_group( resource_tracker, unallocated, progress, placements, chips, all_vertices_placed, machine_graph) # if too big or failed go on to other groups first # check all have been allocated if not do so now. for vertex in machine_graph.vertices: if vertex not in all_vertices_placed: self._allocate_same_chip_as_group( vertex, placements, resource_tracker, same_chip_vertex_groups, all_vertices_placed, progress, machine_graph) progress.end() return placements
def _do_dynamic_routing( self, fixed_route_tables, placements, ethernet_connected_chip, destination_class, machine, board_version): """ Uses a router to route fixed routes :param fixed_route_tables: fixed route tables entry holder :param placements: placements :param ethernet_connected_chip: the chip to consider for this routing :param destination_class: the class at the Ethernet connected chip\ for receiving all these routes. :param machine: SpiNNMachine instance :param board_version: The version of the machine :rtype: None """ graph = MachineGraph(label="routing graph") fake_placements = Placements() # build fake setup for the routing eth_x = ethernet_connected_chip.x eth_y = ethernet_connected_chip.y down_links = set() for (chip_x, chip_y) in machine.get_chips_on_board( ethernet_connected_chip): vertex = RoutingMachineVertex() graph.add_vertex(vertex) rel_x = chip_x - eth_x if rel_x < 0: rel_x += machine.max_chip_x + 1 rel_y = chip_y - eth_y if rel_y < 0: rel_y += machine.max_chip_y + 1 free_processor = 0 while ((free_processor < machine.MAX_CORES_PER_CHIP) and fake_placements.is_processor_occupied( self.FAKE_ETHERNET_CHIP_X, y=self.FAKE_ETHERNET_CHIP_Y, p=free_processor)): free_processor += 1 fake_placements.add_placement(Placement( x=rel_x, y=rel_y, p=free_processor, vertex=vertex)) down_links.update({ (rel_x, rel_y, link) for link in range( Router.MAX_LINKS_PER_ROUTER) if not machine.is_link_at(chip_x, chip_y, link)}) # Create a fake machine consisting of only the one board that # the routes should go over fake_machine = machine if (board_version in machine.BOARD_VERSION_FOR_48_CHIPS and (machine.max_chip_x > machine.MAX_CHIP_X_ID_ON_ONE_BOARD or machine.max_chip_y > machine.MAX_CHIP_Y_ID_ON_ONE_BOARD)): down_chips = { (x, y) for x, y in zip( range(machine.SIZE_X_OF_ONE_BOARD), range(machine.SIZE_Y_OF_ONE_BOARD)) if not machine.is_chip_at( (x + eth_x) % (machine.max_chip_x + 1), (y + eth_y) % (machine.max_chip_y + 1))} # build a fake machine which is just one board but with the missing # bits of the real board fake_machine = VirtualMachine( machine.SIZE_X_OF_ONE_BOARD, machine.SIZE_Y_OF_ONE_BOARD, False, down_chips=down_chips, down_links=down_links) # build destination verts = graph.vertices vertex_dest = RoutingMachineVertex() graph.add_vertex(vertex_dest) destination_processor = self._locate_destination( ethernet_chip_x=ethernet_connected_chip.x, ethernet_chip_y=ethernet_connected_chip.y, destination_class=destination_class, placements=placements) fake_placements.add_placement(Placement( x=self.FAKE_ETHERNET_CHIP_X, y=self.FAKE_ETHERNET_CHIP_Y, p=destination_processor, vertex=vertex_dest)) # deal with edges for vertex in verts: graph.add_edge( MachineEdge(pre_vertex=vertex, post_vertex=vertex_dest), self.FAKE_ROUTING_PARTITION) # route as if using multicast router = BasicDijkstraRouting() routing_tables_by_partition = router( placements=fake_placements, machine=fake_machine, machine_graph=graph, use_progress_bar=False) # convert to fixed route entries for (chip_x, chip_y) in routing_tables_by_partition.get_routers(): mc_entries = routing_tables_by_partition.get_entries_for_router( chip_x, chip_y) # only want the first entry, as that will all be the same. mc_entry = next(itervalues(mc_entries)) fixed_route_entry = FixedRouteEntry( link_ids=mc_entry.link_ids, processor_ids=mc_entry.processor_ids) x = (chip_x + eth_x) % (machine.max_chip_x + 1) y = (chip_y + eth_y) % (machine.max_chip_y + 1) key = (x, y) if key in fixed_route_tables: raise PacmanAlreadyExistsException( "fixed route entry", str(key)) fixed_route_tables[key] = fixed_route_entry
def _create_fake_network(self, ethernet_connected_chip): """ Generate the fake network for each board :param ethernet_connected_chip: the ethernet chip to fire from :return: fake graph, fake placements, fake machine. """ fake_graph = MachineGraph(label="routing fake_graph") fake_placements = Placements() destination_to_partition_id_map = dict() # build fake setup for the routing eth_x = ethernet_connected_chip.x eth_y = ethernet_connected_chip.y fake_machine = virtual_submachine(self._real_machine, ethernet_connected_chip) # Build a fake graph with vertices for all the monitors for chip in self._real_machine.get_chips_by_ethernet(eth_x, eth_y): # locate correct chips extra monitor placement placement = self._real_placements.get_placement_of_vertex( self._monitors[chip.x, chip.y]) # adjust for wrap around's fake_x, fake_y = self._real_machine.get_local_xy(chip) # add destination vertex vertex = RoutingMachineVertex() fake_graph.add_vertex(vertex) # build fake placement fake_placements.add_placement( Placement(x=fake_x, y=fake_y, p=placement.p, vertex=vertex)) # build source vertex, which is for the Gatherer vertex_source = RoutingMachineVertex() fake_graph.add_vertex(vertex_source) for free_processor in range(Machine.MAX_CORES_PER_CHIP): if not fake_placements.is_processor_occupied( x=FAKE_ETHERNET_CHIP_X, y=FAKE_ETHERNET_CHIP_Y, p=free_processor): fake_placements.add_placement( Placement(x=FAKE_ETHERNET_CHIP_X, y=FAKE_ETHERNET_CHIP_Y, p=free_processor, vertex=vertex_source)) break # deal with edges, each one being in a unique partition id, to # allow unique routing to each chip. counter = KEY_START_VALUE for vertex in fake_graph.vertices: if vertex == vertex_source: continue fake_graph.add_edge( MachineEdge(pre_vertex=vertex_source, post_vertex=vertex), counter) placement = fake_placements.get_placement_of_vertex(vertex) # adjust to real chip ids real_chip_xy = self._real_machine.get_global_xy( placement.x, placement.y, eth_x, eth_y) destination_to_partition_id_map[real_chip_xy] = counter counter += N_KEYS_PER_PARTITION_ID return (fake_graph, fake_placements, fake_machine, destination_to_partition_id_map)
def __call__(self, machine_graph, machine, n_keys_map, plan_n_timesteps): """ :param MachineGraph machine_graph: the machine graph :param ~spinn_machine.Machine machine: the SpiNNaker machine :param AbstractMachinePartitionNKeysMap n_keys_map: the n keys from partition map :param int plan_n_timesteps: number of timesteps to plan for :return: placements. :rtype: Placements """ # create progress bar progress_bar = ProgressBar( (machine_graph.n_vertices * self.ITERATIONS) + self.STEPS, "Placing graph vertices via spreading over an entire machine") # check that the algorithm can handle the constraints self._check_constraints( machine_graph.vertices, additional_placement_constraints={SameChipAsConstraint}) progress_bar.update() # get same chip groups same_chip_vertex_groups = get_same_chip_vertex_groups(machine_graph) progress_bar.update() # get chip and core placed verts hard_chip_constraints = self._locate_hard_placement_verts( machine_graph) progress_bar.update() # get one to one groups one_to_one_groups = create_vertices_groups( machine_graph.vertices, functools.partial(self._find_one_to_one_vertices, graph=machine_graph)) progress_bar.update() # sort chips so that they are radial from a given point and other # init data structs chips_in_order = self._determine_chip_list(machine) resource_tracker = ResourceTracker(machine, plan_n_timesteps, chips=chips_in_order) placements = Placements() placed_vertices = set() cost_per_chip = defaultdict(int) progress_bar.update() # allocate hard ones for hard_vertex in hard_chip_constraints: (x, y, p, _, _) = resource_tracker.allocate_constrained_resources( hard_vertex.resources_required, hard_vertex.constraints) placements.add_placement(Placement(hard_vertex, x, y, p)) placed_vertices.add(hard_vertex) cost_per_chip[x, y] += self._get_cost(hard_vertex, machine_graph, n_keys_map) # place groups of verts that need the same chip on the same chip, self._place_same_chip_verts(same_chip_vertex_groups, chips_in_order, placements, progress_bar, resource_tracker, placed_vertices, cost_per_chip, machine_graph, n_keys_map) # place 1 group per chip if possible on same chip as any already # placed verts. if not then radially from it. self._place_one_to_one_verts(one_to_one_groups, chips_in_order, placements, progress_bar, resource_tracker, placed_vertices, cost_per_chip, machine_graph, n_keys_map, machine) # place vertices which don't have annoying placement constraints. # spread them over the chips so that they have minimal impact on the # overall incoming packet cost per router. self._place_left_over_verts(machine_graph, chips_in_order, placements, progress_bar, resource_tracker, placed_vertices, cost_per_chip, n_keys_map) progress_bar.end() # return the built placements return placements
def _do_allocation( self, one_to_one_groups, same_chip_vertex_groups, machine, plan_n_timesteps, machine_graph, progress): """ :param one_to_one_groups: Groups of vertexes that would be nice on same chip :type one_to_one_groups: list(set(vertex)) :param same_chip_vertex_groups: Mapping of Vertex to the Vertex that must be on the same Chip :type same_chip_vertex_groups: dict(vertex, collection(vertex)) :param machine:\ The machine with respect to which to partition the application\ graph :type machine: :py:class:`spinn_machine.Machine` :param plan_n_timesteps: number of timesteps to plan for :type plan_n_timesteps: int :param machine_graph: The machine_graph to place :type machine_graph:\ :py:class:`pacman.model.graphs.machine.MachineGraph` :param progress: :return: """ placements = Placements() resource_tracker = ResourceTracker( machine, plan_n_timesteps, self._generate_radial_chips(machine)) all_vertices_placed = set() # RadialPlacementFromChipConstraint won't work here for vertex in machine_graph.vertices: for constraint in vertex.constraints: if isinstance(constraint, RadialPlacementFromChipConstraint): raise PacmanPlaceException( "A RadialPlacementFromChipConstraint will not work " "with the OneToOnePlacer algorithm; use the " "RadialPlacer algorithm instead") unconstrained = list() # Find and place vertices with hard constraints for vertex in machine_graph.vertices: if isinstance(vertex, AbstractVirtualVertex): virtual_p = 0 while placements.is_processor_occupied( vertex.virtual_chip_x, vertex.virtual_chip_y, virtual_p): virtual_p += 1 placements.add_placement(Placement( vertex, vertex.virtual_chip_x, vertex.virtual_chip_y, virtual_p)) all_vertices_placed.add(vertex) elif locate_constraints_of_type( vertex.constraints, ChipAndCoreConstraint): self._allocate_same_chip_as_group( vertex, placements, resource_tracker, same_chip_vertex_groups, all_vertices_placed, progress) else: unconstrained.append(vertex) for grouped_vertices in one_to_one_groups: # Get unallocated vertices and placements of allocated vertices unallocated = list() chips = list() for vert in grouped_vertices: if vert in all_vertices_placed: placement = placements.get_placement_of_vertex(vert) chips.append((placement.x, placement.y)) else: unallocated.append(vert) if 0 < len(unallocated) <=\ resource_tracker.get_maximum_cores_available_on_a_chip(): # Try to allocate all vertices to the same chip self._allocate_one_to_one_group( resource_tracker, unallocated, progress, placements, chips, all_vertices_placed) # if too big or failed go on to other groups first # check all have been allocated if not do so now. for vertex in machine_graph.vertices: if vertex not in all_vertices_placed: self._allocate_same_chip_as_group( vertex, placements, resource_tracker, same_chip_vertex_groups, all_vertices_placed, progress) progress.end() return placements
def test_local_verts_go_to_local_lpgs(self): machine = VirtualMachine(width=12, height=12, with_wrap_arounds=True) graph = MachineGraph("Test") default_params = { 'use_prefix': False, 'key_prefix': None, 'prefix_type': None, 'message_type': EIEIOType.KEY_32_BIT, 'right_shift': 0, 'payload_as_time_stamps': True, 'use_payload_prefix': True, 'payload_prefix': None, 'payload_right_shift': 0, 'number_of_packets_sent_per_time_step': 0, 'hostname': None, 'port': None, 'strip_sdp': None, 'board_address': None, 'tag': None, 'label': "test" } # data stores needed by algorithm live_packet_gatherers = dict() extended = dict(default_params) extended.update({'partition_id': "EVENTS"}) default_params_holder = LivePacketGatherParameters(**extended) live_packet_gatherers[default_params_holder] = list() live_packet_gatherers_to_vertex_mapping = dict() live_packet_gatherers_to_vertex_mapping[default_params_holder] = dict() placements = Placements() # add LPG's (1 for each Ethernet connected chip) for chip in machine.ethernet_connected_chips: vertex = LivePacketGatherMachineVertex(**default_params) graph.add_vertex(vertex) placements.add_placement( Placement(x=chip.x, y=chip.y, p=2, vertex=vertex)) live_packet_gatherers_to_vertex_mapping[default_params_holder][ chip.x, chip.y] = vertex # tracker of wirings verts_expected = defaultdict(list) positions = list() positions.append([0, 0, 0, 0]) positions.append([4, 4, 0, 0]) positions.append([1, 1, 0, 0]) positions.append([2, 2, 0, 0]) positions.append([8, 4, 8, 4]) positions.append([11, 4, 8, 4]) positions.append([4, 11, 4, 8]) positions.append([4, 8, 4, 8]) positions.append([0, 11, 8, 4]) positions.append([11, 11, 4, 8]) positions.append([8, 8, 4, 8]) positions.append([4, 0, 0, 0]) positions.append([7, 7, 0, 0]) # add graph vertices which reside on areas of the machine to ensure # spread over boards. for x, y, eth_x, eth_y in positions: vertex = SimpleMachineVertex(resources=ResourceContainer()) graph.add_vertex(vertex) live_packet_gatherers[default_params_holder].append(vertex) verts_expected[eth_x, eth_y].append(vertex) placements.add_placement(Placement(x=x, y=y, p=5, vertex=vertex)) # run edge inserter that should go boom edge_inserter = InsertEdgesToLivePacketGatherers() edge_inserter(live_packet_gatherer_parameters=live_packet_gatherers, placements=placements, live_packet_gatherers_to_vertex_mapping=( live_packet_gatherers_to_vertex_mapping), machine=machine, machine_graph=graph, application_graph=None, graph_mapper=None) # verify edges are in the right place for chip in machine.ethernet_connected_chips: edges = graph.get_edges_ending_at_vertex( live_packet_gatherers_to_vertex_mapping[default_params_holder][ chip.x, chip.y]) for edge in edges: self.assertIn(edge.pre_vertex, verts_expected[chip.x, chip.y])
def _do_dynamic_routing( self, fixed_route_tables, placements, ethernet_connected_chip, destination_class, machine, board_version): """ Uses a router to route fixed routes :param fixed_route_tables: fixed route tables entry holder :param placements: placements :param ethernet_connected_chip: the chip to consider for this routing :param destination_class: the class at the Ethernet connected chip\ for receiving all these routes. :param machine: SpiNNMachine instance :param board_version: The version of the machine :rtype: None """ graph = MachineGraph(label="routing graph") fake_placements = Placements() # build fake setup for the routing eth_x = ethernet_connected_chip.x eth_y = ethernet_connected_chip.y down_links = set() for (chip_x, chip_y) in machine.get_chips_on_board( ethernet_connected_chip): vertex = RoutingMachineVertex() graph.add_vertex(vertex) rel_x = chip_x - eth_x if rel_x < 0: rel_x += machine.max_chip_x + 1 rel_y = chip_y - eth_y if rel_y < 0: rel_y += machine.max_chip_y + 1 free_processor = 0 while ((free_processor < machine.MAX_CORES_PER_CHIP) and fake_placements.is_processor_occupied( self.FAKE_ETHERNET_CHIP_X, y=self.FAKE_ETHERNET_CHIP_Y, p=free_processor)): free_processor += 1 fake_placements.add_placement(Placement( x=rel_x, y=rel_y, p=free_processor, vertex=vertex)) down_links.update({ (rel_x, rel_y, link) for link in range( Router.MAX_LINKS_PER_ROUTER) if not machine.is_link_at(chip_x, chip_y, link)}) # Create a fake machine consisting of only the one board that # the routes should go over fake_machine = machine if (board_version in machine.BOARD_VERSION_FOR_48_CHIPS and (machine.max_chip_x > machine.MAX_CHIP_X_ID_ON_ONE_BOARD or machine.max_chip_y > machine.MAX_CHIP_Y_ID_ON_ONE_BOARD)): down_chips = { (x, y) for x, y in zip( range(machine.SIZE_X_OF_ONE_BOARD), range(machine.SIZE_Y_OF_ONE_BOARD)) if not machine.is_chip_at( (x + eth_x) % (machine.max_chip_x + 1), (y + eth_y) % (machine.max_chip_y + 1))} # build a fake machine which is just one board but with the missing # bits of the real board fake_machine = VirtualMachine( machine.SIZE_X_OF_ONE_BOARD, machine.SIZE_Y_OF_ONE_BOARD, False, down_chips=down_chips, down_links=down_links) # build destination verts = graph.vertices vertex_dest = RoutingMachineVertex() graph.add_vertex(vertex_dest) destination_processor = self._locate_destination( ethernet_chip_x=ethernet_connected_chip.x, ethernet_chip_y=ethernet_connected_chip.y, destination_class=destination_class, placements=placements) fake_placements.add_placement(Placement( x=self.FAKE_ETHERNET_CHIP_X, y=self.FAKE_ETHERNET_CHIP_Y, p=destination_processor, vertex=vertex_dest)) # deal with edges for vertex in verts: graph.add_edge( MachineEdge(pre_vertex=vertex, post_vertex=vertex_dest), self.FAKE_ROUTING_PARTITION) # route as if using multicast router = BasicDijkstraRouting() routing_tables_by_partition = router( placements=fake_placements, machine=fake_machine, machine_graph=graph, use_progress_bar=False) # convert to fixed route entries for (chip_x, chip_y) in routing_tables_by_partition.get_routers(): mc_entries = routing_tables_by_partition.get_entries_for_router( chip_x, chip_y) # only want the first entry, as that will all be the same. mc_entry = next(itervalues(mc_entries)) fixed_route_entry = FixedRouteEntry( link_ids=mc_entry.out_going_links, processor_ids=mc_entry.out_going_processors) x = (chip_x + eth_x) % (machine.max_chip_x + 1) y = (chip_y + eth_y) % (machine.max_chip_y + 1) key = (x, y) if key in fixed_route_tables: raise PacmanAlreadyExistsException( "fixed route entry", str(key)) fixed_route_tables[key] = fixed_route_entry
def test_local_verts_go_to_local_lpgs_app_graph(self): machine = virtual_machine(width=12, height=12) app_graph = ApplicationGraph("Test") graph = MachineGraph("Test", app_graph) default_params = { 'use_prefix': False, 'key_prefix': None, 'prefix_type': None, 'message_type': EIEIOType.KEY_32_BIT, 'right_shift': 0, 'payload_as_time_stamps': True, 'use_payload_prefix': True, 'payload_prefix': None, 'payload_right_shift': 0, 'number_of_packets_sent_per_time_step': 0, 'hostname': None, 'port': None, 'strip_sdp': None, 'tag': None, 'label': "Test"} # data stores needed by algorithm live_packet_gatherers = dict() default_params_holder = LivePacketGatherParameters(**default_params) live_packet_gatherers[default_params_holder] = list() live_packet_gatherers_to_vertex_mapping = defaultdict(dict) placements = Placements() # add LPG's (1 for each Ethernet connected chip for chip in machine.ethernet_connected_chips: new_params = dict(default_params) vertex = LivePacketGather( LivePacketGatherParameters(**new_params)) app_graph.add_vertex(vertex) vertex_slice = None resources_required = vertex.get_resources_used_by_atoms( vertex_slice) mac_vertex = vertex.create_machine_vertex( vertex_slice, resources_required) graph.add_vertex(mac_vertex) placements.add_placement( Placement(x=chip.x, y=chip.y, p=2, vertex=mac_vertex)) live_packet_gatherers_to_vertex_mapping[ default_params_holder][chip.x, chip.y] = mac_vertex # tracker of wirings verts_expected = defaultdict(list) positions = list() positions.append([0, 0, 0, 0]) positions.append([4, 4, 0, 0]) positions.append([1, 1, 0, 0]) positions.append([2, 2, 0, 0]) positions.append([8, 4, 8, 4]) positions.append([11, 4, 8, 4]) positions.append([4, 11, 4, 8]) positions.append([4, 8, 4, 8]) positions.append([0, 11, 8, 4]) positions.append([11, 11, 4, 8]) positions.append([8, 8, 4, 8]) positions.append([4, 0, 0, 0]) positions.append([7, 7, 0, 0]) # add graph vertices which reside on areas of the machine to ensure # spread over boards. for x, y, eth_x, eth_y in positions: vertex = SimpleTestVertex(1) app_graph.add_vertex(vertex) vertex_slice = Slice(0, 0) resources_required = vertex.get_resources_used_by_atoms( vertex_slice) mac_vertex = vertex.create_machine_vertex( vertex_slice, resources_required) graph.add_vertex(mac_vertex) partition_ids = ["EVENTS"] live_packet_gatherers[default_params_holder].append( (vertex, partition_ids)) verts_expected[eth_x, eth_y].append(mac_vertex) placements.add_placement( Placement(x=x, y=y, p=5, vertex=mac_vertex)) # run edge inserter that should go boom edge_inserter = InsertEdgesToLivePacketGatherers() edge_inserter( live_packet_gatherer_parameters=live_packet_gatherers, placements=placements, live_packet_gatherers_to_vertex_mapping=( live_packet_gatherers_to_vertex_mapping), machine=machine, machine_graph=graph, application_graph=app_graph) # verify edges are in the right place for chip in machine.ethernet_connected_chips: edges = graph.get_edges_ending_at_vertex( live_packet_gatherers_to_vertex_mapping[ default_params_holder][chip.x, chip.y]) for edge in edges: self.assertIn(edge.pre_vertex, verts_expected[chip.x, chip.y]) # check app graph for chip in machine.ethernet_connected_chips: app_verts_expected = [ vert.app_vertex for vert in verts_expected[chip.x, chip.y]] lpg_machine = live_packet_gatherers_to_vertex_mapping[ default_params_holder][chip.x, chip.y] for edge in app_graph.get_edges_ending_at_vertex( lpg_machine.app_vertex): self.assertIn(edge.pre_vertex, app_verts_expected)
def test_local_verts_when_multiple_lpgs_are_local(self): machine = virtual_machine(width=12, height=12) graph = MachineGraph("Test") default_params = { 'use_prefix': False, 'key_prefix': None, 'prefix_type': None, 'message_type': EIEIOType.KEY_32_BIT, 'right_shift': 0, 'payload_as_time_stamps': True, 'use_payload_prefix': True, 'payload_prefix': None, 'payload_right_shift': 0, 'number_of_packets_sent_per_time_step': 0, 'hostname': None, 'port': None, 'strip_sdp': None, 'tag': None, 'label': "Test"} # data stores needed by algorithm live_packet_gatherers = dict() default_params_holder = LivePacketGatherParameters(**default_params) live_packet_gatherers[default_params_holder] = list() live_packet_gatherers_to_vertex_mapping = defaultdict(dict) placements = Placements() # add LPG's (1 for each Ethernet connected chip) specific_data_holders = dict() index = 1 for chip in machine.ethernet_connected_chips: extended = dict(default_params) vertex = LivePacketGatherMachineVertex( LivePacketGatherParameters(**extended), label='test') graph.add_vertex(vertex) placements.add_placement( Placement(x=chip.x, y=chip.y, p=2, vertex=vertex)) live_packet_gatherers_to_vertex_mapping[ default_params_holder][chip.x, chip.y] = vertex # Add another on each chip separately index += 1 extended = dict(default_params) extended['board_address'] = chip.ip_address default_params_holder2 = LivePacketGatherParameters(**extended) extended = dict(default_params) extended.update({'label': "test"}) vertex = LivePacketGatherMachineVertex( LivePacketGatherParameters(**extended)) specific_data_holders[(chip.x, chip.y)] = default_params_holder2 placements.add_placement(Placement( x=chip.x, y=chip.y, p=3, vertex=vertex)) graph.add_vertex(vertex) live_packet_gatherers_to_vertex_mapping[ default_params_holder2][chip.x, chip.y] = vertex live_packet_gatherers[default_params_holder2] = list() # tracker of wirings verts_expected = defaultdict(list) positions = list() positions.append([0, 0, 0, 0, 2, default_params_holder]) positions.append([4, 4, 0, 0, 2, default_params_holder]) positions.append( [1, 1, 0, 0, 3, specific_data_holders[(0, 0)]]) positions.append( [2, 2, 0, 0, 3, specific_data_holders[(0, 0)]]) positions.append([8, 4, 8, 4, 2, default_params_holder]) positions.append([11, 4, 8, 4, 2, default_params_holder]) positions.append([4, 11, 4, 8, 2, default_params_holder]) positions.append([4, 8, 4, 8, 2, default_params_holder]) positions.append([0, 11, 8, 4, 3, specific_data_holders[(8, 4)]]) positions.append([11, 11, 4, 8, 3, specific_data_holders[(4, 8)]]) positions.append([8, 8, 4, 8, 3, specific_data_holders[(4, 8)]]) positions.append([4, 0, 0, 0, 3, specific_data_holders[(0, 0)]]) positions.append([7, 7, 0, 0, 2, default_params_holder]) # add graph vertices which reside on areas of the machine to ensure # spread over boards. for x, y, eth_x, eth_y, eth_p, params in positions: vertex = SimpleMachineVertex(resources=ResourceContainer()) graph.add_vertex(vertex) live_packet_gatherers[params].append((vertex, ["EVENTS"])) verts_expected[eth_x, eth_y, eth_p].append(vertex) placements.add_placement(Placement(x=x, y=y, p=5, vertex=vertex)) # run edge inserter that should go boom edge_inserter = InsertEdgesToLivePacketGatherers() edge_inserter( live_packet_gatherer_parameters=live_packet_gatherers, placements=placements, live_packet_gatherers_to_vertex_mapping=( live_packet_gatherers_to_vertex_mapping), machine=machine, machine_graph=graph, application_graph=None) # verify edges are in the right place for chip in machine.ethernet_connected_chips: for params, p in zip( (default_params_holder, specific_data_holders[chip.x, chip.y]), (2, 3)): edges = graph.get_edges_ending_at_vertex( live_packet_gatherers_to_vertex_mapping[ params][chip.x, chip.y]) for edge in edges: self.assertIn( edge.pre_vertex, verts_expected[chip.x, chip.y, p])
def test_local_verts_go_to_local_lpgs(self): machine = VirtualMachine(width=12, height=12, with_wrap_arounds=True) graph = MachineGraph("Test") default_params = { 'use_prefix': False, 'key_prefix': None, 'prefix_type': None, 'message_type': EIEIOType.KEY_32_BIT, 'right_shift': 0, 'payload_as_time_stamps': True, 'use_payload_prefix': True, 'payload_prefix': None, 'payload_right_shift': 0, 'number_of_packets_sent_per_time_step': 0, 'hostname': None, 'port': None, 'strip_sdp': None, 'board_address': None, 'tag': None} # data stores needed by algorithm live_packet_gatherers = dict() extended = dict(default_params) extended.update({'partition_id': "EVENTS"}) default_params_holder = LivePacketGatherParameters(**extended) live_packet_gatherers[default_params_holder] = list() live_packet_gatherers_to_vertex_mapping = dict() live_packet_gatherers_to_vertex_mapping[default_params_holder] = dict() placements = Placements() # add LPG's (1 for each Ethernet connected chip) for chip in machine.ethernet_connected_chips: extended = dict(default_params) extended.update({'label': 'test'}) vertex = LivePacketGatherMachineVertex(**extended) graph.add_vertex(vertex) placements.add_placement( Placement(x=chip.x, y=chip.y, p=2, vertex=vertex)) live_packet_gatherers_to_vertex_mapping[ default_params_holder][chip.x, chip.y] = vertex # tracker of wirings verts_expected = defaultdict(list) positions = list() positions.append([0, 0, 0, 0]) positions.append([4, 4, 0, 0]) positions.append([1, 1, 0, 0]) positions.append([2, 2, 0, 0]) positions.append([8, 4, 8, 4]) positions.append([11, 4, 8, 4]) positions.append([4, 11, 4, 8]) positions.append([4, 8, 4, 8]) positions.append([0, 11, 8, 4]) positions.append([11, 11, 4, 8]) positions.append([8, 8, 4, 8]) positions.append([4, 0, 0, 0]) positions.append([7, 7, 0, 0]) # add graph vertices which reside on areas of the machine to ensure # spread over boards. for x, y, eth_x, eth_y in positions: vertex = SimpleMachineVertex(resources=ResourceContainer()) graph.add_vertex(vertex) live_packet_gatherers[default_params_holder].append(vertex) verts_expected[eth_x, eth_y].append(vertex) placements.add_placement(Placement(x=x, y=y, p=5, vertex=vertex)) # run edge inserter that should go boom edge_inserter = InsertEdgesToLivePacketGatherers() edge_inserter( live_packet_gatherer_parameters=live_packet_gatherers, placements=placements, live_packet_gatherers_to_vertex_mapping=( live_packet_gatherers_to_vertex_mapping), machine=machine, machine_graph=graph, application_graph=None, graph_mapper=None) # verify edges are in the right place for chip in machine.ethernet_connected_chips: edges = graph.get_edges_ending_at_vertex( live_packet_gatherers_to_vertex_mapping[ default_params_holder][chip.x, chip.y]) for edge in edges: self.assertIn(edge.pre_vertex, verts_expected[chip.x, chip.y])
class TestRouter(unittest.TestCase): def setUp(self): # sort out graph self.vert1 = Vertex(10, "New AbstractConstrainedVertex 1") self.vert2 = Vertex(5, "New AbstractConstrainedVertex 2") self.edge1 = ApplicationEdge(self.vert1, self.vert2, "First edge") self.verts = [self.vert1, self.vert2] self.edges = [self.edge1] self.graph = ApplicationGraph("Graph", self.verts, self.edges) # sort out graph self.graph = MachineGraph() self.vertex1 = SimpleMachineVertex( 0, 10, self.vert1.get_resources_used_by_atoms(0, 10, [])) self.vertex2 = SimpleMachineVertex( 0, 5, self.vert2.get_resources_used_by_atoms(0, 10, [])) self.edge = MachineEdge(self.vertex1, self.vertex2) self.graph.add_vertex(self.vertex1) self.graph.add_vertex(self.vertex2) self.graph.add_edge(self.edge, "TEST") @unittest.skip("demonstrating skipping") def test_router_with_same_chip_route(self): # sort out placements self.placements = Placements() self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1) self.placement2 = Placement(x=0, y=0, p=3, vertex=self.vertex2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11, mask=DEFAULT_MASK, edge=self.edge) self.routing_info.add_partition_info(self.edge_routing_info1) # create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route(machine=self.machine, placements=self.placements, machine_graph=self.graph, routing_info_allocation=self.routing_info) @unittest.skip("demonstrating skipping") def test_router_with_neighbour_chip(self): # sort out placements self.placements = Placements() self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1) self.placement2 = Placement(x=1, y=1, p=2, vertex=self.vertex2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11, mask=DEFAULT_MASK, edge=self.edge) self.routing_info.add_partition_info(self.edge_routing_info1) # create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route(machine=self.machine, placements=self.placements, machine_graph=self.graph, routing_info_allocation=self.routing_info) @unittest.skip("demonstrating skipping") def test_router_with_one_hop_route_all_default_link_0(self): # sort out placements self.placements = Placements() self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1) self.placement2 = Placement(x=2, y=0, p=2, vertex=self.vertex2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11, mask=DEFAULT_MASK, edge=self.edge) self.routing_info.add_partition_info(self.edge_routing_info1) # create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route(machine=self.machine, placements=self.placements, machine_graph=self.graph, routing_info_allocation=self.routing_info) @unittest.skip("demonstrating skipping") def test_router_with_one_hop_route_all_default_link_1(self): self.placements = Placements() self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1) self.placement2 = Placement(x=2, y=2, p=2, vertex=self.vertex2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11, mask=DEFAULT_MASK, edge=self.edge) self.routing_info.add_partition_info(self.edge_routing_info1) # create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route(machine=self.machine, placements=self.placements, machine_graph=self.graph, routing_info_allocation=self.routing_info) @unittest.skip("demonstrating skipping") def test_router_with_one_hop_route_all_default_link_2(self): self.placements = Placements() self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1) self.placement2 = Placement(x=0, y=2, p=2, vertex=self.vertex2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11, mask=DEFAULT_MASK, edge=self.edge) self.routing_info.add_partition_info(self.edge_routing_info1) # create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route(machine=self.machine, placements=self.placements, machine_graph=self.graph, routing_info_allocation=self.routing_info) @unittest.skip("demonstrating skipping") def test_router_with_one_hop_route_all_default_link_3(self): self.placements = Placements() self.placement1 = Placement(x=2, y=0, p=2, vertex=self.vertex1) self.placement2 = Placement(x=0, y=0, p=2, vertex=self.vertex2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11, mask=DEFAULT_MASK, edge=self.edge) self.routing_info.add_partition_info(self.edge_routing_info1) # create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route(machine=self.machine, placements=self.placements, machine_graph=self.graph, routing_info_allocation=self.routing_info) @unittest.skip("demonstrating skipping") def test_router_with_one_hop_route_all_default_link_4(self): self.placements = Placements() self.placement1 = Placement(x=2, y=2, p=2, vertex=self.vertex1) self.placement2 = Placement(x=0, y=0, p=2, vertex=self.vertex2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11, mask=DEFAULT_MASK, edge=self.edge) self.routing_info.add_partition_info(self.edge_routing_info1) # create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route(machine=self.machine, placements=self.placements, machine_graph=self.graph, routing_info_allocation=self.routing_info) @unittest.skip("demonstrating skipping") def test_router_with_one_hop_route_all_default_link_5(self): self.placements = Placements() self.placement1 = Placement(x=0, y=2, p=2, vertex=self.vertex1) self.placement2 = Placement(x=0, y=0, p=2, vertex=self.vertex2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11, mask=DEFAULT_MASK, edge=self.edge) self.routing_info.add_partition_info(self.edge_routing_info1) # create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route(machine=self.machine, placements=self.placements, machine_graph=self.graph, routing_info_allocation=self.routing_info) @unittest.skip("demonstrating skipping") def test_router_with_one_hop_route_not_default(self): # sort out placements self.placements = Placements() self.placement1 = Placement(x=2, y=1, p=2, vertex=self.vertex1) self.placement2 = Placement(x=0, y=0, p=2, vertex=self.vertex2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11, mask=DEFAULT_MASK, edge=self.edge) self.routing_info.add_partition_info(self.edge_routing_info1) # create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route(machine=self.machine, placements=self.placements, machine_graph=self.graph, routing_info_allocation=self.routing_info) @unittest.skip("demonstrating skipping") def test_router_with_multi_hop_route_across_board(self): # sort out placements self.placements = Placements() self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1) self.placement2 = Placement(x=8, y=7, p=2, vertex=self.vertex2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11, mask=DEFAULT_MASK, edge=self.edge) self.routing_info.add_partition_info(self.edge_routing_info1) # create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route(machine=self.machine, placements=self.placements, machine_graph=self.graph, routing_info_allocation=self.routing_info) @unittest.skip("demonstrating skipping") def test_new_router(self): report_folder = "..\reports" self.routing = BasicDijkstraRouting() self.assertEqual(self.routing._report_folder, report_folder) self.assertEqual(self.routing._graph, None) self.assertEqual(self.routing.report_states, None) self.assertEqual(self.routing._hostname, None) self.assertIsInstance(self.routing._router_algorithm, BasicDijkstraRouting) self.assertEqual(self.routing._graph_mappings, None) @unittest.skip("demonstrating skipping") def test_new_router_set_non_default_routing_algorithm(self): report_folder = "..\reports" self.routing = BasicDijkstraRouting() self.assertEqual(self.routing._report_folder, report_folder) self.assertEqual(self.routing._graph, None) self.assertEqual(self.routing.report_states, None) self.assertEqual(self.routing._hostname, None) self.assertEqual(self.routing._graph_mappings, None) @unittest.skip("demonstrating skipping") def test_run_router(self): # sort out placements self.placements = Placements() self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1) self.placement2 = Placement(x=1, y=1, p=2, vertex=self.vertex2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11, mask=DEFAULT_MASK, edge=self.edge) self.routing_info.add_partition_info(self.edge_routing_info1) # create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route(machine=self.machine, placements=self.placements, machine_graph=self.graph, routing_info_allocation=self.routing_info)