From 8a72f086442555a46f05356f51fb63c8f5a08956 Mon Sep 17 00:00:00 2001
From: Simon Bjurek <simbj106@student.liu.se>
Date: Tue, 18 Mar 2025 17:43:17 +0100
Subject: [PATCH] added exception when attempting cyclic scheduling of
 recursive algorithm with ListScheduler

---
 b_asic/scheduler.py               |  6 ++++++
 b_asic/signal_flow_graph.py       |  2 --
 test/unit/test_list_schedulers.py | 32 +++++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/b_asic/scheduler.py b/b_asic/scheduler.py
index 874d6494..6b136259 100644
--- a/b_asic/scheduler.py
+++ b/b_asic/scheduler.py
@@ -280,6 +280,12 @@ class ListScheduler(Scheduler):
         self._logger.debug("--- Scheduler initializing ---")
         self._initialize_scheduler(schedule)
 
+        if self._sfg.loops and self._schedule.cyclic:
+            raise ValueError(
+                "ListScheduler does not support cyclic scheduling of "
+                "recursive algorithms. Use RecursiveListScheduler instead."
+            )
+
         if self._input_times:
             self._place_inputs_on_given_times()
 
diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py
index e76da8c0..d5ccbc04 100644
--- a/b_asic/signal_flow_graph.py
+++ b/b_asic/signal_flow_graph.py
@@ -1872,8 +1872,6 @@ class SFG(AbstractOperation):
         """
         Return the recursive loops found in the SFG.
 
-        If -1, the SFG does not have any loops.
-
         Returns
         -------
         A list of the recursive loops.
diff --git a/test/unit/test_list_schedulers.py b/test/unit/test_list_schedulers.py
index b9d397b8..fbba4a33 100644
--- a/test/unit/test_list_schedulers.py
+++ b/test/unit/test_list_schedulers.py
@@ -1789,6 +1789,38 @@ class TestListScheduler:
             ),
         )
 
+    def test_cyclic_and_recursive_loops(self):
+        N = 3
+        Wc = 0.2
+        b, a = signal.butter(N, Wc, btype="lowpass", output="ba")
+        sfg = direct_form_1_iir(b, a)
+
+        sfg.set_latency_of_type_name(ConstantMultiplication.type_name(), 2)
+        sfg.set_execution_time_of_type_name(ConstantMultiplication.type_name(), 1)
+        sfg.set_latency_of_type_name(Addition.type_name(), 3)
+        sfg.set_execution_time_of_type_name(Addition.type_name(), 1)
+
+        resources = {
+            Addition.type_name(): 1,
+            ConstantMultiplication.type_name(): 1,
+            Input.type_name(): 1,
+            Output.type_name(): 1,
+        }
+
+        with pytest.raises(
+            ValueError,
+            match="ListScheduler does not support cyclic scheduling of recursive algorithms. Use RecursiveListScheduler instead.",
+        ):
+            Schedule(
+                sfg,
+                scheduler=ListScheduler(
+                    sort_order=((1, True), (3, False), (4, False)),
+                    max_resources=resources,
+                ),
+                cyclic=True,
+                schedule_time=sfg.iteration_period_bound(),
+            )
+
 
 class TestRecursiveListScheduler:
     def test_empty_sfg(self, sfg_empty):
-- 
GitLab