Main Content

arrayfun

Apply function to each element of array on GPU

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 = arrayfun(func,A) 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 and B(i,j,...) = func(A(i,j,...)). The input argument func 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 of A.

example

B = arrayfun(func,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 function func must take n input arguments and return a scalar. The sizes of A1,...,An must match or be compatible.

example

[B1,...,Bm] = arrayfun(func,___) returns multiple output arrays B1,...,Bm when the function func 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.

example

Examples

collapse all

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.

meas = 1:4
meas = 1×4

     1     2     3     4

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.

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              

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

collapse all

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 specify func 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, and randn to generate random numbers within func, each element is generated from a different substream. For more information about generating random numbers on the GPU, see Random Number Streams on a GPU.

When you use switch, case, otherwise within func, case expressions support only numeric and logical values.

Input array, specified as scalars, vectors, matrices, or multidimensional arrays. At least one input array argument must be a gpuArray for arrayfun 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

collapse all

Output array, returned as a gpuArray.

Limitations

  • The sizes of A1,...,An must match or be compatible. The size of output array B depends on the sizes of A1,...,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 array B 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 or subsasgn 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, and try/catch.

  • Calls to arrayfun inside P-code files or using arrayfun 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 of arrayfun with the same function can run faster.

Extended Capabilities

Version History

Introduced in R2010b

expand all