Matlab Coder - How to force generated code to keep Matlab functions prototypes
Show older comments
I generated the C code with Matlab Coder, but the generated code functions interfaces are not the same as the interfaces for appropriate Matlab functions, which I did not expect to happen. Typically if I pass a structure as an argument, but the function does not use all elements of the structure, the generated code passes each individual set of elements of the structure that is used in the function, rather than pointer to entire structure. The problems with that is that the number of input arguments to a C function becomes too big. Plus, more importantly, if the implementation of the function get changed, that number of used elements in the structure is different, the generated C interface changes too, which means that it is not possible keep stable interface. That is not acceptable.
I see that there are options to control the interface with Simulink Coder and Embedded Coder but I cannot find how is that possible with just Matlab Coder. I cannot see a problem for Matlab C Coder to respect simple C stile interface defined in Matlab language. There must be a way to simply control that?
5 Comments
Ezra Stein
on 21 Sep 2021
Hi Dusko,
In general, any generated functions which are not explicitly specified as Entry Point functions will have an unstable interface. You should avoid relying on these non-Entry Point functions since their signature, names, or existance, could be affected by various codegen optimizations or perturbations in the original MATLAB code.
To ensure that a correct and stable interface is generated, you can instead specify the function as an Entry Point for codegen.
If you are instead observing an unstable signature on an entry point function, could please provide us with a small reproducible example which exhibits this issue?
Dusko Vujadinovic
on 22 Sep 2021
Ezra Stein
on 23 Sep 2021
Hi Dusko,
Unfortunately, specifying the %#codegen pragma next to the function prototype in MATLAB is not enough to mark that function as an entry point for codegen. In order to mark a function as an entry point, you must explicitly pass it as an argument to the 'codegen' command. Each such argument to the codegen command should also have a corresponding '-args' argument which specifies the input types for that function.
For instance, to mark the functions 'foo' and 'bar' as entry points, you would need specify them in a codegen command such as:
>> codegen foo -args {0, 0} bar -args {ones(10,10)}
This indicates to MATLAB Coder that foo is an entry point accepting two doubles as input and bar is an entry point accepting a 10x10 matrix as input. All other functions which codegen discovers as a result of compiling foo and bar will not be considered entry points and may have unstable signatures.
In your case, the codegen command would need to pass dynamicReconfigFsm as an argument, for instance:
codegen dynamicReconfigFsm -args {0, 0, true, ones(32,1), ones(8,1), dynamicReconfig, true}
where 'dynamicReconfig' is an example struct value. The above line uses just an example set of arguments, your particular use case might require something different.
Let me know if passing dynamicReconfigFsm and specifying its arguments in the 'codegen' command helps stabalize the signature of the generated function.
-Ezra
Dusko Vujadinovic
on 27 Sep 2021
Ezra Stein
on 28 Sep 2021
Hi Dusko,
Thank you very much for this feedback. We have made an internal note of this use case and will consider supporting stable non-entry point signatures in the future.
I agree that the current workflow requires tedious data entry when specify many entry point functions. One possible way to speed up this work is to use the 'coder.getArgTypes' function described below: https://www.mathworks.com/help/coder/ref/coder.getargtypes.html
This function uses the same technology behind the Coder App's "auto-define" feature to discover argument types for entry points invoked by a test script. For instance, suppose you have a set of entry points defined in a cell string:
>> myEntryPoints = {'fcn1', 'fcn2', 'fcn3', 'fcn4'};
You can then use 'coder.getArgTypes' to get a corresponding structure which represents the types of for each entry point signatures as discovered via a test bench:
>> typeStruct = coder.getArgTypes('myTestBench', myEntryPoints)
Next, you can construct the entry point arguments to the codegen command as follows:
>> args = cellfun(@(field) {field, '-args', typeStruct.(field)}, myEntryPoints, 'UniformOutput', false); args = [args{:}]
Finally, you can pass this directly to the codegen command:
>> codegen(args{:}, '-config', myConfig, '-report')
This should help you automate some of the work of specifying entry points by leveraging the entry-point arguments auto-define feature. Now, if you would like to make a function with a stable signature, you can simply add it to the myEntryPoints cell array.
I agree that it would be helpful if this workflow were simpler and we will consider improving it in the future.
-Ezra
Answers (0)
Categories
Find more on MATLAB Coder in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!