Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shared sdram #582

Merged
merged 17 commits into from
Oct 21, 2024
4 changes: 2 additions & 2 deletions pacman/data/pacman_data_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ def get_all_monitor_sdram(cls) -> AbstractSDRAM:
"""
# Note the sdram can not be calculated in advance as some Vertices
# require the hardware time step not available until simulator run
sdram = ConstantSDRAM(0)
sdram: AbstractSDRAM = ConstantSDRAM(0)
for vertex in cls.__pacman_data._all_monitor_vertices:
sdram += vertex.sdram_required
return sdram
Expand All @@ -580,7 +580,7 @@ def get_ethernet_monitor_sdram(cls) -> AbstractSDRAM:

:rtype: AbstractSDRAM
"""
sdram = ConstantSDRAM(0)
sdram: AbstractSDRAM = ConstantSDRAM(0)
for vertex in cls.__pacman_data._ethernet_monitor_vertices:
sdram += vertex.sdram_required
return sdram
Expand Down
3 changes: 2 additions & 1 deletion pacman/model/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
from .iptag_resource import IPtagResource
from .multi_region_sdram import MultiRegionSDRAM
from .reverse_iptag_resource import ReverseIPtagResource
from .shared_sdram import SharedSDRAM
from .variable_sdram import VariableSDRAM

__all__ = ["AbstractSDRAM", "ConstantSDRAM",
"IPtagResource", "MultiRegionSDRAM",
"ReverseIPtagResource", "VariableSDRAM"]
"ReverseIPtagResource", "SharedSDRAM", "VariableSDRAM"]
42 changes: 15 additions & 27 deletions pacman/model/resources/abstract_sdram.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,28 +43,6 @@ def __add__(self, other: AbstractSDRAM) -> AbstractSDRAM:
"""
raise NotImplementedError

@abstractmethod
def __sub__(self, other: AbstractSDRAM) -> AbstractSDRAM:
"""
Creates a new SDRAM which is this one less the other.

:param AbstractSDRAM other: another SDRAM resource
:return: a New AbstractSDRAM
:rtype: AbstractSDRAM
"""
raise NotImplementedError

@abstractmethod
def sub_from(self, other: AbstractSDRAM) -> AbstractSDRAM:
"""
Creates a new SDRAM which is the other less this one.

:param AbstractSDRAM other: another SDRAM resource
:return: a New AbstractSDRAM
:rtype: AbstractSDRAM
"""
raise NotImplementedError

@property
@abstractmethod
def fixed(self) -> int:
Expand All @@ -84,12 +62,9 @@ def per_timestep(self) -> float:
"""
raise NotImplementedError

@abstractmethod
def __eq__(self, other: Any) -> bool:
if not isinstance(other, AbstractSDRAM):
return False
if other.fixed != self.fixed:
return False
return other.per_timestep == self.per_timestep
raise NotImplementedError

