فهرست منبع

Added a dynamic mode to the compute graph.

The compute graph hierarchy (Python and C++) has been modified.
It will break the code using the CG and the include and import will
have to be modified.

New function prepareForRunning is needed in CG nodes even if not used in
static mode. Without this function, code using compute graph won't build.
Christophe Favergeon 3 سال پیش
والد
کامیت
66ea68b096
100فایلهای تغییر یافته به همراه1802 افزوده شده و 150 حذف شده
  1. 5 5
      ARM.CMSIS-DSP.pdsc
  2. 83 1
      ComputeGraph/README.md
  3. 0 0
      ComputeGraph/cg/nodes/README.md
  4. 36 0
      ComputeGraph/cg/nodes/cpp/CFFT.h
  5. 36 0
      ComputeGraph/cg/nodes/cpp/ICFFT.h
  6. 36 3
      ComputeGraph/cg/nodes/cpp/InterleavedStereoToMono.h
  7. 48 0
      ComputeGraph/cg/nodes/cpp/MFCC.h
  8. 11 0
      ComputeGraph/cg/nodes/cpp/NullSink.h
  9. 12 0
      ComputeGraph/cg/nodes/cpp/OverlapAndAdd.h
  10. 12 0
      ComputeGraph/cg/nodes/cpp/SlidingBuffer.h
  11. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/CMSIS_RTOS/RingPrivate.h
  12. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/CMSIS_RTOS/SchedEvents.h
  13. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/Config/AudioConfig.h
  14. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/Config/RingConfig.h
  15. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/Config/VideoConfig.h
  16. 2 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/README.md
  17. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/RingBuffer/RingBuffer.cpp
  18. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/RingBuffer/RingBuffer.h
  19. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/RingBuffer/RingInit.cpp
  20. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/RingBuffer/RingInit.h
  21. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/audio/AudioInterrupt.cpp
  22. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/audio/audio_drv.c
  23. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/audio/audio_drv.h
  24. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/video/VideoInterrupt.cpp
  25. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/video/video_drv.c
  26. 0 0
      ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/video/video_drv.h
  27. 12 1
      ComputeGraph/cg/nodes/cpp/StreamingSink.h
  28. 12 1
      ComputeGraph/cg/nodes/cpp/StreamingSource.h
  29. 12 0
      ComputeGraph/cg/nodes/cpp/ToComplex.h
  30. 12 0
      ComputeGraph/cg/nodes/cpp/ToReal.h
  31. 13 0
      ComputeGraph/cg/nodes/cpp/Unzip.h
  32. 12 0
      ComputeGraph/cg/nodes/cpp/Zip.h
  33. 11 0
      ComputeGraph/cg/nodes/cpp/host/FileSink.h
  34. 11 0
      ComputeGraph/cg/nodes/cpp/host/FileSource.h
  35. 204 14
      ComputeGraph/cg/src/GenericNodes.h
  36. 17 0
      ComputeGraph/cg/src/cg_status.h
  37. BIN
      ComputeGraph/documentation/supported_configs.png
  38. 30 4
      ComputeGraph/examples/CMakeLists.txt
  39. 34 0
      ComputeGraph/examples/example1/AppNodes.h
  40. 4 2
      ComputeGraph/examples/example1/generated/scheduler.cpp
  41. 1 1
      ComputeGraph/examples/example1/graph.py
  42. 195 0
      ComputeGraph/examples/example10/AppNodes.h
  43. 13 0
      ComputeGraph/examples/example10/CMakeLists.txt
  44. 9 0
      ComputeGraph/examples/example10/custom.h
  45. 297 0
      ComputeGraph/examples/example10/generated/scheduler.cpp
  46. 26 0
      ComputeGraph/examples/example10/generated/scheduler.h
  47. 132 0
      ComputeGraph/examples/example10/graph.py
  48. 11 0
      ComputeGraph/examples/example10/main.cpp
  49. 104 0
      ComputeGraph/examples/example10/test.dot
  50. BIN
      ComputeGraph/examples/example10/test.pdf
  51. 34 0
      ComputeGraph/examples/example2/AppNodes.h
  52. 43 35
      ComputeGraph/examples/example2/generated/scheduler.cpp
  53. 1 1
      ComputeGraph/examples/example2/graph.py
  54. 98 16
      ComputeGraph/examples/example3/generated/scheduler.cpp
  55. 2 1
      ComputeGraph/examples/example3/graph.py
  56. 10 0
      ComputeGraph/examples/example4/CMakeLists.txt
  57. 7 7
      ComputeGraph/examples/example4/appnodes.py
  58. 1 1
      ComputeGraph/examples/example4/graph.py
  59. 1 1
      ComputeGraph/examples/example4/sched.py
  60. 10 0
      ComputeGraph/examples/example5/CMakeLists.txt
  61. 5 5
      ComputeGraph/examples/example5/appnodes.py
  62. 1 1
      ComputeGraph/examples/example5/graph.py
  63. 1 1
      ComputeGraph/examples/example5/sched.py
  64. BIN
      ComputeGraph/examples/example5/test.pdf
  65. 6 4
      ComputeGraph/examples/example6/generated/scheduler.cpp
  66. 1 1
      ComputeGraph/examples/example6/graph.py
  67. 10 0
      ComputeGraph/examples/example7/CMakeLists.txt
  68. 8 8
      ComputeGraph/examples/example7/appnodes.py
  69. 1 1
      ComputeGraph/examples/example7/custom.py
  70. 1 1
      ComputeGraph/examples/example7/graph.py
  71. 1 1
      ComputeGraph/examples/example7/sched.py
  72. 35 0
      ComputeGraph/examples/example8/AppNodes.h
  73. 8 6
      ComputeGraph/examples/example8/generated/scheduler.cpp
  74. 1 1
      ComputeGraph/examples/example8/graph.py
  75. 35 0
      ComputeGraph/examples/example9/AppNodes.h
  76. 6 4
      ComputeGraph/examples/example9/generated/scheduler.cpp
  77. 1 1
      ComputeGraph/examples/example9/graph.py
  78. 1 1
      MANIFEST.in
  79. 1 1
      cmsisdsp/__init__.py
  80. 1 1
      cmsisdsp/cg/nodes/CFFT.py
  81. 1 1
      cmsisdsp/cg/nodes/Duplicate.py
  82. 1 1
      cmsisdsp/cg/nodes/ICFFT.py
  83. 1 1
      cmsisdsp/cg/nodes/InterleavedStereoToMono.py
  84. 1 1
      cmsisdsp/cg/nodes/MFCC.py
  85. 1 1
      cmsisdsp/cg/nodes/NullSink.py
  86. 1 1
      cmsisdsp/cg/nodes/ToComplex.py
  87. 1 1
      cmsisdsp/cg/nodes/ToReal.py
  88. 1 1
      cmsisdsp/cg/nodes/Unzip.py
  89. 1 1
      cmsisdsp/cg/nodes/Zip.py
  90. 2 2
      cmsisdsp/cg/nodes/__init__.py
  91. 1 1
      cmsisdsp/cg/nodes/host/FileSink.py
  92. 1 1
      cmsisdsp/cg/nodes/host/FileSource.py
  93. 1 1
      cmsisdsp/cg/nodes/host/NumpySink.py
  94. 1 1
      cmsisdsp/cg/nodes/host/VHT.py
  95. 0 0
      cmsisdsp/cg/nodes/host/VHTCGSTATIC.py
  96. 1 1
      cmsisdsp/cg/nodes/host/WavSink.py
  97. 0 0
      cmsisdsp/cg/nodes/host/WavSource.py
  98. 0 0
      cmsisdsp/cg/nodes/host/__init__.py
  99. 1 1
      cmsisdsp/cg/nodes/host/message.py
  100. 1 1
      cmsisdsp/cg/nodes/simu.py

+ 5 - 5
ARM.CMSIS-DSP.pdsc

@@ -105,12 +105,12 @@
       </files>
     </component>
 
-    <component Cclass="CMSIS" Cgroup="DSP" Csub="Compute Graph Static Flow" Cversion="0.0.0" isDefaultVariant="true" condition="CMSISDSPLIB">
-      <description>CMSIS-DSP Compute Graph - Static Flow</description>
+    <component Cclass="CMSIS" Cgroup="DSP" Csub="Compute Graph" Cversion="0.0.0" isDefaultVariant="true" condition="CMSISDSPLIB">
+      <description>CMSIS-DSP Compute Graph</description>
       <files>
-          <file category="header" name="ComputeGraph/cg/static/src/GenericNodes.h"/>
-          <file category="include"  name="ComputeGraph/cg/static/nodes/cpp/"/>
-          <file category="include"  name="ComputeGraph/cg/static/src/"/>
+          <file category="header" name="ComputeGraph/cg/src/GenericNodes.h"/>
+          <file category="include"  name="ComputeGraph/cg/nodes/cpp/"/>
+          <file category="include"  name="ComputeGraph/cg/src/"/>
           <file category="other"  name="ComputeGraph/cg.scvd" />
       </files>
     </component>

+ 83 - 1
ComputeGraph/README.md

@@ -49,7 +49,7 @@ The CMSIS-DSP Compute Graph Tools are a set of Python scripts and C++ classes wi
 - The Python script will generate a C++ implementation of the static schedule 
 - The Python script can also generate a Python implementation of the static schedule (for use with the CMSIS-DSP Python wrapper)
 
