Skip to content

Commit

Permalink
merged in master
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian-B committed Aug 12, 2024
2 parents fbcd6f0 + 6d6d988 commit 7d7ba09
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 25 deletions.
6 changes: 3 additions & 3 deletions pacman/operations/placer_algorithms/application_placer.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,10 @@ def _check_could_fit(self, n_cores: int, plan_sdram: int):
if plan_sdram <= self.__max_sdram and n_cores <= self.__max_cores:
# should fit somewhere
return
message = (
message = \
f"{self.__app_vertex_label} will not fit on any possible Chip "
f"as a smae_chip_group ")

if n_cores > 1:
message += f" group has {n_cores=} "
version = PacmanDataView.get_machine_version()
if plan_sdram > self.__max_sdram:
message += f"requires {plan_sdram} bytes but "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,6 @@ def allocate(self, extra_allocations: _XAlloc) -> RoutingInfo:

return self.__allocate()

def __insert_fixed(
self, identifier: str, vertex: AbstractVertex, km: BaseKeyAndMask):
is_app = isinstance(vertex, ApplicationVertex)
for (_, vertex2), km2 in self.__fixed_partitions.items():
if is_app and isinstance(vertex2, MachineVertex) and \
(vertex == vertex2.app_vertex):
continue
# check if any keys could overlap
if (km.key & km2.mask) == (km2.key & km.mask):
raise PacmanRouteInfoAllocationException(
f"{vertex} has {km} which overlaps with {vertex2} {km2}")
self.__fixed_partitions[identifier, vertex] = km

def __find_fixed(self) -> None:
"""
Looks for FixedKeyAmdMask Constraints and keeps track of these.
Expand Down Expand Up @@ -199,7 +186,7 @@ def __find_fixed(self) -> None:
f"For application vertex {pre}, the fixed key for "
f"machine vertex {vert} of {key_and_mask} does "
f"not align with the app key {app_key_and_mask}")
self.__insert_fixed(identifier, vert, key_and_mask)
self.__fixed_partitions[identifier, vert] = key_and_mask
else:
if is_fixed_m_key:
raise PacmanRouteInfoAllocationException(
Expand All @@ -216,8 +203,9 @@ def __find_fixed(self) -> None:
f"On {pre} only a fixed app key has been provided,"
" but there is more than one machine vertex.")
# pylint:disable=undefined-loop-variable
self.__insert_fixed(identifier, vert, app_key_and_mask)
self.__insert_fixed(identifier, pre, app_key_and_mask)
self.__fixed_partitions[
identifier, vert] = app_key_and_mask
self.__fixed_partitions[identifier, pre] = app_key_and_mask

def __calculate_zones(self) -> None:
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
UnCompressedMulticastRoutingTable, MulticastRoutingTables)
from pacman.model.graphs import AbstractVertex
from pacman.model.routing_info import RoutingInfo
from pacman.model.routing_info.base_key_and_mask import BaseKeyAndMask


def basic_routing_table_generator() -> MulticastRoutingTables:
Expand Down Expand Up @@ -59,13 +60,25 @@ def __create_routing_table(
:rtype: MulticastRoutingTable
"""
table = UnCompressedMulticastRoutingTable(x, y)
sources_by_key_mask: Dict[BaseKeyAndMask,
Tuple[AbstractVertex, str]] = dict()
for source_vertex, partition_id in partitions_in_table:
r_info = routing_infos.get_routing_info_from_pre_vertex(
source_vertex, partition_id)
# Should be there; skip if not
if r_info is None:
continue
entry = partitions_in_table[source_vertex, partition_id]
if r_info.key_and_mask in sources_by_key_mask:
if (sources_by_key_mask[r_info.key_and_mask]
!= (source_vertex, partition_id)):
raise KeyError(
f"Source {source_vertex}, {partition_id} is trying to "
f"send to the same key and mask as "
f"{sources_by_key_mask[r_info.key_and_mask]}")
else:
sources_by_key_mask[r_info.key_and_mask] = (
source_vertex, partition_id)
table.add_multicast_routing_entry(MulticastRoutingEntry(
key=r_info.key_and_mask.key_combo,
mask=r_info.key_and_mask.mask, routing_entry=entry))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
RoutingInfo, AppVertexRoutingInfo, MachineVertexRoutingInfo)
from pacman.model.graphs import AbstractVertex
from pacman.model.graphs.machine.machine_vertex import MachineVertex
from pacman.model.routing_info.base_key_and_mask import BaseKeyAndMask


