arrayfun - Apply function to each element of array on GPU - MATLAB (original) (raw)
Apply function to each element of array on GPU
Syntax
Description
Note
This function behaves similarly to the MATLAB® function arrayfun, except that the evaluation of the function happens on the GPU, not on the CPU. Any required data not already on the GPU is moved to GPU memory. The MATLAB function passed in for evaluation is compiled and then executed on the GPU. All output arguments are returned as gpuArray objects.
[B](#mw%5F7153cb02-2d3c-4566-8cf9-a6078a2cd157) = arrayfun([func](#mw%5Fff5bc44a-1f90-4fa0-8227-09214f470ce8),[A](#mw%5Fc2f7dadb-187f-4742-8c05-cb76489d3fcb))
applies a function func
to each element of a gpuArray
A
and then concatenates the outputs from func
into output gpuArray
B
. B
is the same size as A
andB(i,j,...) = func(A(i,j,...))
. The input argumentfunc
is a function handle to a MATLAB function that takes one input argument and returns a scalar.func
is called as many times as there are elements ofA
.
[B](#mw%5F7153cb02-2d3c-4566-8cf9-a6078a2cd157) = arrayfun([func](#mw%5Fff5bc44a-1f90-4fa0-8227-09214f470ce8),A1,...,An)
applies func
to the elements of the arrays A1,...,An
, so that B(i,j,...) = func(A1(i,j,...),...,An(i,j,...))
. The functionfunc
must take n
input arguments and return a scalar. The sizes of A1,...,An
must match or be compatible.
[B1,...,Bm] = arrayfun([func](#mw%5Fff5bc44a-1f90-4fa0-8227-09214f470ce8),___)
returns multiple output arrays B1,...,Bm
when the functionfunc
returns m
output values.func
can return output arguments having different data types, but the data type of each output must be the same each time func
is called.
Examples
Run Function on GPU
Define a function, cal
. The function cal
applies a gain and an offset correction to an array of measurement data. The function performs only element-wise operations when applying the gain
factor and offset
to each element of the rawdata
array.
function c = cal(rawdata,gain,offset) c = (rawdata.*gain) + offset; end
Create an array of measurement data.
Create arrays containing the gain and offset data.
gn = rand([1 4],"gpuArray")/100 + 0.995
gn =
0.9958 0.9967 0.9985 1.0032
offs = rand([1 4],"gpuArray")/50 - 0.01
offs =
0.0063 -0.0045 -0.0081 0.0002
Run the calibration function on the GPU. The function runs on the GPU because the input arguments gn
and offs
are already GPU arrays, and are therefore stored in GPU memory. Before the function runs, it converts the input array meas
to a gpuArray
object.
corrected = arrayfun(@cal,meas,gn,offs)
corrected =
1.0021 1.9889 2.9874 4.0129
Performing a small number of element-wise operations on a GPU is unlikely to speed up your code. For an example showing how arrayfun
execution speed scales with input array size, see Improve Performance of Element-Wise MATLAB Functions on the GPU Using arrayfun.
Use Function with Multiple Outputs
Define a function that applies element-wise operations to multiple inputs and returns multiple outputs.
function [o1,o2] = myFun(a,b,c) o1 = a + b; o2 = o1.*c + 2; end
Create gpuArray
input data, and evaluate the function on the GPU.
s1 = rand(400,"gpuArray"); s2 = rand(400,"gpuArray"); s3 = rand(400,"gpuArray"); [o1,o2] = arrayfun(@myFun,s1,s2,s3); whos
Name Size Bytes Class Attributes
o1 400x400 1280000 gpuArray
o2 400x400 1280000 gpuArray
s1 400x400 1280000 gpuArray
s2 400x400 1280000 gpuArray
s3 400x400 1280000 gpuArray
Use Random Numbers with arrayfun
Define a function that creates and uses a random number, R
.
function Y = myRandFun(X) R = rand; Y = R.*X; end
Run the function on the GPU. As G
is a 4-by-4 gpuArray
object, arrayfun
applies the myRandfun
function 16 times, generating 16 different random scalar values, H
.
G = ones(4,"gpuArray")*2; H = arrayfun(@myRandFun,G)
H =
1.0557 0.3599 1.5303 0.2745
0.4268 1.1226 1.5261 1.7068
0.0302 0.5814 0.2556 0.3902
1.1210 1.5310 1.3665 0.8487
Input Arguments
func
— Function to apply
function handle
Function to apply to the elements of the input arrays, specified as a function handle.
func
must return scalar values.- For each output argument,
func
must return values of the same class each time it is called. func
must accept numerical or logical input data.func
must be a handle to a function that is written in the MATLAB language. You cannot specifyfunc
as a handle to a MEX function.- You cannot specify
func
as a static method or a class constructor method.
func
can contain the following built-in MATLAB functions and operators.
| abs and acos acosh acot acoth acsc acsch asec asech asin asinh atan atan2 atanh beta betaln bitand bitcmp bitget bitor bitset bitshift bitxor cast ceil complex conj cos cosh cot coth csc | csch double eps eq erf erfc erfcinv erfcx erfinv exp expm1 false fix floor gamma gammaln ge gt hypot imag Inf int8 int16 int32 int64 intmax intmin isfinite isinf isnan ldivide le log | log2 log10 log1p logical lt max min minus mod NaN ne not ones or pi plus pow2 power rand randi randn rdivide real reallog realmax realmin realpow realsqrt rem round sec sech sign | sin single sinh sqrt tan tanh times true uint8 uint16 uint32 uint64 xor zeros + - .* ./ .\ .^ == ~= < <= > >= & | ~ && | | | Scalar expansion versions of the following:* / \ ^ Branching instructions:break continue else, elseif, if for return switch, case, otherwise while | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | - | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
Functions that create arrays (such as Inf
, NaN
,ones
, rand
, randi
,randn
, and zeros
) do not support size specifications as input arguments. Instead, the size of the generated array is determined by the size of the input variables to your functions. Enough array elements are generated to satisfy the needs of your input or output variables. You can specify the data type using both class and like
syntaxes. The following examples show supported syntaxes for array-creation functions:
a = rand; b = ones; c = zeros(like=x); d = Inf("single"); e = randi([0 9],"uint32");
When you use rand
, randi
, andrandn
to generate random numbers withinfunc
, each element is generated from a different substream. For more information about generating random numbers on the GPU, seeRandom Number Streams on a GPU.
When you use switch, case, otherwise withinfunc
, case expressions support only numeric and logical values.
A
— Input array
scalars | vectors | matrices | multidimensional arrays
Input array, specified as scalars, vectors, matrices, or multidimensional arrays. At least one input array argument must be a gpuArray
forarrayfun
to run on the GPU. Each array that is stored in CPU memory is converted to a gpuArray
before the function is evaluated. If you plan to make several calls to arrayfun
with the same array, it is more efficient to convert that array to a gpuArray
.
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
| logical
Output Arguments
B
— Output array
gpuArray
Output array, returned as a gpuArray
.
Limitations
- The sizes of
A1,...,An
must match or be compatible. The size of output arrayB
depends on the sizes ofA1,...,An
. For more information, see Compatible Array Sizes for Basic Operations. - Because the operations supported by
arrayfun
are strictly element-wise, and each computation of each element is performed independently of the others, certain restrictions are imposed:- Input and output arrays cannot change shape or size.
- Array-creation functions such as
rand
do not support size specifications. Arrays of random numbers have independent streams for each element.
- You cannot specify the order in which
arrayfun
calculates the elements of output arrayB
or rely on them being done in any particular order. - Like
arrayfun
in MATLAB, matrix exponential power, multiplication, and division (^
,*
,/
,\
) perform element-wise calculations only. - Operations that change the size or shape of the input or output arrays (
cat
,reshape
, and so on) are not supported. - Read-only indexing (
subsref
) and access to variables of the parent (outer) function workspace from within nested functions is supported. You can index variables that exist in the function before the evaluation on the GPU. Assignment orsubsasgn
indexing of these variables from within the nested function is not supported. For an example of the supported usage, see Stencil Operations on a GPU. - Anonymous functions do not have access to their parent function workspace.
- Overloading the supported functions is not allowed.
- The code cannot call scripts.
- There is no
ans
variable to hold unassigned computation results. Make sure to explicitly assign to variables the results of all calculations. - The following language features are not supported: persistent or global variables,
parfor
,spmd
, andtry
/catch
. - Calls to
arrayfun
inside P-code files or usingarrayfun
to evaluate functions obfuscated as a P-code files are not supported in standalone functions compiled using MATLAB Compiler™.
Tips
- The first time you call
arrayfun
to run a particular function on the GPU, there is some overhead time to set up the function for GPU execution. Subsequent calls ofarrayfun
with the same function can run faster.
Extended Capabilities
Thread-Based Environment
Run code in the background using MATLAB® backgroundPool
or accelerate code with Parallel Computing Toolbox™ ThreadPool
.
This function fully supports thread-based environments. For more information, see Run MATLAB Functions in Thread-Based Environment.
GPU Arrays
Accelerate code by running on a graphics processing unit (GPU) using Parallel Computing Toolbox™.
The arrayfun
function fully supports GPU arrays. To run the function on a GPU, specify the input data as a gpuArray. For more information, see Run MATLAB Functions on a GPU.
Version History
Introduced in R2010b
R2024b: Support for functions defined in class definition files
You can now call arrayfun
in a class method to evaluate functions defined in the class definition file (a file with a .m
extension that contains the classdef
keyword).
For example, this class contains a method, output
, that usesarrayfun
to evaluate a local function, localFun
.
classdef TestClass methods function output = func(obj,x) output = arrayfun(@localFun,x); end end end
function output = localFun(x) output = x.*x; end
For more information about defining classes in MATLAB, see Creating a Simple Class.
R2024b: Support for P-Code files
You can now use P-code files with arrayfun
. You can:
- Use
arrayfun
to evaluate a function obfuscated as a P-code file. - Call
arrayfun
inside a P-code file. - Use
arrayfun
when the function it applies contains a call to a function obfuscated as a P-code file.
For more information about P-code files, see Create a Content-Obscured File with P-Code.
R2024a: Support for cell array case expressions in switch
, case
, otherwise
Use a cell array as the case expression to compare the switch expression against multiple values within the function you apply using arrayfun
. For example, you can use case {x1,y1}
to execute the corresponding code if the switch expression matches at least one of x1
andy1
.
R2023b: Support for switch
, case
, and otherwise
You can now use switch conditional statements in functions you apply using arrayfun
. This functionality has these limitations:
- Case expressions support only numeric and logical values.
- Using a cell array as the case expression to compare the switch expression against multiple values, for example,
case {x1,y1}
, is not supported.
R2023b: Changes to indexing into and writing to variables in nested functions
Passing arrays from a parent workspace to a nested function and indexing into the array within the nested function now errors
For example, in the following code, the variable parentWorkspaceVar
is created in the parent workspace of the foo
function. Iffoo
is used in an arrayfun call with gpuArray input, and if thefoo
function passes parentWorkspaceVar
as input to a nested function within foo
, the code errors.
As a workaround, instead of passing the parent workspace variable (parentWorkspaceVar
) to the nested function (bar
), use the parent workspace variable directly as it is already in the scope of the nested function.
Errors | Workaround |
---|---|
function y = exampleFunction parentWorkspaceVar = 1:9; x = ones(2,"gpuArray"); y = arrayfun(@foo,x); function y = foo(x) y = bar(parentWorkspaceVar); function y = bar(z) % ERRORS y = z(1); end end end | function y = exampleFunction parentWorkspaceVar = 1:9; x = ones(2,"gpuArray"); y = arrayfun(@foo,x); function y = foo(x) y = bar; function y = bar % Previously this variable was passed in, now it is used directly as it is in scope. y = parentWorkspaceVar(1); end end end |
Functions writing into variables created in a parent function now error
In the following code, the variable workspaceVar
is created in the workspace of the bar
function. If bar
is used in anarrayfun call with gpuArray input, and if a nested function foo
writes intoworkspaceVar
, the code errors.
As a workaround, instead of writing to the variable (workspaceVar
) within the nested function (foo
), add another output to the nested function and use the output to write to the variable.
Errors | Workaround |
---|---|
function x = exampleFunction z = ones(2,"gpuArray"); x = arrayfun(@bar,z); function y = bar(z) workspaceVar = 2; foo(z); function x = foo(z) workspaceVar = 10; % ERRORS x = z; end y = workspaceVar; end end | function x = exampleFunction z = ones(2,"gpuArray"); x = arrayfun(@bar,z); function y = bar(z) workspaceVar = 2; [out,workspaceVar] = foo(z); % Write to workspaceVar outside foo. function [x,y] = foo(z) % Add another output y to the nested function. y = 10; x = z; end y = workspaceVar; end end |