Main Content

coder.varsize

Resolve size mismatch errors and declare upper bounds

Description

coder.varsize(varName1,...,varNameN) instructs the code generator to allow the dimensions of variables varName1,...,varNameN to change size at run time. If you use this syntax, dimensions with size 1, otherwise known as singleton dimensions, remain fixed size. To instruct the code generator to allow singleton dimensions to vary in size, you must specify variable-size upper bounds by using the upperBounds and variableSize arguments. For more information about defining variable-size data in MATLAB® code for code generation, see Define Variable-Size Data for Code Generation.

example

coder.varsize(varName1,...,varNameN,upperBounds) specifies an upper bound for each dimension of the variables varName1,...,varNameN. If you use this syntax, singleton dimensions remain fixed size.

example

coder.varsize(varName1,...,varNameN,upperBounds,variableSize) specifies, for each upper bound specified in upperBounds, whether that upper bound is fixed size or variable size. To instruct the code generator to allow a singleton dimension to vary in size, explicitly specify an variable-size upper bound.

example

Examples

collapse all

In many cases, the code generator can determine whether a variable is variable size during code generation. However, under certain circumstances, the code generator can produce a size mismatch error because it is unable to correctly determine that a variable changes size. To resolve these types of errors, use coder.varsize to specify that the size of the variable can change.

For example, create a function that defines the variable x as a 3-by-3 array, uses x by passing it to another function, and then changes the size of x depending on run-time input.

function out = changeSizeAfterUse(n) %#codegen
x = zeros(3,3);
numel(x); % use x by passing it to another function
if n < 10
    x = zeros(4,4); % change size of x depending on run-time input
end
out = x;
end

If you try to generate code for this function, the code generator produces a size mismatch error. To resolve this error, add the coder.varsize directive after you define the variable but before you use it.

function out = changeSizeAfterUse(n) %#codegen
x = zeros(3,3);
coder.varsize("x");
numel(x); % use x by passing it to another function
if n < 10
    x = zeros(4,4); % change size of x depending on run-time input
end
out = x;
end

Create a function that defines A as a scalar and then use coder.varsize to specify that A is a variable-size row vector with a maximum length of 20. Generate code for this function and examine the code generation report. A is defined as a 1x:20 array. When you do not provide the variableSize argument, non-singleton dimensions are defined as variable size and singleton dimensions remain fixed size.

function varSizeUpperBounds() %#codegen
A = 0;
coder.varsize("A",[1 20]);
end

Create a function that defines A as a 1-by-1-by-1 array and then use coder.varsize to specify that A has a first dimension that is variable-size with a maximum of 1, a second dimension with a fixed size of 3, and a third dimension that is variable-size with a maximum size of 20. Generate code for this function and examine the code generation report. A is defined as a :1x3x:20 array. The code generator defines the singleton dimension as variable size because you explicitly specified a variable-size upper bound using the upperbound and variableSize arguments.

function fcn2() %#codegen
A = [0 0 0];
coder.varsize("A",[1 3 20],[true false true]);
end

You can use coder.varsize to instruct the code generator to allow structure fields to vary in size.

For example, create a function that defines a structure with three fields: observations1, observations2, and values. Use coder.varsize to define observations1 and observations2 as having a fixed-size first dimension and an unbounded second dimension. Use coder.varsize again to define values as a variable-size row vector with maximum length of 10. Generate code for this function and inspect the code generation report. The code generator uses internal heuristics to determine the maximum size of the unbounded dimensions of observation1 and observations2. The code generator defines observations1, observations2, and values as arrays of size 2x:10, 2x:15, and 1x:10, respectively.

function out = varSizeFields(n) %#codegen
s = struct("observations1",zeros(2,2),"observations2",zeros(2,2), ...
    "values",zeros(1,1));
coder.varsize("s.observations1","s.observations2",[2 Inf],[false true]);
coder.varsize("s.values",[1 10]);
if n <= 10
    s.observations1 = [1:n;rand(1,n)];
    s.values = randi(100,1,n);
end
if n > 0
    s.observations2 = [1:15;zeros(1,15)];
end
out = s;
end

You can apply the coder.varsize directive to all cell array elements or to specific cell array elements.

For example, create a function that defines two 1-by-3 cell arrays, each of which contains three 1-by-2 arrays of doubles. Use coder.varsize to specify that all elements of cell array ca1 are variable-size row vectors with a maximum length of 5. Use the coder.varsize directive again to specify that the second element of ca2 is a variable-size matrix with both dimensions having a maximum size of 2. Generate code for this function and inspect the code generation report. The elements of ca1 are defined as variable-size 1x:5 arrays. The first and third elements of ca2 are defined as fixed-size 1x2 arrays, while the second element is defined as a variable-size :2x:2 matrix.

function varSizeElement %#codegen
ca1 = {[1 2] [3 4] [5 6]};
ca2 = {[1 2] [3 4] [5 6]};
coder.varsize("ca1{:}",[1 5]);
coder.varsize("ca2{2}",[2 2]);
ca1{1} = 1;
ca1{2} = 1:5;
ca1{3} = 1:3;
ca2{1} = [5 6];
ca2{2} = [1 2;3 4];
ca2{3} = [7 8];
end