def merged_routing_table_generator() -> MulticastRoutingTables:
Expand Down Expand Up @@ -64,6 +65,8 @@ def __create_routing_table(
:rtype: MulticastRoutingTable
"""
table = UnCompressedMulticastRoutingTable(x, y)
sources_by_key_mask: Dict[BaseKeyAndMask,
Tuple[AbstractVertex, str]] = dict()
iterator = _IteratorWithNext(partitions_in_table.items())
while iterator.has_next:
(vertex, part_id), entry = iterator.pop()
Expand All @@ -72,6 +75,16 @@ def __create_routing_table(
raise PacmanRoutingException(
f"Missing Routing information for {vertex}, {part_id}")

if r_info.key_and_mask in sources_by_key_mask:
if (sources_by_key_mask[r_info.key_and_mask] != (vertex, part_id)):
raise KeyError(
f"Source {vertex}, {part_id} is trying to "
f"send to the same key and mask as "
f"{sources_by_key_mask[r_info.key_and_mask]}")
else:
sources_by_key_mask[r_info.key_and_mask] = (
vertex, part_id)

# If we have an application vertex, just put the entry in and move on
if isinstance(vertex, ApplicationVertex):
table.add_multicast_routing_entry(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from spinn_utilities.overrides import overrides
from pacman.config_setup import unittest_setup
from pacman.data import PacmanDataView
from pacman.exceptions import PacmanRouteInfoAllocationException
from pacman.operations.routing_info_allocator_algorithms.\
zoned_routing_info_allocator import (flexible_allocate, global_allocate)
from pacman.model.graphs.application import ApplicationEdge, ApplicationVertex
Expand Down Expand Up @@ -299,13 +298,11 @@ def test_fixed_only():


def test_overlap():
# This should work here; overlap is allowed provided routes don't overlap
# (which is found elsewhere)
unittest_setup()
create_graphs_only_fixed(overlap=True)
try:
flexible_allocate([])
raise ValueError
except PacmanRouteInfoAllocationException:
pass
flexible_allocate([])


def test_no_edge():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# limitations under the License.

import unittest
from typing import Optional, cast
from typing_extensions import Self
from spinn_utilities.config_holder import set_config
from pacman.config_setup import unittest_setup
from pacman.data.pacman_data_writer import PacmanDataWriter
Expand All @@ -30,6 +32,27 @@
from pacman.operations.routing_table_generators import (
basic_routing_table_generator)
from pacman_test_objects import SimpleTestVertex
from pacman.model.graphs.application.abstract import (
AbstractOneAppOneMachineVertex)
from pacman.model.routing_info.base_key_and_mask import BaseKeyAndMask
from pacman.model.partitioner_splitters import SplitterOneAppOneMachine


class FixedKeyAppVertex(AbstractOneAppOneMachineVertex):

def __init__(
self, fixed_key_and_mask, label: Optional[str] = None,
n_atoms: int = 1):
AbstractOneAppOneMachineVertex.__init__(
self, SimpleMachineVertex(ConstantSDRAM(1000)), label,
n_atoms=n_atoms)
self.__fixed_key_and_mask = fixed_key_and_mask
self._splitter = SplitterOneAppOneMachine()
self._splitter.set_governed_app_vertex(cast(Self, self))

def get_fixed_key_and_mask(
self, partition_id: str) -> Optional[BaseKeyAndMask]:
return self.__fixed_key_and_mask


class TestBasic(unittest.TestCase):
Expand Down Expand Up @@ -86,3 +109,62 @@ def test_graph3_with_system(self):
self.assertEqual(31, data.get_max_number_of_entries())
self.assertEqual(108, data.get_total_number_of_entries())
self.assertEqual(5, len(list(data.routing_tables)))

def test_overlapping(self):
# Two vertices in the same router can't send with the same key
writer = PacmanDataWriter.mock()
v_target = SimpleTestVertex(1, splitter=SplitterFixedLegacy())
v1 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
v2 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
writer.add_vertex(v_target)
writer.add_vertex(v1)
writer.add_vertex(v2)
writer.add_edge(ApplicationEdge(v1, v_target), "Test")
writer.add_edge(ApplicationEdge(v2, v_target), "Test")
system_placements = Placements()
system_placements.add_placement(Placement(v1.machine_vertex, 0, 0, 1))
system_placements.add_placement(Placement(v2.machine_vertex, 0, 0, 2))
self.make_infos(writer, system_placements)
with self.assertRaises(KeyError):
basic_routing_table_generator()

def test_overlapping_different_chips(self):
# Two vertices in the same router can't send with the same key
writer = PacmanDataWriter.mock()
v_target = SimpleTestVertex(1, splitter=SplitterFixedLegacy())
v1 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
v2 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
writer.add_vertex(v_target)
writer.add_vertex(v1)
writer.add_vertex(v2)
writer.add_edge(ApplicationEdge(v1, v_target), "Test")
writer.add_edge(ApplicationEdge(v2, v_target), "Test")
system_placements = Placements()
system_placements.add_placement(Placement(v1.machine_vertex, 1, 0, 1))
system_placements.add_placement(Placement(v2.machine_vertex, 0, 0, 2))
self.make_infos(writer, system_placements)
with self.assertRaises(KeyError):
basic_routing_table_generator()

def test_non_overlapping_different_chips(self):
# Two vertices with non-overlapping routes can use the same key
writer = PacmanDataWriter.mock()
v_target_1 = FixedKeyAppVertex(None)
v_target_2 = FixedKeyAppVertex(None)
v1 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
v2 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
writer.add_vertex(v_target_1)
writer.add_vertex(v_target_2)
writer.add_vertex(v1)
writer.add_vertex(v2)
writer.add_edge(ApplicationEdge(v1, v_target_1), "Test")
writer.add_edge(ApplicationEdge(v2, v_target_2), "Test")
system_placements = Placements()
system_placements.add_placement(Placement(v1.machine_vertex, 1, 0, 1))
system_placements.add_placement(
Placement(v_target_1.machine_vertex, 1, 0, 2))
system_placements.add_placement(Placement(v2.machine_vertex, 0, 0, 2))
system_placements.add_placement(
Placement(v_target_2.machine_vertex, 0, 0, 3))
self.make_infos(writer, system_placements)
basic_routing_table_generator()
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
from pacman.operations.routing_table_generators.merged_routing_table_generator\
import (merged_routing_table_generator, _IteratorWithNext)
from pacman_test_objects import SimpleTestVertex
from pacman.model.routing_info import BaseKeyAndMask
from .test_basic import FixedKeyAppVertex


class TestMerged(unittest.TestCase):
Expand Down Expand Up @@ -153,3 +155,62 @@ def test_iterator_with_next(self):
# this needs to work even with a debugger look at ten here
check.append(ten.pop())
self.assertEqual(10, len(check))

def test_overlapping(self):
# Two vertices in the same router can't send with the same key
writer = PacmanDataWriter.mock()
v_target = SimpleTestVertex(1, splitter=SplitterFixedLegacy())
v1 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
v2 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
writer.add_vertex(v_target)
writer.add_vertex(v1)
writer.add_vertex(v2)
writer.add_edge(ApplicationEdge(v1, v_target), "Test")
writer.add_edge(ApplicationEdge(v2, v_target), "Test")
system_placements = Placements()
system_placements.add_placement(Placement(v1.machine_vertex, 0, 0, 1))
system_placements.add_placement(Placement(v2.machine_vertex, 0, 0, 2))
self.make_infos(writer, system_placements)
with self.assertRaises(KeyError):
merged_routing_table_generator()

def test_overlapping_different_chips(self):
# Two vertices in the same router can't send with the same key
writer = PacmanDataWriter.mock()
v_target = SimpleTestVertex(1, splitter=SplitterFixedLegacy())
v1 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
v2 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
writer.add_vertex(v_target)
writer.add_vertex(v1)
writer.add_vertex(v2)
writer.add_edge(ApplicationEdge(v1, v_target), "Test")
writer.add_edge(ApplicationEdge(v2, v_target), "Test")
system_placements = Placements()
system_placements.add_placement(Placement(v1.machine_vertex, 1, 0, 1))
system_placements.add_placement(Placement(v2.machine_vertex, 0, 0, 2))
self.make_infos(writer, system_placements)
with self.assertRaises(KeyError):
merged_routing_table_generator()

def test_non_overlapping_different_chips(self):
# Two vertices with non-overlapping routes can use the same key
writer = PacmanDataWriter.mock()
v_target_1 = FixedKeyAppVertex(None)
v_target_2 = FixedKeyAppVertex(None)
v1 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
v2 = FixedKeyAppVertex(BaseKeyAndMask(0x1, 0xFFFFFFFF))
writer.add_vertex(v_target_1)
writer.add_vertex(v_target_2)
writer.add_vertex(v1)
writer.add_vertex(v2)
writer.add_edge(ApplicationEdge(v1, v_target_1), "Test")
writer.add_edge(ApplicationEdge(v2, v_target_2), "Test")
system_placements = Placements()
system_placements.add_placement(Placement(v1.machine_vertex, 1, 0, 1))
system_placements.add_placement(
Placement(v_target_1.machine_vertex, 1, 0, 2))
system_placements.add_placement(Placement(v2.machine_vertex, 0, 0, 2))
system_placements.add_placement(
Placement(v_target_2.machine_vertex, 0, 0, 3))
self.make_infos(writer, system_placements)
merged_routing_table_generator()

0 comments on commit 7d7ba09

Please sign in to comment.