From 758262fc8ed6e5bf56dadd9f9abb9370c0ca50dc Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson <oscar.gustafsson@gmail.com> Date: Thu, 16 Feb 2023 10:15:45 +0100 Subject: [PATCH] Fix resource-related issues --- b_asic/process.py | 2 + b_asic/research/interleaver.py | 44 ++++++---- b_asic/resources.py | 77 +++++++++++------- .../test_draw_matrix_transposer_4.png | Bin 0 -> 21765 bytes .../baseline/test_draw_process_collection.png | Bin 10292 -> 10159 bytes test/fixtures/resources.py | 9 +- test/test_resources.py | 32 +++++++- 7 files changed, 110 insertions(+), 54 deletions(-) create mode 100644 test/baseline/test_draw_matrix_transposer_4.png diff --git a/b_asic/process.py b/b_asic/process.py index d48fa0ee..f25de759 100644 --- a/b_asic/process.py +++ b/b_asic/process.py @@ -138,6 +138,8 @@ class PlainMemoryVariable(Process): if name is None: self._name = str(PlainMemoryVariable._name_cnt) PlainMemoryVariable._name_cnt += 1 + else: + self._name = name super().__init__( start_time=write_time, execution_time=max(self._life_times) ) diff --git a/b_asic/research/interleaver.py b/b_asic/research/interleaver.py index 83eb4b3b..b64a79b9 100644 --- a/b_asic/research/interleaver.py +++ b/b_asic/research/interleaver.py @@ -6,6 +6,7 @@ import random from typing import Optional, Set from b_asic.process import PlainMemoryVariable +from b_asic.resources import ProcessCollection def _insert_delays(inputorder, outputorder, min_lifetime, cyclic): @@ -14,9 +15,7 @@ def _insert_delays(inputorder, outputorder, min_lifetime, cyclic): outputorder = [o - maxdiff + min_lifetime for o in outputorder] maxdelay = max(outputorder[i] - inputorder[i] for i in range(size)) if cyclic: - if maxdelay < size: - outputorder = [o % size for o in outputorder] - else: + if maxdelay >= size: inputorder = inputorder + [i + size for i in inputorder] outputorder = outputorder + [o + size for o in outputorder] return inputorder, outputorder @@ -24,7 +23,7 @@ def _insert_delays(inputorder, outputorder, min_lifetime, cyclic): def generate_random_interleaver( size: int, min_lifetime: int = 0, cyclic: bool = True -) -> Set[PlainMemoryVariable]: +) -> ProcessCollection: """ Generate a ProcessCollection with memory variable corresponding to a random interleaver with length *size*. @@ -48,15 +47,19 @@ def generate_random_interleaver( inputorder = list(range(size)) outputorder = inputorder[:] random.shuffle(outputorder) - print(inputorder, outputorder) inputorder, outputorder = _insert_delays( inputorder, outputorder, min_lifetime, cyclic ) - print(inputorder, outputorder) - return { - PlainMemoryVariable(inputorder[i], 0, {0: outputorder[i]}) - for i in range(size) - } + return ProcessCollection( + { + PlainMemoryVariable( + inputorder[i], 0, {0: outputorder[i] - inputorder[i]} + ) + for i in range(len(inputorder)) + }, + len(inputorder), + cyclic, + ) def generate_matrix_transposer( @@ -64,7 +67,7 @@ def generate_matrix_transposer( width: Optional[int] = None, min_lifetime: int = 0, cyclic: bool = True, -) -> Set[PlainMemoryVariable]: +) -> ProcessCollection: r""" Generate a ProcessCollection with memory variable corresponding to transposing a matrix of size *height* :math:`\times` *width*. If *width* is not provided, a @@ -101,12 +104,19 @@ def generate_matrix_transposer( for col in range(height): outputorder.append(col * width + row) - print(inputorder, outputorder) inputorder, outputorder = _insert_delays( inputorder, outputorder, min_lifetime, cyclic ) - print(inputorder, outputorder) - return { - PlainMemoryVariable(inputorder[i], 0, {0: outputorder[i]}) - for i in range(width * height) - } + return ProcessCollection( + { + PlainMemoryVariable( + inputorder[i], + 0, + {0: outputorder[i] - inputorder[i]}, + name=f"{inputorder[i]}", + ) + for i in range(len(inputorder)) + }, + len(inputorder), + cyclic, + ) diff --git a/b_asic/resources.py b/b_asic/resources.py index eaed928f..121b892d 100644 --- a/b_asic/resources.py +++ b/b_asic/resources.py @@ -1,3 +1,4 @@ +import re from typing import Dict, List, Optional, Set, Tuple, Union import matplotlib.pyplot as plt @@ -8,6 +9,16 @@ from matplotlib.ticker import MaxNLocator from b_asic.process import Process +# From https://stackoverflow.com/questions/2669059/how-to-sort-alpha-numeric-set-in-python +def _sorted_nicely(to_be_sorted): + """Sort the given iterable in the way that humans expect.""" + convert = lambda text: int(text) if text.isdigit() else text + alphanum_key = lambda key: [ + convert(c) for c in re.split('([0-9]+)', str(key)) + ] + return sorted(to_be_sorted, key=alphanum_key) + + def draw_exclusion_graph_coloring( exclusion_graph: nx.Graph, color_dict: Dict[Process, int], @@ -79,14 +90,23 @@ class ProcessCollection: Parameters ---------- - collection : set of :class:`~b_asic.process.Process` objects, optional + collection : set of :class:`~b_asic.process.Process` objects + The Process objects forming this ProcessCollection. + schedule_time : int, default: 0 + Length of the time-axis in the generated graph. + cyclic : bool, default: False + If the processes operates cyclically, i.e., if time 0 == time *schedule_time*. """ - def __init__(self, collection: Optional[Set[Process]] = None): - if collection is None: - self._collection: Set[Process] = set() - else: - self._collection = collection + def __init__( + self, + collection: Set[Process], + schedule_time: int, + cyclic: bool = False, + ): + self._collection = collection + self._schedule_time = schedule_time + self._cyclic = cyclic def add_process(self, process: Process): """ @@ -101,7 +121,6 @@ class ProcessCollection: def draw_lifetime_chart( self, - schedule_time: int = 0, ax: Optional[Axes] = None, show_name: bool = True, ): @@ -110,9 +129,6 @@ class ProcessCollection: Parameters ---------- - schedule_time : int, default: 0 - Length of the time-axis in the generated graph. The time axis will span [0, schedule_time-1]. - If set to zero (which is the default), the ... ax : :class:`matplotlib.axes.Axes`, optional Matplotlib Axes object to draw this lifetime chart onto. If not provided (i.e., set to None), this will return a new axes object on return. @@ -133,26 +149,19 @@ class ProcessCollection: # Draw the lifetime chart PAD_L, PAD_R = 0.05, 0.05 max_execution_time = max( - [process.execution_time for process in self._collection] + process.execution_time for process in self._collection ) - schedule_time = ( - schedule_time - if schedule_time - else max(p.start_time + p.execution_time for p in self._collection) - ) - if max_execution_time > schedule_time: + if max_execution_time > self._schedule_time: # Schedule time needs to be greater than or equal to the maximum process life time raise KeyError( - f'Error: Schedule time: {schedule_time} < Max execution time:' - f' {max_execution_time}' + f'Error: Schedule time: {self._schedule_time} < Max execution' + f' time: {max_execution_time}' ) - for i, process in enumerate( - sorted(self._collection, key=lambda p: str(p)) - ): - bar_start = process.start_time % schedule_time + for i, process in enumerate(_sorted_nicely(self._collection)): + bar_start = process.start_time % self._schedule_time bar_end = ( process.start_time + process.execution_time - ) % schedule_time + ) % self._schedule_time if bar_end > bar_start: _ax.broken_barh( [(PAD_L + bar_start, bar_end - bar_start - PAD_L - PAD_R)], @@ -164,7 +173,7 @@ class ProcessCollection: [ ( PAD_L + bar_start, - schedule_time - bar_start - PAD_L, + self._schedule_time - bar_start - PAD_L, ) ], (i + 0.55, 0.9), @@ -175,7 +184,10 @@ class ProcessCollection: [ ( PAD_L + bar_start, - schedule_time - bar_start - PAD_L - PAD_R, + self._schedule_time + - bar_start + - PAD_L + - PAD_R, ) ], (i + 0.55, 0.9), @@ -190,6 +202,7 @@ class ProcessCollection: _ax.xaxis.set_major_locator(MaxNLocator(integer=True)) _ax.yaxis.set_major_locator(MaxNLocator(integer=True)) + _ax.set_xlim(0, self._schedule_time) return _ax def create_exclusion_graph_from_overlap( @@ -332,12 +345,14 @@ class ProcessCollection: coloring = nx.coloring.greedy_color(exclusion_graph) draw_exclusion_graph_coloring(exclusion_graph, coloring) # process_collection_list = [ProcessCollection()]*(max(coloring.values()) + 1) - process_collection_list = [ - ProcessCollection() for _ in range(max(coloring.values()) + 1) + process_collection_set_list = [ + set() for _ in range(max(coloring.values()) + 1) ] for process, color in coloring.items(): - process_collection_list[color].add_process(process) + process_collection_set_list[color].add(process) return { - process_collection - for process_collection in process_collection_list + ProcessCollection( + process_collection_set, self._schedule_time, self._cyclic + ) + for process_collection_set in process_collection_set_list } diff --git a/test/baseline/test_draw_matrix_transposer_4.png b/test/baseline/test_draw_matrix_transposer_4.png new file mode 100644 index 0000000000000000000000000000000000000000..3e7546972ed9c12dd8441ff39d432604c5a5c4db GIT binary patch literal 21765 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 literal 0 HcmV?d00001 diff --git a/test/baseline/test_draw_process_collection.png b/test/baseline/test_draw_process_collection.png index 0ab1996784015b6d0bc3e5bc68e0f3ae21c64d94..85c7da0622d0a312d4a83ee4b38a8acafc9fb188 100644 GIT binary patch delta 8190 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 a`tM8sZF^U8IGTZhfx*+&&t;ucLK6Ug*HMoE literal 10292 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 FO#p;!n4bUu diff --git a/test/fixtures/resources.py b/test/fixtures/resources.py index 6317e4cb..61c8db25 100644 --- a/test/fixtures/resources.py +++ b/test/fixtures/resources.py @@ -16,12 +16,13 @@ def simple_collection(): PlainMemoryVariable(0, NO_PORT, {NO_PORT: 3}), PlainMemoryVariable(0, NO_PORT, {NO_PORT: 2}), PlainMemoryVariable(0, NO_PORT, {NO_PORT: 6}), - } + }, + 8, ) @pytest.fixture() -def collection(): +def cyclic_simple_collection(): NO_PORT = 0 return ProcessCollection( { @@ -32,5 +33,7 @@ def collection(): PlainMemoryVariable(0, NO_PORT, {NO_PORT: 3}), PlainMemoryVariable(0, NO_PORT, {NO_PORT: 2}), PlainMemoryVariable(0, NO_PORT, {NO_PORT: 6}), - } + }, + 6, + True, ) diff --git a/test/test_resources.py b/test/test_resources.py index 67f20cc9..10e401ad 100644 --- a/test/test_resources.py +++ b/test/test_resources.py @@ -2,8 +2,11 @@ import matplotlib.pyplot as plt import networkx as nx import pytest -from b_asic.process import PlainMemoryVariable -from b_asic.resources import ProcessCollection, draw_exclusion_graph_coloring +from b_asic.research.interleaver import ( + generate_matrix_transposer, + generate_random_interleaver, +) +from b_asic.resources import draw_exclusion_graph_coloring class TestProcessCollectionPlainMemoryVariable: @@ -15,7 +18,7 @@ class TestProcessCollectionPlainMemoryVariable: def test_draw_proces_collection(self, simple_collection): _, ax = plt.subplots(1, 2) - simple_collection.draw_lifetime_chart(schedule_time=8, ax=ax[0]) + simple_collection.draw_lifetime_chart(ax=ax[0]) exclusion_graph = ( simple_collection.create_exclusion_graph_from_overlap() ) @@ -27,3 +30,26 @@ class TestProcessCollectionPlainMemoryVariable: read_ports=1, write_ports=1, total_ports=2 ) assert len(collection_split) == 3 + + @pytest.mark.mpl_image_compare(style='mpl20') + def test_draw_matrix_transposer_4(self): + fig, ax = plt.subplots() + generate_matrix_transposer(4).draw_lifetime_chart(ax=ax) + return fig + + def test_generate_random_interleaver(self): + return + for _ in range(10): + for size in range(5, 20, 5): + assert ( + len( + generate_random_interleaver(size).split( + read_ports=1, write_ports=1 + ) + ) + == 1 + ) + assert ( + len(generate_random_interleaver(size).split(total_ports=1)) + == 2 + ) -- GitLab