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 May 2, 2024
2 parents 36d0180 + b31702e commit e47fc6b
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 1 deletion.
88 changes: 88 additions & 0 deletions pacman/data/pacman_data_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ class _PacmanDataModel(object):
"_precompressed",
"_all_monitor_vertices",
"_ethernet_monitor_vertices",
"_n_boards_required",
"_n_chips_required",
"_n_chips_in_graph",
"_routing_infos",
"_routing_table_by_partition",
"_tags",
Expand All @@ -90,6 +93,8 @@ def _clear(self) -> None:
self._graph = ApplicationGraph()
# set at the start of every run
self._plan_n_timesteps: Optional[int] = None
self._n_boards_required: Optional[int] = None
self._n_chips_required: Optional[int] = None
self._hard_reset()

def _hard_reset(self) -> None:
Expand All @@ -102,6 +107,7 @@ def _hard_reset(self) -> None:
self._precompressed: Optional[MulticastRoutingTables] = None
self._all_monitor_vertices: List[MachineVertex] = []
self._ethernet_monitor_vertices: List[MachineVertex] = []
self._n_chips_in_graph: Optional[int] = None
self._uncompressed: Optional[MulticastRoutingTables] = None
self._routing_infos: Optional[RoutingInfo] = None
self._routing_table_by_partition: Optional[
Expand Down Expand Up @@ -573,3 +579,85 @@ def get_ethernet_monitor_sdram(cls) -> AbstractSDRAM:
for vertex in cls.__pacman_data._ethernet_monitor_vertices:
sdram += vertex.sdram_required
return sdram

# n_boards/chips required

@classmethod
def has_n_boards_required(cls):
"""
Reports if a user has sets the number of boards requested during setup.
:rtype: bool
:raises ~spinn_utilities.exceptions.SpiNNUtilsException:
If n_boards_required is not set or set to `None`
"""
return cls.__pacman_data._n_boards_required is not None

@classmethod
def get_n_boards_required(cls):
"""
Gets the number of boards requested by the user during setup if known.
Guaranteed to be positive
:rtype: int
:raises ~spinn_utilities.exceptions.SpiNNUtilsException:
If the n_boards_required is currently unavailable
"""
if cls.__pacman_data._n_boards_required is None:
raise cls._exception("n_boards_requiredr")
return cls.__pacman_data._n_boards_required

@classmethod
def get_n_chips_needed(cls):
"""
Gets the number of chips needed, if set.
This will be the number of chips requested by the user during setup,
even if this is less that what the partitioner reported.
If the partitioner has run and the user has not specified a number,
this will be what the partitioner requested.
Guaranteed to be positive if set
:rtype: int
:raises ~spinn_utilities.exceptions.SpiNNUtilsException:
If data for n_chips_needed is not available
"""
if cls.__pacman_data._n_chips_required:
return cls.__pacman_data._n_chips_required
if cls.__pacman_data._n_chips_in_graph:
return cls.__pacman_data._n_chips_in_graph
raise cls._exception("n_chips_requiredr")

@classmethod
def has_n_chips_needed(cls):
"""
Detects if the number of chips needed has been set.
This will be the number of chips requested by the use during setup or
what the partitioner requested.
:rtype: bool
"""
if cls.__pacman_data._n_chips_required is not None:
return True
return cls.__pacman_data._n_chips_in_graph is not None

@classmethod
def get_chips_boards_required_str(cls):
"""
Gets a String to say what was required
:return:
"""
if cls.__pacman_data._n_boards_required:
return (f"Setup asked for "
f"{cls.__pacman_data._n_boards_required} Boards")
if cls.__pacman_data._n_chips_required:
return (f"Setup asked for "
f"{cls.__pacman_data._n_chips_required} Chips")
if cls.__pacman_data._n_chips_in_graph:
return (f"Graph requires "
f"{cls.__pacman_data._n_chips_in_graph} Chips")
return "No requirements known"
52 changes: 52 additions & 0 deletions pacman/data/pacman_data_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,55 @@ def add_sample_monitor_vertex(
self.__pacman_data._ethernet_monitor_vertices.append(vertex)
if all_chips:
self.__pacman_data._all_monitor_vertices.append(vertex)

def set_n_required(self, n_boards_required, n_chips_required):
"""
Sets (if not `None`) the number of boards/chips requested by the user.
:param n_boards_required:
`None` or the number of boards requested by the user
:type n_boards_required: int or None
:param n_chips_required:
`None` or the number of chips requested by the user
:type n_chips_required: int or None
"""
if n_boards_required is None:
if n_chips_required is None:
return
elif not isinstance(n_chips_required, int):
raise TypeError("n_chips_required must be an int (or None)")
if n_chips_required <= 0:
raise ValueError(
"n_chips_required must be positive and not "
f"{n_chips_required}")
else:
if n_chips_required is not None:
raise ValueError(
"Illegal call with both both param provided as "
f"{n_boards_required}, {n_chips_required}")
if not isinstance(n_boards_required, int):
raise TypeError("n_boards_required must be an int (or None)")
if n_boards_required <= 0:
raise ValueError(
"n_boards_required must be positive and not "
f"{n_boards_required}")
if self.__pacman_data._n_boards_required is not None or \
self.__pacman_data._n_chips_required is not None:
raise ValueError(
"Illegal second call to set_n_required")
self.__pacman_data._n_boards_required = n_boards_required
self.__pacman_data._n_chips_required = n_chips_required

def set_n_chips_in_graph(self, n_chips_in_graph):
"""
Sets the number of chips needed by the graph.
:param int n_chips_in_graph:
"""
if not isinstance(n_chips_in_graph, int):
raise TypeError("n_chips_in_graph must be an int (or None)")
if n_chips_in_graph <= 0:
raise ValueError(
"n_chips_in_graph must be positive and not "
f"{n_chips_in_graph}")
self.__pacman_data._n_chips_in_graph = n_chips_in_graph
3 changes: 2 additions & 1 deletion pacman/operations/placer_algorithms/application_placer.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,8 @@ def _pop_start_chip(self) -> Chip:
f"No more chips to start with for {self.__app_vertex_label} "
f"Out of {self.__machine.n_chips} "
f"{len(self.__full_chips)} already full "
f"and {len(self.__starts_tried)} tried")
f"and {len(self.__starts_tried)} tried"
f"{PacmanDataView.get_chips_boards_required_str()}")

