matlab coder: It's time to generate a modern C++ API

10 views (last 30 days)
The matlab coder product is very widely used in industry, and since the R2011 version, the generation is still mainly oriented towards the C API interface (C++ is actually a layer of wrapper for C) to common one-/two-dimensional arrays, colum-major, involving low-level operations such as memory management allocation and release. As history progressed, we moved more towards the modern form of the C++ API (C++11), with safer use of smart pointers, threaded support, and better security and convenience similar to the mex C++ API introduced by MATLAB R2017b. Using the older C API can often cause memory management problems and be difficult to debug.
Once we have implemented our algorithms quickly in matlab, we often have to iterate matlab syntax often on generating C/C++ code, and array bounds often have to be considered, as it is particularly important in C to consider is allocating memory on the stack and heap. The array size in the current generated C code can easily be very large, e.g. myarray[largeNumber] in image processing toolbox, and then a Segmentation Fault error will occur. This adds a lot of annoying overhead and requires a lot of effort to keep changing the code. It would be much better if the generated C++ code was in the new C++11, such as std::vector, which does not take into account the array size limit and allows the developer to focus on the algorithm itself.

Accepted Answer

Matan Silver
Matan Silver on 2 Nov 2022
Edited: Walter Roberson on 4 Nov 2022
Hello,
Thank you for the feedback. We agree! There's a lot of opportunity to take advantage of more modern C++ features. I've passed on these notes to the MATLAB Coder development team, and we'll consider them going forward.
A couple things which could make a difference, if you are not aware:
MATLAB Coder doesn't generate code that calls native C++ threading APIs, but we do emit calls to openMP in certain cases. See:
For smart pointers, while MATLAB Coder doesn't generate shared or unique pointers, it can wrap dynamic memory allocation in a more modern interface that guards calls to "new" with a wrapper called coder::array. This should be safer than emxArrays. You can do this by setting DynamicMemoryAllocationInterface to 'C++' which should be the default when generating C++ code. See:
You mention large stack allocations--this can certaintly be a problem, especially in constrained systems. There is one configuration parameter, DynamicMemoryAllocationThreshold, which can be used to decrease the maximum size variable that can be allocated on the stack. This comes at the cost of more uses of heap allocation:
I'll pass along your notes about these use-cases, which I have understood to be:
- Using smart pointers for dynamic memory allocation and tracking of pointer ownership
- Using std::vector to store numerical data
- Generating MEX using the C++ MEX API instead of the C MEX API
- Using dynamic memory allocation even for fixed size arrays that are currently allocated on the stack
Let me know if I've missed anything, and thank you again,
Matan
  2 Comments
cui,xingxing
cui,xingxing on 3 Nov 2022
Edited: cui,xingxing on 4 Nov 2022
@Matan Silver Thank you for your attention, using coder::array is a good suggestion. Summary on your third point is not accurate enough, "Generating MEX using the C++ MEX API instead of the C MEX API" is not correct, I use the new mex c++ introduced by R2017b As an analogy, in matlab coder I would prefer to see a new type of data type to correspond to matlab's matrix types, not the "emxArrays" series of arrays. I've used “DynamicMemoryAllocationThreshold” before, but I'd like to say that it's not user-friendly, so I'll explain the problems I've encountered with image processing:
For example, I have designed an image processing algorithm that takes the same size image as the input each time, and after the algorithm has finished processing, it returns a different size array of images each time. But I don't know how big the upper limit is set to, so i use coder.varsize to declare that it is a variable size array in order to produce an uncapped no-fixed-size array. Unfortunately, just by declaring "coder.varsize" without specifying an upper limit for the array does not work, matlab coder potentially forces the user to set an upper limit for the array, which leads to another problem, if the upper limit is set large, the generated C code will recognise it, and then the "DynamicMemoryAllocationThreshold" value has to be adjusted .The function template is as follows.
function outBigSizeImage = myFcn(inFixedImage)%#codegen
coder.varsize("varsizeImg1","varsizeImg2","varsizeImg3",[6000,6000,3],[1,1,0]);% Note: the upper limit of the array here is very sensitive
% some algotithms here
...
outBigSizeImage.varsizeImg1 = varsizeImg1;
outBigSizeImage.varsizeImg2 = varsizeImg2;
...
end
In the default generated C code, the non-entry function stores the image as a single one-dimensional array, and as the image grows with each iteration, the array becomes very large (close to 6000*6000*3), which can easily lead to a failure of the generated C code and requires manual adjustment of the "DynamicMemoryAllocationThreshold " value, and it is also possible that the generated C code/ or mex file will not execute as fast as the original matlab code, or even slower, which is strange and difficult to debug.
The above is just an illustration of an example, I wanted to show that for the same size array, if I use the OpenCV library, I can easily create an array of 6000*6000*3, or even larger, using cv::Mat. Hopefully a future matlab coder will introduce a data type as good as cv::Mat.

Sign in to comment.

More Answers (0)

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!