From 6e33ce26657e48ef4cc4583233514f19565ab52a Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson <oscar.gustafsson@gmail.com> Date: Thu, 11 Apr 2024 12:40:42 +0200 Subject: [PATCH] Apply new pre-commit versions --- .pre-commit-config.yaml | 2 +- README.md | 88 +++++++++++++++-------------- b_asic/GUI/arrow.py | 2 +- b_asic/GUI/gui_interface.py | 3 +- b_asic/GUI/main_window.py | 5 +- b_asic/architecture.py | 25 ++++---- b_asic/codegen/vhdl/architecture.py | 3 +- b_asic/codegen/vhdl/common.py | 2 +- b_asic/operation.py | 10 ++-- b_asic/resources.py | 6 +- b_asic/schedule.py | 24 ++++---- b_asic/scheduler_gui/logger.py | 1 - b_asic/signal_flow_graph.py | 8 +-- examples/firstorderiirfilter.py | 3 +- examples/twotapfirsfg.py | 15 +---- legacy/README.md | 4 +- legacy/simulation_oop/operation.cpp | 2 +- pyproject.toml | 5 +- test/test_codegen.py | 1 - test/test_core_operations.py | 8 ++- test/test_resources.py | 2 +- test/test_schedule.py | 42 ++++++++------ test/test_sfg.py | 40 ++++++------- 23 files changed, 155 insertions(+), 146 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b95df2b2..53a34ad9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,7 +30,7 @@ repos: name: isort (python) - repo: https://github.com/Carreau/velin - rev: 0.0.12 + rev: 0.0.11 hooks: - id: velin diff --git a/README.md b/README.md index 58c7f54b..074f2828 100644 --- a/README.md +++ b/README.md @@ -14,46 +14,46 @@ How to build and debug the library during development. The following packages are required in order to build the library: -- [Python](https://python.org/) 3.8+ -- Python dependencies (install with `pip install -r requirements.txt` or they will be installed as part of the - installation process): - - [Graphviz](https://graphviz.org/) - - [Matplotlib](https://matplotlib.org/) - - [NumPy](https://numpy.org/) - - [QtPy](https://github.com/spyder-ide/qtpy) - - [setuptools_scm](https://github.com/pypa/setuptools_scm/) - - [NetworkX](https://networkx.org/) - - [QtAwesome](https://github.com/spyder-ide/qtawesome/) -- Qt 5 or 6, with Python bindings, one of: - - pyside2 - - pyqt5 - - pyside6 - - pyqt6 +- [Python](https://python.org/) 3.8+ +- Python dependencies (install with `pip install -r requirements.txt` or they will be installed as part of the + installation process): + - [Graphviz](https://graphviz.org/) + - [Matplotlib](https://matplotlib.org/) + - [NumPy](https://numpy.org/) + - [QtPy](https://github.com/spyder-ide/qtpy) + - [setuptools_scm](https://github.com/pypa/setuptools_scm/) + - [NetworkX](https://networkx.org/) + - [QtAwesome](https://github.com/spyder-ide/qtawesome/) +- Qt 5 or 6, with Python bindings, one of: + - pyside2 + - pyqt5 + - pyside6 + - pyqt6 To build a binary distribution, the following additional packages are required: -- Python: - - wheel +- Python: + - wheel To run the test suite, the following additional packages are required: -- Python (install with `pip install -r requirements_test.txt`): - - [pytest](https://pytest.org/) - - [pytest-qt](https://pytest-qt.readthedocs.io/) - - [pytest-mpl](https://github.com/matplotlib/pytest-mpl/) - - [pytest-cov](https://pytest-cov.readthedocs.io/en/latest/) (for testing with coverage) - - [pytest-xvfb](https://github.com/The-Compiler/pytest-xvfb) (for testing without showing windows on Linux, you will also need to install [xvfb](https://www.x.org/releases/X11R7.6/doc/man/man1/Xvfb.1.xhtml)) - - [pytest-xdist](https://pytest-xdist.readthedocs.io/) (for parallel testing) +- Python (install with `pip install -r requirements_test.txt`): + - [pytest](https://pytest.org/) + - [pytest-qt](https://pytest-qt.readthedocs.io/) + - [pytest-mpl](https://github.com/matplotlib/pytest-mpl/) + - [pytest-cov](https://pytest-cov.readthedocs.io/en/latest/) (for testing with coverage) + - [pytest-xvfb](https://github.com/The-Compiler/pytest-xvfb) (for testing without showing windows on Linux, you will also need to install [xvfb](https://www.x.org/releases/X11R7.6/doc/man/man1/Xvfb.1.xhtml)) + - [pytest-xdist](https://pytest-xdist.readthedocs.io/) (for parallel testing) To generate the documentation, the following additional packages are required: -- Python (install with `pip install -r requirements_doc.txt`): - - [Sphinx](https://www.sphinx-doc.org/) - - [Furo](https://pradyunsg.me/furo/) - - [numpydoc](https://numpydoc.readthedocs.io/) - - [Sphinx-Gallery](https://sphinx-gallery.github.io/) - - [mplsignal](https://mplsignal.readthedocs.io/) - - [sphinx-copybutton](https://sphinx-copybutton.readthedocs.io/) +- Python (install with `pip install -r requirements_doc.txt`): + - [Sphinx](https://www.sphinx-doc.org/) + - [Furo](https://pradyunsg.me/furo/) + - [numpydoc](https://numpydoc.readthedocs.io/) + - [Sphinx-Gallery](https://sphinx-gallery.github.io/) + - [mplsignal](https://mplsignal.readthedocs.io/) + - [sphinx-copybutton](https://sphinx-copybutton.readthedocs.io/) ### Using setuptools to create a package @@ -63,7 +63,7 @@ How to create a package using setuptools that can be installed using pip. In `B-ASIC`: -``` +```bash python3 setup.py bdist_wheel ``` @@ -73,7 +73,7 @@ The output gets written to `B-ASIC/dist/b_asic-<version>-<python_tag>-<abi_tag>- In `B-ASIC`: -``` +```bash python3 setup.py sdist ``` @@ -83,7 +83,7 @@ The output gets written to `B-ASIC/dist/b-asic-<version>.tar.gz`. In `B-ASIC/dist`: -``` +```bash pip install b_asic-<version>-<python_tag>-<abi_tag>-<platform_tag>.whl ``` @@ -91,7 +91,7 @@ pip install b_asic-<version>-<python_tag>-<abi_tag>-<platform_tag>.whl In `B-ASIC/dist`: -``` +```bash pip install b-asic-<version>.tar.gz ``` @@ -103,7 +103,7 @@ How to run the tests using pytest in a virtual environment. In `B-ASIC`: -``` +```bash python3 -m venv env source env/bin/activate pip install . @@ -114,7 +114,7 @@ pytest In `B-ASIC` (as admin): -``` +```bash python3 -m venv env .\env\Scripts\activate.bat pip install . @@ -123,7 +123,7 @@ pytest #### Test with coverage -``` +```bash pytest --cov=b_asic --cov-report=html test ``` @@ -131,18 +131,20 @@ pytest --cov=b_asic --cov-report=html test In `B-ASIC`: -``` +```bash pytest # The image comparison tests will fail cp -a result_images/* test/baseline_images/ ``` ### Generating documentation -``` +```bash sphinx-build -b html docs_sphinx docs_sphinx/_build ``` + or in `B-ASIC/docs_sphinx`: -``` + +```bash make html ``` @@ -154,13 +156,13 @@ How to build and use the library as a user. ### Installation -``` +```bash pip install . ``` ### Importing -``` +```bash python3 >>> import b_asic as asic >>> help(asic) diff --git a/b_asic/GUI/arrow.py b/b_asic/GUI/arrow.py index 8cb05fec..e1b66d75 100644 --- a/b_asic/GUI/arrow.py +++ b/b_asic/GUI/arrow.py @@ -101,7 +101,7 @@ class Arrow(QGraphicsPathItem): return cast("OutputPort", self._source_port_button.port) @property - def desination_port(self) -> "InputPort": + def destination_port(self) -> "InputPort": """The destination InputPort.""" return cast("InputPort", self._destination_port_button.port) diff --git a/b_asic/GUI/gui_interface.py b/b_asic/GUI/gui_interface.py index 8c6fe601..748d7042 100644 --- a/b_asic/GUI/gui_interface.py +++ b/b_asic/GUI/gui_interface.py @@ -1,10 +1,9 @@ -# -*- coding: utf-8 -*- # Originally generated from QT designer, but now manually maintained from qtpy import QtCore, QtWidgets -class Ui_main_window(object): +class Ui_main_window: def setupUi(self, main_window): main_window.setObjectName("main_window") main_window.setEnabled(True) diff --git a/b_asic/GUI/main_window.py b/b_asic/GUI/main_window.py index 698621d4..b3ab5a76 100644 --- a/b_asic/GUI/main_window.py +++ b/b_asic/GUI/main_window.py @@ -4,7 +4,6 @@ B-ASIC Signal Flow Graph Editor Module. This file opens the main SFG editor window of the GUI for B-ASIC when run. """ - import importlib.util import logging import os @@ -814,8 +813,8 @@ class SFGMainWindow(QMainWindow): raise ValueError("Exactly one output port must be selected!") pressed_op_outport = pressed_op_outports[0] - for pressed_op_inport in pressed_op_inports: - self._connect_button(pressed_op_outport, pressed_op_inport) + for pressed_op_input_port in pressed_op_inports: + self._connect_button(pressed_op_outport, pressed_op_input_port) for port in self._pressed_ports: port.select_port() diff --git a/b_asic/architecture.py b/b_asic/architecture.py index c2943e6e..7e6ad322 100644 --- a/b_asic/architecture.py +++ b/b_asic/architecture.py @@ -1,6 +1,7 @@ """ B-ASIC architecture classes. """ + from collections import defaultdict from io import TextIOWrapper from itertools import chain @@ -588,13 +589,13 @@ of :class:`~b_asic.architecture.ProcessingElement` ) self._memories = [memories] if isinstance(memories, Memory) else list(memories) self._direct_interconnects = direct_interconnects - self._variable_inport_to_resource: DefaultDict[ + self._variable_input_port_to_resource: DefaultDict[ InputPort, Set[Tuple[Resource, int]] ] = defaultdict(set) self._variable_outport_to_resource: DefaultDict[ OutputPort, Set[Tuple[Resource, int]] ] = defaultdict(set) - self._operation_inport_to_resource: Dict[InputPort, Resource] = {} + self._operation_input_port_to_resource: Dict[InputPort, Resource] = {} self._operation_outport_to_resource: Dict[OutputPort, Resource] = {} self._schedule_time = self._check_and_get_schedule_time() @@ -617,25 +618,27 @@ of :class:`~b_asic.architecture.ProcessingElement` return schedule_times.pop() def _build_dicts(self) -> None: - self._variable_inport_to_resource: DefaultDict[ + self._variable_input_port_to_resource: DefaultDict[ InputPort, Set[Tuple[Resource, int]] ] = defaultdict(set) self._variable_outport_to_resource: DefaultDict[ OutputPort, Set[Tuple[Resource, int]] ] = defaultdict(set) - self._operation_inport_to_resource = {} + self._operation_input_port_to_resource = {} self._operation_outport_to_resource = {} for pe in self.processing_elements: for operator in pe.processes: for input_port in operator.operation.inputs: - self._operation_inport_to_resource[input_port] = pe + self._operation_input_port_to_resource[input_port] = pe for output_port in operator.operation.outputs: self._operation_outport_to_resource[output_port] = pe for memory in self.memories: for mv in memory: for read_port in mv.read_ports: - self._variable_inport_to_resource[read_port].add((memory, 0)) # Fix + self._variable_input_port_to_resource[read_port].add( + (memory, 0) + ) # Fix self._variable_outport_to_resource[mv.write_port].add( (memory, 0) ) # Fix @@ -643,7 +646,7 @@ of :class:`~b_asic.architecture.ProcessingElement` for di in self._direct_interconnects: di = cast(MemoryVariable, di) for read_port in di.read_ports: - self._variable_inport_to_resource[read_port].add( + self._variable_input_port_to_resource[read_port].add( ( self._operation_outport_to_resource[di.write_port], di.write_port.index, @@ -651,7 +654,7 @@ of :class:`~b_asic.architecture.ProcessingElement` ) self._variable_outport_to_resource[di.write_port].add( ( - self._operation_inport_to_resource[read_port], + self._operation_input_port_to_resource[read_port], read_port.index, ) ) @@ -718,7 +721,7 @@ of :class:`~b_asic.architecture.ProcessingElement` var = cast(MemoryVariable, var) d_in[self._operation_outport_to_resource[var.write_port]] += 1 for read_port in var.read_ports: - d_out[self._operation_inport_to_resource[read_port]] += 1 + d_out[self._operation_input_port_to_resource[read_port]] += 1 return dict(d_in), dict(d_out) def get_interconnects_for_pe( @@ -739,7 +742,7 @@ of :class:`~b_asic.architecture.ProcessingElement` Returns ------- list - List of dictionaries indicating the sources for each inport and the + List of dictionaries indicating the sources for each import and the frequency of accesses. list List of dictionaries indicating the sources for each outport and the @@ -757,7 +760,7 @@ of :class:`~b_asic.architecture.ProcessingElement` for var in pe.collection: var = cast(OperatorProcess, var) for i, input_ in enumerate(var.operation.inputs): - for v in self._variable_inport_to_resource[input_]: + for v in self._variable_input_port_to_resource[input_]: d_in[i][v] += 1 for i, output in enumerate(var.operation.outputs): for v in self._variable_outport_to_resource[output]: diff --git a/b_asic/codegen/vhdl/architecture.py b/b_asic/codegen/vhdl/architecture.py index 880b8b01..4b708f08 100644 --- a/b_asic/codegen/vhdl/architecture.py +++ b/b_asic/codegen/vhdl/architecture.py @@ -1,6 +1,7 @@ """ Module for code generation of VHDL architectures. """ + from math import ceil, log2 from typing import TYPE_CHECKING, Dict, List, Optional, Set, TextIO, Tuple, cast @@ -320,7 +321,7 @@ def memory_based_storage( for mv in collection: mv = cast(MemoryVariable, mv) if mv.start_time >= schedule_time: - raise ValueError('start_time greater than scheudle_time') + raise ValueError('start_time greater than schedule_time') if mv.execution_time: write_list[mv.start_time] = (i, mv) diff --git a/b_asic/codegen/vhdl/common.py b/b_asic/codegen/vhdl/common.py index a090e2f9..7baeedf3 100644 --- a/b_asic/codegen/vhdl/common.py +++ b/b_asic/codegen/vhdl/common.py @@ -162,7 +162,7 @@ def constant_declaration( Signal name. signal_type : str Signal type. - value : anything convertable to str + value : anything convertible to str Default value to the signal. name_pad : int, optional An optional left padding value applied to the name. diff --git a/b_asic/operation.py b/b_asic/operation.py index 28502c08..3598eb2d 100644 --- a/b_asic/operation.py +++ b/b_asic/operation.py @@ -552,12 +552,12 @@ class AbstractOperation(Operation, AbstractGraphComponent): def __str__(self) -> str: """Get a string representation of this operation.""" inputs_dict: Dict[int, Union[List[GraphID], str]] = {} - for i, inport in enumerate(self.inputs): - if inport.signal_count == 0: + for i, current_input in enumerate(self.inputs): + if current_input.signal_count == 0: inputs_dict[i] = "-" break dict_ele = [] - for signal in inport.signals: + for signal in current_input.signals: if signal.source: if signal.source_operation.graph_id: dict_ele.append(signal.source_operation.graph_id) @@ -919,8 +919,8 @@ class AbstractOperation(Operation, AbstractGraphComponent): def set_latency(self, latency: int) -> None: if latency < 0: raise ValueError("Latency cannot be negative") - for inport in self.inputs: - inport.latency_offset = 0 + for current_input in self.inputs: + current_input.latency_offset = 0 for outport in self.outputs: outport.latency_offset = latency diff --git a/b_asic/resources.py b/b_asic/resources.py index b3f97bdb..bda63612 100644 --- a/b_asic/resources.py +++ b/b_asic/resources.py @@ -963,10 +963,10 @@ class ProcessCollection: Split this collection into multiple new collections by sequentially assigning processes in the order of `sequence`. - This method takes the processes from `sequence`, in order, and assignes them to + This method takes the processes from `sequence`, in order, and assigns them to to multiple new `ProcessCollection` based on port collisions in a first-come first-served manner. The first `Process` in `sequence` is assigned first, and - the last `Proccess` in `sequence is assigned last. + the last `Process` in `sequence is assigned last. Parameters ---------- @@ -1369,7 +1369,7 @@ class ProcessCollection: raise ValueError('input_sync needs to be set to use address pipelining') if not log2(adr_mux_size).is_integer(): raise ValueError( - f'adr_mux_size={adr_mux_size} needs to be interger power of two' + f'adr_mux_size={adr_mux_size} needs to be integer power of two' ) if adr_mux_size**adr_pipe_depth > assignment[0].schedule_time: raise ValueError( diff --git a/b_asic/schedule.py b/b_asic/schedule.py index b342c022..2e846960 100644 --- a/b_asic/schedule.py +++ b/b_asic/schedule.py @@ -178,7 +178,7 @@ class Schedule: Returns ------- int - The number of time steps the operation with *graph_id* can ba moved + The number of time steps the operation with *graph_id* can be moved forward in time. See Also @@ -243,7 +243,7 @@ class Schedule: Returns ------- int - The number of time steps the operation with *graph_id* can ba moved + The number of time steps the operation with *graph_id* can be moved backward in time. .. note:: The backward slack is positive, but a call to :func:`move_operation` should be negative to move the operation @@ -723,7 +723,7 @@ class Schedule: schedule.move_operation(graph_id, -schedule.backward_slack(graph_id)) - but operations that do not have a preceeding operation (Inputs and Constants) + but operations that do not have a preceding operation (Inputs and Constants) will only move to the start of the schedule. Parameters @@ -825,16 +825,16 @@ class Schedule: if operation.graph_id not in self._start_times: # Schedule the operation if it does not have a start time yet. op_start_time = 0 - for inport in operation.inputs: - if len(inport.signals) != 1: + for current_input in operation.inputs: + if len(current_input.signals) != 1: raise ValueError( "Error in scheduling, dangling input port detected." ) - if inport.signals[0].source is None: + if current_input.signals[0].source is None: raise ValueError( "Error in scheduling, signal with no source detected." ) - source_port = inport.signals[0].source + source_port = current_input.signals[0].source if source_port.operation.graph_id in non_schedulable_ops: source_end_time = 0 @@ -855,13 +855,15 @@ class Schedule: source_op_time + source_port.latency_offset ) - if inport.latency_offset is None: + if current_input.latency_offset is None: raise ValueError( - f"Input port {inport.index} of operation" - f" {inport.operation.graph_id} has no" + f"Input port {current_input.index} of operation" + f" {current_input.operation.graph_id} has no" " latency-offset." ) - op_start_time_from_in = source_end_time - inport.latency_offset + op_start_time_from_in = ( + source_end_time - current_input.latency_offset + ) op_start_time = max(op_start_time, op_start_time_from_in) self._start_times[operation.graph_id] = op_start_time diff --git a/b_asic/scheduler_gui/logger.py b/b_asic/scheduler_gui/logger.py index d4c55287..e6615ed0 100644 --- a/b_asic/scheduler_gui/logger.py +++ b/b_asic/scheduler_gui/logger.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- """ B-ASIC Scheduler-gui Logger Module. diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py index f33f36bd..3be91ad3 100644 --- a/b_asic/signal_flow_graph.py +++ b/b_asic/signal_flow_graph.py @@ -1224,12 +1224,12 @@ class SFG(AbstractOperation): for outport in curr_iter_ports: for signal in outport.signals: - new_inport = signal.destination + new_input_port = signal.destination # Do not traverse over delays. - if new_inport is not None and not isinstance( - new_inport.operation, Delay + if new_input_port is not None and not isinstance( + new_input_port.operation, Delay ): - new_op = new_inport.operation + new_op = new_input_port.operation remaining_inports_per_operation[new_op] -= 1 if remaining_inports_per_operation[new_op] == 0: next_iter_ports.extend(new_op.outputs) diff --git a/examples/firstorderiirfilter.py b/examples/firstorderiirfilter.py index 3a2ed744..3d27a0cd 100644 --- a/examples/firstorderiirfilter.py +++ b/examples/firstorderiirfilter.py @@ -7,6 +7,7 @@ In this example, a direct form first-order IIR filter is designed. First, we need to import the operations that will be used in the example: """ + from b_asic.core_operations import ConstantMultiplication from b_asic.special_operations import Delay, Input, Output @@ -127,7 +128,7 @@ firstorderiir.print_precedence_graph() # add1 -> "add1.0" # add1 [label=add1 shape=ellipse] # } -# +# # As seen, each operation has an id, in addition to the optional name. # This can be used to access the operation. For example, firstorderiir.find_by_id('cmul0') diff --git a/examples/twotapfirsfg.py b/examples/twotapfirsfg.py index 3d8b6b7e..a287f6ac 100644 --- a/examples/twotapfirsfg.py +++ b/examples/twotapfirsfg.py @@ -3,15 +3,8 @@ Two-tap FIR filter ================== """ -from b_asic import ( - SFG, - Addition, - ConstantMultiplication, - Delay, - Input, - Output, - Signal, -) + +from b_asic import SFG, Addition, ConstantMultiplication, Delay, Input, Output, Signal # Inputs: in0 = Input(name="in_0") @@ -24,9 +17,7 @@ t0 = Delay(initial_value=0, name="t0") cmul0 = ConstantMultiplication( value=0.5, name="cmul0", latency_offsets={'in0': None, 'out0': None} ) -add0 = Addition( - name="add0", latency_offsets={'in0': None, 'in1': None, 'out0': None} -) +add0 = Addition(name="add0", latency_offsets={'in0': None, 'in1': None, 'out0': None}) cmul1 = ConstantMultiplication( value=0.5, name="cmul1", latency_offsets={'in0': None, 'out0': None} ) diff --git a/legacy/README.md b/legacy/README.md index a450266c..7a8b933a 100644 --- a/legacy/README.md +++ b/legacy/README.md @@ -1,7 +1,7 @@ # Legacy files -This folder contains currently unused code that is kept for acedemic purposes, -or to be used as a refererence for future development. +This folder contains currently unused code that is kept for academic purposes, +or to be used as a reference for future development. ## simulation_oop diff --git a/legacy/simulation_oop/operation.cpp b/legacy/simulation_oop/operation.cpp index 8ba04954..a76eae2e 100644 --- a/legacy/simulation_oop/operation.cpp +++ b/legacy/simulation_oop/operation.cpp @@ -64,7 +64,7 @@ number abstract_operation::quantize_input(std::size_t index, number value, std:: } if (bits > 64) { throw py::value_error{ - fmt::format("Cannot quantize to {} (more than 64) bits as requested by the singal connected to input #{}", bits, index)}; + fmt::format("Cannot quantize to {} (more than 64) bits as requested by the signal connected to input #{}", bits, index)}; } return number{static_cast<number::value_type>(static_cast<std::int64_t>(value.real()) & ((std::int64_t{1} << bits) - 1))}; } diff --git a/pyproject.toml b/pyproject.toml index 95d5929d..558e8e9f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,7 +59,7 @@ documentation = "https://da.gitlab-pages.liu.se/B-ASIC/" skip-string-normalization = true preview = true line-length = 88 -exclude = ["test/test_gui", "b_asic/scheduler_gui/ui_main_window.py"] +exclude = "(test/test_gui/*|b_asic/scheduler_gui/ui_main_window.py)" [tool.isort] profile = "black" @@ -77,3 +77,6 @@ precision = 2 [tool.ruff] ignore = ["F403"] + +[tool.typos] +default.extend-identifiers = { addd0 = "addd0", inout = "inout", ArChItEctUrE = "ArChItEctUrE" } diff --git a/test/test_codegen.py b/test/test_codegen.py index b52be275..6a404db1 100644 --- a/test/test_codegen.py +++ b/test/test_codegen.py @@ -20,7 +20,6 @@ def test_is_valid_vhdl_identifier(): "architecture", "Architecture", "ArChItEctUrE", - "architectURE", "entity", "invalid+", "invalid}", diff --git a/test/test_core_operations.py b/test/test_core_operations.py index 002e38c9..f9d13fd6 100644 --- a/test/test_core_operations.py +++ b/test/test_core_operations.py @@ -1,7 +1,9 @@ """B-ASIC test suite for the core operations.""" + import pytest from b_asic import ( + SFG, Absolute, Addition, AddSub, @@ -17,11 +19,10 @@ from b_asic import ( Reciprocal, RightShift, Shift, + Sink, SquareRoot, Subtraction, SymmetricTwoportAdaptor, - Sink, - SFG, ) @@ -407,6 +408,7 @@ class TestDepends: assert set(bfly1.inputs_required_for_output(0)) == {0, 1} assert set(bfly1.inputs_required_for_output(1)) == {0, 1} + class TestSink: def test_create_sfg_with_sink(self): bfly = Butterfly() @@ -418,4 +420,4 @@ class TestSink: assert sfg2.output_count == 1 assert sfg2.input_count == 2 - assert sfg.evaluate_output(1, [0,1]) == sfg2.evaluate_output(0, [0,1]) + assert sfg.evaluate_output(1, [0, 1]) == sfg2.evaluate_output(0, [0, 1]) diff --git a/test/test_resources.py b/test/test_resources.py index 59ba4959..a8aafc3a 100644 --- a/test/test_resources.py +++ b/test/test_resources.py @@ -212,7 +212,7 @@ class TestProcessCollectionPlainMemoryVariable: fig, ax = plt.subplots() collection = ProcessCollection( { - # Process starting exactly at scheudle start + # Process starting exactly at schedule start PlainMemoryVariable(0, 0, {0: 0}, "S1"), PlainMemoryVariable(0, 0, {0: 5}, "S2"), # Process starting somewhere between schedule start and end diff --git a/test/test_schedule.py b/test/test_schedule.py index d9e4fe17..c307798a 100644 --- a/test/test_schedule.py +++ b/test/test_schedule.py @@ -1,17 +1,18 @@ """ B-ASIC test suite for the schedule module and Schedule class. """ + import re -import pytest import matplotlib.testing.decorators +import pytest from b_asic.core_operations import Addition, Butterfly, ConstantMultiplication from b_asic.process import OperatorProcess from b_asic.schedule import Schedule +from b_asic.sfg_generators import direct_form_fir from b_asic.signal_flow_graph import SFG from b_asic.special_operations import Delay, Input, Output -from b_asic.sfg_generators import direct_form_fir class TestInit: @@ -293,7 +294,9 @@ class TestSlacks: schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") schedule.print_slacks() captured = capsys.readouterr() - assert captured.out == """Graph ID | Backward | Forward + assert ( + captured.out + == """Graph ID | Backward | Forward ---------|----------|--------- add0 | 0 | 0 add1 | 0 | 0 @@ -309,6 +312,7 @@ cmul6 | 4 | 0 in0 | oo | 0 out0 | 0 | oo """ + ) assert captured.err == "" def test_print_slacks_sorting(self, capsys, precedence_sfg_delays): @@ -318,7 +322,9 @@ out0 | 0 | oo schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") schedule.print_slacks(1) captured = capsys.readouterr() - assert captured.out == """Graph ID | Backward | Forward + assert ( + captured.out + == """Graph ID | Backward | Forward ---------|----------|--------- cmul0 | 0 | 1 add0 | 0 | 0 @@ -334,6 +340,7 @@ cmul4 | 16 | 0 cmul5 | 16 | 0 in0 | oo | 0 """ + ) assert captured.err == "" def test_slacks_errors(self, precedence_sfg_delays): @@ -521,11 +528,15 @@ class TestRescheduling: assert schedule._start_times["add0"] == 0 assert schedule._start_times["out0"] == 2 - def test_reintroduce_delays(self, precedence_sfg_delays, sfg_direct_form_iir_lp_filter): + def test_reintroduce_delays( + self, precedence_sfg_delays, sfg_direct_form_iir_lp_filter + ): precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 1) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) sfg_direct_form_iir_lp_filter.set_latency_of_type(Addition.type_name(), 1) - sfg_direct_form_iir_lp_filter.set_latency_of_type(ConstantMultiplication.type_name(), 3) + sfg_direct_form_iir_lp_filter.set_latency_of_type( + ConstantMultiplication.type_name(), 3 + ) schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") sfg = schedule.sfg @@ -536,20 +547,15 @@ class TestRescheduling: assert sfg_direct_form_iir_lp_filter.evaluate(5) == sfg.evaluate(5) fir_sfg = direct_form_fir( - list(range(1, 10)), - mult_properties={ - 'latency': 2, - 'execution_time': 1 - }, - add_properties={ - 'latency': 2, - 'execution_time': 1 - } - ) + list(range(1, 10)), + mult_properties={'latency': 2, 'execution_time': 1}, + add_properties={'latency': 2, 'execution_time': 1}, + ) schedule = Schedule(fir_sfg, algorithm="ASAP") sfg = schedule.sfg assert fir_sfg.evaluate(5) == sfg.evaluate(5) + class TestTimeResolution: def test_increase_time_resolution( self, sfg_two_inputs_two_outputs_independent_with_cmul @@ -694,7 +700,9 @@ class TestProcesses: class TestFigureGeneration: - @matplotlib.testing.decorators.image_comparison(['test__get_figure_no_execution_times.png'], remove_text=True) + @matplotlib.testing.decorators.image_comparison( + ['test__get_figure_no_execution_times.png'], remove_text=True + ) def test__get_figure_no_execution_times(self, secondorder_iir_schedule): return secondorder_iir_schedule._get_figure() diff --git a/test/test_sfg.py b/test/test_sfg.py index da60341d..44cba824 100644 --- a/test/test_sfg.py +++ b/test/test_sfg.py @@ -22,10 +22,10 @@ from b_asic.core_operations import ( ) from b_asic.operation import ResultKey from b_asic.save_load_structure import python_to_sfg, sfg_to_python +from b_asic.sfg_generators import wdf_allpass from b_asic.signal_flow_graph import SFG, GraphID from b_asic.simulation import Simulation from b_asic.special_operations import Delay -from b_asic.sfg_generators import wdf_allpass class TestInit: @@ -816,7 +816,7 @@ class TestConnectExternalSignalsToComponentsSoloComp: assert not test_sfg.connect_external_signals_to_components() def test_connect_external_signals_to_components_multiple_operations_after_input( - self + self, ): """ Replaces an SFG with a symmetric two-port adaptor to test when the input @@ -830,6 +830,7 @@ class TestConnectExternalSignalsToComponentsSoloComp: assert test_sfg.evaluate(1) == -0.5 assert not test_sfg.connect_external_signals_to_components() + class TestConnectExternalSignalsToComponentsMultipleComp: def test_connect_external_signals_to_components_operation_tree( self, operation_tree @@ -1176,7 +1177,7 @@ class TestGetComponentsOfType: ) ] == [] - def test_get_multple_operations_of_type(self, sfg_two_inputs_two_outputs): + def test_get_multiple_operations_of_type(self, sfg_two_inputs_two_outputs): assert [ op.name for op in sfg_two_inputs_two_outputs.find_by_type_name(Addition.type_name()) @@ -1480,9 +1481,7 @@ class TestUnfold: ): self.do_tests(sfg_two_inputs_two_outputs_independent) - def test_threetapiir( - self, sfg_direct_form_iir_lp_filter: SFG - ): + def test_threetapiir(self, sfg_direct_form_iir_lp_filter: SFG): self.do_tests(sfg_direct_form_iir_lp_filter) def do_tests(self, sfg: SFG): @@ -1527,7 +1526,7 @@ class TestUnfold: ref_values = list(ref[ResultKey(f"{n}")]) # Output n will be split into `factor` output ports, compute the - # indicies where we find the outputs + # indices where we find the outputs out_indices = [n + k * len(sfg.outputs) for k in range(factor)] u_values = [ [unfolded_results[ResultKey(f"{idx}")][k] for idx in out_indices] @@ -1635,6 +1634,7 @@ class TestInsertComponentAfter: with pytest.raises(ValueError, match="Unknown component:"): sfg.insert_operation_after('foo', SquareRoot()) + class TestInsertComponentBefore: def test_insert_component_before_in_sfg(self, butterfly_operation_tree): sfg = SFG(outputs=list(map(Output, butterfly_operation_tree.outputs))) @@ -1653,22 +1653,22 @@ class TestInsertComponentBefore: SquareRoot, ) assert isinstance( - _sfg.find_by_name("bfly1")[0] - .input(0) - .signals[0] - .source.operation, + _sfg.find_by_name("bfly1")[0].input(0).signals[0].source.operation, SquareRoot, ) - assert sfg.find_by_name("bfly1")[0].input(0).signals[ - 0 - ].source.operation is sfg.find_by_name("bfly2")[0] - assert _sfg.find_by_name("bfly1")[0].input(0).signals[ - 0 - ].destination.operation is not _sfg.find_by_name("bfly2")[0] - assert _sfg.find_by_id("sqrt0").input(0).signals[ - 0 - ].source.operation is _sfg.find_by_name("bfly2")[0] + assert ( + sfg.find_by_name("bfly1")[0].input(0).signals[0].source.operation + is sfg.find_by_name("bfly2")[0] + ) + assert ( + _sfg.find_by_name("bfly1")[0].input(0).signals[0].destination.operation + is not _sfg.find_by_name("bfly2")[0] + ) + assert ( + _sfg.find_by_id("sqrt0").input(0).signals[0].source.operation + is _sfg.find_by_name("bfly2")[0] + ) def test_insert_component_before_mimo_operation_error( self, large_operation_tree_names -- GitLab