def _get_next_neighbour(self, n_cores: int, plan_sdram: int):
"""
Expand Down
79 changes: 79 additions & 0 deletions unittests/data/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,82 @@ def test_get_monitors(self):
self.assertEqual(3, PacmanDataView.get_ethernet_monitor_cores())
self.assertEqual(VariableSDRAM(200 + 100 + 55, 10 + 15),
PacmanDataView.get_ethernet_monitor_sdram())

def test_required(self):
writer = PacmanDataWriter.setup()
with self.assertRaises(DataNotYetAvialable):
self.assertIsNone(PacmanDataView.get_n_boards_required())
self.assertFalse(PacmanDataView.has_n_boards_required())
with self.assertRaises(DataNotYetAvialable):
self.assertIsNone(PacmanDataView.get_n_chips_needed())
self.assertFalse(PacmanDataView.has_n_chips_needed())

# required higher than in graph
writer.set_n_required(None, 20)
self.assertFalse(PacmanDataView.has_n_boards_required())
self.assertEqual(20, PacmanDataView.get_n_chips_needed())
writer.set_n_chips_in_graph(15)
self.assertFalse(PacmanDataView.has_n_boards_required())
self.assertEqual(20, PacmanDataView.get_n_chips_needed())

# required higher than in graph
writer.set_n_chips_in_graph(25)
self.assertFalse(PacmanDataView.has_n_boards_required())
self.assertEqual(20, PacmanDataView.get_n_chips_needed())

# reset does not remove required
writer.start_run()
writer.finish_run()
writer.hard_reset()
self.assertFalse(PacmanDataView.has_n_boards_required())
self.assertEqual(20, PacmanDataView.get_n_chips_needed())

writer = PacmanDataWriter.setup()
self.assertFalse(PacmanDataView.has_n_boards_required())
self.assertFalse(PacmanDataView.has_n_chips_needed())

# in graph only
writer.set_n_chips_in_graph(25)
self.assertEqual(25, PacmanDataView.get_n_chips_needed())

# reset clears in graph
writer.start_run()
writer.finish_run()
writer.hard_reset()
self.assertFalse(PacmanDataView.has_n_chips_needed())

# N boards
writer = PacmanDataWriter.setup()
writer.set_n_required(5, None)
self.assertEqual(5, PacmanDataView.get_n_boards_required())
self.assertFalse(PacmanDataView.has_n_chips_needed())

# boards does not hide in graph
writer.set_n_chips_in_graph(40)
self.assertEqual(5, PacmanDataView.get_n_boards_required())
self.assertEqual(40, PacmanDataView.get_n_chips_needed())

# reset does not clear required
writer.start_run()
writer.finish_run()
writer.hard_reset()
self.assertEqual(5, PacmanDataView.get_n_boards_required())
self.assertFalse(PacmanDataView.has_n_chips_needed())

# two Nones fine
writer = PacmanDataWriter.setup()
writer.set_n_required(None, None)
self.assertFalse(PacmanDataView.has_n_boards_required())
self.assertFalse(PacmanDataView.has_n_chips_needed())

# Ilegal calls
with self.assertRaises(ValueError):
writer.set_n_required(5, 5)
with self.assertRaises(ValueError):
writer.set_n_required(None, -5)
with self.assertRaises(ValueError):
writer.set_n_required(0, None)
with self.assertRaises(TypeError):
writer.set_n_required(None, "five")
with self.assertRaises(TypeError):
writer.set_n_required("2.3", None)

0 comments on commit e47fc6b

Please sign in to comment.