Passing constant struct to entry point in Matlab Coder

19 vues (au cours des 30 derniers jours)
Ludger Solbach
Ludger Solbach le 10 Juil 2015
Commenté : Jan Siegmund le 18 Mar 2020
I am trying to prevent code generation for unused execution paths. The system I am trying to compile to C with Matlab Coder is parametrized with a nested params struct, which also includes the switches for the execution paths I am trying to exclude. A simple solution would be declaring the whole nested parameter struct as constant, like this
codegen systemCode -args {1, coder.Constant(params)}
but this does not seem to have any effect. It seems the params struct is still treated as a non-constant. I'm looking for a solution to this problem that does not involve pulling the control path switches out of the params struct.
  4 commentaires
Ludger Solbach
Ludger Solbach le 13 Juil 2015
Addendum: I was thinking that I might have to help coder by propagating the const property through the call hierarchies but already changing the wrapper line calling the constructor to
sys = sysFunc(coder.const(params));
makes coder throw an error saying that params cannot be reduced to a constant, which is rather odd, since it was explicitly labeled as such in the codegen arguments.
??? Expression could not be reduced to a constant.
Error in ==> sysWrapper Line: 6 Column: 35
Code generation failed: Open error report.
Error using codegen (line 144)
Ludger Solbach
Ludger Solbach le 13 Juil 2015
Modifié(e) : Ludger Solbach le 13 Juil 2015
What's puzzling is that even if I go straight to line where the switch is used in the run() function, by changing
if obj.params.doThis
to
if coder.const(obj.params.doThis)
I get the error that the expression cannot be reduced to a constant. How is it that coder gets the idea that this value can ever change?

Connectez-vous pour commenter.

Réponse acceptée

Ryan Livingston
Ryan Livingston le 14 Juil 2015
Modifié(e) : Ryan Livingston le 14 Juil 2015
Typically when you want to filter some code from code generation, the best approach is to use coder.target. In this case you could use the code:
if coder.target('MATLAB')
'this'
a = cell({1,2,3}); % not supported by coder
else
'that'
out = 0;
end
to filter out the code that uses cell arrays.
There appear to be some limitations regarding tracking constants through objects with code generation. Another workaround you may consider is to implement a System Object. These are special MATLAB classes that have some properties which are designed to interact well with code generation.
The basic idea is that they maintain some state and implement a step method which performs the actual computation to be done, much like your run method. They also have the notion of nontunable properties which are special properties in the class that abide by certain rules (e.g. they must have 1 assignment with a constant value). Because of these rules, they can generally be treated as constants by the code generation software.
I changed sysFunc to a System Object:
classdef sysFunc < matlab.System
properties (Nontunable)
params
end
methods
function obj = sysFunc(params)
obj.params = params;
end
end
methods (Access = protected)
function setupImpl(obj)
% Implement tasks that need to be performed only once,
% such as pre-computed constants.
end
function out = stepImpl(obj,in)
% Implement algorithm. Calculate out as a function of
% input in and discrete states.
out = in;
if obj.params.doThis
'this'
a = cell({1,2,3}); % not supported by coder
else
'that'
out = 0;
end
end
function resetImpl(obj)
% Initialize discrete-state properties.
end
end
end
You'll also need to change sys.run(x) to sys.step(x) in sysWrapper. After doing this, I was able to generate code using:
params.doThis = 0; codegen sysWrapper -args {1, coder.Constant(params)}
Despite this, I would still recommend using coder.target to determine if you are in code generation mode or running in MATLAB. However, leveraging nontunable properties of System Objects may allow you to better propagate constants through object properties for code generation.
Lastly, in MATLAB you can go to the Editor tab and click the arrow under New and choose System Object->Advanced to get a template System Object that shows all of the supported behaviors you can override.
  3 commentaires
Ryan Livingston
Ryan Livingston le 14 Juil 2015
Modifié(e) : Ryan Livingston le 14 Juil 2015
You're quite welcome, glad to hear it was helpful. I was using the editor in R2015a, so I assume that option was added sometime between the release you are using and R2015a. You can see the overridable functions in the matlab.System documentation page as well.
Jan Siegmund
Jan Siegmund le 18 Mar 2020
This works well with the original matlab coder, however in MATLAB HDL coder, the fixed-point converter step complains:
Property 'param' of class 'ExampleClass' is a structure type. Classes with structure properties are not supported.
I just basically want to achieve the same thing:
Excluding not supported code paths by using a constant struct.
Using the coder.Constant input class does also not work for the fixed point converter.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Input Specification dans Help Center et File Exchange

Produits

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by