Source code for pacman.utilities.rig_converters

from collections import defaultdict

from rig.machine import Machine, Links
from rig.netlist import Net
from rig.place_and_route.constraints import \
    LocationConstraint, ReserveResourceConstraint, RouteEndpointConstraint
from rig.place_and_route.routing_tree import RoutingTree
from rig.routing_table import Routes
from six import iteritems

from pacman.model.constraints.placer_constraints\
    import ChipAndCoreConstraint, RadialPlacementFromChipConstraint
from pacman.model.graphs import AbstractFPGAVertex, AbstractVirtualVertex
from pacman.model.graphs import AbstractSpiNNakerLinkVertex
from rig.place_and_route.constraints import SameChipConstraint
from pacman.utilities.algorithm_utilities import placer_algorithm_utilities
from pacman.model.placements import Placement, Placements
from pacman.model.routing_table_by_partition import \
    MulticastRoutingTableByPartition, MulticastRoutingTableByPartitionEntry
from pacman.utilities.constants import EDGES

# A lookup from link name (string) to Links enum entry.
LINK_LOOKUP = {l.name: l for l in Links}
ROUTE_LOOKUP = {"core_{}".format(r.core_num) if r.is_core else r.name: r
                for r in Routes}

CHIP_HOMOGENEOUS_CORES = 18
CHIP_HOMOGENEOUS_SDRAM = 119275520
CHIP_HOMOGENEOUS_SRAM = 24320
CHIP_HOMOGENEOUS_TAGS = 0
ROUTER_MAX_NUMBER_OF_LINKS = 6
ROUTER_HOMOGENEOUS_ENTRIES = 1023

N_CORES_PER_VERTEX = 1


