From 169a2bbe7bb0a19146ba6a0d65b55373180ac9df Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson <rasmus@rasmus.local> Date: Sat, 25 Apr 2020 16:17:44 +0200 Subject: [PATCH] Wrote hella lot of tests --- b_asic/signal_flow_graph.py | 4 +- test/test_signal_flow_graph.py | 195 ++++++++++++++++++++++++++++++++- 2 files changed, 196 insertions(+), 3 deletions(-) diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py index 50045763..2aeb13aa 100644 --- a/b_asic/signal_flow_graph.py +++ b/b_asic/signal_flow_graph.py @@ -242,14 +242,14 @@ class SFG(AbstractOperation): return ops # Need any checking before returning? - def replace_self(self): + def replace_self(self) -> None: """ Iterates over the SFG's (self) Input- and OutputSignals to reconnect them to each necessary operation inside the SFG, so that the inner operations of the SFG can function on their own, effectively replacing the SFG. """ assert len(self.inputs) == len(self.input_operations), "Number of inputs does not match the number of input_operations in SFG." assert len(self.outputs) == len(self.output_operations), "Number of outputs does not match the number of output_operations SFG." - # Add check so it does not Split the SFG if not a component of a larger SFG + # Does this function need a check for if the user wants call this on an SFG which is not a component of another SFG # For each input_signal, connect it to the corresponding operation for port, input_operation in zip(self.inputs, self.input_operations): diff --git a/test/test_signal_flow_graph.py b/test/test_signal_flow_graph.py index 51267cc4..e6863929 100644 --- a/test/test_signal_flow_graph.py +++ b/test/test_signal_flow_graph.py @@ -1,6 +1,6 @@ import pytest -from b_asic import SFG, Signal, Input, Output, Constant, Addition, Multiplication +from b_asic import SFG, Signal, Input, Output, Constant, Addition, Multiplication, Subtraction class TestConstructor: @@ -147,3 +147,196 @@ class TestComponents: mac_sfg = SFG(inputs = [inp1, inp2], outputs = [out1], name = "mac_sfg") assert set([comp.name for comp in mac_sfg.components]) == {"INP1", "INP2", "INP3", "ADD1", "ADD2", "MUL1", "OUT1", "S1", "S2", "S3", "S4", "S5", "S6", "S7"} + + +class TestReplaceSelfSoloComp: + + def test_replace_self_mac(self): + """ Replace a MAC with inner components in an SFG """ + + inp1 = Input("INP1") + inp2 = Input("INP2") + inp3 = Input("INP3") + add1 = Addition(None, None, "ADD1") + add2 = Addition(None, None, "ADD2") + mul1 = Multiplication(None, None, "MUL1") + out1 = Output(None, "OUT1") + + add1.input(0).connect(inp1, "S1") + add1.input(1).connect(inp2, "S2") + add2.input(0).connect(add1, "S3") + add2.input(1).connect(inp3, "S4") + mul1.input(0).connect(add1, "S5") + mul1.input(1).connect(add2, "S6") + out1.input(0).connect(mul1, "S7") + + mac_sfg = SFG(inputs = [inp1, inp2], outputs = [out1]) + + inp4 = Input("INP4") + inp5 = Input("INP5") + out2 = Output(None, "OUT2") + + mac_sfg.inputs[0].connect(inp4, "S8") + mac_sfg.inputs[1].connect(inp5, "S9") + out2.input(0).connect(mac_sfg.outputs[0], "S10") + + test_sfg = SFG(inputs = [inp4, inp5], outputs = [out2]) + + assert test_sfg.evaluate(1,2) == 9 + + mac_sfg.replace_self() + + assert test_sfg.evaluate(1,2) == 9 + + def test_replace_self_operation_tree(self, operation_tree): + """ Replaces an SFG with only a operation_tree component with its inner components """ + + sfg1 = SFG(outputs = [Output(operation_tree)]) + + out1 = Output(None, "OUT1") + + out1.input(0).connect(sfg1.outputs[0], "S1") + + test_sfg = SFG(outputs = [out1]) + + assert test_sfg.evaluate_output(0, []) == 5 + + sfg1.replace_self() + + assert test_sfg.evaluate_output(0, []) == 5 + + def test_replace_self_large_operation_tree(self, large_operation_tree): + """ Replaces an SFG with only a large_operation_tree component with its inner components """ + + sfg1 = SFG(outputs = [Output(large_operation_tree)]) + + out1 = Output(None, "OUT1") + + out1.input(0).connect(sfg1.outputs[0], "S1") + + test_sfg = SFG(outputs = [out1]) + + assert test_sfg.evaluate_output(0, []) == 14 + + sfg1.replace_self() + + assert test_sfg.evaluate_output(0, []) == 14 + +class TestReplaceSelfMultipleComp: + + + + def test_replace_self_operation_tree(self, operation_tree): + """ Replaces a operation_tree in an SFG with other components """ + sfg1 = SFG(outputs = [Output(operation_tree)]) + + inp1 = Input("INP1") + inp2 = Input("INP2") + out1 = Output(None, "OUT1") + + add1 = Addition(None, None, "ADD1") + add2 = Addition(None, None, "ADD2") + + add1.input(0).connect(inp1, "S1") + add1.input(1).connect(inp2, "S2") + + add2.input(0).connect(add1, "S3") + add2.input(1).connect(sfg1.outputs[0], "S4") + + out1.input(0).connect(add2, "S5") + + test_sfg = SFG(inputs = [inp1, inp2], outputs = [out1]) + + assert test_sfg.evaluate(1, 2) == 8 + + sfg1.replace_self() + + assert test_sfg.evaluate(1, 2) == 8 + + def test_replace_self_large_operation_tree(self, large_operation_tree): + """ Replaces a large_operation_tree in an SFG with other components """ + sfg1 = SFG(outputs = [Output(large_operation_tree)]) + + inp1 = Input("INP1") + inp2 = Input("INP2") + out1 = Output(None, "OUT1") + + add1 = Addition(None, None, "ADD1") + add2 = Addition(None, None, "ADD2") + + add1.input(0).connect(inp1, "S1") + add1.input(1).connect(inp2, "S2") + + add2.input(0).connect(add1, "S3") + add2.input(1).connect(sfg1.outputs[0], "S4") + + out1.input(0).connect(add2, "S5") + + test_sfg = SFG(inputs = [inp1, inp2], outputs = [out1]) + + assert test_sfg.evaluate(1, 2) == 17 + + sfg1.replace_self() + + assert test_sfg.evaluate(1, 2) == 17 + + def create_sfg(self, op_tree): + """ Create a simple SFG with either operation_tree or large_operation_tree """ + + sfg1 = SFG(outputs = [Output(op_tree)]) + + inp1 = Input("INP1") + inp2 = Input("INP2") + out1 = Output(None, "OUT1") + + add1 = Addition(None, None, "ADD1") + add2 = Addition(None, None, "ADD2") + + add1.input(0).connect(inp1, "S1") + add1.input(1).connect(inp2, "S2") + + add2.input(0).connect(add1, "S3") + add2.input(1).connect(sfg1.outputs[0], "S4") + + out1.input(0).connect(add2, "S5") + + return SFG(inputs = [inp1, inp2], outputs = [out1]) + + def test_replace_self_many_op(self, large_operation_tree): + """ Replaces an sfg component in a larger SFG with several component operations """ + + inp1 = Input("INP1") + inp2 = Input("INP2") + inp3 = Input("INP3") + inp4 = Input("INP4") + out1 = Output(None, "OUT1") + + add1 = Addition(None, None, "ADD1") + sub1 = Subtraction(None, None, "SUB1") + + + add1.input(0).connect(inp1, "S1") + add1.input(1).connect(inp2, "S2") + + sfg1 = self.create_sfg(large_operation_tree) + + sfg1.inputs[0].connect(add1, "S3") + sfg1.inputs[1].connect(inp3, "S4") + + sub1.input(0).connect(sfg1.outputs[0], "S5") + + sub1.input(1).connect(inp4, "S6") + + out1.input(0).connect(sub1, "S7") + + test_sfg = SFG(inputs = [inp1, inp2, inp3, inp4], outputs = [out1]) + + assert test_sfg.evaluate(1, 2, 3, 4) == 16 + + sfg1.replace_self() + + assert test_sfg.evaluate(1, 2, 3, 4) == 16 + + + + -- GitLab