Added support for CMSIS Event Recorder to the Compute Graph.

Added also more customization options for the compute graph.
pull/53/head v1.14.0
Christophe Favergeon 3 years ago
parent 142dcec5c3
commit b8177102d9

@ -111,6 +111,7 @@
<file category="header" name="ComputeGraph/cg/static/src/GenericNodes.h"/> <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/nodes/cpp/"/>
<file category="include" name="ComputeGraph/cg/static/src/"/> <file category="include" name="ComputeGraph/cg/static/src/"/>
<file category="other" name="ComputeGraph/cg.scvd" />
</files> </files>
</component> </component>
</components> </components>

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Project: CMSIS DSP Library
Title: cg.SCVD
Description: Event definitions for use in Keil MDK
$Date: 19 September 2022
Target Processor: Cortex-M and Cortex-A cores
Copyright (C) 2010-2022 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.
-->
<component_viewer schemaVersion="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
<component name="CMSIS-DSP Compute Graph" version="1.0.0"/> <!-- name and version of the component -->
<events>
<group name="CMSIS-DSP Compute Graph">
<component name="Scheduler" brief="CG" no="0x01" prefix="EvrSchedCG_" info="CG Static Scheduler"/>
</group>
<event id="0x0100 + 0x00" level="API" property="ScheduleIteration" info="New iteration of scheduling loop" value="nb=%d[val1]" />
<event id="0x0100 + 0x01" level="API" property="NodeExecution" info="Execution of a node" value="ID=%d[val1]" />
<event id="0x0100 + 0x02" level="NodeError" property="Error" info="Error during execution of a node" value="err=%d[val1]" />
</events>
</component_viewer>

@ -389,4 +389,13 @@ public:
} }
#endif #endif
#if !defined(CG_BEFORE_ITERATION)
#define CG_BEFORE_ITERATION
#endif
#if !defined(CG_AFTER_ITERATION)
#define CG_AFTER_ITERATION
#endif
#endif #endif

@ -181,6 +181,7 @@ There are other fields for the configuration:
- `memoryOptimization` : Experimental. It is attempting to reuse buffer memory and share it between several FIFOs - `memoryOptimization` : Experimental. It is attempting to reuse buffer memory and share it between several FIFOs
- `pathToSDFModule` : Path to the Python SDF module so that the generated Python code can find it - `pathToSDFModule` : Path to the Python SDF module so that the generated Python code can find it
- `codeArray` : Experimental. When a schedule is very long, representing it as a sequence of function calls is not good for the code size of the generated solution. When this option is enabled, the schedule is described with an array. It implies that the pure function calls cannot be inlined any more and are replaced by new nodes which are automatically generated. - `codeArray` : Experimental. When a schedule is very long, representing it as a sequence of function calls is not good for the code size of the generated solution. When this option is enabled, the schedule is described with an array. It implies that the pure function calls cannot be inlined any more and are replaced by new nodes which are automatically generated.
- `eventRecorder` : Enable the support for the CMSIS Event Recorder.
In the example 1, we are passing a variable to initialize the node of type ProcessingNode. So, it would be great if this variable was an argument of the scheduler function. So we define: In the example 1, we are passing a variable to initialize the node of type ProcessingNode. So, it would be great if this variable was an argument of the scheduler function. So we define:

@ -122,6 +122,7 @@ PACK_BASE_FILES="
ComputeGraph/cg/static/nodes/cpp/ToReal.h ComputeGraph/cg/static/nodes/cpp/ToReal.h
ComputeGraph/cg/static/nodes/cpp/Unzip.h ComputeGraph/cg/static/nodes/cpp/Unzip.h
ComputeGraph/cg/static/nodes/cpp/Zip.h ComputeGraph/cg/static/nodes/cpp/Zip.h
ComputeGraph/cg.scvd
" "
# Specify file names to be deleted from pack build directory # Specify file names to be deleted from pack build directory

@ -23,7 +23,7 @@ cmsis_dsp_version="1.12.1"
# CMSIS-DSP Commit hash used to build the wrapper # CMSIS-DSP Commit hash used to build the wrapper
commit_hash="89610e31cbb3c67067f5bfbcacb338fd7910023e" commit_hash="142dcec5c333781c2299fe43824545cc57a5bcb0"
# True if development version of CMSIS-DSP used # True if development version of CMSIS-DSP used
# (So several CMSIS-DSP versions may have same version number hence the commit hash) # (So several CMSIS-DSP versions may have same version number hence the commit hash)

