arrayfun

Apply function to each element of array on GPU

Syntax

``B = arrayfun(FUN,A)``
``B = arrayfun(FUN,A1,...,An)``
``[B1,...,Bm] = arrayfun(FUN,___)``

Description

example

``` NoteThis 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 `gather` function. `B = arrayfun(FUN,A)` applies the function `FUN` to each element of the `gpuArray` `A`. `arrayfun` then concatenates the outputs from `FUN` into output `gpuArray` `B`. `B` is the same size as `A` and `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 `A`.You cannot specify the order in which `arrayfun` calculates the elements of `B` or rely on them being done in any particular order.```

example

````B = arrayfun(FUN,A1,...,An)` applies `FUN` to the elements of the arrays `A1,...,An`, so that `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 `FUN`.```

example

````[B1,...,Bm] = arrayfun(FUN,___)` returns multiple output arrays `B1,...,Bm` when the function `FUN` returns `m` output values. `arrayfun` calls `FUN` each time with as many outputs as there are in the call to `arrayfun`, that is, `m` times. 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.```

Examples

collapse all

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 here.

```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 `rawdata` array.

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 `gn` and `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 Attributes o1 400x400 1280000 gpuArray o2 400x400 1280000 gpuArray s1 400x400 1280000 gpuArray s2 400x400 1280000 gpuArray s3 400x400 1280000 gpuArray ```

Use `gather` to retrieve the data from the GPU to the MATLAB workspace.

`d = gather(o2);`

The function `myfun.m` generates and uses a random number `R`.

```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 `X` determines the number of random elements to generate. The following code passes the `gpuArray` matrix `G` to `myfun` on the GPU.

```G = 2*ones(4,4,"gpuArray") H = arrayfun(@myfun, G)```

Because `G` is a 4-by-4 `gpuArray`, `myfun` generates 16 random value scalar elements for `R`, one for each calculation with an element of `G`.

Input Arguments

collapse all

Function to apply to the elements of the input arrays, specified as a function handle. `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 MEX function.

`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 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 `FUN`, 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 `FUN`:

• 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.

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`.

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.

• 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 `1`), `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, `arrayfun` virtually diminishes the singleton dimension to `0`.

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.

• Array-creation functions such as `rand` do not support size specifications. Arrays of random numbers have independent streams for each element.

• 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.

• 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`.

• P-code files cannot contain a call to `arrayfun` with `gpuArray` data.

Version History

Introduced in R2010b

expand all