If you use coder.varsize to set upper bounds for a variable and the size of the variable depends on run-time input, you can encounter run-time overflow errors if the run-time input exceeds the upper bounds you define.

For example, create a function that uses coder.varsize to declare variable x as a variable-size array two-dimensional array and sets upper bounds of 5 for both dimensions.

function out = boundedVarSize1(n) %#codegen
x = zeros(3,3);
coder.varsize("x",[5 5])
x = zeros(n,n);
out = x;
end

Generate MEX code for this function at the command line and inspect the code generation report. The code generator defines x as a :5x:5 array.

codegen boundedVarSize -args {0} -report
Code generation successful: View report

If you pass the generated MEX function a value greater than 5, you see a size overflow error. To avoid overflow errors, ensure that run-time inputs do not exceed the upper bounds defined by coder.varsize. Alternatively, rewrite your MATLAB code to prevent run-time size overflow.

function out = boundedVarSize2(n) %#codegen
x = zeros(3,3);
coder.varsize("x",[5 5])
if n <= 5
    x = zeros(n,n);
else
    x = zeros(5,5);
end
out = x;
end

Input Arguments

collapse all

Names of variables to declare as variable size, specified as a comma-separated list of character vectors or string scalars. Variables cannot be strings, input arguments, global variables, MATLAB classes, or MATLAB class properties.

Example: coder.varsize("x","y")

Upper bounds for each array dimension, specified as a vector of doubles. Upper bounds must be integers or Inf. Specified upper bounds apply to all variables passed to coder.varsize. Integers passed as upper bounds must be constant at code generation time. You must specify upper bounds for each dimension of varName1,...,varNameN. To specify a variable without an upper bound, use Inf.

Example: coder.varsize("x","y",[5 Inf])

Whether each dimension specified in upperBounds is variable size, specified as a vector of logical values. The variableSize vector must be the same length as the upperBounds vector.

Example: coder.varsize("x","y",[10 10 10], [false true true])

Limitations

  • Code generation does not support using coder.varsize with global variables, MATLAB classes, and MATLAB class properties.

  • Code generation does not support using coder.varsize with strings. See Resolve Issue: coder.varsize Not Supported for Strings (MATLAB Coder).

  • The coder.varsize directive instructs the code generator to allow the size of a variable to change. It does not change the size of the variable. Consider this code snippet:

    ...
    x = 7;
    coder.varsize("x", [1 5]);
    disp(size(x));
    ...

    After the coder.varsize directive, x is still a 1-by-1 array. You cannot assign a value to an element beyond the current size of x. For example, this code produces a run-time error because the index 3 exceeds the dimensions of x.

    ...
    x = 7;
    coder.varsize("x", [1,5]);
    x(3) = 1;
    ...

  • coder.varsize is not supported for function input arguments. Instead:

    • If the function is an entry-point function, specify that an input argument has a variable size by using coder.typeof (MATLAB Coder) at the command line. Alternatively, specify that an entry-point function input argument has a variable size by using the Define Input Types step of the app.

    • If the function is not an entry-point function, use coder.varsize in the calling function with the variable that is the input to the called function.

  • For sparse matrices, coder.varsize treats variable-size dimensions as unbounded.

  • To use coder.varsize with a cell array, the cell array must be homogeneous. See Cell Array Limitations for Code Generation.

Tips

  • In many cases, the code generator is able to determine that the size of a variable can change at run time. In such cases, the code generator correctly defines the variable as variable size and you do not need to use the coder.varsize directive. You should use coder.varize only if you see a size overflow error or if you want to specify upper bounds.

  • To declare variable-size output variables in MATLAB Function blocks, use the Symbols pane and the Property Inspector. If you provide upper bounds in a coder.varsize declaration, the upper bounds must match the upper bounds in the Property Inspector. See Declare Variable-Size MATLAB Function Block Variables.

  • The code generator uses a colon (:) to indicate a variable-size dimension. For example, if the size of an array is 3x:5x:Inf, the first dimension has a fixed size of one, the second dimensions is variable size with an upper bound of five, and the third dimension is unbounded. See MATLAB Function Reports.

  • If you do not specify upper bounds in the coder.varsize declaration and the code generator is unable to infer upper bounds, the generated code uses dynamic memory allocation. Dynamic memory allocation can reduce the speed of the generated code. In some cases, you can avoid dynamic memory allocation by specifying upper bounds by using the upperBounds argument.

  • If you use coder.varsize to specify that the upper bound of a dimension is 1, the dimension has a fixed size of 1 by default. To specify that the dimension can be 0 (empty array) or 1, set the corresponding element of the variableSize vector to true. For example, this directive specifies that the first dimension of x has a fixed size of 1 and the other dimensions have a variable size of 5 (1x:5x:5).

    coder.varsize('x',[1 5 5])

    In contrast, this code specifies that the first dimension of x is variable size with an upper bound of 1 (:1x:5x:5).

    coder.varsize("x",[1 5 5],[true true true])

  • When you use the output of an extrinsic function, the code generator is unable to determine the size of this output at code generation time. Use coder.varsize to instruct the code generator to treat the variable you use to store this output as variable size. See Use Variable-Size Output of Extrinsic Function at Run Time.

  • Under certain circumstances, you can force a cell array to be homogeneous by using coder.varsize. See Control Whether a Cell Array Is Variable-Size.

Version History

Introduced in R2011a