Skip to content
Snippets Groups Projects
Commit a64358e6 authored by Hugo Winbladh's avatar Hugo Winbladh Committed by Oscar Gustafsson
Browse files

Add method to reconstruct SFG from a schedule

parent c2b55947
No related branches found
No related tags found
1 merge request!420Add method to reconstruct SFG from a schedule
Pipeline #100173 failed
......@@ -113,7 +113,6 @@ class Schedule:
if not isinstance(sfg, SFG):
raise TypeError("An SFG must be provided")
self._original_sfg = sfg() # Make a copy
self._sfg = sfg
self._start_times = {}
self._laps = defaultdict(_laps_default)
......@@ -390,13 +389,14 @@ class Schedule:
operation_id : GraphID
The GraphID of the operation to swap.
"""
self._original_sfg.swap_io_of_operation(operation_id)
self._sfg.swap_io_of_operation(operation_id)
@property
def sfg(self) -> SFG:
"""The SFG of the current schedule."""
return self._original_sfg
"""The SFG corresponding to the current schedule."""
reconstructed_sfg = self._reintroduce_delays()
simplified_sfg = reconstructed_sfg.simplify_delay_element_placement()
return simplified_sfg
@property
def start_times(self) -> Dict[GraphID, int]:
......@@ -529,7 +529,6 @@ class Schedule:
The execution time of the operation.
"""
self._sfg.set_execution_time_of_type(type_name, execution_time)
self._original_sfg.set_execution_time_of_type(type_name, execution_time)
def move_y_location(
self, graph_id: GraphID, new_y: int, insert: bool = False
......@@ -760,6 +759,16 @@ class Schedule:
del self._laps[delay_input_id]
delay_list = self._sfg.find_by_type_name(Delay.type_name())
def _reintroduce_delays(self) -> SFG:
"""
Reintroduce delay elements to each signal according to the ``_laps`` variable.
"""
new_sfg = self._sfg()
for signal_id,lap in self._laps.items():
for delays in range(lap):
new_sfg = new_sfg.insert_operation_after(signal_id, Delay())
return new_sfg()
def _schedule_alap(self) -> None:
"""Schedule the operations using as-late-as-possible scheduling."""
precedence_list = self._sfg.get_precedence_list()
......
......@@ -439,7 +439,6 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
self.save_as()
return
self._schedule._sfg._graph_id_generator = None
self._schedule._original_sfg._graph_id_generator = None
with open(self._file_name, 'wb') as f:
pickle.dump(self._schedule, f)
self._add_recent_file(self._file_name)
......@@ -462,7 +461,6 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
filename += '.bsc'
self._file_name = filename
self._schedule._sfg._graph_id_generator = None
self._schedule._original_sfg._graph_id_generator = None
with open(self._file_name, 'wb') as f:
pickle.dump(self._schedule, f)
self._add_recent_file(self._file_name)
......
......@@ -736,6 +736,35 @@ class SFG(AbstractOperation):
# Recreate the newly coupled SFG so that all attributes are correct.
return sfg_copy()
def simplify_delay_element_placement(self) -> "SFG":
"""
Simplify an SFG by removing some redundant delay elements.
For example two signals originating from the same starting point, each
connected to a delay element will combine into a single delay element.
Returns a copy of the simplified SFG.
"""
sfg_copy = self()
for delay_element in sfg_copy.find_by_type_name(Delay.type_name()):
neighboring_delays = []
if len(delay_element.inputs[0].signals) > 0:
for signal in delay_element.inputs[0].signals[0].source.signals:
if isinstance(signal.destination.operation, Delay):
neighboring_delays.append(signal.destination.operation)
if delay_element in neighboring_delays:
neighboring_delays.remove(delay_element)
for delay in neighboring_delays:
for output in delay.outputs[0].signals:
output.set_source(delay_element.outputs[0])
in_sig = delay.input(0).signals[0]
delay.input(0).remove_signal(in_sig)
in_sig.source.remove_signal(in_sig)
return sfg_copy()
def _insert_operation_after_operation(
self, output_operation: Operation, new_operation: Operation
):
......
......@@ -520,6 +520,23 @@ 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):
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)
schedule = Schedule(precedence_sfg_delays, algorithm="ASAP")
sfg = schedule.sfg
assert precedence_sfg_delays.evaluate(5) == sfg.evaluate(5)
schedule = Schedule(sfg_direct_form_iir_lp_filter, algorithm="ASAP")
sfg = schedule.sfg
assert sfg_direct_form_iir_lp_filter.evaluate(5) == sfg.evaluate(5)
class TestTimeResolution:
def test_increase_time_resolution(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment