def __call__(self, subgraph, n_keys_map, routing_paths): # check that this algorithm supports the constraints utility_calls.check_algorithm_can_support_constraints( constrained_vertices=subgraph.subedges, supported_constraints=[ KeyAllocatorFixedMaskConstraint, KeyAllocatorFixedKeyAndMaskConstraint, KeyAllocatorContiguousRangeContraint], abstract_constraint_type=AbstractKeyAllocatorConstraint) routing_tables = MulticastRoutingTables() # Get the partitioned edges grouped by those that require the same key same_key_groups = \ routing_info_allocator_utilities.get_edge_groups(subgraph) # Go through the groups and allocate keys progress_bar = ProgressBar(len(same_key_groups), "Allocating routing keys") routing_infos = RoutingInfo() for group in same_key_groups: # Check how many keys are needed for the edges of the group edge_n_keys = None for edge in group: n_keys = n_keys_map.n_keys_for_partitioned_edge(edge) if edge_n_keys is None: edge_n_keys = n_keys elif edge_n_keys != n_keys: raise PacmanRouteInfoAllocationException( "Two edges require the same keys but request a" " different number of keys") # Get any fixed keys and masks from the group and attempt to # allocate them keys_and_masks = routing_info_allocator_utilities.\ get_fixed_key_and_mask(group) fixed_mask, fields = \ routing_info_allocator_utilities.get_fixed_mask(group) if keys_and_masks is not None: self._allocate_fixed_keys_and_masks(keys_and_masks, fixed_mask) else: keys_and_masks = self._allocate_keys_and_masks( fixed_mask, fields, edge_n_keys) # Allocate the routing information for edge in group: subedge_info = SubedgeRoutingInfo(keys_and_masks, edge) routing_infos.add_subedge_info(subedge_info) # update routing tables with entries routing_info_allocator_utilities.add_routing_key_entries( routing_paths, subedge_info, edge, routing_tables) progress_bar.update() progress_bar.end() return {'routing_infos': routing_infos, 'routing_tables': routing_tables}
def test_get_subedge_information_from_subedge(self): subv1 = PartitionedVertex(None, "") subv2 = PartitionedVertex(None, "") sube = MultiCastPartitionedEdge(subv1, subv2) keys_and_masks = list() keys_and_masks.append(BaseKeyAndMask(0x0012, 0x00ff)) sri = SubedgeRoutingInfo(keys_and_masks, sube) ri = RoutingInfo([sri]) self.assertEqual(ri.get_subedge_information_from_subedge(sri.subedge), sri)
def test_get_key_from_subedge_info_not_matching(self): subv1 = PartitionedVertex(None, "") subv2 = PartitionedVertex(None, "") sube = MultiCastPartitionedEdge(subv1, subv2) subz = MultiCastPartitionedEdge(subv2, subv1) keys_and_masks = list() keys_and_masks.append(BaseKeyAndMask(0x0012, 0x00ff)) sri = SubedgeRoutingInfo(keys_and_masks, sube) ri = RoutingInfo([sri]) ri_keys_and_masks = ri.get_keys_and_masks_from_subedge(subz) self.assertEqual(ri_keys_and_masks, None)
def test_full_machine_routing(self): placements = Placements() self.placement1 = Placement(x=1, y=0, p=2, subvertex=self.subvert1) self.placement2 = Placement(x=1, y=0, p=3, subvertex=self.subvert2) subvertices = list() for i in range(4 * 17): #51 atoms per each processor on 20 chips subvertices.append(PartitionedVertex( 0, 50, get_resources_used_by_atoms(0, 50, []), "Subvertex " + str(i))) subedges = list() for i in range(len(subvertices)): subedges.append(AbstractPartitionedEdge( subvertices[i], subvertices[(i + 1)%len(subvertices)])) subgraph = PartitionedGraph("Subgraph", subvertices, subedges) p = 1 x = 0 y = 0 for subvert in subvertices: placements.add_placement(Placement(subvert, x, y, p)) p = (p + 1) % 18 if p == 0: p += 1 y += 1 if y == 2: y = 0 x += 1 routing_info = RoutingInfo() subedge_routing_info = list() for i in range(len(subedges)): subedge_routing_info.append(SubedgeRoutingInfo( subedges[i], i<<11, constants.DEFAULT_MASK)) for subedge_info in subedge_routing_info: routing_info.add_subedge_info(subedge_info) self.set_up_4_node_board() dijkstra_router = BasicDijkstraRouting() routing_tables = dijkstra_router.route( machine=self.machine, placements=placements, partitioned_graph=subgraph, routing_info_allocation=routing_info) for entry in routing_tables.routing_tables: print entry.x, entry.y for routing_entry in entry.multicast_routing_entries: print "\t\tProcessor_ids:{}, Link_ids:{}".format( routing_entry.processor_ids, routing_entry.link_ids)
def test_get_subedge_info_by_key_not_matching(self): """ check that trying to locate a subedge info with an invalid key and mask results in no subedge info being returned :return: """ subv1 = PartitionedVertex(None, "") subv2 = PartitionedVertex(None, "") sube = MultiCastPartitionedEdge(subv1, subv2) keys_and_masks = list() keys_and_masks.append(BaseKeyAndMask(0x0012, 0x00ff)) sri = SubedgeRoutingInfo(keys_and_masks, sube) ri = RoutingInfo([sri]) self.assertEqual(ri.get_subedge_infos_by_key(0xff12, 0x000f), None)
def test_get_subedge_info_by_key_matching(self): """ check that you can get a subedge routing info from a routing info based off key :return: """ subv1 = PartitionedVertex(None, "") subv2 = PartitionedVertex(None, "") sube = MultiCastPartitionedEdge(subv1, subv2) keys_and_masks = list() keys_and_masks.append(BaseKeyAndMask(0x0012, 0x00ff)) sri = SubedgeRoutingInfo(keys_and_masks, sube) ri = RoutingInfo([sri]) self.assertIn(sri, ri.get_subedge_infos_by_key(0xff12, 0x00ff))
def test_get_key_from_subedge_info(self): """ :return: """ subv1 = PartitionedVertex(None, "") subv2 = PartitionedVertex(None, "") sube = MultiCastPartitionedEdge(subv1, subv2) keys_and_masks = list() keys_and_masks.append(BaseKeyAndMask(0x0012, 0x00ff)) sri = SubedgeRoutingInfo(keys_and_masks, sube) ri = RoutingInfo([sri]) ri_keys_and_masks = ri.get_keys_and_masks_from_subedge(sri.subedge) for key_and_mask in ri_keys_and_masks: self.assertEqual(key_and_mask.key, 0x0012)
def test_routing_on_chip_custom_4_node_machine(self): self.placements = Placements() self.placement1 = Placement(x=1, y=0, p=2, subvertex=self.subvert1) self.placement2 = Placement(x=1, y=0, p=3, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) self.set_up_4_node_board() dijkstra_router = BasicDijkstraRouting() routing_tables = dijkstra_router.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, routing_info_allocation=self.routing_info) for entry in routing_tables.routing_tables: print entry.x, entry.y for routing_entry in entry.multicast_routing_entries: print "\t\tProcessor_ids:{}, Link_ids:{}".format( routing_entry.processor_ids, routing_entry.link_ids)
def setUp(self): # sort out graph self.vert1 = Vertex(10, "New AbstractConstrainedVertex 1") self.vert2 = Vertex(5, "New AbstractConstrainedVertex 2") self.edge1 = AbstractPartitionableEdge(self.vert1, self.vert2, "First edge") self.verts = [self.vert1, self.vert2] self.edges = [self.edge1] self.graph = PartitionableGraph("Graph", self.verts, self.edges) # sort out subgraph self.subgraph = PartitionedGraph() self.subvert1 = PartitionedVertex( 0, 10, get_resources_used_by_atoms(0, 10, [])) self.subvert2 = PartitionedVertex( 0, 5, get_resources_used_by_atoms(0, 10, [])) self.subedge = AbstractPartitionedEdge(self.subvert1, self.subvert2) self.subgraph.add_subvertex(self.subvert1) self.subgraph.add_subvertex(self.subvert2) self.subgraph.add_subedge(self.subedge) # sort out placements self.placements = Placements() self.placement1 = Placement(x=0, y=0, p=2, subvertex=self.subvert1) self.placement2 = Placement(x=1, y=1, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) # create machine flops = 1000 (e, ne, n, w, sw, s) = range(6) processors = list() for i in range(18): processors.append(Processor(i, flops)) _sdram = SDRAM(128 * (2 ** 20)) ip = "192.162.240.253" chips = list() for x in range(10): for y in range(10): links = list() links.append(Link(x, y, 0, (x + 1) % 10, y, n, n)) links.append(Link(x, y, 1, (x + 1) % 10, (y + 1) % 10, s, s)) links.append(Link(x, y, 2, x, (y + 1) % 10, n, n)) links.append(Link(x, y, 3, (x - 1) % 10, y, s, s)) links.append(Link(x, y, 4, (x - 1) % 10, (y - 1) % 10, n, n)) links.append(Link(x, y, 5, x, (y - 1) % 10, s, s)) r = Router(links, False, 100, 1024) chips.append(Chip(x, y, processors, r, _sdram, ip)) self.machine = Machine(chips)
def test_router_with_one_hop_route_all_default_link_5(self): self.placements = Placements() self.placement1 = Placement(x=0, y=2, p=2, subvertex=self.subvert1) self.placement2 = Placement(x=0, y=0, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, routing_info_allocation=self.routing_info)
def __call__(self, subgraph, placements, n_keys_map, routing_paths): """ Allocates routing information to the partitioned edges in a\ partitioned graph :param subgraph: The partitioned graph to allocate the routing info for :type subgraph:\ :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` :param routing_paths: the paths each partitioned edge takes to get\ from source to destination. :type routing_paths: :py:class:`pacman.model.routing_paths.multicast_routing_paths.MulticastRoutingPaths :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 = [RequiresRoutingInfoPartitionedVertex] utility_calls.check_algorithm_can_support_constraints( constrained_vertices=subgraph.subedges, supported_constraints=supported_constraints, abstract_constraint_type=AbstractKeyAllocatorConstraint) # take each subedge and create keys from its placement progress_bar = ProgressBar(len(subgraph.subvertices), "Allocating routing keys") routing_infos = RoutingInfo() routing_tables = MulticastRoutingTables() for subvert in subgraph.subvertices: out_going_subedges = subgraph.outgoing_subedges_from_subvertex( subvert) for out_going_subedge in out_going_subedges: n_keys = n_keys_map.n_keys_for_partitioned_edge( out_going_subedge) 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, out_going_subedge, 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 = SubedgeRoutingInfo( keys_and_masks, out_going_subedge) routing_infos.add_subedge_info(subedge_routing_info) else: raise PacmanRouteInfoAllocationException( "This subvertex '{}' has no placement! this should " "never occur, please fix and try again." .format(subvert)) # update routing tables with entries routing_info_allocator_utilities.add_routing_key_entries( routing_paths, subedge_routing_info, out_going_subedge, routing_tables) progress_bar.update() progress_bar.end() return {'routing_infos': routing_infos, 'routing_tables': routing_tables}
def test_write_synaptic_matrix_and_master_population_table(self): MockSimulator.setup() default_config_paths = os.path.join( os.path.dirname(abstract_spinnaker_common.__file__), AbstractSpiNNakerCommon.CONFIG_FILE_NAME) config = conf_loader.load_config( AbstractSpiNNakerCommon.CONFIG_FILE_NAME, default_config_paths) config.set("Simulation", "one_to_one_connection_dtcm_max_bytes", 40) machine_time_step = 1000.0 pre_app_vertex = SimpleApplicationVertex(10) pre_vertex = SimpleMachineVertex(resources=None) pre_vertex_slice = Slice(0, 9) post_app_vertex = SimpleApplicationVertex(10) post_vertex = SimpleMachineVertex(resources=None) post_vertex_slice = Slice(0, 9) post_slice_index = 0 one_to_one_connector_1 = OneToOneConnector(None) one_to_one_connector_1.set_projection_information( pre_app_vertex, post_app_vertex, None, machine_time_step) one_to_one_connector_1.set_weights_and_delays(1.5, 1.0) one_to_one_connector_2 = OneToOneConnector(None) one_to_one_connector_2.set_projection_information( pre_app_vertex, post_app_vertex, None, machine_time_step) one_to_one_connector_2.set_weights_and_delays(2.5, 2.0) all_to_all_connector = AllToAllConnector(None) all_to_all_connector.set_projection_information( pre_app_vertex, post_app_vertex, None, machine_time_step) all_to_all_connector.set_weights_and_delays(4.5, 4.0) direct_synapse_information_1 = SynapseInformation( one_to_one_connector_1, SynapseDynamicsStatic(), 0) direct_synapse_information_2 = SynapseInformation( one_to_one_connector_2, SynapseDynamicsStatic(), 1) all_to_all_synapse_information = SynapseInformation( all_to_all_connector, SynapseDynamicsStatic(), 0) app_edge = ProjectionApplicationEdge( pre_app_vertex, post_app_vertex, direct_synapse_information_1) app_edge.add_synapse_information(direct_synapse_information_2) app_edge.add_synapse_information(all_to_all_synapse_information) machine_edge = ProjectionMachineEdge( app_edge.synapse_information, pre_vertex, post_vertex) partition_name = "TestPartition" graph = MachineGraph("Test") graph.add_vertex(pre_vertex) graph.add_vertex(post_vertex) graph.add_edge(machine_edge, partition_name) graph_mapper = GraphMapper() graph_mapper.add_vertex_mapping( pre_vertex, pre_vertex_slice, pre_app_vertex) graph_mapper.add_vertex_mapping( post_vertex, post_vertex_slice, post_app_vertex) graph_mapper.add_edge_mapping(machine_edge, app_edge) weight_scales = [4096.0, 4096.0] key = 0 routing_info = RoutingInfo() routing_info.add_partition_info(PartitionRoutingInfo( [BaseKeyAndMask(key, 0xFFFFFFF0)], graph.get_outgoing_edge_partition_starting_at_vertex( pre_vertex, partition_name))) temp_spec = tempfile.mktemp() spec_writer = FileDataWriter(temp_spec) spec = DataSpecificationGenerator(spec_writer, None) master_pop_sz = 1000 master_pop_region = 0 all_syn_block_sz = 2000 synapse_region = 1 spec.reserve_memory_region(master_pop_region, master_pop_sz) spec.reserve_memory_region(synapse_region, all_syn_block_sz) synapse_type = MockSynapseType() synaptic_manager = SynapticManager( synapse_type=synapse_type, ring_buffer_sigma=5.0, spikes_per_second=100.0, config=config) synaptic_manager._write_synaptic_matrix_and_master_population_table( spec, [post_vertex_slice], post_slice_index, post_vertex, post_vertex_slice, all_syn_block_sz, weight_scales, master_pop_region, synapse_region, routing_info, graph_mapper, graph, machine_time_step) spec.end_specification() spec_writer.close() spec_reader = FileDataReader(temp_spec) executor = DataSpecificationExecutor( spec_reader, master_pop_sz + all_syn_block_sz) executor.execute() master_pop_table = executor.get_region(0) synaptic_matrix = executor.get_region(1) all_data = bytearray() all_data.extend(master_pop_table.region_data[ :master_pop_table.max_write_pointer]) all_data.extend(synaptic_matrix.region_data[ :synaptic_matrix.max_write_pointer]) master_pop_table_address = 0 synaptic_matrix_address = master_pop_table.max_write_pointer direct_synapses_address = struct.unpack_from( "<I", synaptic_matrix.region_data)[0] direct_synapses_address += synaptic_matrix_address + 8 indirect_synapses_address = synaptic_matrix_address + 4 placement = Placement(None, 0, 0, 1) transceiver = MockTransceiverRawData(all_data) # Get the master population table details items = synaptic_manager._poptable_type\ .extract_synaptic_matrix_data_location( key, master_pop_table_address, transceiver, placement.x, placement.y) # The first entry should be direct, but the rest should be indirect; # the second is potentially direct, but has been restricted by the # restriction on the size of the direct matrix assert len(items) == 3 # TODO: This has been changed because direct matrices are disabled! assert not items[0][2] assert not items[1][2] assert not items[2][2] data_1, row_len_1 = synaptic_manager._retrieve_synaptic_block( transceiver=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=0, using_extra_monitor_cores=False) connections_1 = synaptic_manager._synapse_io.read_synapses( direct_synapse_information_1, pre_vertex_slice, post_vertex_slice, row_len_1, 0, 2, weight_scales, data_1, None, app_edge.n_delay_stages, machine_time_step) # The first matrix is a 1-1 matrix, so row length is 1 assert row_len_1 == 1 # Check that all the connections have the right weight and delay assert len(connections_1) == post_vertex_slice.n_atoms assert all([conn["weight"] == 1.5 for conn in connections_1]) assert all([conn["delay"] == 1.0 for conn in connections_1]) data_2, row_len_2 = synaptic_manager._retrieve_synaptic_block( transceiver=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=1, using_extra_monitor_cores=False) connections_2 = synaptic_manager._synapse_io.read_synapses( direct_synapse_information_2, pre_vertex_slice, post_vertex_slice, row_len_2, 0, 2, weight_scales, data_2, None, app_edge.n_delay_stages, machine_time_step) # The second matrix is a 1-1 matrix, so row length is 1 assert row_len_2 == 1 # Check that all the connections have the right weight and delay assert len(connections_2) == post_vertex_slice.n_atoms assert all([conn["weight"] == 2.5 for conn in connections_2]) assert all([conn["delay"] == 2.0 for conn in connections_2]) data_3, row_len_3 = synaptic_manager._retrieve_synaptic_block( transceiver=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=2, using_extra_monitor_cores=False) connections_3 = synaptic_manager._synapse_io.read_synapses( all_to_all_synapse_information, pre_vertex_slice, post_vertex_slice, row_len_3, 0, 2, weight_scales, data_3, None, app_edge.n_delay_stages, machine_time_step) # The third matrix is an all-to-all matrix, so length is n_atoms assert row_len_3 == post_vertex_slice.n_atoms # Check that all the connections have the right weight and delay assert len(connections_3) == \ post_vertex_slice.n_atoms * pre_vertex_slice.n_atoms assert all([conn["weight"] == 4.5 for conn in connections_3]) assert all([conn["delay"] == 4.0 for conn in connections_3])
def __call__(self, subgraph, placements, n_keys_map, routing_paths): """ Allocates routing information to the partitioned edges in a\ partitioned graph :param subgraph: The partitioned graph to allocate the routing info for :type subgraph:\ :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` :param routing_paths: the paths each partitioned edge takes to get\ from source to destination. :type routing_paths: :py:class:`pacman.model.routing_paths.multicast_routing_paths.MulticastRoutingPaths :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 = [] utility_calls.check_algorithm_can_support_constraints( constrained_vertices=subgraph.subedges, supported_constraints=supported_constraints, abstract_constraint_type=AbstractKeyAllocatorConstraint) # take each subedge and create keys from its placement progress_bar = ProgressBar(len(subgraph.subedges), "Allocating routing keys") routing_infos = RoutingInfo() routing_tables = MulticastRoutingTables() for subedge in subgraph.subedges: destination = subedge.post_subvertex placement = placements.get_placement_of_subvertex(destination) key = self._get_key_from_placement(placement) keys_and_masks = list( [BaseKeyAndMask(base_key=key, mask=self.MASK)]) n_keys = n_keys_map.n_keys_for_partitioned_edge(subedge) if n_keys > self.MAX_KEYS_SUPPORTED: raise exceptions.PacmanConfigurationException( "Only edges which require less than {} keys are supported". format(self.MAX_KEYS_SUPPORTED)) partition_info = PartitionRoutingInfo(keys_and_masks, subedge) routing_infos.add_partition_info(partition_info) progress_bar.update() progress_bar.end() return { 'routing_infos': routing_infos, 'routing_tables': routing_tables }
class MyTestCase(unittest.TestCase): def setUp(self): # sort out graph self.vert1 = Vertex(10, "New AbstractConstrainedVertex 1") self.vert2 = Vertex(5, "New AbstractConstrainedVertex 2") self.edge1 = AbstractPartitionableEdge(self.vert1, self.vert2, "First edge") self.verts = [self.vert1, self.vert2] self.edges = [self.edge1] self.graph = PartitionableGraph("Graph", self.verts, self.edges) # sort out subgraph self.subgraph = PartitionedGraph() self.subvert1 = PartitionedVertex( 0, 10, get_resources_used_by_atoms(0, 10, [])) self.subvert2 = PartitionedVertex( 0, 5, get_resources_used_by_atoms(0, 10, [])) self.subedge = AbstractPartitionedEdge(self.subvert1, self.subvert2) self.subgraph.add_subvertex(self.subvert1) self.subgraph.add_subvertex(self.subvert2) self.subgraph.add_subedge(self.subedge) # sort out placements self.placements = Placements() self.placement1 = Placement(x=0, y=0, p=2, subvertex=self.subvert1) self.placement2 = Placement(x=1, y=1, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) # create machine flops = 1000 (e, ne, n, w, sw, s) = range(6) processors = list() for i in range(18): processors.append(Processor(i, flops)) _sdram = SDRAM(128 * (2 ** 20)) ip = "192.162.240.253" chips = list() for x in range(10): for y in range(10): links = list() links.append(Link(x, y, 0, (x + 1) % 10, y, n, n)) links.append(Link(x, y, 1, (x + 1) % 10, (y + 1) % 10, s, s)) links.append(Link(x, y, 2, x, (y + 1) % 10, n, n)) links.append(Link(x, y, 3, (x - 1) % 10, y, s, s)) links.append(Link(x, y, 4, (x - 1) % 10, (y - 1) % 10, n, n)) links.append(Link(x, y, 5, x, (y - 1) % 10, s, s)) r = Router(links, False, 100, 1024) chips.append(Chip(x, y, processors, r, _sdram, ip)) self.machine = Machine(chips) @unittest.skip("demonstrating skipping") def set_up_4_node_board(self): flops = 1000 (e, ne, n, w, sw, s) = range(6) processors = list() for i in range(18): processors.append(Processor(i, flops)) _sdram = SDRAM(128 * (2 ** 20)) ip = "192.162.240.253" chips = list() for x in range(2): for y in range(2): links = list() links.append(Link(x, y, 0, (x + 1) % 2, y, n, n)) links.append(Link(x, y, 1, (x + 1) % 2, (y + 1) % 2, s, s)) links.append(Link(x, y, 2, x, (y + 1) % 2, n, n)) links.append(Link(x, y, 3, (x - 1) % 2, y, s, s)) links.append(Link(x, y, 4, (x - 1) % 2, (y - 1) % 2, n, n)) links.append(Link(x, y, 5, x, (y - 1) % 2, s, s)) r = Router(links, False, 100, 1024) chips.append(Chip(x, y, processors, r, _sdram, ip)) self.machine = Machine(chips) @unittest.skip("demonstrating skipping") def test_new_basic_router(self): dijkstra_router = BasicDijkstraRouting() self.assertEqual(dijkstra_router._k, 1) self.assertEqual(dijkstra_router._l, 0) self.assertEqual(dijkstra_router._m, 0) self.assertEqual(dijkstra_router._bw_per_route_entry, dijkstra_router.BW_PER_ROUTE_ENTRY) self.assertEqual(dijkstra_router._max_bw, dijkstra_router.MAX_BW) @unittest.skip("demonstrating skipping") def test_run_basic_routing_off_chip_custom_100_node_machine(self): dijkstra_router = BasicDijkstraRouting() routing_tables = dijkstra_router.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, routing_info_allocation=self.routing_info) for entry in routing_tables.routing_tables: print entry.x, entry.y for routing_entry in entry.multicast_routing_entries: print "\t\tProcessor_ids:{}, Link_ids:{}".format( routing_entry.processor_ids, routing_entry.link_ids) @unittest.skip("demonstrating skipping") def test_run_basic_routing_off_chip_custom_4_node_machine(self): self.set_up_4_node_board() dijkstra_router = BasicDijkstraRouting() routing_tables = dijkstra_router.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, routing_info_allocation=self.routing_info) for entry in routing_tables.routing_tables: print entry.x, entry.y for routing_entry in entry.multicast_routing_entries: print "\t\tProcessor_ids:{}, Link_ids:{}".format( routing_entry.processor_ids, routing_entry.link_ids) @unittest.skip("demonstrating skipping") def test_bad_machine_setup(self): # create machine flops = 1000 (e, ne, n, w, sw, s) = range(6) processors = list() for i in range(18): processors.append(Processor(i, flops)) links = list() links.append(Link(0, 0, 0, 0, 1, s, s)) _sdram = SDRAM(128 * (2 ** 20)) links = list() links.append(Link(0, 0, 0, 1, 1, n, n)) links.append(Link(0, 1, 1, 1, 0, s, s)) links.append(Link(1, 1, 2, 0, 0, e, e)) links.append(Link(1, 0, 3, 0, 1, w, w)) r = Router(links, False, 100, 1024) ip = "192.162.240.253" chips = list() for x in range(5): for y in range(5): chips.append(Chip(x, y, processors, r, _sdram, ip)) self.machine = Machine(chips) dijkstra_router = BasicDijkstraRouting() with self.assertRaises(PacmanRoutingException): dijkstra_router.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, routing_info_allocation=self.routing_info) @unittest.skip("demonstrating skipping") def test_routing_on_chip_custom_4_node_machine(self): self.placements = Placements() self.placement1 = Placement(x=1, y=0, p=2, subvertex=self.subvert1) self.placement2 = Placement(x=1, y=0, p=3, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) # sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) self.set_up_4_node_board() dijkstra_router = BasicDijkstraRouting() routing_tables = dijkstra_router.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, routing_info_allocation=self.routing_info) for entry in routing_tables.routing_tables: print entry.x, entry.y for routing_entry in entry.multicast_routing_entries: print "\t\tProcessor_ids:{}, Link_ids:{}".format( routing_entry.processor_ids, routing_entry.link_ids) @unittest.skip("demonstrating skipping") def test_full_machine_routing(self): placements = Placements() self.placement1 = Placement(x=1, y=0, p=2, subvertex=self.subvert1) self.placement2 = Placement(x=1, y=0, p=3, subvertex=self.subvert2) subvertices = list() for i in range(4 * 17): #51 atoms per each processor on 20 chips subvertices.append(PartitionedVertex( 0, 50, get_resources_used_by_atoms(0, 50, []), "Subvertex " + str(i))) subedges = list() for i in range(len(subvertices)): subedges.append(AbstractPartitionedEdge( subvertices[i], subvertices[(i + 1)%len(subvertices)])) subgraph = PartitionedGraph("Subgraph", subvertices, subedges) p = 1 x = 0 y = 0 for subvert in subvertices: placements.add_placement(Placement(subvert, x, y, p)) p = (p + 1) % 18 if p == 0: p += 1 y += 1 if y == 2: y = 0 x += 1 routing_info = RoutingInfo() subedge_routing_info = list() for i in range(len(subedges)): subedge_routing_info.append(SubedgeRoutingInfo( subedges[i], i<<11, constants.DEFAULT_MASK)) for subedge_info in subedge_routing_info: routing_info.add_subedge_info(subedge_info) self.set_up_4_node_board() dijkstra_router = BasicDijkstraRouting() routing_tables = dijkstra_router.route( machine=self.machine, placements=placements, partitioned_graph=subgraph, routing_info_allocation=routing_info) for entry in routing_tables.routing_tables: print entry.x, entry.y for routing_entry in entry.multicast_routing_entries: print "\t\tProcessor_ids:{}, Link_ids:{}".format( routing_entry.processor_ids, routing_entry.link_ids) @unittest.skip("demonstrating skipping") def test_routing_to_other_machine(self): self.assertEqual(True, False, "Test not implemented yet")
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}
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 = AbstractPartitionableEdge(self.vert1, self.vert2, "First edge") self.verts = [self.vert1, self.vert2] self.edges = [self.edge1] self.graph = PartitionableGraph("Graph", self.verts, self.edges) #sort out subgraph self.subgraph = PartitionedGraph() self.subvert1 = PartitionedVertex( 0, 10, self.vert1.get_resources_used_by_atoms(0, 10, [])) self.subvert2 = PartitionedVertex( 0, 5, self.vert2.get_resources_used_by_atoms(0, 10, [])) self.subedge = AbstractPartitionedEdge(self.subvert1, self.subvert2) self.subgraph.add_subvertex(self.subvert1) self.subgraph.add_subvertex(self.subvert2) self.subgraph.add_subedge(self.subedge) @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, subvertex=self.subvert1) self.placement2 = Placement(x=0, y=0, p=3, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, 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, subvertex=self.subvert1) self.placement2 = Placement(x=1, y=1, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, 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, subvertex=self.subvert1) self.placement2 = Placement(x=2, y=0, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, 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, subvertex=self.subvert1) self.placement2 = Placement(x=2, y=2, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, 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, subvertex=self.subvert1) self.placement2 = Placement(x=0, y=2, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, 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, subvertex=self.subvert1) self.placement2 = Placement(x=0, y=0, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, 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, subvertex=self.subvert1) self.placement2 = Placement(x=0, y=0, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, 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, subvertex=self.subvert1) self.placement2 = Placement(x=0, y=0, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, 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, subvertex=self.subvert1) self.placement2 = Placement(x=0, y=0, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, 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, subvertex=self.subvert1) self.placement2 = Placement(x=8, y=7, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, 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_to_subgraph_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_to_subgraph_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, subvertex=self.subvert1) self.placement2 = Placement(x=1, y=1, p=2, subvertex=self.subvert2) self.placements.add_placement(self.placement1) self.placements.add_placement(self.placement2) #sort out routing infos self.routing_info = RoutingInfo() self.subedge_routing_info1 = \ SubedgeRoutingInfo(key=2 << 11, mask=constants.DEFAULT_MASK, subedge=self.subedge) self.routing_info.add_subedge_info(self.subedge_routing_info1) #create machine self.machine = VirtualMachine(10, 10, False) self.routing = BasicDijkstraRouting() self.routing.route( machine=self.machine, placements=self.placements, partitioned_graph=self.subgraph, routing_info_allocation=self.routing_info)
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}