@ -58,8 +58,8 @@ def gencode(sched,directory,config):
htemplate = env.get_template("code.h") htemplate = env.get_template("code.h")
cfile=os.path.join(directory,"scheduler.cpp") cfile=os.path.join(directory,"%s.cpp" % config.schedulerCFileName)
hfile=os.path.join(directory,"scheduler.h") hfile=os.path.join(directory,"%s.h" % config.schedulerCFileName)
nbFifos = len(sched._graph._allFIFOs) nbFifos = len(sched._graph._allFIFOs)

@ -74,6 +74,21 @@ class Configuration:
# Display FIFO buffers in graph instead of datatype # Display FIFO buffers in graph instead of datatype
self.displayFIFOBuf = False self.displayFIFOBuf = False
# Enable support for CMSIS Event Recorder
self.eventRecorder = False
# Name of AppNode file
self.appNodesCName = "AppNodes.h"
self.appNodesPythonName = "appnodes"
# Name of custom file
self.customCName = "custom.h"
self.customPythonName = "custom"
# Name of scheduler source and header files
self.schedulerCFileName = "scheduler"
self.schedulerPythonFileName = "sched"
@property @property
def debug(self): def debug(self):

@ -40,7 +40,7 @@ def gencode(sched,directory,config):
template = env.get_template("code.py") template = env.get_template("code.py")
cfile=os.path.join(directory,"sched.py") cfile=os.path.join(directory,"sched.py" % config.schedulerPythonFileName)
with open(cfile,"w") as f: with open(cfile,"w") as f:

@ -1,26 +1,4 @@
{% extends "commonc.cpp" %} {% extends "commonc.cpp" %}
/*
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.
*/
{% if config.dumpFIFO %}
#define DEBUGSCHED 1
{% endif %}
#include "arm_math.h"
#include "custom.h"
#include "GenericNodes.h"
#include "AppNodes.h"
#include "scheduler.h"
{% macro optionalargs() -%}
{% if config.cOptionalArgs %},{{config.cOptionalArgs}}{% endif %}
{% endmacro -%}
{% block schedArray %} {% block schedArray %}
{% endblock %} {% endblock %}
@ -33,8 +11,21 @@ The support classes and code is covered by CMSIS-DSP license.
{% endif %} {% endif %}
{ {
/* Run a schedule iteration */ /* Run a schedule iteration */
{% if config.eventRecorder -%}
EventRecord2 (Evt_Scheduler, nbSchedule, 0);
{% endif -%}
CG_BEFORE_ITERATION;
{% for s in schedule %} {% for s in schedule %}
{% if config.eventRecorder -%}
EventRecord2 (Evt_Node, {{nodes[s].codeID}}, 0);
{% endif -%}
{{nodes[s].cRun()}} {{nodes[s].cRun()}}
{% if config.eventRecorder -%}
if (cgStaticError<0)
{
EventRecord2 (Evt_Error, cgStaticError, 0);
}
{% endif -%}
CHECKERROR; CHECKERROR;
{% if config.dumpFIFO %} {% if config.dumpFIFO %}
{% for fifoID in sched.outputFIFOs(nodes[s]) %} {% for fifoID in sched.outputFIFOs(nodes[s]) %}
@ -47,6 +38,7 @@ The support classes and code is covered by CMSIS-DSP license.
{% if config.debug %} {% if config.debug %}
debugCounter--; debugCounter--;
{% endif %} {% endif %}
CG_AFTER_ITERATION;
nbSchedule++; nbSchedule++;
} }