[docs]def convert_to_rig_machine(machine): chip_resources = dict() chip_resources['cores'] = CHIP_HOMOGENEOUS_CORES chip_resources['sdram'] = CHIP_HOMOGENEOUS_SDRAM chip_resources['sram'] = CHIP_HOMOGENEOUS_SRAM chip_resources["router_entries"] = ROUTER_HOMOGENEOUS_ENTRIES chip_resources['tags'] = CHIP_HOMOGENEOUS_TAGS # handle exceptions dead_chips = list() dead_links = list() chip_resource_exceptions = list() # write dead chips for x_coord in range(0, machine.max_chip_x + 1): for y_coord in range(0, machine.max_chip_y + 1): if (not machine.is_chip_at(x_coord, y_coord) or machine.get_chip_at(x_coord, y_coord).virtual): dead_chips.append([x_coord, y_coord]) else: chip = machine.get_chip_at(x_coord, y_coord) # write dead links for link_id in range(0, ROUTER_MAX_NUMBER_OF_LINKS): router = chip.router is_dead = False if not router.is_link(link_id): is_dead = True else: link = router.get_link(link_id) if not machine.is_chip_at( link.destination_x, link.destination_y): is_dead = True else: dest_chip = machine.get_chip_at( link.destination_x, link.destination_y) if dest_chip.virtual: is_dead = True if is_dead: dead_links.append([x_coord, y_coord, "{}".format( EDGES(link_id).name.lower())]) # Fix the number of processors when there are less resource_exceptions = dict() n_processors = len([ processor for processor in chip.processors]) if n_processors < CHIP_HOMOGENEOUS_CORES: resource_exceptions["cores"] = n_processors # Add tags if Ethernet chip if chip.ip_address is not None: resource_exceptions["tags"] = len(chip.tag_ids) if len(resource_exceptions) > 0: chip_resource_exceptions.append( (x_coord, y_coord, resource_exceptions)) return Machine( width=machine.max_chip_x + 1, height=machine.max_chip_y + 1, chip_resources=chip_resources, chip_resource_exceptions={ (x, y): { resource: r.get( resource, chip_resources[resource]) for resource in chip_resources} for x, y, r in chip_resource_exceptions}, dead_chips=set((x, y) for x, y in dead_chips), dead_links=set( (x, y, LINK_LOOKUP[link]) for x, y, link in dead_links))
[docs]def convert_to_rig_graph(machine_graph): vertices_resources = dict() edges_resources = defaultdict() for vertex in machine_graph.vertices: # handle external devices if isinstance(vertex, AbstractVirtualVertex): vertex_resources = dict() vertices_resources[vertex] = vertex_resources vertex_resources["cores"] = 0 # handle standard vertices else: vertex_resources = dict() vertices_resources[vertex] = vertex_resources vertex_resources["cores"] = N_CORES_PER_VERTEX vertex_resources["sdram"] = int( vertex.resources_required.sdram.get_value()) vertex_outgoing_partitions = \ machine_graph.get_outgoing_edge_partitions_starting_at_vertex( vertex) # handle the vertex edges for partition in vertex_outgoing_partitions: hyper_edge_dict = dict() edges_resources[partition] = hyper_edge_dict hyper_edge_dict["source"] = vertex sinks = list() weight = 0 for edge in partition.edges: sinks.append(edge.post_vertex) weight += edge.traffic_weight hyper_edge_dict['sinks'] = sinks hyper_edge_dict["weight"] = weight hyper_edge_dict["type"] = partition.traffic_type.name.lower() net_names = { Net(edge["source"], edge["sinks"], edge["weight"]): name for name, edge in iteritems(edges_resources) } nets = list(net_names) return vertices_resources, nets, net_names
[docs]def create_rig_graph_constraints(machine_graph, machine): constraints = [] for vertex in machine_graph.vertices: if isinstance(vertex, AbstractVirtualVertex): link_data = None if isinstance(vertex, AbstractFPGAVertex): link_data = machine.get_fpga_link_with_id( vertex.fpga_id, vertex.fpga_link_id, vertex.board_address) elif isinstance(vertex, AbstractSpiNNakerLinkVertex): link_data = machine.get_spinnaker_link_with_id( vertex.spinnaker_link_id, vertex.board_address) constraints.append(LocationConstraint( vertex, (link_data.connected_chip_x, link_data.connected_chip_y))) constraints.append(RouteEndpointConstraint( vertex, LINK_LOOKUP[EDGES( link_data.connected_link).name.lower()])) else: for constraint in vertex.constraints: if isinstance(constraint, ( ChipAndCoreConstraint, RadialPlacementFromChipConstraint)): constraints.append(LocationConstraint( vertex, (constraint.x, constraint.y))) vertices_on_same_chip = \ placer_algorithm_utilities.get_same_chip_vertex_groups( machine_graph.vertices) for group in vertices_on_same_chip.values(): if len(group) > 1: constraints.append(SameChipConstraint(group)) return constraints
[docs]def create_rig_machine_constraints(machine): constraints = [] for chip in machine.chips: for processor in chip.processors: if processor.is_monitor: constraints.append(ReserveResourceConstraint( "cores", slice(processor.processor_id, processor.processor_id + 1), (chip.x, chip.y))) return constraints
[docs]def convert_to_rig_placements(placements, machine): rig_placements = dict() for placement in placements: if not isinstance(placement.vertex, AbstractVirtualVertex): rig_placements[placement.vertex] = (placement.x, placement.y) else: link_data = None vertex = placement.vertex if isinstance(vertex, AbstractFPGAVertex): link_data = machine.get_fpga_link_with_id( vertex.fpga_id, vertex.fpga_link_id, vertex.board_address) elif isinstance(vertex, AbstractSpiNNakerLinkVertex): link_data = machine.get_spinnaker_link_with_id( vertex.spinnaker_link_id, vertex.board_address) rig_placements[placement.vertex] = ( link_data.connected_chip_x, link_data.connected_chip_y ) core_allocations = { p.vertex: {"cores": slice(p.p, p.p + 1)} for p in placements.placements if not isinstance(p.vertex, AbstractVirtualVertex)} return rig_placements, core_allocations
[docs]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
[docs]def convert_from_rig_routes(rig_routes, machine_graph): routing_tables = MulticastRoutingTableByPartition() for partition in rig_routes: partition_route = rig_routes[partition] _convert_next_route( routing_tables, partition, 0, None, partition_route) return routing_tables
def _convert_next_route( routing_tables, partition, incoming_processor, incoming_link, partition_route): x, y = partition_route.chip next_hops = list() processor_ids = list() link_ids = list() for (route, next_hop) in partition_route.children: if route is not None: link = None if isinstance(route, Routes): if route.is_core: processor_ids.append(route.core_num) else: link = route.value link_ids.append(link) elif isinstance(route, Links): link = route.value link_ids.append(link) if isinstance(next_hop, RoutingTree): next_incoming_link = None if link is not None: next_incoming_link = (link + 3) % 6 next_hops.append((next_hop, next_incoming_link)) routing_tables.add_path_entry(MulticastRoutingTableByPartitionEntry( link_ids, processor_ids, incoming_processor, incoming_link), x, y, partition) for next_hop, next_incoming_link in next_hops: _convert_next_route( routing_tables, partition, None, next_incoming_link, next_hop)