From cf6e58082d8cb1b5c595467cbd34ef0be7bebddc 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                             |  62 ++++++++++----
 b_asic/research/interleaver.py                |  44 ++++++----
 b_asic/resources.py                           |  78 +++++++++++-------
 .../test_draw_matrix_transposer_4.png         | Bin 0 -> 21399 bytes
 .../baseline/test_draw_process_collection.png | Bin 10292 -> 15052 bytes
 test/fixtures/resources.py                    |   9 +-
 test/test_resources.py                        |  32 ++++++-
 7 files changed, 153 insertions(+), 72 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..8d7e7620 100644
--- a/b_asic/process.py
+++ b/b_asic/process.py
@@ -20,11 +20,20 @@ class Process:
         Start time of process.
     execution_time : int
         Execution time (lifetime) of process.
+    name : str, optional
+        The name of the process. If not provided, generate a name.
     """
 
-    def __init__(self, start_time: int, execution_time: int):
+    def __init__(
+        self, start_time: int, execution_time: int, name: Optional[str] = None
+    ):
         self._start_time = start_time
         self._execution_time = execution_time
+        if name is None:
+            self._name = f"Proc. {PlainMemoryVariable._name_cnt}"
+            PlainMemoryVariable._name_cnt += 1
+        else:
+            self._name = name
 
     def __lt__(self, other):
         return self._start_time < other.start_time or (
@@ -42,6 +51,16 @@ class Process:
         """Return the execution time."""
         return self._execution_time
 
+    @property
+    def name(self) -> str:
+        return self._name
+
+    def __str__(self) -> str:
+        return self._name
+
+    # Static counter for default names
+    _name_cnt = 0
+
 
 class OperatorProcess(Process):
     """
@@ -53,16 +72,27 @@ class OperatorProcess(Process):
         Start time of process.
     operation : Operation
         Operation that the process corresponds to.
+    name : str, optional
+        The name of the process.
     """
 
-    def __init__(self, start_time: int, operation: Operation):
+    def __init__(
+        self,
+        start_time: int,
+        operation: Operation,
+        name: Optional[str] = None,
+    ):
         execution_time = operation.execution_time
         if execution_time is None:
             raise ValueError(
                 "Operation {operation!r} does not have an execution time"
                 " specified!"
             )
-        super().__init__(start_time, execution_time)
+        super().__init__(
+            start_time,
+            execution_time,
+            name=name,
+        )
         self._operation = operation
 
 
@@ -80,6 +110,8 @@ class MemoryVariable(Process):
     reads : {InputPort: int, ...}
         Dictionary with the InputPorts that reads the memory variable and
         for how long after the *write_time* they will read.
+    name : str, optional
+        The name of the process.
     """
 
     def __init__(
@@ -87,12 +119,15 @@ class MemoryVariable(Process):
         write_time: int,
         write_port: OutputPort,
         reads: Dict[InputPort, int],
+        name: Optional[str] = None,
     ):
         self._read_ports = tuple(reads.keys())
         self._life_times = tuple(reads.values())
         self._write_port = write_port
         super().__init__(
-            start_time=write_time, execution_time=max(self._life_times)
+            start_time=write_time,
+            execution_time=max(self._life_times),
+            name=name,
         )
 
     @property
@@ -123,6 +158,8 @@ class PlainMemoryVariable(Process):
     reads : {int: int, ...}
         Dictionary where the key is the destination identifier and the value
         is the time after *write_time* that the memory variable is read.
+    name : str, optional
+        The name of the process.
     """
 
     def __init__(
@@ -135,11 +172,10 @@ class PlainMemoryVariable(Process):
         self._read_ports = tuple(reads.keys())
         self._life_times = tuple(reads.values())
         self._write_port = write_port
-        if name is None:
-            self._name = str(PlainMemoryVariable._name_cnt)
-            PlainMemoryVariable._name_cnt += 1
         super().__init__(
-            start_time=write_time, execution_time=max(self._life_times)
+            start_time=write_time,
+            execution_time=max(self._life_times),
+            name=name,
         )
 
     @property
@@ -153,13 +189,3 @@ class PlainMemoryVariable(Process):
     @property
     def write_port(self) -> int:
         return self._write_port
-
-    @property
-    def name(self) -> str:
-        return self._name
-
-    def __str__(self) -> str:
-        return self._name
-
-    # Static counter for default names
-    _name_cnt = 0
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..c91047b2 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,8 @@ 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)
+        _ax.set_ylim(0.25, len(self._collection) + 0.75)
         return _ax
 
     def create_exclusion_graph_from_overlap(
@@ -332,12 +346,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..962fc776b73b1096b8d6080fce8d88a380f52c60
GIT binary patch
literal 21399
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
P>?PJ7c3`#t!IS?01KyKd

literal 0
HcmV?d00001

diff --git a/test/baseline/test_draw_process_collection.png b/test/baseline/test_draw_process_collection.png
index 0ab1996784015b6d0bc3e5bc68e0f3ae21c64d94..87a5bf7fd1ce3055f5cc993ab684c560ef06e4b5 100644
GIT binary patch
literal 15052
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

literal 10292
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

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