diff --git a/b_asic/resources.py b/b_asic/resources.py index 2eb3562d6b852f365fa25ce2e7115530e0ea4f5b..945ccba802d8eedd787e686b0552bf0bb985ea60 100644 --- a/b_asic/resources.py +++ b/b_asic/resources.py @@ -94,21 +94,30 @@ def draw_exclusion_graph_coloring( color_list: Optional[Union[List[str], List[Tuple[float, float, float]]]] = None, ) -> None: """ - Draw a colored exclusion graph from the memory assignment. + Helper function for drawing a colored exclusion graphs. + + Example usage: .. code-block:: python - _, ax = plt.subplots(1, 1) + import networkx as nx + import matplotlib.pyplot as plt + + _, ax = plt.subplots() collection = ProcessCollection(...) - exclusion_graph = collection.create_exclusion_graph_from_overlap() - color_dict = nx.greedy_color(exclusion_graph) - draw_exclusion_graph_coloring(exclusion_graph, color_dict, ax=ax[0]) + exclusion_graph = collection.create_exclusion_graph_from_ports( + read_ports = 1, + write_ports = 1, + total_ports = 2, + ) + coloring = nx.greedy_color(exclusion_graph) + draw_exclusion_graph_coloring(exclusion_graph, coloring, ax=ax) plt.show() Parameters ---------- - exclusion_graph : nx.Graph - A nx.Graph exclusion graph object that is to be drawn. + exclusion_graph : :class:`networkx.Graph` + The :class:`networkx.Graph` exclusion graph object that is to be drawn. color_dict : dict A dict where keys are :class:`~b_asic.process.Process` objects and values are integers representing colors. These dictionaries are automatically generated by @@ -413,17 +422,21 @@ class _ForwardBackwardTable: class ProcessCollection: - """ - Collection of one or more processes + r""" + Collection of :class:`~b_asic.process.Process` objects. Parameters ---------- - collection : set of :class:`~b_asic.process.Process` objects - The Process objects forming this ProcessCollection. + collection : Iterable of :class:`~b_asic.process.Process` objects + The :class:`~b_asic.process.Process` objects forming this + :class:`~b_asic.resources.ProcessCollection`. schedule_time : int - Length of the time-axis in the generated graph. + The scheduling time associated with this + :class:`~b_asic.resources.ProcessCollection`. cyclic : bool, default: False - If the processes operates cyclically, i.e., if time 0 == time *schedule_time*. + Whether the processes operates cyclically, i.e., if time + + .. math:: t = t \bmod T_{\textrm{schedule}}. """ def __init__( @@ -449,12 +462,13 @@ class ProcessCollection: def add_process(self, process: Process): """ - Add a new process to this process collection. + Add a new :class:`~b_asic.process.Process` to this + :class:`~b_asic.resources.ProcessCollection`. Parameters ---------- - process : Process - The process object to be added to the collection. + process : :class:`~b_asic.process.Process` + The :class:`~b_asic.process.Process` object to add. """ if process in self.collection: raise ValueError("Process already in ProcessCollection") @@ -462,14 +476,16 @@ class ProcessCollection: def remove_process(self, process: Process): """ - Remove a processes from this process collection. + Remove a :class:`~b_asic.process.Process` from this + :class:`~b_asic.resources.ProcessCollection`. - Raises KeyError if the process is not in this collection. + Raises :class:`KeyError` if the specified :class:`~b_asic.process.Process` is + not in this collection. Parameters ---------- - process : Process - The processes object to remove from this collection + process : :class:`~b_asic.process.Process` + The :class:`~b_asic.process.Process` object to remove from this collection. """ if process not in self.collection: raise KeyError( @@ -492,7 +508,16 @@ class ProcessCollection: allow_excessive_lifetimes: bool = False, ): """ - Plot a process variable lifetime chart. + Plot all :class:`~b_asic.process.Process` objects of this + :class:`~b_asic.resources.ProcessCollection` in a lifetime diagram. + + If the ``ax`` parameter is not specified, a new Matplotlib figure is created. + + Raises :class:`KeyError` if any :class:`~b_asic.process.Process` lifetime + excedes this :class:`~b_asic.resources.ProcessCollection` schedule time, + unless ``allow_excessive_lifetimes`` is specified. In that case, + :class:`~b_asic.process.Process` objects whose lifetime exceed the scheudle + time are drawn using the B-ASIC warning color. Parameters ---------- @@ -642,7 +667,8 @@ class ProcessCollection: title: Optional[str] = None, ) -> None: """ - Show the process collection using the current Matplotlib backend. + Display this :class:`~b_asic.resources.ProcessCollection` using the current + Matplotlib backend. Equivalent to creating a Matplotlib figure, passing it and arguments to :meth:`plot` and invoking :py:meth:`matplotlib.figure.Figure.show`. @@ -689,7 +715,9 @@ class ProcessCollection: total_ports: Optional[int] = None, ) -> nx.Graph: """ - Create an exclusion graph based on a number of read/write ports. + Create an exclusion graph from a given number of read and write ports based on + concurrent read and write accesses to this + :class:`~b_asic.resources.ProcessCollection`. Parameters ---------- @@ -705,7 +733,7 @@ class ProcessCollection: Returns ------- - nx.Graph + A :class:`networkx.Graph` object. """ read_ports, write_ports, total_ports = _sanitize_port_option( @@ -763,12 +791,11 @@ class ProcessCollection: def create_exclusion_graph_from_execution_time(self) -> nx.Graph: """ - Generate exclusion graph based on processes overlapping in time + Create an exclusion graph from processes overlapping in execution time. Returns ------- - An nx.Graph exclusion graph where nodes are processes and arcs - between two processes indicated overlap in time + A :class:`networkx.Graph` object. """ exclusion_graph = nx.Graph() exclusion_graph.add_nodes_from(self._collection) @@ -1234,7 +1261,7 @@ class ProcessCollection: Forward-Backward Register Allocation [1]. [1]: K. Parhi: VLSI Digital Signal Processing Systems: Design and - Implementation, Ch. 6.3.2 + Implementation, Ch. 6.3.2 Parameters ---------- @@ -1301,16 +1328,17 @@ class ProcessCollection: def get_by_type_name(self, type_name: TypeName) -> "ProcessCollection": """ - Return a ProcessCollection with only a given type of operation. + Return a new :class:`~b_asic.resources.ProcessCollection` with only a given + type of operation. Parameters ---------- type_name : TypeName - The type_name of the operation. + The TypeName of the operation to extract. Returns ------- - ProcessCollection + A new :class:`~b_asic.resources.ProcessCollection`. """ return ProcessCollection( @@ -1325,6 +1353,14 @@ class ProcessCollection: ) def read_ports_bound(self) -> int: + """ + Get the read port lower-bound (maximum number of concurrent reads) of this + :class:`~b_asic.resources.ProcessCollection`. + + Returns + ------- + int + """ reads = [] for process in self._collection: reads.extend( @@ -1334,6 +1370,14 @@ class ProcessCollection: return max(count.values()) def write_ports_bound(self) -> int: + """ + Get the write port lower-bound (maximum number of concurrent writes) of this + :class:`~b_asic.resources.ProcessCollection`. + + Returns + ------- + int + """ writes = [process.start_time for process in self._collection] count = Counter(writes) return max(count.values())