Skip to content

Commit

Permalink
Merge branch 'master' into region_downloading
Browse files Browse the repository at this point in the history
  • Loading branch information
rowleya authored Sep 6, 2024
2 parents 9fa1363 + 9278446 commit 8a4620c
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 29 deletions.
31 changes: 15 additions & 16 deletions pacman/operations/router_algorithms/application_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,9 @@ def route_application_graph() -> MulticastRoutingTableByPartition:

source_xy = next(iter(source_mappings.keys()))
# Get all source chips coordinates
all_source_xys = _get_all_xys(source)
all_source_xys = {
vertex_xy(m_vertex)
for m_vertex in source.machine_vertices}

# Keep track of the source edge chips
source_edge_xys: Set[XY] = set()
Expand Down Expand Up @@ -234,7 +236,8 @@ def route_application_graph() -> MulticastRoutingTableByPartition:
_route_source_to_source(source, partition, targets, self_xys)

# Deal with internal multicast partitions
internal = source.splitter.get_internal_multicast_partitions()
internal = list(_get_filtered_internal_partitions(
source, partition.identifier))
if internal:
self_connected = True
_route_internal(internal, targets, self_xys)
Expand All @@ -258,6 +261,12 @@ def route_application_graph() -> MulticastRoutingTableByPartition:
return routing_tables


def _get_filtered_internal_partitions(vertex, identifier):
for partition in vertex.splitter.get_internal_multicast_partitions():
if partition.identifier == identifier:
yield partition


