MATLAB Answers

Why do I always need coder.varsize directives?

5 views (last 30 days)
It's more a question about how C/C++ Coder works internally:
I'm checking the option "Enable variable-sizing" and setting the "Dynamic Memory allocation" option to "For all variable-sized arrays". With this, I'm telling coder: "Hey the size of the variables can change indefinitely and you should use dynamic memory allocation", right?
So, why do I still need to put directives like "coder.varsize('my_var',[Inf Inf], [1 1])" in the Matlab code to get past errors like "Dimension n is fixed on one side but varies on the other side" if I already configured the Coder to use dynamic allocation? Shouldn't it be able to figure out the sizing of variables at this point?
Thank you so much!

  0 Comments

Sign in to comment.

Accepted Answer

Darshan Ramakant Bhat
Darshan Ramakant Bhat on 16 Jan 2020
Thanks for asking this interesting question. I will try to answer this to the best of my knowledge.
  • Enable / Disable variable sizing :
This setting enforces the global rule for the author to allow / or not allow the variable sizing. Consider the below example :
function y = myVarSize(u)
if u > 0
y = ones(1,2);
else
y = ones(1,3);
end
Let's generate code for this function :
>> cfg = coder.config('lib');
>> codegen -config cfg myVarSize -args {0} -report
Code generation successful: View report
One can inspect the report to see how each variables are inferred during code generation :
varsize_inference.JPG
So the variable 'y' is inferred as 1x:3 -> meaning the second diminsion is a variable dimension with a fixed upper bound as 3
Whenever the upper bounds are fixed variables can be still allocated in stack, so the dynamic memory alloaction may not be required (not always true !) .
So the above code will work even if you turn off dynamic memory alloaction :
>> cfg.DynamicMemoryAllocation ="Off";
>> codegen -config cfg myVarSize -args {0} -report
Code generation successful: View report
Note here that we are not using coder.varsize() anywhere in the code.
However, the above code will not go through codegen if you turn off variable sizing :
>> cfg.EnableVariableSizing =false;
>> codegen -config cfg myVarSize -args {0} -report
??? Size mismatch (size [1 x 2] ~= size [1 x 3]).
The size to the left is the size of the left-hand side of the assignment.
So the "EnableVariableSizing" can be used to impose stricter rules on the author. This may improve the efficiency of the generated code / make it more readable.
  • Dynamic memory alloaction :
This is required when the variables cannot be created on the stack. Consider the below example :
function y = myVarSize(u)
if u > 0
y = ones(1,u);
else
y = ones(1,3);
end
Let's do codegen again by turning off the dynamic memory alloaction :
>> cfg.DynamicMemoryAllocation ="Off";
>> codegen -config cfg myVarSize -args {0} -report
??? Computed maximum size is not bounded.
Static memory allocation requires all sizes to be bounded.
The computed size is [1 x :?].
On seeing the report :
varsize_inference2.JPG
variable 'y' is inferred as 1x:? -> meaning the second dimension can be unbounded. This is because of 'ones(1,u)', and 'u' can take any value during runtime.
So in this scenario the variable 'y' has to be allocated in heap, so we require dynamic memory alloaction as well as variable sizing.
Again, by turning on dynamic memory this codegene goes through without using coder.varsize()
  • coder.varsize()
This is like a compiler pragma. This hints the MATLAB Coder compiler that a variable can grow dynamically.
Consider the below example :
function Y = var_by_if(u) %#codegen
if (u > 0)
Y = zeros(2,2);
%coder.varsize('Y');
if (u < 10)
Y = Y + u;
end
else
Y = zeros(5,5);
end
In this example we commented out the varize hint to compiler. Let's do codegen again :
>> codegen -config cfg var_by_if -args {0} -report
??? Size mismatch (size [2 x 2] ~= size [5 x 5]).
The size to the left is the size of the left-hand side of the assignment.
The codegen fails !!
This is because, we are using Y (reading from Y) inside the nested if branch and for this use 'Y' is inferred as 2X2 size. However in the other branch 'Y' is assigned 5x5 size. Now in such scenarios compiler needs explicit hints to make it clear that 'Y' can vary in size.
Alos coder.varsize() gives lots of customizations on each variable level sizing.
The codegen will go through by uncommenting coder.varsize (Dynamic memory can be even turned off here).
References :
Hope this answer gives you little more clarity.

  1 Comment

Jose Cazarin
Jose Cazarin on 21 Jan 2020
Thanks, I haven't had time to look into that with proper attention yet, but your answer seems to be what I was looking for. I'll check it out in the future

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!