@ -19,6 +19,17 @@ extern "C"
{ {
#endif #endif
{% if config.eventRecorder %}
#include "EventRecorder.h"
#define EvtSched 0x01
#define Evt_Scheduler EventID (EventLevelAPI, EvtSched, 0x00)
#define Evt_Node EventID (EventLevelAPI, EvtSched, 0x01)
#define Evt_Error EventID (EventLevelError, EvtSched, 0x02)
{% endif %}
extern uint32_t {{config.schedName}}(int *error{{optionalargs()}}); extern uint32_t {{config.schedName}}(int *error{{optionalargs()}});
#ifdef __cplusplus #ifdef __cplusplus

@ -11,8 +11,8 @@ import sys
import numpy as np import numpy as np
import cmsisdsp as dsp import cmsisdsp as dsp
from cmsisdsp.cg.static.nodes.simu import * from cmsisdsp.cg.static.nodes.simu import *
from appnodes import * from {{config.appNodesPythonName}} import *
from custom import * from {{config.customPythonName}} import *
{% macro optionalargs() -%} {% macro optionalargs() -%}
{% if config.pyOptionalArgs %}{{config.pyOptionalArgs}}{% endif %} {% if config.pyOptionalArgs %}{{config.pyOptionalArgs}}{% endif %}

@ -12,10 +12,10 @@ The support classes and code is covered by CMSIS-DSP license.
{% endif %} {% endif %}
#include "arm_math.h" #include "arm_math.h"
#include "custom.h" #include "{{config.customCName}}"
#include "GenericNodes.h" #include "GenericNodes.h"
#include "AppNodes.h" #include "{{config.appNodesCName}}"
#include "scheduler.h" #include "{{config.schedulerCFileName}}.h"
{% macro optionalargs() -%} {% macro optionalargs() -%}
{% if config.cOptionalArgs %},{{config.cOptionalArgs}}{% endif %} {% if config.cOptionalArgs %},{{config.cOptionalArgs}}{% endif %}
@ -116,15 +116,29 @@ uint32_t {{config.schedName}}(int *error{{optionalargs()}})
{% endif %} {% endif %}
{ {
/* Run a schedule iteration */ /* Run a schedule iteration */
{% if config.eventRecorder -%}
EventRecord2 (Evt_Scheduler, nbSchedule, 0);
{% endif -%}
CG_BEFORE_ITERATION;
for(unsigned long id=0 ; id < {{schedLen}}; id++) for(unsigned long id=0 ; id < {{schedLen}}; id++)
{ {
unsigned int nodeId = schedule[id]; unsigned int nodeId = schedule[id];
{% if config.eventRecorder -%}
EventRecord2 (Evt_Node, nodeId, 0);
{% endif -%}
cgStaticError = nodeArray[nodeId]->run(); cgStaticError = nodeArray[nodeId]->run();
{% if config.eventRecorder -%}
if (cgStaticError<0)
{
EventRecord2 (Evt_Error, cgStaticError, 0);
}
{% endif -%}
CHECKERROR; CHECKERROR;
} }
{% if config.debug %} {% if config.debug %}
debugCounter--; debugCounter--;
{% endif %} {% endif %}
CG_AFTER_ITERATION;
nbSchedule++; nbSchedule++;
} }

@ -20,25 +20,40 @@ static unsigned int schedule[{{schedLen}}]=
{% endif %} {% endif %}
{ {
/* Run a schedule iteration */ /* Run a schedule iteration */
{% if config.eventRecorder -%}
EventRecord2 (Evt_Scheduler, nbSchedule, 0);
{% endif -%}
CG_BEFORE_ITERATION;
for(unsigned long id=0 ; id < {{schedLen}}; id++) for(unsigned long id=0 ; id < {{schedLen}}; id++)
{ {
{% if config.eventRecorder -%}
EventRecord2 (Evt_Node, schedule[id], 0);
{% endif -%}
switch(schedule[id]) switch(schedule[id])
{ {
{% for nodeID in range(nbNodes) -%} {% for nodeID in range(nbNodes) -%}
case {{nodeID}}: case {{nodeID}}:
{ {
{{nodes[nodeID].cRun()}} {{nodes[nodeID].cRun()}}
CHECKERROR;
} }
break; break;
{% endfor %}default: {% endfor -%}
default:
break; break;
} }
{% if config.eventRecorder -%}
if (cgStaticError<0)
{
EventRecord2 (Evt_Error, cgStaticError, 0);
}
{% endif -%}
CHECKERROR;
} }
{% if config.debug %} {% if config.debug %}
debugCounter--; debugCounter--;
{% endif %} {% endif %}
CG_AFTER_ITERATION;
nbSchedule++; nbSchedule++;
} }

@ -12,10 +12,12 @@ The support classes and code is covered by CMSIS-DSP license.
{% endif %} {% endif %}
#include "arm_math.h" #include "arm_math.h"
#include "custom.h" #include "{{config.customCName}}"
#include "GenericNodes.h" #include "GenericNodes.h"
#include "AppNodes.h" #include "{{config.appNodesCName}}"
#include "scheduler.h" #include "{{config.schedulerCFileName}}.h"
{% macro optionalargs() -%} {% macro optionalargs() -%}
{% if config.cOptionalArgs %},{{config.cOptionalArgs}}{% endif %} {% if config.cOptionalArgs %},{{config.cOptionalArgs}}{% endif %}

@ -1,2 +1,2 @@
# Python wrapper version # Python wrapper version
__version__ = "1.7.1" __version__ = "1.8.0"

Loading…
Cancel
Save