Source code for pacman.operations.router_compressors.abstract_compressor
# Copyright (c) 2017 The University of Manchester
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
based on https://github.com/project-rig/
"""
from abc import abstractmethod
import logging
from typing import List, cast
from spinn_utilities.config_holder import get_config_bool
from spinn_utilities.log import FormatAdapter
from spinn_utilities.progress_bar import ProgressBar
from spinn_machine import MulticastRoutingEntry
from pacman.data import PacmanDataView
from pacman.model.routing_tables import (
CompressedMulticastRoutingTable, MulticastRoutingTables)
from pacman.exceptions import MinimisationFailedError
from pacman.model.routing_tables import UnCompressedMulticastRoutingTable
logger = FormatAdapter(logging.getLogger(__name__))
class AbstractCompressor(object):
"""
Basic model of a router table compressor.
.. note::
Not all compressors use this model.
"""
__slots__ = (
# String of problems detected. Must be "" to finish
"_problems",
# Flag to say if the results can be order dependent
"_ordered",
# Flag to say that results too large should be ignored
"_accept_overflow")
def __init__(self, ordered: bool = True, accept_overflow: bool = False):
self._ordered = ordered
self._accept_overflow = accept_overflow
self._problems = ""
[docs]
def compress_all_tables(self) -> MulticastRoutingTables:
"""
Apply compression to all uncompressed tables.
:rtype: MulticastRoutingTables
"""
router_tables = PacmanDataView.get_precompressed()
# create progress bar
progress = ProgressBar(
router_tables.routing_tables,
f"Compressing routing Tables using {self.__class__.__name__}")
return self.compress_tables(router_tables, progress)
[docs]
@abstractmethod
def compress_table(
self, router_table: UnCompressedMulticastRoutingTable) -> List[
MulticastRoutingEntry]:
"""
:param UnCompressedMulticastRoutingTable router_table:
Original routing table for a single chip
:return: Raw compressed routing table entries for the same chip
:rtype: list(MulticastRoutingEntry)
"""
raise NotImplementedError
[docs]
def compress_tables(
self, router_tables: MulticastRoutingTables,
progress: ProgressBar) -> MulticastRoutingTables:
"""
Compress the given unordered routing tables.
Tables who start of smaller than global_target are not compressed
:param MulticastRoutingTables router_tables: Routing tables
:param ~spinn_utilities.progress_bar.ProgressBar progress:
Progress bar to show while working
:return: The compressed but still unordered routing tables
:rtype: MulticastRoutingTables
:raises MinimisationFailedError: on failure
"""
compressed_tables = MulticastRoutingTables()
as_needed = not (get_config_bool(
"Mapping", "router_table_compress_as_far_as_possible"))
for table in progress.over(router_tables.routing_tables):
chip = PacmanDataView.get_chip_at(table.x, table.y)
target = chip.router.n_available_multicast_entries
if as_needed and table.number_of_entries <= target:
new_table = table
else:
compressed_table = self.compress_table(cast(
UnCompressedMulticastRoutingTable, table))
new_table = CompressedMulticastRoutingTable(table.x, table.y)
for entry in compressed_table:
new_table.add_multicast_routing_entry(entry)
if new_table.number_of_entries > target:
self._problems += (
f"(x:{new_table.x},y:{new_table.y})="
f"{new_table.number_of_entries} ")
compressed_tables.add_routing_table(new_table)
if len(self._problems) > 0:
if self._ordered and not self._accept_overflow:
raise MinimisationFailedError(
"The routing table after compression will still not fit"
f" within the machines router: {self._problems}")
else:
logger.warning(self._problems)
return compressed_tables