coder.sameSizeBinaryOp - Apply element-wise binary operations without implicit expansion - MATLAB (original) (raw)

Apply element-wise binary operations without implicit expansion

Since R2021b

Syntax

Description

`result` = coder.sameSizeBinaryOp([func_handle](#mw%5F4cdbe604-a36b-4c95-9ffe-6819b35eaa8c),[u](#mw%5F0e2d7908-594e-45eb-9908-fd038f347832),[v](#mw%5F87d128fd-41eb-4923-8b43-02a1abf5adef)) performs an error check that the operands are of the same size and applies the binary operation or function specified by the function handle func_handle on the operands u and v without implicitly expanding them. The operands must be of the same size because this function does not allow scalar expansion.

Use coder.sameSizeBinaryOp to disable implicit expansion for a specific binary operation or function. Disable implicit expansion to avoid automatic size change of output sizes, additional code generation, and performance variation. See Generate Code With Implicit Expansion Enabled, Optimize Implicit Expansion in Generated Code and Compatible Array Sizes for Basic Operations.

To disable implicit expansion for binary operations and functions within a specific function in the generated code, call coder.noImplicitExpansionInFunction within that function.

example

Examples

collapse all

Apply Operations and Functions Without Implicit Expansion

Use coder.sameSizeBinaryOp to apply binary operations and functions where implicit expansion is not required.

Using coder.sameSizeBinaryOp ensures that any variable-size operands of compatible sizes are not expanded automatically. The generated code does not include additional code to enable the automatic expansion of the operands.

In this example, the plus function applies the operation with implicit expansion. The coder.sameSizeBinaryOp function applies the operation without implicit expansion.

function [out1,out2] = addExample(a,b) out1 = coder.sameSizeBinaryOp(@plus,a,b); out2 = plus(a,b); end

Define the input types.

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

Generate code for the function addExample by using this command.

codegen addExample -args {a_type, b_type} -config:lib -report

Code generation successful: To view the report, open('codegen/lib/addExample/html/report.mldatx')

Compare Output Sizes

In the code generation report created in the previous step, place your cursor over the two operations.

plusSizeInfer.png sameSizeBinarySizeInfer.png

The size of the output from the plus operation is 5x:? whereas the size of the output of coder.sameSizeBinaryOp is 5x1.

The plus function implicitly expands its operands to the output size.

The coder.sameSizeBinaryOp function disables implicit expansion to prevent the automatic expansion of the operands.

Examine the Generated Code

type codegen/lib/addExample/addExample.c

/*

/* Include Files */ #include "addExample.h" #include "addExample_emxutil.h" #include "addExample_types.h" #include <emmintrin.h>

/* Function Definitions / /

{ const double *b_data; double *out2_data; int i; int loop_ub; b_data = b->data; for (i = 0; i < 5; i++) { out1[i] = a[i] + b_data[i]; } i = out2->size[0] * out2->size[1]; out2->size[0] = 5; loop_ub = b->size[1]; out2->size[1] = b->size[1]; emxEnsureCapacity_real_T(out2, i); out2_data = out2->data; for (i = 0; i < loop_ub; i++) { int i1; _mm_storeu_pd(&out2_data[5 * i], _mm_add_pd(_mm_loadu_pd(&a[0]), _mm_loadu_pd(&b_data[5 * i]))); i1 = 5 * i + 2; _mm_storeu_pd(&out2_data[i1], _mm_add_pd(_mm_loadu_pd(&a[2]), _mm_loadu_pd(&b_data[i1]))); i1 = 5 * i + 4; out2_data[i1] = a[4] + b_data[i1]; } }

/*

The code generated to calculate out1 by using coder.sameSizeBinaryOp is seen in the first for loop in the function addExample. The code generated to calculate out2 is seen below the first for loop. The generated code for out1 is much smaller, as compared to the code generated to calculate out2.

The code generated for the plus function needs additional code to expand its operands.

Generate Code for Binary Operations and Functions Without Implicit Expansion

This example shows how to generate code for binary operations and functions without implicitly expanding its operands.

The coder.sameSizeBinaryOp function applies the required operation and bypasses additional code generation and change in output size associated with implicit expansion.

This example highlights the difference between the code generated for coder.sameSizeBinaryOp and the code generated for the minus function.

Subtracting Two Operands With Implicit Expansion

For this code snippet, the generated code implicitly expands the output.

function out = fooImpEx(a,b) out = b - a; end

Define the operand types.

a = coder.typeof(1,[2 1])

a = coder.PrimitiveType 2×1 double

b = coder.typeof(1,[2 inf])

b = coder.PrimitiveType 2×:inf double

Generate code for the function by running this command:

codegen fooImpEx -config:lib -args {a,b}

Code generation successful.

The code generated for the function fooImpEx is shown here.

type codegen/lib/fooImpEx/fooImpEx.c

/*

/* Include Files */ #include "fooImpEx.h" #include "fooImpEx_emxutil.h" #include "fooImpEx_types.h" #include <emmintrin.h>

/* Function Definitions / /

} }

/*

The generated code includes code to automatically expand the size of compatible operands.

Subtracting Two Same-Size Operands Without Implicit Expansion

This code snippet uses coder.sameSizeBinaryOp to apply the operation without using implicit expansion.

function out = fooSameSize(a,b) out = coder.sameSizeBinaryOp(@minus,b,a); end

Generate code for the function by running this command:

codegen fooSameSize -config:lib -args {a,b}

Code generation successful.

The code generated for the function fooImpEx is shown here.

type codegen/lib/fooSameSize/fooSameSize.c

/*

/* Include Files */ #include "fooSameSize.h" #include "fooSameSize_types.h"

/* Function Definitions / /

/*

In this case, the variable out is fixed-size and the code generated for the operation applied by the coder.sameSizeBinaryOp function does not expand the operands. The generated function fooSameSize does not contain additional loops to increase the size of the operands.

Input Arguments

collapse all

func_handle — Binary function to apply

function handle

Binary function to apply, specified as a function handle,func_handle must be a binary (two-input) element-wise function of the form C = func_handle(u,v) that accepts arraysu and v with the same-size. Apply these binary functions without implicit expansion by usingcoder.sameSizeBinaryOp:

Function Symbol Description
plus + Plus
minus - Minus
times .* Array multiply
rdivide ./ Right array divide
ldivide .\ Left array divide
power .^ Array power
eq == Equal
ne ~= Not equal
gt > Greater than
ge >= Greater than equal to
lt < Less than
le <= Less than equal to
and & Element-wise logical AND
or | Element-wise logical OR
xor N/A Logical exclusive OR
bitand N/A Bit-wise AND
bitor N/A Bit-wise OR
bitxor N/A Bit-wise XOR
max N/A Binary maximum
min N/A Binary minimum
mod N/A Modulus after division
rem N/A Remainder after division
atan2 N/A Four-quadrant inverse tangent; result in radians
atan2d N/A Four-quadrant inverse tangent; result in degrees
hypot N/A Square root of sum of squares

Example: result = coder.sameSizeBinaryOp(@plus, u, v);

Data Types: function_handle

u — Input array

scalars | vectors | matrices | multidimensional arrays

Input array, specified as scalar, vector, matrix, or multidimensional array. Inputsu and v must be of the same sizes.

Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical | char | string | struct | table | cell | function_handle | categorical | datetime | duration | calendarDuration | fi
Complex Number Support: Yes

v — Input array

scalars | vectors | matrices | multidimensional arrays

Input array, specified as scalar, vector, matrix, or multidimensional array. Inputsu and v must be of the same sizes.

Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical | char | string | struct | table | cell | function_handle | categorical | datetime | duration | calendarDuration | fi
Complex Number Support: Yes

Version History

Introduced in R2021b