exponenta event banner

arrayfun

Применение функции к каждому элементу массива графического процессора

Описание

пример

Примечание

Эта функция работает аналогично функции MATLAB ®arrayfun, за исключением того, что оценка функции выполняется на GPU, а не на CPU. Все требуемые данные, еще не находящиеся на GPU, перемещаются в память GPU. Функция MATLAB, переданная для оценки, компилируется и затем выполняется на GPU. Все выходные аргументы возвращаются как объекты gpuArray. Вы можете получить данные gpuArray с помощью gather функция.

B = arrayfun(FUN,A) применяет функцию FUN каждому элементу gpuArray A. arrayfun затем объединяет выходные сигналы FUN в выходной gpuArray B. B имеет тот же размер, что и A и B(i,j,...) = FUN(A(i,j,...)). Входной аргумент FUN - дескриптор функции для функции MATLAB, которая принимает один входной аргумент и возвращает скалярное значение. FUN вызывается столько раз, сколько элементов A.

Невозможно указать порядок, в котором arrayfun вычисляет элементы B или полагаться на их выполнение в каком-либо конкретном порядке.

пример

B = arrayfun(FUN,A1,...,An) применяется FUN к элементам массивов A1,...,An, так что B(i,j,...) = FUN(A1(i,j,...),...,An(i,j,...)). Функция FUN должны принять n и возвращает скаляр. Несинглетонные размеры вводов A1,...,An все должны совпадать, либо входные данные должны быть скалярными. Любые одиночные размеры или скалярные входы виртуально реплицируются перед вводом в функцию FUN.

пример

[B1,...,Bm] = arrayfun(FUN,___) возвращает несколько выходных массивов B1,...,Bm когда функция FUN прибыль m выходные значения. arrayfun требования FUN каждый раз с таким количеством выходов, какое имеется в вызове arrayfun, то есть m времена. При звонке arrayfun с большим количеством выходных аргументов, чем поддерживается FUN, MATLAB генерирует ошибку. FUN может возвращать выходные аргументы, имеющие различные типы данных, но тип данных каждого вывода должен быть одинаковым каждый раз FUN вызывается.

Примеры

свернуть все

В этом примере небольшая функция применяет данные коррекции к массиву данных измерения. Функция, определенная в файле myCal.m показан здесь.

function c = myCal(rawdata, gain, offset)
    c = (rawdata .* gain) + offset;
end

Функция выполняет только элементные операции при применении коэффициента усиления и смещения к каждому элементу rawdata массив.

Создайте номинальное измерение.

meas = ones(1000)*3; % 1000-by-1000 matrix

Функция позволяет использовать массивы с тем же размером, что и rawdata, так что уникальные поправки могут быть применены к отдельным измерениям. В типичной ситуации можно сохранить данные коррекции на GPU, чтобы не переносить их для каждого приложения:

gn   = rand(1000,'gpuArray')/100 + 0.995; 
offs = rand(1000,'gpuArray')/50  - 0.01;

Запустите функцию калибровки на графическом процессоре.

corrected = arrayfun(@myCal,meas,gn,offs);

Функция выполняется на GPU, поскольку входные аргументы gn и offs уже находятся в памяти графического процессора. Входной массив meas преобразуется в gpuArray перед запуском функции.

Извлеките исправленные результаты из графического процессора в рабочую область MATLAB.

results = gather(corrected);

Функцию MATLAB можно определить следующим образом.

function [o1,o2] = aGpuFunction(a,b,c)
    o1 = a + b;
    o2 = o1 .* c + 2;
end

Оцените эту функцию на графическом процессоре.

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 для извлечения данных из графического процессора в рабочую область MATLAB.

d = gather(o2);

Функция myfun.m генерирует и использует случайное число R.

function Y = myfun(X)
    R = rand();
    Y = R.*X;
end

Если вы используете arrayfun для запуска этой функции с входной переменной, которая является gpuArray, функция запускается на GPU. Размер X определяет количество генерируемых случайных элементов. Следующий код передает матрицу gpuArray G кому myfun на GPU.

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

Поскольку G является 4-х по 4 gpuArray, myfun генерирует 16 скалярных элементов случайного значения для R, по одному для каждого расчета с элементом G.

Входные аргументы

свернуть все

Функция для применения к элементам входных массивов, заданная как дескриптор функции. FUN должен возвращать скалярные значения. Для каждого выходного аргумента FUN должен возвращать значения одного и того же класса при каждом вызове. FUN должен принимать числовые или логические входные данные.

