Main Content

Generate Code With Implicit Expansion Enabled

Implicit expansion refers to the automatic size change of compatible operands to apply element-wise operations. Two dimensions have compatible sizes if, for every dimension, the dimension sizes of the arrays are either the same or one of them is singleton. See Compatible Array Sizes for Basic Operations.

Implicit expansion in the generated code is enabled by default. Code generated with implicit expansion enabled might differ from code generated with implicit expansion disabled in these ways:

  • Output size

  • Additional code generation

  • Performance variation

For variable-size dynamic arrays, the generated code exhibits these changes to accomplish implicit expansion at run-time.

For fixed-size and constant arrays, because the values and sizes of the operands are known at compile time, the code generated to calculate the implicitly expanded output does not require additional code generation or cause performance variations.

To control implicit expansion in the generated code, see Optimize Implicit Expansion in Generated Code.

Output Size

Implicit expansion automatically expands the operands to apply element-wise operations. For example, consider these input types of compatible size:

a_type = coder.typeof(1,[2 1]);
b_type = coder.typeof(1,[2 inf]);

A binary operation on these two operands with implicit expansion enabled automatically expands the second dimension of a_type to result in an output size of 2-by-Inf. With implicit expansion disabled, the second dimension of a_type is not automatically expanded, and the output size is 2-by-1.

For existing workflows created with implicit expansion disabled in the generated code, generating code for the same MATLAB® code with implicit expansion enabled might generate size mismatch errors or change the size of outputs from binary operations and functions. To troubleshoot size mismatch errors, see Diagnose and Fix Variable-Size Data Errors.

Additional Code Generation

Implicit expansion enables the operands to be automatically expanded if the operand sizes are compatible. To perform this size change, the generated code introduces code that allows the operands to be expanded.

For example, consider the following code snippet. The function vector_sum finds the sum of two arrays.

function out = vector_sum(a,b)
out = a + b;
end

Consider the variable-size dynamic array defined here:

c_type = coder.typeof(1,[1 Inf]);

Generate code for vector_sum by using this command:

codegen vector_sum -args {c_type, c_type} -config:lib -report

The generated code for this function with implicit expansion:

static void plus(emxArray_real_T *out, 
  ... const emxArray_real_T *b, const emxArray_real_T *a)
{
  int i;
  ....
 if (a->size[1] == 1) {
    out->size[1] = b->size[1];
  } else {
    out->size[1] = a->size[1];
  }
  ....
  if (a->size[1] == 1) {
    loop_ub = b->size[1];
  } 
  else {
  loop_ub = a->size[1];
  }
  for (i = 0; i < loop_ub; i++) {
    out->data[i] = b->data[i * stride_0_1] + a->data[i * stride_1_1];
  }
}
void vector_sum(const emxArray_real_T *a, const emxArray_real_T *b, emxArray_real_T *out)
{
  int i;
  int loop_ub;
  if (b->size[1] == a->size[1]) {
    i = out->size[0] * out->size[1];
    out->size[0] = 1;
    out->size[1] = b->size[1];
    emxEnsureCapacity_real_T(out, i);
    loop_ub = b->size[1];
    for (i = 0; i < loop_ub; i++) {
      out->data[i] = b->data[i] + a->data[i];
    }
  } else {
    plus(out, b, a);
  }
}

The generated code for this function without implicit expansion:

void vector_sum(const emxArray_real_T *a, 
  ... const emxArray_real_T *b, emxArray_real_T *out){
  int i;
  int loop_ub;
  i = out->size[0] * out->size[1];
  out->size[0] = 1;
  out->size[1] = b->size[1];
  emxEnsureCapacity_real_T(out, i);
  loop_ub = b->size[1];
  for (i = 0; i < loop_ub; i++) {
    out->data[i] = b->data[i] + a->data[i]; 
  }
}

With implicit expansion enabled, the code generator creates a supporting function, in this case plus, to carry out the size change and to calculate the output.

In most cases, the supporting function carrying out implicit expansion is named after the binary operation it is assisting. In the previous example, if the expression out = a + b is changed to out = a - b, the name of the supporting function changes to minus.

Some supporting functions might also be named as expand_op, where op refers to the binary operation. In the previous example, if the expression out = a + b is replaced with out = max(a,b), the name of the supporting function in the generated code changes to expand_max.

If multiple operations in an expression require implicit expansion, the generated code includes a supporting function that is named binary_expand_op. The supporting functions change the size of the operand and apply the binary operations.

If you want to apply specific binary operations and functions without implicit expansion, use coder.sameSizeBinaryOp. The code generated to apply this function does not include additional code to expand the operands. The output of this function does not expand the operands in MATLAB. This function does not support scalar expansion. Operands must be of the same size.

If you want to disable implicit expansion inside a function for all binary operations within that function in the generated code, call coder.noImplicitExpansionInFunction in the required function. Implicit expansion in MATLAB code is still enabled.

Performance Variation

Code generated with implicit expansion enabled might perform differently than when implicit expansion is disabled. Depending on the input to the generated code that uses implicit expansion, the code might take longer to evaluate the output.

If the generated code does not match the performance requirements of your workflow due to implicit expansion, generate code for your project by turning off implicit expansion for specific binary operations, specific function bodies, or for your whole project. See Optimize Implicit Expansion in Generated Code.

Note

Before disabling implicit expansion, ensure that the external code does not use implicit expansion. Disabling implicit expansion for an entire project might cause errors when generating code if your project includes MATLAB code from external sources.

See Also

|

Related Topics