@abstractmethod
def report(self, timesteps: Optional[int], indent: str = "",
Expand All @@ -105,3 +80,16 @@ def report(self, timesteps: Optional[int], indent: str = "",
``None`` is standard print
"""
raise NotImplementedError

@property
@abstractmethod
def short_str(self) -> str:
"""
A short string representation of this SDRAM.

To be used within main str methods
"""
raise NotImplementedError

def __str__(self):
return f"SDRAM:{self.short_str}"
31 changes: 12 additions & 19 deletions pacman/model/resources/constant_sdram.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Optional, TextIO
from typing import Any, Optional, TextIO
from spinn_utilities.overrides import overrides
from .abstract_sdram import AbstractSDRAM

Expand Down Expand Up @@ -49,32 +49,25 @@ def fixed(self) -> int:
def per_timestep(self) -> float:
return 0

def __add__(self, other):
def __eq__(self, other: Any) -> bool:
if not isinstance(other, ConstantSDRAM):
return False
return other.fixed == self.fixed

def __add__(self, other: AbstractSDRAM) -> AbstractSDRAM:
if isinstance(other, ConstantSDRAM):
return ConstantSDRAM(
self._sdram + other.fixed)
else:
# The other is more complex so delegate to it
return other.__add__(self)

def __sub__(self, other):
if isinstance(other, ConstantSDRAM):
return ConstantSDRAM(
self._sdram - other.fixed)
else:
# The other is more complex so delegate to it
return other.sub_from(self)

@overrides(AbstractSDRAM.sub_from)
def sub_from(self, other: AbstractSDRAM) -> AbstractSDRAM:
if isinstance(other, ConstantSDRAM):
return ConstantSDRAM(
other.fixed - self._sdram)
else:
# The other is more complex so delegate to it
return other - self

@overrides(AbstractSDRAM.report)
def report(self, timesteps: Optional[int], indent: str = "",
preamble: str = "", target: Optional[TextIO] = None):
print(indent, preamble, f"Constant {self._sdram} bytes", file=target)

@property
@overrides(AbstractSDRAM.short_str)
def short_str(self) -> str:
return f"fixed: {self._sdram}"
80 changes: 59 additions & 21 deletions pacman/model/resources/multi_region_sdram.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from __future__ import annotations
from enum import Enum
import math
from typing import Dict, Optional, TextIO, Union
from typing import Any, Dict, Optional, TextIO, Union

import numpy
from typing_extensions import TypeAlias
Expand All @@ -33,7 +33,7 @@ def _ceil(value: _Value) -> int:
return math.ceil(value)


class MultiRegionSDRAM(VariableSDRAM):
class MultiRegionSDRAM(AbstractSDRAM):
"""
A resource for SDRAM that comes in regions.

Expand All @@ -48,16 +48,18 @@ class MultiRegionSDRAM(VariableSDRAM):

__slots__ = (
# The regions of SDRAM, each of which is an AbstractSDRAM
"__regions", )
"__regions",
# The total cost of all the regions
"_total")

def __init__(self) -> None:
super().__init__(0, 0)
self.__regions: Dict[_RegionKey, AbstractSDRAM] = {}
self._total: AbstractSDRAM = ConstantSDRAM(0)

@property
def regions(self):
"""
The map from region identifiers to the to the amount of SDRAM required.
The map from region identifiers to the amount of SDRAM required.

:rtype: dict(int or str or enum, AbstractSDRAM)
"""
Expand All @@ -75,18 +77,11 @@ def add_cost(self, region: _RegionKey, fixed_sdram: _Value,
:param per_timestep_sdram: The variable cost for this region is any
:type per_timestep_sdram: int or numpy.integer
"""
self._fixed_sdram += _ceil(fixed_sdram)
self._per_timestep_sdram += _ceil(per_timestep_sdram)
sdram: AbstractSDRAM
if per_timestep_sdram:
sdram = VariableSDRAM(
_ceil(fixed_sdram), _ceil(per_timestep_sdram))
self.nest(region, VariableSDRAM(
_ceil(fixed_sdram), _ceil(per_timestep_sdram)))
else:
sdram = ConstantSDRAM(_ceil(fixed_sdram))
if region in self.__regions:
self.__regions[region] += sdram
else:
self.__regions[region] = sdram
self.nest(region, ConstantSDRAM(_ceil(fixed_sdram)))

def nest(self, region: _RegionKey, other: AbstractSDRAM):
"""
Expand All @@ -102,15 +97,14 @@ def nest(self, region: _RegionKey, other: AbstractSDRAM):
:param AbstractSDRAM other:
Another SDRAM model to make combine by nesting
"""
self._fixed_sdram += other.fixed
self._per_timestep_sdram += other.per_timestep
self._total += other
if region in self.__regions:
if isinstance(other, MultiRegionSDRAM):
r = self.__regions[region]
if isinstance(r, MultiRegionSDRAM):
r.merge(other)
else:
other.add_cost(region, r.fixed, r.per_timestep)
other.nest(region, r)
self.__regions[region] = other
else:
self.__regions[region] += other
Expand All @@ -127,8 +121,7 @@ def merge(self, other: MultiRegionSDRAM):

:param MultiRegionSDRAM other: Another mapping of costs by region
"""
self._fixed_sdram += other.fixed
self._per_timestep_sdram += other.per_timestep
self._total += other
for region in other.regions:
if region in self.regions:
self.__regions[region] += other.regions[region]
Expand All @@ -138,7 +131,52 @@ def merge(self, other: MultiRegionSDRAM):
@overrides(AbstractSDRAM.report)
def report(self, timesteps: Optional[int], indent: str = "",
preamble: str = "", target: Optional[TextIO] = None):
super().report(timesteps, indent, preamble, target)
self._total.report(timesteps, indent, preamble, target)
for region in self.__regions:
self.__regions[region].report(
timesteps, indent+" ", str(region)+":", target)

def get_total_sdram(self, n_timesteps: Optional[int]) -> int:
"""
The total SDRAM.

:param int n_timesteps: number of timesteps to cost for
:return:
"""
return self._total.get_total_sdram(n_timesteps)

def __eq__(self, other: Any) -> bool:
if isinstance(other, MultiRegionSDRAM):
return self._total == other._total
return self._total == other

def __add__(self, other: AbstractSDRAM) -> AbstractSDRAM:
"""
Combines this SDRAM resource with the other one and creates a new one.

:param other: another SDRAM resource
:return: a New AbstractSDRAM
"""
return self._total + other

@property
def fixed(self) -> int:
"""
The fixed SDRAM cost.
"""
return self._total.fixed

@property
def per_timestep(self) -> float:
"""
The extra SDRAM cost for each additional timestep.

.. warning::
May well be zero.
"""
return self._total.per_timestep

@property
@overrides(AbstractSDRAM.short_str)
def short_str(self) -> str:
return f"Multi:{self._total.short_str}"
Loading