def _route_source_to_target(
machine: Machine, source: ApplicationVertex,
source_xy: XY, all_source_xys: Set[XY],
Expand Down Expand Up @@ -313,7 +322,8 @@ def _route_source_to_target(
overlaps = None
else:
# Find all coordinates for chips (xy) that are in the target
target_xys = _get_all_xys(target)
target_xys = {vertex_xy(m_vertex)
for m_vertex, _srcs in target_vertices}

# Pick one to actually use as a target
target_xy, overlaps = _find_target_xy(
Expand Down Expand Up @@ -459,6 +469,7 @@ def _route_internal(
"""
for in_part in internal_partitions:
src = in_part.pre_vertex
xy = vertex_xy(src)
for edge in in_part.edges:
tgt = edge.post_vertex
xy, (_vertex, core, link) = vertex_xy_and_route(tgt)
Expand Down Expand Up @@ -628,25 +639,13 @@ def _get_outgoing_mapping(
for m_vertex in app_vertex.splitter.get_out_going_vertices(partition_id):
xy, route = vertex_xy_and_route(m_vertex)
outgoing_mapping[xy].append(route)
for in_part in app_vertex.splitter.get_internal_multicast_partitions():
for in_part in _get_filtered_internal_partitions(app_vertex, partition_id):
if in_part.identifier == partition_id:
xy, route = vertex_xy_and_route(in_part.pre_vertex)
outgoing_mapping[xy].append(route)
return outgoing_mapping


def _get_all_xys(app_vertex: ApplicationVertex) -> Set[XY]:
"""
Gets the list of all the x,y coordinates that the vertex's machine vertices
are placed on.
:param ApplicationVertex app_vertex:
:rtype: set(tuple(int, int))
"""
return {vertex_xy(m_vertex)
for m_vertex in app_vertex.machine_vertices}


def _route_to_xys(
first_xy: XY, all_xys: Set[XY], machine: Machine,
routes: Dict[XY, RoutingTree], targets: Iterable[XY], label: str):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from spinn_utilities.log import FormatAdapter
from spinn_utilities.progress_bar import ProgressBar
from spinn_utilities.ordered_set import OrderedSet
from pacman.data import PacmanDataView
from pacman.model.routing_info import (
RoutingInfo, MachineVertexRoutingInfo, BaseKeyAndMask,
AppVertexRoutingInfo)
Expand All @@ -28,6 +27,8 @@
get_key_ranges, allocator_bits_needed)
from pacman.exceptions import PacmanRouteInfoAllocationException
from pacman.utilities.constants import BITS_IN_KEY, FULL_MASK
from pacman.utilities.algorithm_utilities.routing_algorithm_utilities import (
get_app_partitions)
_XAlloc = Iterable[Tuple[ApplicationVertex, str]]
logger = FormatAdapter(logging.getLogger(__name__))

Expand Down Expand Up @@ -137,13 +138,8 @@ def allocate(self, extra_allocations: _XAlloc) -> RoutingInfo:
"""
self.__vertex_partitions = OrderedSet(
(p.pre_vertex, p.identifier)
for p in PacmanDataView.iterate_partitions())
for p in get_app_partitions())
self.__vertex_partitions.update(extra_allocations)
self.__vertex_partitions.update(
(v, p.identifier)
for v in PacmanDataView.iterate_vertices()
if isinstance(v, ApplicationVertex)
for p in v.splitter.get_internal_multicast_partitions())

self.__find_fixed()
self.__calculate_zones()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,18 @@ def get_app_partitions() -> List[ApplicationEdgePartition]:
# Find all partitions that need to be dealt with
# Make a copy which we can edit
partitions = list(PacmanDataView.iterate_partitions())
sources = frozenset(p.pre_vertex for p in partitions)
sources = set((p.pre_vertex, p.identifier) for p in partitions)

# Convert internal partitions to self-connected partitions
for v in PacmanDataView.iterate_vertices():
if not isinstance(v, ApplicationVertex) or not v.splitter:
continue
internal_partitions = v.splitter.get_internal_multicast_partitions()
if v not in sources and internal_partitions:
# guarantee order
for identifier in dict.fromkeys(
p.identifier for p in internal_partitions):
for p in internal_partitions:
if (v, p.identifier) not in sources:
# Add a partition with no edges to identify this as internal
partitions.append(ApplicationEdgePartition(identifier, v))
partitions.append(ApplicationEdgePartition(p.identifier, v))
sources.add((v, p.identifier))
return partitions


Expand Down
82 changes: 82 additions & 0 deletions unittests/operations_tests/router_algorithms_tests/test_routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,60 @@ def placements(self):
return self.__placements


class MockInputOutputSplitter(AbstractSplitterCommon):
def __init__(self, n_incoming, n_outgoing):
super().__init__()
self.__n_incoming = n_incoming
self.__n_outgoing = n_outgoing
self.__incoming_machine_vertices = list()
self.__outgoing_machine_vertices = list()
self.__internal_multicast_partitions = list()

def create_machine_vertices(self, chip_counter):
self.__incoming_machine_vertices = [
SimpleMachineVertex(
ConstantSDRAM(0), app_vertex=self.governed_app_vertex,
label=f"{self.governed_app_vertex.label}_input_{j}")
for j in range(self.__n_incoming)]
self.__outgoing_machine_vertices = [
SimpleMachineVertex(
ConstantSDRAM(0), app_vertex=self.governed_app_vertex,
label=f"{self.governed_app_vertex.label}_output_{j}")
for j in range(self.__n_outgoing)]
for out_v in self.__outgoing_machine_vertices:
self.governed_app_vertex.remember_machine_vertex(out_v)
for in_v in self.__incoming_machine_vertices:
self.governed_app_vertex.remember_machine_vertex(in_v)

# The partition is from outgoing to incoming
for start_v in self.__outgoing_machine_vertices:
part = MulticastEdgePartition(start_v, "internal")
self.__internal_multicast_partitions.append(part)
for end_v in self.__incoming_machine_vertices:
part.add_edge(MachineEdge(start_v, end_v))

def get_out_going_slices(self):
return None

def get_in_coming_slices(self):
return None

def get_out_going_vertices(self, partition_id):
return self.__outgoing_machine_vertices

def get_in_coming_vertices(self, partition_id):
return self.__incoming_machine_vertices

def machine_vertices_for_recording(self, variable_to_record):
return []

def get_internal_multicast_partitions(self):
return self.__internal_multicast_partitions

def reset_called(self):
pass


class MockAppVertex(ApplicationVertex):
def __init__(self, n_atoms, label):
super(MockAppVertex, self).__init__(label)
Expand Down Expand Up @@ -313,6 +367,15 @@ def _make_vertices_split(
return vertex


def _make_input_output_vertices(
writer, n_atoms, n_incoming, n_outgoing, label):
vertex = MockAppVertex(n_atoms, label)
vertex.splitter = MockInputOutputSplitter(n_incoming, n_outgoing)
writer.add_vertex(vertex)
vertex.splitter.create_machine_vertices(None)
return vertex


def _get_entry(routing_tables, x, y, source_vertex, partition_id, allow_none):
app_entry = routing_tables.get_entry_on_coords_for_edge(
source_vertex.app_vertex, partition_id, x, y)
Expand Down Expand Up @@ -826,3 +889,22 @@ def test_route_around():

print(nodes)
print(nodes_fixed)


def test_internal_io_routes(params):
algorithm, _n_vertices, _n_m_vertices = params
unittest_setup()
set_config("Machine", "versions", VersionStrings.BIG.text)
machine = PacmanDataView.get_machine()
writer = PacmanDataWriter.mock()
writer.set_machine(machine)
vertex = _make_input_output_vertices(writer, 1, 1, 3, "app_vertex")
placements = Placements()
for i, m_vertex in enumerate(vertex.splitter.get_out_going_vertices(None)):
placements.add_placement(Placement(m_vertex, 0, 1, i))

for i, m_vertex in enumerate(vertex.splitter.get_in_coming_vertices(None)):
placements.add_placement(Placement(m_vertex, 0, 0, i))
writer.set_placements(placements)
routing_tables = _route_and_time(algorithm)
_check_edges(routing_tables)

0 comments on commit 8a4620c

Please sign in to comment.