-
+(There is no FIFO underflow or overflow due to the scheduling. If there are not enough cycles to run the processing, the real-time will be broken and the solution won't work But this problem is independent from the scheduling itself. )
 
 ## Why it is useful
 
@@ -93,6 +93,10 @@ The schedule is (the size of the FIFOs after the execution of the node displayed
 
 At the end, both FIFOs are empty so the schedule can be run again : it is periodic !
 
+The latest version of the compute graph also supports dynamic scheduling.
+
+![supported_configs](documentation/supported_configs.png)
+
 ## How to use the static scheduler generator
 
 First, you must install the `CMSIS-DSP` PythonWrapper:
@@ -130,6 +134,8 @@ Example 7 is communicating with OpenModelica. The Modelica model (PythonTest) in
 
 Example 8 is showing how to define a new custom datatype for the IOs of the nodes. Example 8 is also demonstrating a new feature where an IO can be connected up to 3 inputs and the static scheduler will automatically generate duplicate nodes.
 
+
+
 ## Frequently asked questions:
 
 There is a [FAQ](FAQ.md) document.
@@ -181,10 +187,60 @@ The drawback of cyclo static scheduling is that the schedule length is increased
 
 Since schedule tend to be bigger with cyclo static scheduling, a new code generation mode has been introduced and is enabled by default : now instead of having a sequence of function calls, the schedule is coded by an array of number and there is a switch / case to select the function to be called.
 
+## Dynamic Data Flow
+
+Versions of the compute graph corresponding to CMSIS-DSP Version >= 1.14.4 and Python wrapper version >= 1.10.0 are supporting  a new dynamic / asynchronous mode.
+
+ With a dynamic flow, the flow of data is potentially changing at each execution. The IOs can generate or consume a different amount of data at each execution of their node (including no data).
+
+This can be useful for sample oriented use cases where not all samples are available but a processing must nevertheless take place each time a subset of samples is available (samples could come from sensors).
+
+With a dynamic flow and scheduling, there is no more any way to ensure that there won't be FIFO underflow of overflow due to scheduling. As consequence, the nodes must be able to check for this problem and decide what to do.
+
+* A sink may decide to generate fake data in case of FIFO underflow
+* A source may decide to skip some data in case of FIFO overflow
+* Another node may decide to do nothing and skip the execution
+* Another node may decide to raise an error.
+
+With dynamic scheduling, a node must implement the function `prepareForRunning` and decide what to do.
+
+3 error / status codes are reserved for this. They are defined in the header `cg_status.h`. This header is not included by default, but if you define you own error codes, they should be coherent with `cg_status` and use the same values for the 3 status / error codes which are used in dynamic mode:
+
+* `CG_SUCCESS`  = 0 : Node can execute
+* `CG_SKIP_EXECUTION` = -5 : Node will skip the execution
+* `CG_BUFFER_ERROR` = -6 : Unrecoverable error due to FIFO underflow / overflow (only raised in pure function like CMSIS-DSP ones called directly)
+
+Any other returned value will stop the execution.
+
+The dynamic mode (also named asynchronous), is enabled with option : `asynchronous`
+
+The system will still compute a scheduling and FIFO sizes as if the flow was static. We can see the static flow as an average of the dynamic flow. In dynamic mode, the FIFOs may need to be bigger than the ones computed in static mode.  The static estimation is giving a first idea of what the size of the FIFOs should be. The size can be increased by specifying a percent increase with option `FIFOIncrease`.
+
+For pure compute functions (like CMSIS-DSP ones), which are not packaged into a C++ class, there is no way to customize the decision logic in case of a problem with FIFO. There is a global option : `asyncDefaultSkip`. 
+
+When `true`, a pure function that cannot run will just skip the execution. With `false`, the execution will stop. For any other decision algorithm, the pure function needs to be packaged in a C++ class.
+
+`Duplicate` nodes are skipping the execution in case of problems with FIFOs. If it is not the wanted behavior, you can either:
+
+* Replace the Duplicate class by a custom one by changing the class name with option `duplicateNodeClassName` on the graph.
+* Don't use the automatic duplication feature and introduce your duplicate nodes in the compute graph
+
+When you don't want to generate or consume data in a node, just don't call the functions `getReadBuffer` or `getWriteBuffer` for your IOs.
+
 ## Options
 
 Several options and be used to control the schedule generation. Some options are used by the scheduling algorithm and other options are used by the code generator:
 
+### Options for the graph
+
+#### defaultFIFOClass (default = "FIFO")
+
+Class used for FIFO by default. Can also be customized for each connection (`connect` of `connectWithDelay` call)
+
+#### duplicateNodeClassName(default="Duplicate")
+
+Prefix used to generate the duplicate node classes like `Duplicate2`, `Duplicate3` ...
+
 ### Options for the scheduling
 
 #### memoryOptimization (default = False)
@@ -235,6 +291,8 @@ Prefix to add before the FIFO buffer definition. Those buffers are not static an
 
 Another possibility would be to make the buffer static by redefining the macro `CG_BEFORE_BUFFER`
 
+
+
 #### Options for C Code Generation only
 
 ##### cOptionalArgs (default = "")
@@ -289,6 +347,30 @@ By default, the scheduler function is callable from C. When false, it is a stand
 
 If you don't use any of the datatypes or functions of the CMSIS-DSP, you don't need to include the `arm_math.h` in the scheduler file. This option can thus be set to `False`.
 
+##### asynchronous (default = False)
+
+When true, the scheduling is for a dynamic / asynchronous flow. A node may not always produce or consume the same amount of data. As consequence, a scheduling can fail. Each node needs to implement a `prepareForRunning` function to identify and recover from FIFO underflows and overflows.
+
+A synchronous schedule is used as start and should describe the average case.
+
+This implies `codeArray` and `switchCase`. This disables `memoryOptimizations`.
+
+Synchronous FIFOs that are just buffers will be considered as FIFOs in asynchronous mode.
+
+##### FIFOIncrease (default 0)
+
+In case of asynchronous scheduling, the FIFOs may need to be bigger than what is computed assuming a synchronous scheduling. This option is used to increase the FIFO size. It represents a percent increase.
+
+For instance, a value of 10 means the FIFO will have their size updated from `oldSize` to `1.1 * oldSize` which is ` (1 + 10%)* oldSize`
+
+##### asyncDefaultSkip (default True)
+
+Behavior of a pure function (like CMSIS-DSP) in asynchronous mode. When `True`, the execution is skipped if the function can't be executed. If `False`, an error is raised.
+
+If another error recovery is needed, the function must be packaged into a C++ class to implement a `prepareForRun` function.
+
+
+
 #### Options for Python code generation only
 
 ##### pyOptionalArgs (default = "")

+ 0 - 0
ComputeGraph/cg/static/nodes/README.md → ComputeGraph/cg/nodes/README.md


+ 36 - 0
ComputeGraph/cg/static/nodes/cpp/CFFT.h → ComputeGraph/cg/nodes/cpp/CFFT.h

@@ -45,6 +45,18 @@ public:
          status=arm_cfft_init_f32(&sfft,inputSize>>1);
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         float32_t *a=this->getReadBuffer();
         float32_t *b=this->getWriteBuffer();
@@ -72,6 +84,18 @@ public:
          status=arm_cfft_init_f16(&sfft,inputSize>>1);
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         float16_t *a=this->getReadBuffer();
         float16_t *b=this->getWriteBuffer();
@@ -98,6 +122,18 @@ public:
          status=arm_cfft_init_q15(&sfft,inputSize>>1);
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+    
     int run(){
         q15_t *a=this->getReadBuffer();
         q15_t *b=this->getWriteBuffer();

+ 36 - 0
ComputeGraph/cg/static/nodes/cpp/ICFFT.h → ComputeGraph/cg/nodes/cpp/ICFFT.h

@@ -45,6 +45,18 @@ public:
          status=arm_cfft_init_f32(&sifft,inputSize>>1);
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         float32_t *a=this->getReadBuffer();
         float32_t *b=this->getWriteBuffer();
@@ -72,6 +84,18 @@ public:
          status=arm_cfft_init_f16(&sifft,inputSize>>1);
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         float16_t *a=this->getReadBuffer();
         float16_t *b=this->getWriteBuffer();
@@ -99,6 +123,18 @@ public:
          status=arm_cfft_init_q15(&sifft,inputSize>>1);
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+    
     int run(){
         q15_t *a=this->getReadBuffer();
         q15_t *b=this->getWriteBuffer();

+ 36 - 3
ComputeGraph/cg/static/nodes/cpp/InterleavedStereoToMono.h → ComputeGraph/cg/nodes/cpp/InterleavedStereoToMono.h

@@ -40,7 +40,18 @@ public:
     InterleavedStereoToMono(FIFOBase<q15_t> &src,FIFOBase<q15_t> &dst):
     GenericNode<q15_t,inputSize,q15_t,outputSize>(src,dst){};
 
-   
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         q15_t *a=this->getReadBuffer();
         q15_t *b=this->getWriteBuffer();
@@ -60,7 +71,18 @@ public:
     InterleavedStereoToMono(FIFOBase<q31_t> &src,FIFOBase<q31_t> &dst):
     GenericNode<q31_t,inputSize,q31_t,outputSize>(src,dst){};
 
-   
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         q31_t *a=this->getReadBuffer();
         q31_t *b=this->getWriteBuffer();
@@ -80,7 +102,18 @@ public:
     InterleavedStereoToMono(FIFOBase<float32_t> &src,FIFOBase<float32_t> &dst):
     GenericNode<float32_t,inputSize,float32_t,outputSize>(src,dst){};
 
-   
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+    
     int run(){
         float32_t *a=this->getReadBuffer();
         float32_t *b=this->getWriteBuffer();

+ 48 - 0
ComputeGraph/cg/static/nodes/cpp/MFCC.h → ComputeGraph/cg/nodes/cpp/MFCC.h

@@ -58,6 +58,18 @@ public:
 #endif
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         float32_t *a=this->getReadBuffer();
         float32_t *b=this->getWriteBuffer();
@@ -88,6 +100,18 @@ public:
 #endif
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         float16_t *a=this->getReadBuffer();
         float16_t *b=this->getWriteBuffer();
@@ -114,6 +138,18 @@ public:
          memory.resize(2*inputSize);
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         q31_t *a=this->getReadBuffer();
         q31_t *b=this->getWriteBuffer();
@@ -139,6 +175,18 @@ public:
          memory.resize(2*inputSize);
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         q15_t *a=this->getReadBuffer();
         q15_t *b=this->getWriteBuffer();

+ 11 - 0
ComputeGraph/cg/static/nodes/cpp/NullSink.h → ComputeGraph/cg/nodes/cpp/NullSink.h

@@ -35,6 +35,17 @@ class NullSink: public GenericSink<IN, inputSize>
 public:
     NullSink(FIFOBase<IN> &src):GenericSink<IN,inputSize>(src){};
 
+    int prepareForRunning() override
+    {
+        if (this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run()
     {
         IN *b=this->getReadBuffer();

+ 12 - 0
ComputeGraph/cg/static/nodes/cpp/OverlapAndAdd.h → ComputeGraph/cg/nodes/cpp/OverlapAndAdd.h

@@ -40,6 +40,18 @@ public:
         memory.resize(overlap);
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         int i;
         IN *a=this->getReadBuffer();

+ 12 - 0
ComputeGraph/cg/static/nodes/cpp/SlidingBuffer.h → ComputeGraph/cg/nodes/cpp/SlidingBuffer.h

@@ -40,6 +40,18 @@ public:
         memory.resize(overlap);
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         IN *a=this->getReadBuffer();
         IN *b=this->getWriteBuffer();

+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/CMSIS_RTOS/RingPrivate.h → ComputeGraph/cg/nodes/cpp/StreamingNodes/CMSIS_RTOS/RingPrivate.h


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/CMSIS_RTOS/SchedEvents.h → ComputeGraph/cg/nodes/cpp/StreamingNodes/CMSIS_RTOS/SchedEvents.h


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/Config/AudioConfig.h → ComputeGraph/cg/nodes/cpp/StreamingNodes/Config/AudioConfig.h


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/Config/RingConfig.h → ComputeGraph/cg/nodes/cpp/StreamingNodes/Config/RingConfig.h


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/Config/VideoConfig.h → ComputeGraph/cg/nodes/cpp/StreamingNodes/Config/VideoConfig.h


+ 2 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/README.md → ComputeGraph/cg/nodes/cpp/StreamingNodes/README.md

@@ -10,6 +10,8 @@ Those files are kept because they are used in the AVH-SystemModeling example.
 
 But there are simpler way to interface the compute graph to an audio interrupt.
 
+Those nodes are considered as deprecated. Don't use them.
+
 ## RingBuffer
 
 It is a way to connect the compute graph with static flow to an audio source or sink.

+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/RingBuffer/RingBuffer.cpp → ComputeGraph/cg/nodes/cpp/StreamingNodes/RingBuffer/RingBuffer.cpp


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/RingBuffer/RingBuffer.h → ComputeGraph/cg/nodes/cpp/StreamingNodes/RingBuffer/RingBuffer.h


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/RingBuffer/RingInit.cpp → ComputeGraph/cg/nodes/cpp/StreamingNodes/RingBuffer/RingInit.cpp


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/RingBuffer/RingInit.h → ComputeGraph/cg/nodes/cpp/StreamingNodes/RingBuffer/RingInit.h


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/VHT/audio/AudioInterrupt.cpp → ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/audio/AudioInterrupt.cpp


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/VHT/audio/audio_drv.c → ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/audio/audio_drv.c


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/VHT/audio/audio_drv.h → ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/audio/audio_drv.h


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/VHT/video/VideoInterrupt.cpp → ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/video/VideoInterrupt.cpp


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/VHT/video/video_drv.c → ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/video/video_drv.c


+ 0 - 0
ComputeGraph/cg/static/nodes/cpp/StreamingNodes/VHT/video/video_drv.h → ComputeGraph/cg/nodes/cpp/StreamingNodes/VHT/video/video_drv.h


+ 12 - 1
ComputeGraph/cg/static/nodes/cpp/StreamingSink.h → ComputeGraph/cg/nodes/cpp/StreamingSink.h

@@ -30,7 +30,7 @@
 
 #include "RingBuffer.h"
 
-
+/* This is deprecated. Don't use it */
 template<typename IN, int inputSize>
 class StreamingSink: public GenericSink<IN, inputSize>
 {
@@ -38,6 +38,17 @@ public:
     StreamingSink(FIFOBase<IN> &src,ring_config_t *config):
     GenericSink<IN,inputSize>(src),mConfig(config){};
 
+    int prepareForRunning() override
+    {
+        if (this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run()
     {
         IN *b=this->getReadBuffer();

+ 12 - 1
ComputeGraph/cg/static/nodes/cpp/StreamingSource.h → ComputeGraph/cg/nodes/cpp/StreamingSource.h

@@ -30,7 +30,7 @@
 
 #include "RingBuffer.h"
 
-
+/* This is deprecated. Don't use it */
 template<typename OUT,int outputSize>
 class StreamingSource: public GenericSource<OUT,outputSize>
 {
@@ -38,6 +38,17 @@ public:
     StreamingSource(FIFOBase<OUT> &dst,ring_config_t *config):
     GenericSource<OUT,outputSize>(dst),mConfig(config){};
 
+    int prepareForRunning() override
+    {
+        if (this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         OUT *b=this->getWriteBuffer();
         /* 

+ 12 - 0
ComputeGraph/cg/static/nodes/cpp/ToComplex.h → ComputeGraph/cg/nodes/cpp/ToComplex.h

@@ -44,6 +44,18 @@ public:
     ToComplex(FIFOBase<IN> &src,FIFOBase<IN> &dst):GenericNode<IN,inputSize,IN,outputSize>(src,dst){
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         IN *a=this->getReadBuffer();
         IN *b=this->getWriteBuffer();

+ 12 - 0
ComputeGraph/cg/static/nodes/cpp/ToReal.h → ComputeGraph/cg/nodes/cpp/ToReal.h

@@ -43,6 +43,18 @@ public:
     ToReal(FIFOBase<IN> &src,FIFOBase<IN> &dst):GenericNode<IN,inputSize,IN,outputSize>(src,dst){
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         IN *a=this->getReadBuffer();
         IN *b=this->getWriteBuffer();

+ 13 - 0
ComputeGraph/cg/static/nodes/cpp/Unzip.h → ComputeGraph/cg/nodes/cpp/Unzip.h

@@ -46,6 +46,19 @@ public:
     Unzip(FIFOBase<IN> &src,FIFOBase<IN> &dst1,FIFOBase<IN> &dst2):
     GenericNode12<IN,inputSize,IN,output1Size,IN,output2Size>(src,dst1,dst2){};
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow1() ||
+            this->willOverflow2() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+    
     /*
           2*outputSize1 == 2*outSize2 == inputSize
     */

+ 12 - 0
ComputeGraph/cg/static/nodes/cpp/Zip.h → ComputeGraph/cg/nodes/cpp/Zip.h

@@ -39,6 +39,18 @@ public:
     Zip(FIFOBase<IN> &src1,FIFOBase<IN> &src2,FIFOBase<IN> &dst):
     GenericNode21<IN,inputSize,IN,inputSize,IN,outputSize>(src1,src2,dst){};
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow1() ||
+            this->willUnderflow2()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
 
     int run(){
         IN *a1=this->getReadBuffer1();

+ 11 - 0
ComputeGraph/cg/static/nodes/cpp/host/FileSink.h → ComputeGraph/cg/nodes/cpp/host/FileSink.h

@@ -35,6 +35,17 @@ class FileSink: public GenericSink<IN, inputSize>
 public:
     FileSink(FIFOBase<IN> &src, std::string name):GenericSink<IN,inputSize>(src),output(name){};
 
+    int prepareForRunning() override
+    {
+        if (this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+    
     int run()
     {
         IN *b=this->getReadBuffer();

+ 11 - 0
ComputeGraph/cg/static/nodes/cpp/host/FileSource.h → ComputeGraph/cg/nodes/cpp/host/FileSource.h

@@ -46,6 +46,17 @@ public:
 
     };
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         string str;
         int i;

+ 204 - 14
ComputeGraph/cg/static/src/GenericNodes.h → ComputeGraph/cg/src/GenericNodes.h

@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------
  * Project:      CMSIS DSP Library
- * Title:        Sched.h
+ * Title:        GenericNodes.h
  * Description:  C++ support templates for the compute graph with static scheduler
  *
  * $Date:        29 July 2021
@@ -9,7 +9,7 @@
  * Target Processor: Cortex-M and Cortex-A cores
  * -------------------------------------------------------------------- */
 /*
- * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -31,10 +31,20 @@
 
 #include <vector>
 
+/* 
+Defined in cg_status.h by default but user
+may want to use a different header to define the 
+error codes of the application
+*/
+#define CG_SKIP_EXECUTION_ID_CODE (-5)
+#define CG_BUFFER_ERROR_ID_CODE (-6)
+
 // FIFOS 
 
 #ifdef DEBUGSCHED
 
+#include <iostream>
+
 template<typename T>
 struct debugtype{
     typedef T type;
@@ -55,23 +65,29 @@ class FIFOBase{
 public:
     virtual T* getWriteBuffer(int nb)=0;
     virtual T* getReadBuffer(int nb)=0;
+    virtual bool willUnderflowWith(int nb)=0;
+    virtual bool willOverflowWith(int nb)=0;
+
 };
 
+template<typename T, int length, int isArray=0, int isAsync = 0>
+class FIFO;
 
-template<typename T, int length, int isArray=0>
-class FIFO: public FIFOBase<T> 
+/* Real FIFO, Synchronous */
+template<typename T, int length>
+class FIFO<T,length,0,0>: public FIFOBase<T> 
 {
     public:
         FIFO(T *buffer,int delay=0):mBuffer(buffer),readPos(0),writePos(delay) {};
         FIFO(uint8_t *buffer,int delay=0):mBuffer((T*)buffer),readPos(0),writePos(delay) {};
 
+        /* Not used in synchronous mode */
+        bool willUnderflowWith(int nb) override {return false;};
+        bool willOverflowWith(int nb) override {return false;};
+
         T * getWriteBuffer(int nb) override
         {
-            if (isArray==1)
-            {
-                return(mBuffer);
-            }
-
+            
             T *ret;
             if (readPos > 0)
             {
@@ -87,24 +103,148 @@ class FIFO: public FIFOBase<T>
 
         T* getReadBuffer(int nb) override
         {
-            if (isArray==1)
+            
+            T *ret = mBuffer + readPos;
+            readPos += nb;
+            return(ret);
+        }
+
+        #ifdef DEBUGSCHED
+        void dump()
+        {
+            int nb=0;
+            std::cout << std::endl;
+            for(int i=0; i < length ; i++)
             {
-                return(mBuffer);
+                std::cout << (typename Debug<T>::type)mBuffer[i] << " ";
+                nb++;
+                if (nb == 10)
+                {
+                    nb=0;
+                    std::cout << std::endl;
+                }
             }
+            std::cout << std::endl;
+            std::cout << std::endl;
+        }
+        #endif
+
+    protected:
+        T *mBuffer;
+        int readPos,writePos;
+};
+
+/* Buffer, Synchronous */
+template<typename T, int length>
+class FIFO<T,length,1,0>: public FIFOBase<T> 
+{
+    public:
+        FIFO(T *buffer,int delay=0):mBuffer(buffer),readPos(0),writePos(delay) {};
+        FIFO(uint8_t *buffer,int delay=0):mBuffer((T*)buffer),readPos(0),writePos(delay) {};
+
+        bool willUnderflowWith(int nb) override {return false;};
+        bool willOverflowWith(int nb) override {return false;};
+
+        T * getWriteBuffer(int nb) override
+        {
+            return(mBuffer);
+        };
+
+        T* getReadBuffer(int nb) override
+        {
+            return(mBuffer);
+        }
+
+        #ifdef DEBUGSCHED
+        void dump()
+        {
+            int nb=0;
+            std::cout << std::endl;
+            for(int i=0; i < length ; i++)
+            {
+                std::cout << (typename Debug<T>::type)mBuffer[i] << " ";
+                nb++;
+                if (nb == 10)
+                {
+                    nb=0;
+                    std::cout << std::endl;
+                }
+            }
+            std::cout << std::endl;
+            std::cout << std::endl;
+        }
+        #endif
+
+    protected:
+        T *mBuffer;
+        int readPos,writePos;
+};
+
+/* Real FIFO, Asynchronous */
+template<typename T, int length>
+class FIFO<T,length,0,1>: public FIFOBase<T> 
+{
+    public:
+        FIFO(T *buffer,int delay=0):mBuffer(buffer),readPos(0),writePos(delay),nbSamples(delay) {};
+        FIFO(uint8_t *buffer,int delay=0):mBuffer((T*)buffer),readPos(0),writePos(delay),nbSamples(delay) {};
+
+        /* 
+
+        Check for overflow must have been done
+        before using this function 
+        
+        */
+        T * getWriteBuffer(int nb) override
+        {
             
+            T *ret;
+            if (readPos > 0)
+            {
+                memcpy((void*)mBuffer,(void*)(mBuffer+readPos),(writePos-readPos)*sizeof(T));
+                writePos -= readPos;
+                readPos = 0;
+            }
+            
+            ret = mBuffer + writePos;
+            writePos += nb; 
+            nbSamples += nb;
+            return(ret);
+        };
+
+        /* 
+        
+        Check for undeflow must have been done
+        before using this function 
+        
+        */
+        T* getReadBuffer(int nb) override
+        {
+           
             T *ret = mBuffer + readPos;
             readPos += nb;
+            nbSamples -= nb;
             return(ret);
         }
 
+        bool willUnderflowWith(int nb) override
+        {
+            return((nbSamples - nb)<0);
+        }
+
+        bool willOverflowWith(int nb) override
+        {
+            return((nbSamples + nb)>length);
+        }
+
         #ifdef DEBUGSCHED
         void dump()
         {
             int nb=0;
             std::cout << std::endl;
+            std::cout << "FIFO nb samples = " << nbSamples << std::endl;
             for(int i=0; i < length ; i++)
             {
-                std::cout << (Debug<T>::type)mBuffer[i] << " ";
+                std::cout << (typename Debug<T>::type)mBuffer[i] << " ";
                 nb++;
                 if (nb == 10)
                 {
@@ -120,6 +260,7 @@ class FIFO: public FIFOBase<T>
     protected:
         T *mBuffer;
         int readPos,writePos;
+        int nbSamples;
 };
 
 // GENERIC NODES 
@@ -128,6 +269,7 @@ class NodeBase
 {
 public:
     virtual int run()=0;
+    virtual int prepareForRunning()=0;
 };
 
 template<typename IN, int inputSize,typename OUT, int outputSize>
@@ -140,6 +282,9 @@ protected:
      OUT * getWriteBuffer(int nb = outputSize){return mDst.getWriteBuffer(nb);};
      IN * getReadBuffer(int nb = inputSize){return mSrc.getReadBuffer(nb);};
 
+     bool willOverflow(int nb = outputSize){return mDst.willOverflowWith(nb);};
+     bool willUnderflow(int nb = inputSize){return mSrc.willUnderflowWith(nb);};
+
 private:
     FIFOBase<IN> &mSrc;
     FIFOBase<OUT> &mDst;
@@ -157,6 +302,11 @@ protected:
      OUT2 * getWriteBuffer2(int nb=output2Size){return mDst2.getWriteBuffer(nb);};
      IN * getReadBuffer(int nb=inputSize){return mSrc.getReadBuffer(nb);};
 
+     bool willOverflow1(int nb = output1Size){return mDst1.willOverflowWith(nb);};
+     bool willOverflow2(int nb = output2Size){return mDst2.willOverflowWith(nb);};
+
+     bool willUnderflow(int nb = inputSize){return mSrc.willUnderflowWith(nb);};
+
 private:
     FIFOBase<IN> &mSrc;
     FIFOBase<OUT1> &mDst1;
@@ -184,6 +334,12 @@ protected:
 
      IN * getReadBuffer(int nb=inputSize){return mSrc.getReadBuffer(nb);};
 
+     bool willOverflow1(int nb = output1Size){return mDst1.willOverflowWith(nb);};
+     bool willOverflow2(int nb = output2Size){return mDst2.willOverflowWith(nb);};
+     bool willOverflow3(int nb = output3Size){return mDst3.willOverflowWith(nb);};
+
+     bool willUnderflow(int nb = inputSize){return mSrc.willUnderflowWith(nb);};
+
 private:
     FIFOBase<IN> &mSrc;
     FIFOBase<OUT1> &mDst1;
@@ -205,6 +361,10 @@ protected:
      IN1 * getReadBuffer1(int nb=input1Size){return mSrc1.getReadBuffer(nb);};
      IN2 * getReadBuffer2(int nb=input2Size){return mSrc2.getReadBuffer(nb);};
 
+     bool willOverflow(int nb = outputSize){return mDst.willOverflowWith(nb);};
+     bool willUnderflow1(int nb = input1Size){return mSrc1.willUnderflowWith(nb);};
+     bool willUnderflow2(int nb = input2Size){return mSrc2.willUnderflowWith(nb);};
+
 private:
     FIFOBase<IN1> &mSrc1;
     FIFOBase<IN2> &mSrc2;
@@ -222,6 +382,8 @@ public:
 protected:
      OUT * getWriteBuffer(int nb=outputSize){return mDst.getWriteBuffer(nb);};
 
+     bool willOverflow(int nb = outputSize){return mDst.willOverflowWith(nb);};
+
 private:
     FIFOBase<OUT> &mDst;
 };
@@ -235,6 +397,8 @@ public:
 protected:
      IN * getReadBuffer(int nb=inputSize){return mSrc.getReadBuffer(nb);};
 
+     bool willUnderflow(int nb = inputSize){return mSrc.willUnderflowWith(nb);};
+
 private:
     FIFOBase<IN> &mSrc;
 };
@@ -253,7 +417,19 @@ public:
     Duplicate2(FIFOBase<IN> &src,FIFOBase<IN> &dst1,FIFOBase<IN> &dst2):
     GenericNode12<IN,inputSize,IN,inputSize,IN,inputSize>(src,dst1,dst2){};
 
-    int run(){
+    int prepareForRunning() override
+    {
+        if (this->willUnderflow() || 
+            this->willOverflow1() ||
+            this->willOverflow2())
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
+    int run() override {
         IN *a=this->getReadBuffer();
         IN *b1=this->getWriteBuffer1();
         IN *b2=this->getWriteBuffer2();
@@ -293,7 +469,21 @@ public:
                   IN,inputSize,
                   IN,inputSize>(src,dst1,dst2,dst3){};
 
-    int run(){
+    int prepareForRunning() override
+    {
+        if (this->willUnderflow() || 
+            this->willOverflow1() ||
+            this->willOverflow2() ||
+            this->willOverflow3()
+            )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
+    int run() override {
         IN *a=this->getReadBuffer();
         IN *b1=this->getWriteBuffer1();
         IN *b2=this->getWriteBuffer2();

+ 17 - 0
ComputeGraph/cg/src/cg_status.h

@@ -0,0 +1,17 @@
+#ifndef _CG_STATUS_H_
+
+
+ typedef enum
+  {
+    CG_SUCCESS                    =  0, /**< No error */
+    CG_BUFFER_UNDERFLOW           = -1, /**< FIFO underflow */
+    CG_BUFFER_OVERFLOW            = -2, /**< FIFO overflow */
+    CG_MEMORY_ALLOCATION_FAILURE  = -3, /**< Memory allocation failure */
+    CG_INIT_FAILURE               = -4, /**< Node initialization failure */
+    CG_SKIP_EXECUTION             = -5, /**< Skip node execution (asynchronous mode) */
+    CG_BUFFER_ERROR               = -6, /**< Stop execution due to FIFO overflow or underflow (asynchronous mode for pure function) */
+  } cg_status;
+
+
+
+#endif /* _CG_STATUS_H_ */

BIN
ComputeGraph/documentation/supported_configs.png


+ 30 - 4
ComputeGraph/examples/CMakeLists.txt

@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 3.14)
+cmake_minimum_required (VERSION 3.15)
 include(CMakePrintHelpers)
 
 set(Python_FIND_REGISTRY "LAST")
@@ -26,13 +26,33 @@ function(sdf TARGET)
     target_sources(${TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/generated/scheduler.cpp)
 endfunction()
 
-set(CGSTATICDIR ${CMAKE_CURRENT_SOURCE_DIR}/../cg/static)
+function(sdfpython TARGET)
+    if (DOT)
+    add_custom_command(TARGET ${TARGET} PRE_BUILD 
+        BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/test.pdf
+        COMMAND ${DOT} -Tpdf -o ${CMAKE_CURRENT_SOURCE_DIR}/test.pdf ${CMAKE_CURRENT_SOURCE_DIR}/test.dot
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/test.dot
+        VERBATIM
+        )
+    endif()
+
+    add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/sched.py
+        ${CMAKE_CURRENT_SOURCE_DIR}/test.dot
+        COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/graph.py
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/graph.py
+        VERBATIM
+        )
+endfunction()
+
+set(CGDIR ${CMAKE_CURRENT_SOURCE_DIR}/../cg)
 
 set(DSP ${CMAKE_CURRENT_SOURCE_DIR}/../..)
 
 function(add_sdf_dir TARGET)
-    target_include_directories(${TARGET} PRIVATE ${CGSTATICDIR}/src)
-    target_include_directories(${TARGET} PRIVATE ${CGSTATICDIR}/nodes/cpp)
+    target_include_directories(${TARGET} PRIVATE ${CGDIR}/src)
+    target_include_directories(${TARGET} PRIVATE ${CGDIR}/nodes/cpp)
     target_include_directories(${TARGET} PRIVATE ${CMSISCORE})
     target_include_directories(${TARGET} PRIVATE ${DSP}/Include)
 endfunction()
@@ -52,3 +72,9 @@ add_subdirectory(example3 bin_example3)
 add_subdirectory(example6 bin_example6)
 add_subdirectory(example8 bin_example8)
 add_subdirectory(example9 bin_example9)
+add_subdirectory(example10 bin_example10)
+
+# Python examples
+add_subdirectory(example4 bin_example4)
+add_subdirectory(example5 bin_example5)
+add_subdirectory(example7 bin_example7)

+ 34 - 0
ComputeGraph/examples/example1/AppNodes.h

@@ -36,6 +36,17 @@ class Sink: public GenericSink<IN, inputSize>
 public:
     Sink(FIFOBase<IN> &src):GenericSink<IN,inputSize>(src){};
 
+    int prepareForRunning() override
+    {
+        if (this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run()
     {
         IN *b=this->getReadBuffer();
@@ -55,6 +66,17 @@ class Source: GenericSource<OUT,outputSize>
 public:
     Source(FIFOBase<OUT> &dst):GenericSource<OUT,outputSize>(dst),mCounter(0){};
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         OUT *b=this->getWriteBuffer();
 
@@ -76,6 +98,18 @@ class ProcessingNode: public GenericNode<IN,inputSize,OUT,outputSize>
 public:
     ProcessingNode(FIFOBase<IN> &src,FIFOBase<OUT> &dst,int,const char*,int):GenericNode<IN,inputSize,OUT,outputSize>(src,dst){};
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+    
     int run(){
         printf("ProcessingNode\n");
         IN *a=this->getReadBuffer();

+ 4 - 2
ComputeGraph/examples/example1/generated/scheduler.cpp

@@ -72,6 +72,7 @@ The support classes and code is covered by CMSIS-DSP license.
 
 CG_AFTER_INCLUDES
 
+
 /*
 
 Description of the scheduling. 
@@ -111,8 +112,8 @@ uint32_t scheduler(int *error,int someVariable)
     /*
     Create FIFOs objects
     */
-    FIFO<float32_t,FIFOSIZE0,0> fifo0(buf1);
-    FIFO<float32_t,FIFOSIZE1,1> fifo1(buf2);
+    FIFO<float32_t,FIFOSIZE0,0,0> fifo0(buf1);
+    FIFO<float32_t,FIFOSIZE1,1,0> fifo1(buf2);
 
     CG_BEFORE_NODE_INIT;
     /* 
@@ -131,6 +132,7 @@ uint32_t scheduler(int *error,int someVariable)
         for(unsigned long id=0 ; id < 17; id++)
         {
             CG_BEFORE_NODE_EXECUTION;
+
             switch(schedule[id])
             {
                 case 0:

+ 1 - 1
ComputeGraph/examples/example1/graph.py

@@ -1,4 +1,4 @@
-from cmsisdsp.cg.static.scheduler import *
+from cmsisdsp.cg.scheduler import *
 
 ### Define new types of Nodes 
 

+ 195 - 0
ComputeGraph/examples/example10/AppNodes.h

@@ -0,0 +1,195 @@
+/* ----------------------------------------------------------------------
+ * Project:      CMSIS DSP Library
+ * Title:        AppNodes.h
+ * Description:  Application nodes for Example 1
+ *
+ * $Date:        29 July 2021
+ * $Revision:    V1.10.0
+ *
+ * Target Processor: Cortex-M and Cortex-A cores
+ * -------------------------------------------------------------------- */
+/*
+ * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _APPNODES_H_
+#define _APPNODES_H_
+
+#include <iostream>
+#include <cstdio>
+
+static int count=0;
+
+template<typename OUT,int outputSize>
+class SourceOdd;
+
+template<typename OUT,int outputSize>
+class SourceEven;
+
+template<>
+class SourceOdd<int16_t,1>: public GenericSource<int16_t,1>
+{
+public:
+    SourceOdd(FIFOBase<int16_t> &dst):
+    GenericSource<int16_t,1>(dst){};
+
+    int prepareForRunning() override
+    {
+        if (this->willOverflow())
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
+    int run() override{
+        if (count & 1)
+        {
+           int16_t *b=this->getWriteBuffer();
+           b[0] = count;
+        }
+        return(0);
+    };
+
+
+
+};
+
+template<>
+class SourceEven<int16_t,1>: public GenericSource<int16_t,1>
+{
+public:
+    SourceEven(FIFOBase<int16_t> &dst):
+    GenericSource<int16_t,1>(dst){};
+
+    int prepareForRunning() override
+    {
+        if (this->willOverflow())
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
+    int run() override{
+        if (!(count & 1))
+        {
+           int16_t *b=this->getWriteBuffer();
+           b[0] = count;
+        }
+        return(0);
+    };
+
+
+};
+
+template<typename INA, int inputSizeA,
+         typename INB, int inputSizeB,
+         typename OUT,int outputSize>
+class ProcessingOddEven;
+
+template<>
+class ProcessingOddEven<int16_t,1,
+                        int16_t,1,
+                        int16_t,1>: 
+public GenericNode21<int16_t,1,
+                     int16_t,1,
+                     int16_t,1>
+{
+public:
+    ProcessingOddEven(FIFOBase<int16_t> &srcOdd,
+                      FIFOBase<int16_t> &srcEven,
+                      FIFOBase<int16_t> &dst):
+    GenericNode21<int16_t,1,
+                  int16_t,1,
+                  int16_t,1>(srcOdd,srcEven,dst){};
+
+    int prepareForRunning() override
+    {
+        if (this->willOverflow())
+        {
+            return(CG_SKIP_EXECUTION_ID_CODE);
+        }
+        return(0);
+    };
+
+    int run()  override{
+        int16_t oddVal=0;
+        int16_t evenVal=0;
+        if (!this->willUnderflow1())
+        {
+           int16_t *odd=this->getReadBuffer1();
+           oddVal=odd[0];
+        }
+
+        if (!this->willUnderflow2())
+        {
+           int16_t *even=this->getReadBuffer2();
+           evenVal=even[0];
+        }
+
+        int16_t *dst=this->getWriteBuffer();
+        
+        dst[0] = (evenVal + oddVal);
+       
+        return(0);
+    };
+
+};
+
+template<typename IN, int inputSize>
+class SinkAsync;
+
+template<int inputSize>
+class SinkAsync<int16_t,inputSize>: 
+public GenericSink<int16_t, inputSize>
+{
+public:
+    SinkAsync(FIFOBase<int16_t> &src):
+    GenericSink<int16_t,inputSize>(src){
+    };
+
+    int prepareForRunning() override
+    {
+        if (this->willUnderflow())
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
+    int run()  override
+    {
+        int16_t *b=this->getReadBuffer();
+        for(int i=0;i<inputSize;i++)
+        {
+            printf("%d\n",b[i]);
+        }
+        return(0);
+    };
+
+    
+
+};
+
+void compute(int16_t *in,int16_t *out, int nb)
+{
+   out[0] = in[0];
+}
+#endif

+ 13 - 0
ComputeGraph/examples/example10/CMakeLists.txt

@@ -0,0 +1,13 @@
+cmake_minimum_required (VERSION 3.14)
+include(CMakePrintHelpers)
+
+project(Example10)
+
+
+add_executable(example10 main.cpp)
+
+sdf(example10)
+add_sdf_dir(example10)
+
+target_include_directories(example10 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(example10 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/generated)

+ 9 - 0
ComputeGraph/examples/example10/custom.h

@@ -0,0 +1,9 @@
+#ifndef _CUSTOM_H_
+
+#include "cg_status.h"
+
+#define CG_BEFORE_BUFFER __ALIGNED(4)
+
+#define CG_AFTER_ITERATION count++
+
+#endif 

+ 297 - 0
ComputeGraph/examples/example10/generated/scheduler.cpp

@@ -0,0 +1,297 @@
+/*
+
+Generated with CMSIS-DSP Compute Graph Scripts.
+The generated code is not covered by CMSIS-DSP license.
+
+The support classes and code is covered by CMSIS-DSP license.
+
+*/
+
+
+#include "arm_math.h"
+#include "custom.h"
+#include "GenericNodes.h"
+#include "AppNodes.h"
+#include "scheduler.h"
+
+#if !defined(CHECKERROR)
+#define CHECKERROR       if (cgStaticError < 0) \
+       {\
+         goto errorHandling;\
+       }
+
+#endif
+
+#if !defined(CG_BEFORE_ITERATION)
+#define CG_BEFORE_ITERATION
+#endif 
+
+#if !defined(CG_AFTER_ITERATION)
+#define CG_AFTER_ITERATION
+#endif 
+
+#if !defined(CG_BEFORE_SCHEDULE)
+#define CG_BEFORE_SCHEDULE
+#endif
+
+#if !defined(CG_AFTER_SCHEDULE)
+#define CG_AFTER_SCHEDULE
+#endif
+
+#if !defined(CG_BEFORE_BUFFER)
+#define CG_BEFORE_BUFFER
+#endif
+
+#if !defined(CG_BEFORE_FIFO_BUFFERS)
+#define CG_BEFORE_FIFO_BUFFERS
+#endif
+
+#if !defined(CG_BEFORE_FIFO_INIT)
+#define CG_BEFORE_FIFO_INIT
+#endif
+
+#if !defined(CG_BEFORE_NODE_INIT)
+#define CG_BEFORE_NODE_INIT
+#endif
+
+#if !defined(CG_AFTER_INCLUDES)
+#define CG_AFTER_INCLUDES
+#endif
+
+#if !defined(CG_BEFORE_SCHEDULER_FUNCTION)
+#define CG_BEFORE_SCHEDULER_FUNCTION
+#endif
+
+#if !defined(CG_BEFORE_NODE_EXECUTION)
+#define CG_BEFORE_NODE_EXECUTION
+#endif
+
+#if !defined(CG_AFTER_NODE_EXECUTION)
+#define CG_AFTER_NODE_EXECUTION
+#endif
+
+CG_AFTER_INCLUDES
+
+
+/*
+
+Description of the scheduling. 
+
+*/
+static unsigned int schedule[7]=
+{ 
+5,6,2,0,1,3,4,
+};
+
+CG_BEFORE_FIFO_BUFFERS
+/***********
+
+FIFO buffers
+
+************/
+#define FIFOSIZE0 2
+#define FIFOSIZE1 2
+#define FIFOSIZE2 2
+#define FIFOSIZE3 2
+#define FIFOSIZE4 2
+#define FIFOSIZE5 2
+
+#define BUFFERSIZE1 2
+CG_BEFORE_BUFFER
+int16_t buf1[BUFFERSIZE1]={0};
+
+#define BUFFERSIZE2 2
+CG_BEFORE_BUFFER
+int16_t buf2[BUFFERSIZE2]={0};
+
+#define BUFFERSIZE3 2
+CG_BEFORE_BUFFER
+int16_t buf3[BUFFERSIZE3]={0};
+
+#define BUFFERSIZE4 2
+CG_BEFORE_BUFFER
+int16_t buf4[BUFFERSIZE4]={0};
+
+#define BUFFERSIZE5 2
+CG_BEFORE_BUFFER
+int16_t buf5[BUFFERSIZE5]={0};
+
+#define BUFFERSIZE6 2
+CG_BEFORE_BUFFER
+int16_t buf6[BUFFERSIZE6]={0};
+
+
+CG_BEFORE_SCHEDULER_FUNCTION
+uint32_t scheduler(int *error)
+{
+    int cgStaticError=0;
+    uint32_t nbSchedule=0;
+    int32_t debugCounter=10;
+
+    CG_BEFORE_FIFO_INIT;
+    /*
+    Create FIFOs objects
+    */
+    FIFO<int16_t,FIFOSIZE0,0,1> fifo0(buf1);
+    FIFO<int16_t,FIFOSIZE1,0,1> fifo1(buf2);
+    FIFO<int16_t,FIFOSIZE2,0,1> fifo2(buf3);
+    FIFO<int16_t,FIFOSIZE3,0,1> fifo3(buf4);
+    FIFO<int16_t,FIFOSIZE4,0,1> fifo4(buf5);
+    FIFO<int16_t,FIFOSIZE5,0,1> fifo5(buf6);
+
+    CG_BEFORE_NODE_INIT;
+    /* 
+    Create node objects
+    */
+    Duplicate2<int16_t,1,int16_t,1,int16_t,1> dup0(fifo3,fifo4,fifo5);
+    ProcessingOddEven<int16_t,1,int16_t,1,int16_t,1> proc(fifo0,fifo1,fifo2);
+    SinkAsync<int16_t,1> sinka(fifo4);
+    SinkAsync<int16_t,1> sinkb(fifo5);
+    SourceEven<int16_t,1> sourceEven(fifo1);
+    SourceOdd<int16_t,1> sourceOdd(fifo0);
+
+    /* Run several schedule iterations */
+    CG_BEFORE_SCHEDULE;
+    while((cgStaticError==0) && (debugCounter > 0))
+    {
+        /* Run a schedule iteration */
+        CG_BEFORE_ITERATION;
+        for(unsigned long id=0 ; id < 7; id++)
+        {
+            CG_BEFORE_NODE_EXECUTION;
+
+            cgStaticError = 0;
+            switch(schedule[id])
+            {
+                case 0:
+                {
+                                        
+                    bool canRun=true;
+                    canRun &= !fifo2.willUnderflowWith(1);
+                    canRun &= !fifo3.willOverflowWith(1);
+
+                    if (!canRun)
+                    {
+                      cgStaticError = CG_SKIP_EXECUTION_ID_CODE;
+                    }
+                    else
+                    {
+                        cgStaticError = 0;
+                    }
+                }
+                break;
+
+                case 1:
+                {
+                    cgStaticError = dup0.prepareForRunning();
+                }
+                break;
+
+                case 2:
+                {
+                    cgStaticError = proc.prepareForRunning();
+                }
+                break;
+
+                case 3:
+                {
+                    cgStaticError = sinka.prepareForRunning();
+                }
+                break;
+
+                case 4:
+                {
+                    cgStaticError = sinkb.prepareForRunning();
+                }
+                break;
+
+                case 5:
+                {
+                    cgStaticError = sourceEven.prepareForRunning();
+                }
+                break;
+
+                case 6:
+                {
+                    cgStaticError = sourceOdd.prepareForRunning();
+                }
+                break;
+
+                default:
+                break;
+            }
+
+            if (cgStaticError == CG_SKIP_EXECUTION_ID_CODE)
+                continue;
+
+            CHECKERROR;
+
+            switch(schedule[id])
+            {
+                case 0:
+                {
+                   
+                  {
+
+                   int16_t* i0;
+                   int16_t* o1;
+                   i0=fifo2.getReadBuffer(1);
+                   o1=fifo3.getWriteBuffer(1);
+                   compute(i0,o1,1);
+                   cgStaticError = 0;
+                  }
+                }
+                break;
+
+                case 1:
+                {
+                   cgStaticError = dup0.run();
+                }
+                break;
+
+                case 2:
+                {
+                   cgStaticError = proc.run();
+                }
+                break;
+
+                case 3:
+                {
+                   cgStaticError = sinka.run();
+                }
+                break;
+
+                case 4:
+                {
+                   cgStaticError = sinkb.run();
+                }
+                break;
+
+                case 5:
+                {
+                   cgStaticError = sourceEven.run();
+                }
+                break;
+
+                case 6:
+                {
+                   cgStaticError = sourceOdd.run();
+                }
+                break;
+
+                default:
+                break;
+            }
+            CG_AFTER_NODE_EXECUTION;
+            CHECKERROR;
+        }
+       debugCounter--;
+       CG_AFTER_ITERATION;
+       nbSchedule++;
+    }
+
+errorHandling:
+    CG_AFTER_SCHEDULE;
+    *error=cgStaticError;
+    return(nbSchedule);
+}

+ 26 - 0
ComputeGraph/examples/example10/generated/scheduler.h

@@ -0,0 +1,26 @@
+/*
+
+Generated with CMSIS-DSP Compute Graph Scripts.
+The generated code is not covered by CMSIS-DSP license.
+
+The support classes and code is covered by CMSIS-DSP license.
+
+*/
+
+#ifndef _SCHEDULER_H_ 
+#define _SCHEDULER_H_
+
+#ifdef   __cplusplus
+extern "C"
+{
+#endif
+
+
+extern uint32_t scheduler(int *error);
+
+#ifdef   __cplusplus
+}
+#endif
+
+#endif
+

+ 132 - 0
ComputeGraph/examples/example10/graph.py

@@ -0,0 +1,132 @@
+from cmsisdsp.cg.scheduler import *
+
+### Define new types of Nodes 
+
+  
+
+class SinkAsync(GenericSink):
+    def __init__(self,name,theType,inLength):
+        GenericSink.__init__(self,name)
+        self.addInput("i",theType,inLength)
+
+    @property
+    def typeName(self):
+        return "SinkAsync"
+
+class SourceOdd(GenericSource):
+    def __init__(self,name,theType,inLength):
+        GenericSource.__init__(self,name)
+        self.addOutput("o",theType,inLength)
+
+    @property
+    def typeName(self):
+        return "SourceOdd"
+
+class SourceEven(GenericSource):
+    def __init__(self,name,theType,inLength):
+        GenericSource.__init__(self,name)
+        self.addOutput("o",theType,inLength)
+
+    @property
+    def typeName(self):
+        return "SourceEven"
+
+class ProcessingOddEven(GenericNode):
+    def __init__(self,name,theType,inLength,outLength):
+        GenericNode.__init__(self,name)
+        self.addInput("ia",theType,inLength)
+        self.addInput("ib",theType,inLength)
+        self.addOutput("o",theType,outLength)
+
+    @property
+    def typeName(self):
+        return "ProcessingOddEven"
+
+
+
+### Define nodes
+dataType=CType(SINT16)
+odd=SourceOdd("sourceOdd",dataType,1)
+even=SourceEven("sourceEven",dataType,1)
+
+proc=ProcessingOddEven("proc",dataType,1,1)
+comp=Unary("compute",dataType,1)
+
+sinka=SinkAsync("sinka",dataType,1)
+sinkb=SinkAsync("sinkb",dataType,1)
+
+g = Graph()
+
+# Option to customize the default class
+# to use for Duplicate and FIFO
+# FIFO class can also be changed in the connect
+# function to change the class for a specific
+# connection
+g.defaultFIFOClass = "FIFO"
+g.duplicateNodeClassName = "Duplicate"
+
+g.connect(odd.o,proc.ia)
+g.connect(even.o,proc.ib)
+
+g.connect(proc.o,comp.i)
+g.connect(comp.o,sinka.i)
+g.connect(comp.o,sinkb.i)
+
+
+print("Generate graphviz and code")
+
+conf=Configuration()
+conf.debugLimit=10
+conf.cOptionalArgs=""
+
+# It is disabled in asynchronous mode
+# since the schedule has no mor any reason to
+# be periodic and thus the FIFO content can
+# overlap several executions of the schedule
+conf.memoryOptimization=True
+
+conf.codeArray = True
+conf.switchCase = True
+
+# Asynchronous mode enable. It implies
+# switchCase and codeArray true
+conf.asynchronous = True 
+
+# Increase size of synchronous FIFOs by 100%
+# for the asynchronous case (so 2 samples
+# instead of 1 in this example)
+conf.FIFOIncrease = 100 # percent
+
+
+#conf.displayFIFOSizes=True
+# Prefix for global FIFO buffers
+#conf.prefix="sched1"
+
+#conf.dumpSchedule = True 
+sched = g.computeSchedule(config=conf)
+#print(sched.schedule)
+print("Schedule length = %d" % sched.scheduleLength)
+print("Memory usage %d bytes" % sched.memory)
+#
+
+
+#conf.postCustomCName = "post.h"
+#conf.CAPI = True
+#conf.prefix="global"
+#conf.dumpFIFO = True
+#conf.CMSISDSP = False
+#conf.codeArray = False
+#conf.switchCase = False
+
+# For pure functions (like CMSIS-DSP) which are not
+# packaged in a C++ class, we have to decide of the
+# asynchronous policy. What must be done in case of
+# FIFO overflow or underflow.
+# By default, the execution is skipped.
+conf.asyncDefaultSkip = True 
+
+sched.ccode("./generated",conf)
+
+with open("test.dot","w") as f:
+    sched.graphviz(f)
+

+ 11 - 0
ComputeGraph/examples/example10/main.cpp

@@ -0,0 +1,11 @@
+#include <cstdio>
+#include <cstdint>
+#include "scheduler.h"
+
+int main(int argc, char const *argv[])
+{
+    int error;
+    printf("Start\n");
+    uint32_t nbSched=scheduler(&error);
+    return 0;
+}

+ 104 - 0
ComputeGraph/examples/example10/test.dot

@@ -0,0 +1,104 @@
+
+
+
+
+digraph structs {
+    node [shape=plaintext]
+    rankdir=LR
+    edge [arrowsize=0.5]
+    fontname="times"
+
+
+compute1 [label=<
+<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
+  <TR>
+    <TD ALIGN="CENTER" PORT="i">compute<BR/>(Function)</TD>
+  </TR>
+</TABLE>>];
+
+dup0 [shape=point,label=dup0]
+
+
+proc [label=<
+<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
+  <TR>
+    <TD PORT="ia"><FONT POINT-SIZE="9.0">ia</FONT></TD>
+    <TD ALIGN="CENTER" ROWSPAN="2">proc<BR/>(ProcessingOddEven)</TD>
+    <TD PORT="o"><FONT POINT-SIZE="9.0">o</FONT></TD>
+  </TR>
+<TR>
+<TD PORT="ib"><FONT POINT-SIZE="9.0">ib</FONT></TD>
+
+ 
+<TD></TD></TR>
+
+</TABLE>>];
+
+sinka [label=<
+<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
+  <TR>
+    <TD ALIGN="CENTER" PORT="i">sinka<BR/>(SinkAsync)</TD>
+  </TR>
+</TABLE>>];
+
+sinkb [label=<
+<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
+  <TR>
+    <TD ALIGN="CENTER" PORT="i">sinkb<BR/>(SinkAsync)</TD>
+  </TR>
+</TABLE>>];
+
+sourceEven [label=<
+<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
+  <TR>
+    <TD ALIGN="CENTER" PORT="i">sourceEven<BR/>(SourceEven)</TD>
+  </TR>
+</TABLE>>];
+
+sourceOdd [label=<
+<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
+  <TR>
+    <TD ALIGN="CENTER" PORT="i">sourceOdd<BR/>(SourceOdd)</TD>
+  </TR>
+</TABLE>>];
+
+
+
+sourceOdd:i -> proc:ia [label="s16(2)"
+,headlabel=<<TABLE BORDER="0" CELLPADDING="2"><TR><TD><FONT COLOR="blue" POINT-SIZE="12.0" >1</FONT>
+</TD></TR></TABLE>>
+,taillabel=<<TABLE BORDER="0" CELLPADDING="2"><TR><TD><FONT COLOR="blue" POINT-SIZE="12.0" >1</FONT>
+</TD></TR></TABLE>>]
+
+sourceEven:i -> proc:ib [label="s16(2)"
+,headlabel=<<TABLE BORDER="0" CELLPADDING="2"><TR><TD><FONT COLOR="blue" POINT-SIZE="12.0" >1</FONT>
+</TD></TR></TABLE>>
+,taillabel=<<TABLE BORDER="0" CELLPADDING="2"><TR><TD><FONT COLOR="blue" POINT-SIZE="12.0" >1</FONT>
+</TD></TR></TABLE>>]
+
+proc:o -> compute1:i [label="s16(2)"
+,headlabel=<<TABLE BORDER="0" CELLPADDING="2"><TR><TD><FONT COLOR="blue" POINT-SIZE="12.0" >1</FONT>
+</TD></TR></TABLE>>
+,taillabel=<<TABLE BORDER="0" CELLPADDING="2"><TR><TD><FONT COLOR="blue" POINT-SIZE="12.0" >1</FONT>
+</TD></TR></TABLE>>]
+
+compute1:i ->  
+dup0 [label="s16(2)"
+
+,taillabel=<<TABLE BORDER="0" CELLPADDING="2"><TR><TD><FONT COLOR="blue" POINT-SIZE="12.0" >1</FONT>
+</TD></TR></TABLE>>]
+
+ 
+dup0 -> sinka:i [label="s16(2)"
+,headlabel=<<TABLE BORDER="0" CELLPADDING="2"><TR><TD><FONT COLOR="blue" POINT-SIZE="12.0" >1</FONT>
+</TD></TR></TABLE>>
+]
+
+ 
+dup0 -> sinkb:i [label="s16(2)"
+,headlabel=<<TABLE BORDER="0" CELLPADDING="2"><TR><TD><FONT COLOR="blue" POINT-SIZE="12.0" >1</FONT>
+</TD></TR></TABLE>>
+]
+
+
+}

BIN
ComputeGraph/examples/example10/test.pdf


+ 34 - 0
ComputeGraph/examples/example2/AppNodes.h

@@ -39,6 +39,17 @@ class TFLite: public GenericSink<IN, inputSize>
 public:
     TFLite(FIFOBase<IN> &src):GenericSink<IN,inputSize>(src){};
 
+    int prepareForRunning() override
+    {
+        if (this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run()
     {
         IN *b=this->getReadBuffer();
@@ -58,6 +69,17 @@ class StereoSource: GenericSource<OUT,outputSize>
 public:
     StereoSource(FIFOBase<OUT> &dst):GenericSource<OUT,outputSize>(dst),mCounter(0){};
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         OUT *b=this->getWriteBuffer();
 
@@ -80,6 +102,18 @@ class MFCC: public GenericNode<IN,inputSize,OUT,outputSize>
 public:
     MFCC(FIFOBase<IN> &src,FIFOBase<OUT> &dst):GenericNode<IN,inputSize,OUT,outputSize>(src,dst){};
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+    
     int run(){
         printf("MFCC\n");
         IN *a=this->getReadBuffer();

+ 43 - 35
ComputeGraph/examples/example2/generated/scheduler.cpp

@@ -72,6 +72,7 @@ The support classes and code is covered by CMSIS-DSP license.
 
 CG_AFTER_INCLUDES
 
+
 /*
 
 Description of the scheduling. 
@@ -153,15 +154,15 @@ uint32_t scheduler(int *error,int opt1,int opt2)
     /*
     Create FIFOs objects
     */
-    FIFO<float32_t,FIFOSIZE0,0> fifo0(buf1,10);
-    FIFO<float32_t,FIFOSIZE1,1> fifo1(buf2);
-    FIFO<float32_t,FIFOSIZE2,1> fifo2(buf3);
-    FIFO<float32_t,FIFOSIZE3,1> fifo3(buf4);
-    FIFO<float32_t,FIFOSIZE4,1> fifo4(buf5);
-    FIFO<float32_t,FIFOSIZE5,0> fifo5(buf6);
-    FIFO<float32_t,FIFOSIZE6,1> fifo6(buf7);
-    FIFO<float32_t,FIFOSIZE7,0> fifo7(buf8);
-    FIFO<float32_t,FIFOSIZE8,1> fifo8(buf9);
+    FIFO<float32_t,FIFOSIZE0,0,0> fifo0(buf1,10);
+    FIFO<float32_t,FIFOSIZE1,1,0> fifo1(buf2);
+    FIFO<float32_t,FIFOSIZE2,1,0> fifo2(buf3);
+    FIFO<float32_t,FIFOSIZE3,1,0> fifo3(buf4);
+    FIFO<float32_t,FIFOSIZE4,1,0> fifo4(buf5);
+    FIFO<float32_t,FIFOSIZE5,0,0> fifo5(buf6);
+    FIFO<float32_t,FIFOSIZE6,1,0> fifo6(buf7);
+    FIFO<float32_t,FIFOSIZE7,0,0> fifo7(buf8);
+    FIFO<float32_t,FIFOSIZE8,1,0> fifo8(buf9);
 
     CG_BEFORE_NODE_INIT;
     /* 
@@ -183,6 +184,7 @@ uint32_t scheduler(int *error,int opt1,int opt2)
         for(unsigned long id=0 ; id < 302; id++)
         {
             CG_BEFORE_NODE_EXECUTION;
+
             switch(schedule[id])
             {
                 case 0:
@@ -193,42 +195,48 @@ uint32_t scheduler(int *error,int opt1,int opt2)
 
                 case 1:
                 {
-                   {
-         float32_t* i0;
-         float32_t* i1;
-         float32_t* o2;
-         i0=fifo3.getReadBuffer(160);
-         i1=fifo4.getReadBuffer(160);
-         o2=fifo5.getWriteBuffer(160);
-         arm_add_f32(i0,i1,o2,160);
-         cgStaticError = 0;
-}
+                   
+                  {
+
+                   float32_t* i0;
+                   float32_t* i1;
+                   float32_t* o2;
+                   i0=fifo3.getReadBuffer(160);
+                   i1=fifo4.getReadBuffer(160);
+                   o2=fifo5.getWriteBuffer(160);
+                   arm_add_f32(i0,i1,o2,160);
+                   cgStaticError = 0;
+                  }
                 }
                 break;
 
                 case 2:
                 {
-                   {
-         float32_t* i0;
-         float32_t* o2;
-         i0=fifo1.getReadBuffer(160);
-         o2=fifo3.getWriteBuffer(160);
-         arm_scale_f32(i0,HALF,o2,160);
-         cgStaticError = 0;
-}
+                   
+                  {
+
+                   float32_t* i0;
+                   float32_t* o2;
+                   i0=fifo1.getReadBuffer(160);
+                   o2=fifo3.getWriteBuffer(160);
+                   arm_scale_f32(i0,HALF,o2,160);
+                   cgStaticError = 0;
+                  }
                 }
                 break;
 
                 case 3:
                 {
-                   {
-         float32_t* i0;
-         float32_t* o2;
-         i0=fifo2.getReadBuffer(160);
-         o2=fifo4.getWriteBuffer(160);
-         arm_scale_f32(i0,HALF,o2,160);
-         cgStaticError = 0;
-}
+                   
+                  {
+
+                   float32_t* i0;
+                   float32_t* o2;
+                   i0=fifo2.getReadBuffer(160);
+                   o2=fifo4.getWriteBuffer(160);
+                   arm_scale_f32(i0,HALF,o2,160);
+                   cgStaticError = 0;
+                  }
                 }
                 break;
 

+ 1 - 1
ComputeGraph/examples/example2/graph.py

@@ -1,4 +1,4 @@
-from cmsisdsp.cg.static.scheduler import *
+from cmsisdsp.cg.scheduler import *
 
 
 AUDIO_INTERRUPT_LENGTH = 160

+ 98 - 16
ComputeGraph/examples/example3/generated/scheduler.cpp

@@ -72,6 +72,7 @@ The support classes and code is covered by CMSIS-DSP license.
 
 CG_AFTER_INCLUDES
 
+
 /*
 
 Description of the scheduling. 
@@ -141,14 +142,14 @@ uint32_t scheduler(int *error)
     /*
     Create FIFOs objects
     */
-    FIFO<float32_t,FIFOSIZE0,0> fifo0(buf1);
-    FIFO<float32_t,FIFOSIZE1,1> fifo1(buf2);
-    FIFO<float32_t,FIFOSIZE2,1> fifo2(buf3);
-    FIFO<float32_t,FIFOSIZE3,1> fifo3(buf4);
-    FIFO<float32_t,FIFOSIZE4,1> fifo4(buf5);
-    FIFO<float32_t,FIFOSIZE5,1> fifo5(buf6);
-    FIFO<float32_t,FIFOSIZE6,1> fifo6(buf7);
-    FIFO<float32_t,FIFOSIZE7,0> fifo7(buf8);
+    FIFO<float32_t,FIFOSIZE0,0,1> fifo0(buf1);
+    FIFO<float32_t,FIFOSIZE1,0,1> fifo1(buf2);
+    FIFO<float32_t,FIFOSIZE2,0,1> fifo2(buf3);
+    FIFO<float32_t,FIFOSIZE3,0,1> fifo3(buf4);
+    FIFO<float32_t,FIFOSIZE4,0,1> fifo4(buf5);
+    FIFO<float32_t,FIFOSIZE5,0,1> fifo5(buf6);
+    FIFO<float32_t,FIFOSIZE6,0,1> fifo6(buf7);
+    FIFO<float32_t,FIFOSIZE7,0,1> fifo7(buf8);
 
     CG_BEFORE_NODE_INIT;
     /* 
@@ -172,18 +173,99 @@ uint32_t scheduler(int *error)
         for(unsigned long id=0 ; id < 25; id++)
         {
             CG_BEFORE_NODE_EXECUTION;
+
+            cgStaticError = 0;
             switch(schedule[id])
             {
                 case 0:
                 {
-                   {
-         float32_t* i0;
-         float32_t* o2;
-         i0=fifo1.getReadBuffer(256);
-         o2=fifo2.getWriteBuffer(256);
-         arm_mult_f32(i0,HANN,o2,256);
-         cgStaticError = 0;
-}
+                                        
+                    bool canRun=true;
+                    canRun &= !fifo1.willUnderflowWith(256);
+                    canRun &= !fifo2.willOverflowWith(256);
+
+                    if (!canRun)
+                    {
+                      cgStaticError = CG_SKIP_EXECUTION_ID_CODE;
+                    }
+                    else
+                    {
+                        cgStaticError = 0;
+                    }
+                }
+                break;
+
+                case 1:
+                {
+                    cgStaticError = audioOverlap.prepareForRunning();
+                }
+                break;
+
+                case 2:
+                {
+                    cgStaticError = audioWin.prepareForRunning();
+                }
+                break;
+
+                case 3:
+                {
+                    cgStaticError = cfft.prepareForRunning();
+                }
+                break;
+
+                case 4:
+                {
+                    cgStaticError = icfft.prepareForRunning();
+                }
+                break;
+
+                case 5:
+                {
+                    cgStaticError = sink.prepareForRunning();
+                }
+                break;
+
+                case 6:
+                {
+                    cgStaticError = src.prepareForRunning();
+                }
+                break;
+
+                case 7:
+                {
+                    cgStaticError = toCmplx.prepareForRunning();
+                }
+                break;
+
+                case 8:
+                {
+                    cgStaticError = toReal.prepareForRunning();
+                }
+                break;
+
+                default:
+                break;
+            }
+
+            if (cgStaticError == CG_SKIP_EXECUTION_ID_CODE)
+                continue;
+
+            CHECKERROR;
+
+            switch(schedule[id])
+            {
+                case 0:
+                {
+                   
+                  {
+
+                   float32_t* i0;
+                   float32_t* o2;
+                   i0=fifo1.getReadBuffer(256);
+                   o2=fifo2.getWriteBuffer(256);
+                   arm_mult_f32(i0,HANN,o2,256);
+                   cgStaticError = 0;
+                  }
                 }
                 break;
 

+ 2 - 1
ComputeGraph/examples/example3/graph.py

@@ -1,6 +1,6 @@
 import numpy as np 
 
-from cmsisdsp.cg.static.scheduler import *
+from cmsisdsp.cg.scheduler import *
 
 
 FS=16000
@@ -53,6 +53,7 @@ conf.debugLimit=40
 #conf.memoryOptimization=True
 
 #conf.dumpSchedule = True 
+
 sched = g.computeSchedule(conf)
 #print(sched.schedule)
 print("Schedule length = %d" % sched.scheduleLength)

+ 10 - 0
ComputeGraph/examples/example4/CMakeLists.txt

@@ -0,0 +1,10 @@
+cmake_minimum_required (VERSION 3.14)
+include(CMakePrintHelpers)
+
+project(Example4)
+
+
+add_custom_target(example4 ALL DEPENDS sched.py)
+
+sdfpython(example4)
+

+ 7 - 7
ComputeGraph/examples/example4/appnodes.py

@@ -25,12 +25,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 ############################################
-from cmsisdsp.cg.static.nodes.simu import *
+from cmsisdsp.cg.nodes.simu import *
 from custom import *
 
-from cmsisdsp.cg.static.nodes.host.FileSink import *
-from cmsisdsp.cg.static.nodes.host.FileSource import *
-from cmsisdsp.cg.static.nodes.CFFT import *
-from cmsisdsp.cg.static.nodes.ICFFT import *
-from cmsisdsp.cg.static.nodes.ToComplex import *
-from cmsisdsp.cg.static.nodes.ToReal import *
+from cmsisdsp.cg.nodes.host.FileSink import *
+from cmsisdsp.cg.nodes.host.FileSource import *
+from cmsisdsp.cg.nodes.CFFT import *
+from cmsisdsp.cg.nodes.ICFFT import *
+from cmsisdsp.cg.nodes.ToComplex import *
+from cmsisdsp.cg.nodes.ToReal import *

+ 1 - 1
ComputeGraph/examples/example4/graph.py

@@ -1,6 +1,6 @@
 import numpy as np 
 
-from cmsisdsp.cg.static.scheduler import *
+from cmsisdsp.cg.scheduler import *
 
 
 FS=16000

+ 1 - 1
ComputeGraph/examples/example4/sched.py

@@ -10,7 +10,7 @@ import sys
 
 import numpy as np
 import cmsisdsp as dsp
-from cmsisdsp.cg.static.nodes.simu import *
+from cmsisdsp.cg.nodes.simu import *
 from appnodes import * 
 from custom import *
 

+ 10 - 0
ComputeGraph/examples/example5/CMakeLists.txt

@@ -0,0 +1,10 @@
+cmake_minimum_required (VERSION 3.14)
+include(CMakePrintHelpers)
+
+project(Example5)
+
+
+add_custom_target(example5 ALL DEPENDS sched.py)
+
+sdfpython(example5)
+

+ 5 - 5
ComputeGraph/examples/example5/appnodes.py

@@ -25,16 +25,16 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 ############################################
-from cmsisdsp.cg.static.nodes.simu import *
+from cmsisdsp.cg.nodes.simu import *
 from custom import *
 
 # Host only nodes
-from cmsisdsp.cg.static.nodes.host.NumpySink import *
-from cmsisdsp.cg.static.nodes.host.WavSource import *
+from cmsisdsp.cg.nodes.host.NumpySink import *
+from cmsisdsp.cg.nodes.host.WavSource import *
 
 # Embedded nodes
-from cmsisdsp.cg.static.nodes.StereoToMono import *
-from cmsisdsp.cg.static.nodes.MFCC import *
+from cmsisdsp.cg.nodes.InterleavedStereoToMono import *
+from cmsisdsp.cg.nodes.MFCC import *
 
 
 

+ 1 - 1
ComputeGraph/examples/example5/graph.py

@@ -1,6 +1,6 @@
 import numpy as np 
 
-from cmsisdsp.cg.static.scheduler import *
+from cmsisdsp.cg.scheduler import *
 
 
 from sharedconfig import *

+ 1 - 1
ComputeGraph/examples/example5/sched.py

@@ -10,7 +10,7 @@ import sys
 
 import numpy as np
 import cmsisdsp as dsp
-from cmsisdsp.cg.static.nodes.simu import *
+from cmsisdsp.cg.nodes.simu import *
 from appnodes import * 
 from custom import *
 

BIN
ComputeGraph/examples/example5/test.pdf


+ 6 - 4
ComputeGraph/examples/example6/generated/scheduler.cpp

@@ -72,6 +72,7 @@ The support classes and code is covered by CMSIS-DSP license.
 
 CG_AFTER_INCLUDES
 
+
 /*
 
 Description of the scheduling. 
@@ -121,10 +122,10 @@ uint32_t scheduler(int *error,arm_mfcc_instance_f32 *mfccConfig)
     /*
     Create FIFOs objects
     */
-    FIFO<float32_t,FIFOSIZE0,0> fifo0(buf1);
-    FIFO<float32_t,FIFOSIZE1,1> fifo1(buf2);
-    FIFO<float32_t,FIFOSIZE2,1> fifo2(buf3);
-    FIFO<float32_t,FIFOSIZE3,0> fifo3(buf4);
+    FIFO<float32_t,FIFOSIZE0,0,0> fifo0(buf1);
+    FIFO<float32_t,FIFOSIZE1,1,0> fifo1(buf2);
+    FIFO<float32_t,FIFOSIZE2,1,0> fifo2(buf3);
+    FIFO<float32_t,FIFOSIZE3,0,0> fifo3(buf4);
 
     CG_BEFORE_NODE_INIT;
     /* 
@@ -145,6 +146,7 @@ uint32_t scheduler(int *error,arm_mfcc_instance_f32 *mfccConfig)
         for(unsigned long id=0 ; id < 17; id++)
         {
             CG_BEFORE_NODE_EXECUTION;
+
             switch(schedule[id])
             {
                 case 0:

+ 1 - 1
ComputeGraph/examples/example6/graph.py

@@ -1,6 +1,6 @@
 import numpy as np 
 
-from cmsisdsp.cg.static.scheduler import *
+from cmsisdsp.cg.scheduler import *
 
 
 from sharedconfig import *

+ 10 - 0
ComputeGraph/examples/example7/CMakeLists.txt

@@ -0,0 +1,10 @@
+cmake_minimum_required (VERSION 3.14)
+include(CMakePrintHelpers)
+
+project(Example7)
+
+
+add_custom_target(example7 ALL DEPENDS sched.py)
+
+sdfpython(example7)
+

+ 8 - 8
ComputeGraph/examples/example7/appnodes.py

@@ -25,17 +25,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 ############################################
-from cmsisdsp.cg.static.nodes.simu import *
+from cmsisdsp.cg.nodes.simu import *
 from custom import *
 
-from cmsisdsp.cg.static.nodes.host.FileSink import *
-from cmsisdsp.cg.static.nodes.host.FileSource import *
-from cmsisdsp.cg.static.nodes.CFFT import *
-from cmsisdsp.cg.static.nodes.ICFFT import *
-from cmsisdsp.cg.static.nodes.ToComplex import *
-from cmsisdsp.cg.static.nodes.ToReal import *
+from cmsisdsp.cg.nodes.host.FileSink import *
+from cmsisdsp.cg.nodes.host.FileSource import *
+from cmsisdsp.cg.nodes.CFFT import *
+from cmsisdsp.cg.nodes.ICFFT import *
+from cmsisdsp.cg.nodes.ToComplex import *
+from cmsisdsp.cg.nodes.ToReal import *
 
-from cmsisdsp.cg.static.nodes.host.VHTCGSTATIC import *
+from cmsisdsp.cg.nodes.host.VHTCGSTATIC import *
 
 
 

+ 1 - 1
ComputeGraph/examples/example7/custom.py

@@ -1,4 +1,4 @@
-from cmsisdsp.cg.static.nodes.simu import *
+from cmsisdsp.cg.nodes.simu import *
 
 import numpy as np 
 import cmsisdsp as dsp

+ 1 - 1
ComputeGraph/examples/example7/graph.py

@@ -1,6 +1,6 @@
 import numpy as np 
 
-from cmsisdsp.cg.static.scheduler import *
+from cmsisdsp.cg.scheduler import *
 
 
 class Processing(GenericNode):

+ 1 - 1
ComputeGraph/examples/example7/sched.py

@@ -10,7 +10,7 @@ import sys
 
 import numpy as np
 import cmsisdsp as dsp
-from cmsisdsp.cg.static.nodes.simu import *
+from cmsisdsp.cg.nodes.simu import *
 from appnodes import * 
 from custom import *
 

+ 35 - 0
ComputeGraph/examples/example8/AppNodes.h

@@ -36,6 +36,17 @@ class Sink: public GenericSink<IN, inputSize>
 public:
     Sink(FIFOBase<IN> &src):GenericSink<IN,inputSize>(src){};
 
+    int prepareForRunning() override
+    {
+        if (this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run()
     {
         IN *b=this->getReadBuffer();
@@ -58,6 +69,17 @@ class Source<complex,outputSize>: GenericSource<complex,outputSize>
 public:
     Source(FIFOBase<complex> &dst):GenericSource<complex,outputSize>(dst),mCounter(0){};
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         complex *b=this->getWriteBuffer();
 
@@ -90,6 +112,19 @@ public:
                   OUT1,outputSize1,
                   OUT2,outputSize2>(src,dst1,dst2){};
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow1() ||
+            this->willOverflow2() ||
+            this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+    
     int run(){
         printf("ProcessingNode\n");
         IN *a=this->getReadBuffer();

+ 8 - 6
ComputeGraph/examples/example8/generated/scheduler.cpp

@@ -72,6 +72,7 @@ The support classes and code is covered by CMSIS-DSP license.
 
 CG_AFTER_INCLUDES
 
+
 /*
 
 Description of the scheduling. 
@@ -131,12 +132,12 @@ uint32_t scheduler(int *error,int someVariable)
     /*
     Create FIFOs objects
     */
-    FIFO<complex,FIFOSIZE0,0> fifo0(buf1);
-    FIFO<complex,FIFOSIZE1,1> fifo1(buf2);
-    FIFO<complex,FIFOSIZE2,1> fifo2(buf3);
-    FIFO<complex,FIFOSIZE3,1> fifo3(buf4);
-    FIFO<complex,FIFOSIZE4,1> fifo4(buf5);
-    FIFO<complex,FIFOSIZE5,1> fifo5(buf6);
+    FIFO<complex,FIFOSIZE0,0,0> fifo0(buf1);
+    FIFO<complex,FIFOSIZE1,1,0> fifo1(buf2);
+    FIFO<complex,FIFOSIZE2,1,0> fifo2(buf3);
+    FIFO<complex,FIFOSIZE3,1,0> fifo3(buf4);
+    FIFO<complex,FIFOSIZE4,1,0> fifo4(buf5);
+    FIFO<complex,FIFOSIZE5,1,0> fifo5(buf6);
 
     CG_BEFORE_NODE_INIT;
     /* 
@@ -159,6 +160,7 @@ uint32_t scheduler(int *error,int someVariable)
         for(unsigned long id=0 ; id < 37; id++)
         {
             CG_BEFORE_NODE_EXECUTION;
+
             switch(schedule[id])
             {
                 case 0:

+ 1 - 1
ComputeGraph/examples/example8/graph.py

@@ -1,4 +1,4 @@
-from cmsisdsp.cg.static.scheduler import *
+from cmsisdsp.cg.scheduler import *
 
 ### Define new types of Nodes 
 

+ 35 - 0
ComputeGraph/examples/example9/AppNodes.h

@@ -36,6 +36,17 @@ class Sink: public GenericSink<IN, inputSize>
 public:
     Sink(FIFOBase<IN> &src):GenericSink<IN,inputSize>(src){};
 
+    int prepareForRunning() override
+    {
+        if (this->willUnderflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run()
     {
         IN *b=this->getReadBuffer();
@@ -55,6 +66,17 @@ class Source: GenericSource<OUT,outputSize>
 public:
     Source(FIFOBase<OUT> &dst):GenericSource<OUT,outputSize>(dst),mCounter(0){};
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         OUT *b=this->getWriteBuffer();
 
@@ -91,6 +113,19 @@ public:
                           float32_t,inputSize,
                           float32_t,inputSize>(src1,src2,dst){};
 
+    int prepareForRunning() override
+    {
+        if (this->willOverflow() ||
+            this->willUnderflow1() ||
+            this->willUnderflow2()
+           )
+        {
+           return(CG_SKIP_EXECUTION_ID_CODE); // Skip execution
+        }
+
+        return(0);
+    };
+
     int run(){
         printf("ProcessingNode\n");
         float32_t *a=this->getReadBuffer1();

+ 6 - 4
ComputeGraph/examples/example9/generated/scheduler.cpp

@@ -72,6 +72,7 @@ The support classes and code is covered by CMSIS-DSP license.
 
 CG_AFTER_INCLUDES
 
+
 /*
 
 Description of the scheduling. 
@@ -121,10 +122,10 @@ uint32_t scheduler(int *error,int someVariable)
     /*
     Create FIFOs objects
     */
-    FIFO<float32_t,FIFOSIZE0,1> fifo0(buf1);
-    FIFO<float32_t,FIFOSIZE1,1> fifo1(buf2);
-    FIFO<float32_t,FIFOSIZE2,1> fifo2(buf3);
-    FIFO<float32_t,FIFOSIZE3,0> fifo3(buf4,5);
+    FIFO<float32_t,FIFOSIZE0,1,0> fifo0(buf1);
+    FIFO<float32_t,FIFOSIZE1,1,0> fifo1(buf2);
+    FIFO<float32_t,FIFOSIZE2,1,0> fifo2(buf3);
+    FIFO<float32_t,FIFOSIZE3,0,0> fifo3(buf4,5);
 
     CG_BEFORE_NODE_INIT;
     /* 
@@ -144,6 +145,7 @@ uint32_t scheduler(int *error,int someVariable)
         for(unsigned long id=0 ; id < 4; id++)
         {
             CG_BEFORE_NODE_EXECUTION;
+
             switch(schedule[id])
             {
                 case 0:

+ 1 - 1
ComputeGraph/examples/example9/graph.py

@@ -1,4 +1,4 @@
-from cmsisdsp.cg.static.scheduler import *
+from cmsisdsp.cg.scheduler import *
 
 ### Define new types of Nodes 
 

+ 1 - 1
MANIFEST.in

@@ -2,6 +2,6 @@ include PythonWrapper_README.md
 recursive-include Include *.h 
 recursive-include PrivateInclude *.h 
 recursive-include PythonWrapper/cmsisdsp_pkg/src *.h 
-include cmsisdsp/cg/static/scheduler/templates/*
+include cmsisdsp/cg/scheduler/templates/*
 include Source/DistanceFunctions/arm_boolean_distance_template.h
 

+ 1 - 1
cmsisdsp/__init__.py

@@ -20,7 +20,7 @@ from cmsisdsp_window import *
 __version__ = cmsisdsp.version.__version__
 
 # CMSIS-DSP Version used to build the wrapper
-cmsis_dsp_version="1.15.0"
+cmsis_dsp_version="1.14.4"
 
 
 # CMSIS-DSP Commit hash used to build the wrapper

+ 1 - 1
cmsisdsp/cg/static/nodes/CFFT.py → cmsisdsp/cg/nodes/CFFT.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/Duplicate.py → cmsisdsp/cg/nodes/Duplicate.py

@@ -8,7 +8,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/ICFFT.py → cmsisdsp/cg/nodes/ICFFT.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/InterleavedStereoToMono.py → cmsisdsp/cg/nodes/InterleavedStereoToMono.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/MFCC.py → cmsisdsp/cg/nodes/MFCC.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/NullSink.py → cmsisdsp/cg/nodes/NullSink.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/ToComplex.py → cmsisdsp/cg/nodes/ToComplex.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/ToReal.py → cmsisdsp/cg/nodes/ToReal.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/Unzip.py → cmsisdsp/cg/nodes/Unzip.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/Zip.py → cmsisdsp/cg/nodes/Zip.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 2 - 2
cmsisdsp/cg/static/nodes/__init__.py → cmsisdsp/cg/nodes/__init__.py

@@ -1,7 +1,7 @@
 ###########################################
 # Project:      CMSIS DSP Library
 # Title:        __init__.py
-# Description:  CG static flow module
+# Description:  CG default nodes
 # 
 # $Date:        30 August 2021
 # $Revision:    V1.10.0
@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/host/FileSink.py → cmsisdsp/cg/nodes/host/FileSink.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/host/FileSource.py → cmsisdsp/cg/nodes/host/FileSource.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/host/NumpySink.py → cmsisdsp/cg/nodes/host/NumpySink.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 1 - 1
cmsisdsp/cg/static/nodes/host/VHT.py → cmsisdsp/cg/nodes/host/VHT.py

@@ -1,7 +1,7 @@
 from multiprocessing import Process,Semaphore
 import multiprocessing as mp
 import socket
-import cmsisdsp.cg.static.nodes.host.message as msg
+import cmsisdsp.cg.nodes.host.message as msg
 
 HOST = '127.0.0.1'    # The remote host
 PORT = 50007 

+ 0 - 0
cmsisdsp/cg/static/nodes/host/VHTCGSTATIC.py → cmsisdsp/cg/nodes/host/VHTCGSTATIC.py


+ 1 - 1
cmsisdsp/cg/static/nodes/host/WavSink.py → cmsisdsp/cg/nodes/host/WavSink.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

+ 0 - 0
cmsisdsp/cg/static/nodes/host/WavSource.py → cmsisdsp/cg/nodes/host/WavSource.py


+ 0 - 0
cmsisdsp/cg/static/nodes/host/__init__.py → cmsisdsp/cg/nodes/host/__init__.py


+ 1 - 1
cmsisdsp/cg/static/nodes/host/message.py → cmsisdsp/cg/nodes/host/message.py

@@ -107,7 +107,7 @@ def getBufferMsg(conn,nbBytes):
     data = receiveBytes(conn,nbBytes)
     return(data)
 
-# Stop the server when the end of the static scheduling has been reached.
+# Stop the server when the end of the scheduling has been reached.
 # It is to make it easier to end the demo.
 # Only the VHT client has to be killed.
 # Client -> Server

+ 1 - 1
cmsisdsp/cg/static/nodes/simu.py → cmsisdsp/cg/nodes/simu.py

@@ -9,7 +9,7 @@
 # Target Processor: Cortex-M and Cortex-A cores
 # -------------------------------------------------------------------- */
 # 
-# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
+# Copyright (C) 2010-2023 ARM Limited or its affiliates. All rights reserved.
 # 
 # SPDX-License-Identifier: Apache-2.0
 # 

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است