From 3b2d67c2082088c990f43a5adbaf0c657cfd8a92 Mon Sep 17 00:00:00 2001 From: Simon Bjurek <simbj106@student.liu.se> Date: Wed, 29 Jan 2025 09:18:50 +0100 Subject: [PATCH] tests now working --- b_asic/schedule.py | 11 ++--- b_asic/signal_flow_graph.py | 3 +- test/fixtures/schedule.py | 9 ++-- test/test_architecture.py | 3 +- test/test_schedule.py | 83 +++++++++++++++++++------------------ test/test_scheduler_gui.py | 3 +- 6 files changed, 58 insertions(+), 54 deletions(-) diff --git a/b_asic/schedule.py b/b_asic/schedule.py index d1c63041..acb6572b 100644 --- a/b_asic/schedule.py +++ b/b_asic/schedule.py @@ -64,24 +64,19 @@ class Schedule: ---------- sfg : :class:`~b_asic.signal_flow_graph.SFG` The signal flow graph to schedule. + scheduler : Scheduler, default: None + The automatic scheduler to be used. schedule_time : int, optional The schedule time. If not provided, it will be determined by the scheduling algorithm. cyclic : bool, default: False If the schedule is cyclic. - algorithm : SchedulingAlgorithm, default: 'ASAP' - The scheduling algorithm to use. start_times : dict, optional Dictionary with GraphIDs as keys and start times as values. Used when *algorithm* is 'provided'. laps : dict, optional Dictionary with GraphIDs as keys and laps as values. Used when *algorithm* is 'provided'. - max_resources : dict, optional - Dictionary like ``{Addition.type_name(): 2}`` denoting the maximum number of - resources for a given operation type if the scheduling algorithm considers - that. If not provided, or an operation type is not provided, at most one - resource is used. """ _sfg: SFG @@ -113,7 +108,7 @@ class Schedule: if scheduler: self._scheduler = scheduler - scheduler.apply_scheduling(self) + self._scheduler.apply_scheduling(self) else: if start_times is None: raise ValueError("Must provide start_times when using 'provided'") diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py index d3600a68..c1ff7ee6 100644 --- a/b_asic/signal_flow_graph.py +++ b/b_asic/signal_flow_graph.py @@ -38,6 +38,7 @@ from b_asic.operation import ( ResultKey, ) from b_asic.port import InputPort, OutputPort, SignalSourceProvider +from b_asic.scheduler import ASAPScheduler from b_asic.signal import Signal from b_asic.special_operations import Delay, Input, Output from b_asic.types import GraphID, GraphIDNumber, Name, Num, TypeName @@ -1709,7 +1710,7 @@ class SFG(AbstractOperation): # Import here needed to avoid circular imports from b_asic.schedule import Schedule - return Schedule(self, algorithm="ASAP").schedule_time + return Schedule(self, ASAPScheduler()).schedule_time def _dfs(self, graph, start, end): """ diff --git a/test/fixtures/schedule.py b/test/fixtures/schedule.py index e11b95c9..39b375ed 100644 --- a/test/fixtures/schedule.py +++ b/test/fixtures/schedule.py @@ -2,6 +2,7 @@ import pytest from b_asic.core_operations import Addition, ConstantMultiplication from b_asic.schedule import Schedule +from b_asic.scheduler import ASAPScheduler from b_asic.signal_flow_graph import SFG @@ -10,7 +11,7 @@ def secondorder_iir_schedule(precedence_sfg_delays): precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 4) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) return schedule @@ -23,7 +24,7 @@ def secondorder_iir_schedule_with_execution_times(precedence_sfg_delays): ConstantMultiplication.type_name(), 1 ) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) return schedule @@ -37,7 +38,9 @@ def schedule_direct_form_iir_lp_filter(sfg_direct_form_iir_lp_filter: SFG): sfg_direct_form_iir_lp_filter.set_execution_time_of_type( ConstantMultiplication.type_name(), 1 ) - schedule = Schedule(sfg_direct_form_iir_lp_filter, algorithm="ASAP", cyclic=True) + schedule = Schedule( + sfg_direct_form_iir_lp_filter, scheduler=ASAPScheduler(), cyclic=True + ) schedule.move_operation('cmul3', -1) schedule.move_operation('cmul2', -1) schedule.move_operation('cmul3', -10) diff --git a/test/test_architecture.py b/test/test_architecture.py index 2dac82ff..2ab9c539 100644 --- a/test/test_architecture.py +++ b/test/test_architecture.py @@ -9,6 +9,7 @@ from b_asic.core_operations import Addition, ConstantMultiplication from b_asic.process import PlainMemoryVariable from b_asic.resources import ProcessCollection from b_asic.schedule import Schedule +from b_asic.scheduler import ASAPScheduler from b_asic.special_operations import Input, Output @@ -253,7 +254,7 @@ def test_resource_errors(precedence_sfg_delays): ConstantMultiplication.type_name(), 1 ) - schedule = Schedule(precedence_sfg_delays) + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) operations = schedule.get_operations() additions = operations.get_by_type_name(Addition.type_name()) with pytest.raises( diff --git a/test/test_schedule.py b/test/test_schedule.py index c307798a..bbd98c36 100644 --- a/test/test_schedule.py +++ b/test/test_schedule.py @@ -10,6 +10,7 @@ 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.scheduler import ALAPScheduler, ASAPScheduler 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 @@ -20,7 +21,7 @@ class TestInit: sfg_simple_filter.set_latency_of_type(Addition.type_name(), 5) sfg_simple_filter.set_latency_of_type(ConstantMultiplication.type_name(), 4) - schedule = Schedule(sfg_simple_filter) + schedule = Schedule(sfg_simple_filter, scheduler=ASAPScheduler()) assert schedule._start_times == { "in0": 0, @@ -39,7 +40,7 @@ class TestInit: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 4) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) start_times_names = {} for op_id, start_time in schedule._start_times.items(): @@ -69,7 +70,7 @@ class TestInit: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 4) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ALAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ALAPScheduler()) start_times_names = {} for op_id in schedule.start_times: @@ -99,7 +100,9 @@ class TestInit: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 4) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, schedule_time=25, algorithm="ALAP") + schedule = Schedule( + precedence_sfg_delays, schedule_time=25, scheduler=ALAPScheduler() + ) start_times_names = {} for op_id in schedule.start_times: @@ -129,7 +132,7 @@ class TestInit: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 4) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) with pytest.raises(ValueError, match="Too short schedule time. Minimum is 21."): - Schedule(precedence_sfg_delays, schedule_time=19, algorithm="ALAP") + Schedule(precedence_sfg_delays, schedule_time=19, scheduler=ALAPScheduler()) def test_complicated_single_outputs_normal_latency_from_fixture( self, secondorder_iir_schedule @@ -193,7 +196,7 @@ class TestInit: {"in0": 6, "in1": 7, "out0": 9} ) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) start_times_names = {} for op_id, start_time in schedule._start_times.items(): @@ -221,7 +224,7 @@ class TestInit: def test_independent_sfg(self, sfg_two_inputs_two_outputs_independent_with_cmul): schedule = Schedule( sfg_two_inputs_two_outputs_independent_with_cmul, - algorithm="ASAP", + scheduler=ASAPScheduler(), ) start_times_names = {} @@ -250,7 +253,7 @@ class TestSlacks: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 1) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) assert ( schedule.forward_slack( precedence_sfg_delays.find_by_name("ADD3")[0].graph_id @@ -279,7 +282,7 @@ class TestSlacks: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 1) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) assert schedule.slacks( precedence_sfg_delays.find_by_name("ADD3")[0].graph_id ) == (0, 7) @@ -291,7 +294,7 @@ class TestSlacks: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 1) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) schedule.print_slacks() captured = capsys.readouterr() assert ( @@ -319,7 +322,7 @@ out0 | 0 | oo precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 1) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) schedule.print_slacks(1) captured = capsys.readouterr() assert ( @@ -347,7 +350,7 @@ in0 | oo | 0 precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 1) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) with pytest.raises( ValueError, match="No operation with graph_id 'foo' in schedule" ): @@ -367,7 +370,7 @@ class TestRescheduling: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 4) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) schedule.move_operation( precedence_sfg_delays.find_by_name("ADD3")[0].graph_id, 4 @@ -404,7 +407,7 @@ class TestRescheduling: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 1) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) add3_id = precedence_sfg_delays.find_by_name("ADD3")[0].graph_id schedule.move_operation(add3_id, 4) assert schedule.forward_slack(add3_id) == 3 @@ -426,7 +429,7 @@ class TestRescheduling: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 1) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) with pytest.raises( ValueError, match="Operation 'add3' got incorrect move: -4. Must be between 0 and 7.", @@ -439,7 +442,7 @@ class TestRescheduling: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 1) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) with pytest.raises( ValueError, match="Operation 'add3' got incorrect move: 10. Must be between 0 and 7.", @@ -452,7 +455,7 @@ class TestRescheduling: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 1) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) assert schedule.backward_slack('cmul5') == 16 assert schedule.forward_slack('cmul5') == 0 schedule.move_operation_asap('cmul5') @@ -465,7 +468,7 @@ class TestRescheduling: precedence_sfg_delays.set_latency_of_type(Addition.type_name(), 1) precedence_sfg_delays.set_latency_of_type(ConstantMultiplication.type_name(), 3) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) old_laps = schedule.laps['in0'] schedule.move_operation_asap('in0') assert schedule.start_time_of_operation('in0') == 0 @@ -479,7 +482,7 @@ class TestRescheduling: d <<= a sfg = SFG([in0], [out0]) sfg.set_latency_of_type(Addition.type_name(), 1) - schedule = Schedule(sfg, cyclic=True) + schedule = Schedule(sfg, scheduler=ASAPScheduler(), cyclic=True) # Check initial conditions assert schedule.laps[sfg.find_by_id("add0").input(0).signals[0].graph_id] == 1 @@ -538,11 +541,11 @@ class TestRescheduling: ConstantMultiplication.type_name(), 3 ) - schedule = Schedule(precedence_sfg_delays, algorithm="ASAP") + schedule = Schedule(precedence_sfg_delays, scheduler=ASAPScheduler()) sfg = schedule.sfg assert precedence_sfg_delays.evaluate(5) == sfg.evaluate(5) - schedule = Schedule(sfg_direct_form_iir_lp_filter, algorithm="ASAP") + schedule = Schedule(sfg_direct_form_iir_lp_filter, scheduler=ASAPScheduler()) sfg = schedule.sfg assert sfg_direct_form_iir_lp_filter.evaluate(5) == sfg.evaluate(5) @@ -551,7 +554,7 @@ class TestRescheduling: mult_properties={'latency': 2, 'execution_time': 1}, add_properties={'latency': 2, 'execution_time': 1}, ) - schedule = Schedule(fir_sfg, algorithm="ASAP") + schedule = Schedule(fir_sfg, scheduler=ASAPScheduler()) sfg = schedule.sfg assert fir_sfg.evaluate(5) == sfg.evaluate(5) @@ -562,7 +565,7 @@ class TestTimeResolution: ): schedule = Schedule( sfg_two_inputs_two_outputs_independent_with_cmul, - algorithm="ASAP", + scheduler=ASAPScheduler(), ) old_schedule_time = schedule.schedule_time assert schedule.get_possible_time_resolution_decrements() == [1] @@ -596,7 +599,7 @@ class TestTimeResolution: ): schedule = Schedule( sfg_two_inputs_two_outputs_independent_with_cmul, - algorithm="ASAP", + scheduler=ASAPScheduler(), ) old_schedule_time = schedule.schedule_time @@ -633,7 +636,7 @@ class TestTimeResolution: ): schedule = Schedule( sfg_two_inputs_two_outputs_independent_with_cmul, - algorithm="ASAP", + scheduler=ASAPScheduler(), ) old_schedule_time = schedule.schedule_time assert schedule.get_possible_time_resolution_decrements() == [1] @@ -713,7 +716,7 @@ class TestErrors: ValueError, match="Input port 0 of operation add0 has no latency-offset.", ): - Schedule(sfg_simple_filter) + Schedule(sfg_simple_filter, scheduler=ASAPScheduler()) def test_no_output_latency(self): in1 = Input() @@ -726,7 +729,7 @@ class TestErrors: ValueError, match="Output port 1 of operation bfly0 has no latency-offset.", ): - Schedule(sfg) + Schedule(sfg, scheduler=ASAPScheduler()) in1 = Input() in2 = Input() bfly1 = Butterfly(in1, in2, latency_offsets={"in0": 4, "in1": 2, "out1": 10}) @@ -742,28 +745,28 @@ class TestErrors: ValueError, match="Output port 0 of operation bfly0 has no latency-offset.", ): - Schedule(sfg) + Schedule(sfg, scheduler=ASAPScheduler()) def test_too_short_schedule_time(self, sfg_simple_filter): sfg_simple_filter.set_latency_of_type(Addition.type_name(), 5) sfg_simple_filter.set_latency_of_type(ConstantMultiplication.type_name(), 4) with pytest.raises(ValueError, match="Too short schedule time. Minimum is 9."): - Schedule(sfg_simple_filter, schedule_time=3) + Schedule(sfg_simple_filter, scheduler=ASAPScheduler(), schedule_time=3) - schedule = Schedule(sfg_simple_filter) + schedule = Schedule(sfg_simple_filter, scheduler=ASAPScheduler()) with pytest.raises( ValueError, match=re.escape("New schedule time (3) too short, minimum: 9."), ): schedule.set_schedule_time(3) - def test_incorrect_scheduling_algorithm(self, sfg_simple_filter): - sfg_simple_filter.set_latency_of_type(Addition.type_name(), 1) - sfg_simple_filter.set_latency_of_type(ConstantMultiplication.type_name(), 2) - with pytest.raises( - NotImplementedError, match="No algorithm with name: foo defined." - ): - Schedule(sfg_simple_filter, algorithm="foo") + # def test_incorrect_scheduling_algorithm(self, sfg_simple_filter): + # sfg_simple_filter.set_latency_of_type(Addition.type_name(), 1) + # sfg_simple_filter.set_latency_of_type(ConstantMultiplication.type_name(), 2) + # with pytest.raises( + # NotImplementedError, match="No algorithm with name: foo defined." + # ): + # Schedule(sfg_simple_filter, algorithm="foo") def test_no_sfg(self): with pytest.raises(TypeError, match="An SFG must be provided"): @@ -775,13 +778,13 @@ class TestErrors: with pytest.raises( ValueError, match="Must provide start_times when using 'provided'" ): - Schedule(sfg_simple_filter, algorithm="provided") + Schedule(sfg_simple_filter) def test_provided_no_laps(self, sfg_simple_filter): sfg_simple_filter.set_latency_of_type(Addition.type_name(), 1) sfg_simple_filter.set_latency_of_type(ConstantMultiplication.type_name(), 2) with pytest.raises(ValueError, match="Must provide laps when using 'provided'"): - Schedule(sfg_simple_filter, algorithm="provided", start_times={'in0': 0}) + Schedule(sfg_simple_filter, start_times={'in0': 0}) class TestGetUsedTypeNames: @@ -798,7 +801,7 @@ class TestYLocations: def test_provided_no_laps(self, sfg_simple_filter): sfg_simple_filter.set_latency_of_type(Addition.type_name(), 1) sfg_simple_filter.set_latency_of_type(ConstantMultiplication.type_name(), 2) - schedule = Schedule(sfg_simple_filter) + schedule = Schedule(sfg_simple_filter, ASAPScheduler()) # Assign locations schedule.show() print(schedule._y_locations) diff --git a/test/test_scheduler_gui.py b/test/test_scheduler_gui.py index d6ca2517..02e9d36e 100644 --- a/test/test_scheduler_gui.py +++ b/test/test_scheduler_gui.py @@ -2,6 +2,7 @@ import pytest from b_asic.core_operations import Addition, ConstantMultiplication from b_asic.schedule import Schedule +from b_asic.scheduler import ASAPScheduler try: from b_asic.scheduler_gui.main_window import ScheduleMainWindow @@ -22,6 +23,6 @@ def test_load_schedule(qtbot, sfg_simple_filter): widget = ScheduleMainWindow() qtbot.addWidget(widget) - schedule = Schedule(sfg_simple_filter) + schedule = Schedule(sfg_simple_filter, ASAPScheduler()) widget.open(schedule) assert widget.statusbar.currentMessage() == "Schedule loaded successfully" -- GitLab