FUN должен быть дескриптором функции, написанной на языке MATLAB. Невозможно указать FUN в качестве дескриптора функции MEX.

FUN может содержать следующие встроенные функции и операторы MATLAB.

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

+
-
.*
./
.\
.^
==
~=
<
<=
>
>=
&
|
~
&&
||

Версии скалярного расширения:

*
/
\
^
Инструкции по ветвлению:
break
continue
else
elseif
for
if
return
while

Функции, создающие массивы (например, Inf, NaN, ones, rand, randi, randn, и zeros) не поддерживают спецификации размера в качестве входных аргументов. Вместо этого размер создаваемого массива определяется размером входных переменных для функций. Создается достаточное количество элементов массива для удовлетворения потребностей входных или выходных переменных. Тип данных можно указать с помощью класса и "like" синтаксисы. В следующих примерах показаны поддерживаемые синтаксисы для функций создания массива:

a = rand;
b = ones();
c = zeros("like", x);
d = Inf("single");
e = randi([0 9], "uint32");

При использовании rand, randi, и randn для генерации случайных чисел в пределах FUNкаждый элемент генерируется из другого подпотока. Дополнительные сведения о генерации случайных чисел на GPU см. в разделе Потоки случайных чисел на GPU.

Входной массив, заданный как скаляры, векторы, матрицы или многомерные массивы. По крайней мере один аргумент входного массива должен быть gpuArray для arrayfun для запуска на GPU. Каждый массив, который хранится в памяти ЦП, преобразуется в gpuArray перед оценкой функции. Если планируется выполнить несколько вызовов arrayfun с тем же массивом более эффективно преобразовать этот массив в gpuArray.

Типы данных: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical

Выходные аргументы

свернуть все

Выходной массив, возвращаемый как gpuArray.

Совет

  • При первом звонке arrayfun для выполнения определенной функции на GPU существует некоторое время на создание функции для выполнения GPU. Последующие вызовы arrayfun с той же функцией может работать быстрее.

  • Несинглетонные размеры входных массивов должны соответствовать друг другу. Другими словами, соответствующие измерения аргументов A1,...,An, должны быть равны друг другу или равны единице. Всякий раз, когда размер входного массива является одиночным (равным 1), arrayfun использует синглтонное расширение. Массив виртуально реплицируется вдоль одиночного измерения, чтобы соответствовать самому большому из других массивов в этом измерении. Если размерность входного массива является одиночной, а соответствующая размерность в другом массиве аргументов равна нулю, arrayfun фактически уменьшает размер одиночки до 0.

    Каждое измерение выходного массива B является тем же размером, что и наибольший из входных массивов в этом измерении для ненулевого размера, или нулем в противном случае. Следующий код показывает, как размеры размера 1 масштабируются или уменьшаются в соответствии с размером соответствующего измерения в других аргументах.

    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
    
  • Потому что операции поддерживаются arrayfun строго по элементам, и каждое вычисление каждого элемента выполняется независимо от других, накладываются определённые ограничения:

    • Массивы ввода и вывода не могут изменять форму или размер.

    • Функции создания массива, такие как rand не поддерживают спецификации размеров. Массивы случайных чисел имеют независимые потоки для каждого элемента.

  • Как arrayfun в MATLAB - экспоненциальная мощность матрицы, умножение и деление (^, *, /, \) выполнять только расчеты по элементам.

  • Операции, изменяющие размер или форму входных или выходных массивов (cat, reshape, и так далее) не поддерживаются.

  • Индексирование только для чтения (subsref) и поддерживается доступ к переменным рабочей области родительской (внешней) функции из вложенных функций. Можно проиндексировать переменные, которые существуют в функции до анализа на GPU. Назначение или subsasgn индексирование этих переменных из вложенной функции не поддерживается. Пример поддерживаемого использования см. в разделе Операции с набором элементов на графическом процессоре.

  • Анонимные функции не имеют доступа к родительской рабочей области.

  • Перегрузка поддерживаемых функций не допускается.

  • Код не может вызывать сценарии.

  • Здесь нет ans для хранения неназначенных результатов вычислений. Убедитесь в явном назначении переменным результатов всех вычислений.

  • Следующие языковые функции не поддерживаются: постоянные или глобальные переменные, parfor, spmd, switch, и try/catch.

  • Файлы P-кода не могут содержать вызов arrayfun с данными gpuArray.

Представлен в R2010b