Apply function to each element of array on GPU
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. You can retrieve gpuArray
data using the
applies the function
B = arrayfun(
FUN to each element of the gpuArray
arrayfun then concatenates the outputs from
FUN into output gpuArray
the same size as
B(i,j,...) = FUN(A(i,j,...)).
The input argument
FUN is a function handle to a MATLAB function that takes one input argument and returns a scalar value.
FUN is called as many times as there are elements of
You cannot specify the order in which
arrayfun calculates the
B or rely on them being done in any particular order.
B = arrayfun(
FUN to the elements of the arrays
B(i,j,...) = FUN(A1(i,j,...),...,An(i,j,...)). The function
FUN must take
n input arguments and return a scalar.
The nonsingleton dimensions of the inputs
A1,...,An must all match, or
the inputs must be scalar. Any singleton dimensions or scalar inputs are virtually
replicated before being input to the function
[B1,...,Bm] = arrayfun(
returns multiple output arrays
B1,...,Bm when the function
m output values.
FUN each time with as many outputs as
there are in the call to
arrayfun, that is,
If you call
arrayfun with more output arguments than supported by
FUN, MATLAB generates an error.
FUN can return output arguments having
different data types, but the data type of each output must be the same each time
FUN is called.
In this example, a small function applies correction data to an array
of measurement data. The function defined in the file
myCal.m is shown
function c = myCal(rawdata, gain, offset) c = (rawdata .* gain) + offset; end
The function performs only element-wise operations when applying a gain factor and
offset to each element of the
Create a nominal measurement.
meas = ones(1000)*3; % 1000-by-1000 matrix
The function allows the gain and offset to be arrays of the same size as
rawdata, so that unique corrections can be applied to individual
measurements. In a typical situation, you can keep the correction data on the GPU so
that you do not have to transfer it for each application:
gn = rand(1000,'gpuArray')/100 + 0.995; offs = rand(1000,'gpuArray')/50 - 0.01;
Run your calibration function on the GPU.
corrected = arrayfun(@myCal,meas,gn,offs);
The function runs on the GPU because the input arguments
offs are already in GPU memory. The input array
meas is converted to a gpuArray before the function runs.
Retrieve the corrected results from the GPU to the MATLAB workspace.
results = gather(corrected);
You can define a MATLAB function as follows.
function [o1,o2] = aGpuFunction(a,b,c) o1 = a + b; o2 = o1 .* c + 2; end
Evaluate this function on the GPU.
s1 = rand(400,'gpuArray'); s2 = rand(400,'gpuArray'); s3 = rand(400,'gpuArray'); [o1,o2] = arrayfun(@aGpuFunction,s1,s2,s3); whos
Name Size Bytes Class o1 400x400 108 gpuArray o2 400x400 108 gpuArray s1 400x400 108 gpuArray s2 400x400 108 gpuArray s3 400x400 108 gpuArray Use gather to retrieve the data from the GPU to the MATLAB
gather to retrieve the data from the GPU to the MATLAB
d = gather(o2);
myfun.m generates and uses a random
function y = myfun(x) R = rand(); Y = R.*X; end
If you use
arrayfun to run this function with an input variable
that is a gpuArray, the function runs on the GPU. The size of
determines the number of random elements to generate. The following code passes the
myfun on the GPU.
G = 2*ones(4,4,'gpuArray') H = arrayfun(@myfun, G)
G is a 4-by-4 gpuArray,
generates 16 random value scalar elements for
R, one for each
calculation with an element of
FUN— Function to apply
Function to apply to the elements of the input arrays, specified as a function
FUN must return scalar values. For each output argument,
FUN must return values of the same class each time it is called.
FUN must accept numerical or logical input data.
FUN must be a handle to a function that is written in the MATLAB
language. You cannot specify
FUN as a handle to a
FUN 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 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 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 + - .* ./ .\ .^ == ~= < <= > >= & | ~ && ||
|Scalar expansion versions of the following:|
* / \ ^
break continue else elseif for if return while
The following syntaxes are supported for random matrix generation on the GPU.
rand rand() rand('single') rand('double') randn randn() randn('single') randn('double')
randi randi() randi(IMAX, ...) randi([IMIN IMAX], ...) randi(..., 'single') randi(..., 'double') randi(..., 'int32') randi(..., 'uint32')
You do not specify the array size for random generation. Instead, the number of generated random values is determined by the sizes of the input variables to your function. Enough random number elements are generated to satisfy the needs of your input or output variables. Arrays of random numbers have independent substreams for each element.
For more information about generating random numbers on the GPU, see Random Number Streams on a GPU.
A— Input array
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.
B— Output array
Output array, returned as a gpuArray.
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
arrayfun with the same function can run faster.
Nonsingleton dimensions of input arrays must match each other. In other words, the
corresponding dimensions of arguments
A1,...,An, must be equal to each
other, or equal to one. Whenever a dimension of an input array is singleton (equal to
arrayfun uses singleton expansion. The array
is virtually replicated along the singleton dimension to match the largest of the other
arrays in that dimension. When a dimension of an input array is singleton and the
corresponding dimension in another argument array is zero,
virtually diminishes the singleton dimension to
Each dimension of the output array
B is the same size as the
largest of the input arrays in that dimension for nonzero size, or zero otherwise. The
following code shows how dimensions of size
1 are scaled up or down to
match the size of the corresponding dimension in other arguments.
R1 = rand(2,5,4,'gpuArray'); R2 = rand(2,1,4,3,'gpuArray'); R3 = rand(1,5,4,3,'gpuArray'); R = arrayfun(@(x,y,z)(x+y.*z),R1,R2,R3); size(R)
2 5 4 3
R1 = rand(2,2,0,4,'gpuArray'); R2 = rand(2,1,1,4,'gpuArray'); R = arrayfun(@plus,R1,R2); size(R)
2 2 0 4
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.
Functions such as
rand do not support size specifications.
Arrays of random numbers have independent streams for each element.
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
reshape, and so on), are not
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,
P-code files cannot contain a call to
arrayfun with gpuArray