Main Content

arrayfun

GPU에서 배열의 각 요소에 함수 적용

설명

예제

참고

함수 실행이 CPU가 아닌 GPU에서 발생한다는 점을 제외하면 이 함수는 MATLAB® 함수 arrayfun과 유사하게 작동합니다. GPU에 아직 없는 모든 필수 데이터는 GPU 메모리로 이동합니다. 실행을 위해 전달된 MATLAB 함수는 컴파일되고 GPU에서 실행됩니다. 모든 출력 인수는 gpuArray 객체로 반환됩니다. gather 함수를 사용하여 gpuArray 데이터를 가져올 수 있습니다.

B = arrayfun(FUN,A)는 함수 FUN을 gpuArray A의 각 요소에 적용합니다. 그런 다음, arrayfunFUN의 출력값을 출력 인수 gpuArray B로 결합합니다. BA와 크기가 같고 B(i,j,...) = FUN(A(i,j,...))입니다. 입력 인수 FUN은 하나의 입력 인수를 취하고 스칼라 값을 반환하는 MATLAB 함수에 대한 함수 핸들입니다. FUNA의 요소 수만큼 호출됩니다.

arrayfunB의 요소를 계산하는 순서를 사용자가 지정할 수 없으며, 또한 특정 순서로 수행된다고 믿어서도 안 됩니다.

예제

B = arrayfun(FUN,A1,...,An)FUN을 배열 A1,...,An의 요소에 적용하므로 B(i,j,...) = FUN(A1(i,j,...),...,An(i,j,...))이 됩니다. 함수 FUNn개의 입력 인수를 받고 스칼라를 반환해야 합니다. 입력 인수 A1,...,An의 비한원소 차원은 모두 일치하거나 입력값이 스칼라여야 합니다. 실제 계산에서 모든 한원소 차원이나 스칼라 입력값은 함수 FUN에 입력되기 전에 복제됩니다.

예제

[B1,...,Bm] = arrayfun(FUN,___)은 함수 FUNm개의 출력값을 반환할 때 다중 출력 배열 B1,...,Bm을 반환합니다. arrayfunarrayfun 호출에 있는 출력값 수만큼 매번 FUN을 호출합니다. 즉 m번의 호출이 이루어집니다. FUN에서 지원하는 것보다 더 많은 출력 인수를 사용하여 arrayfun을 호출하면 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;

GPU에서 보정 함수를 실행합니다.

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

입력 인수 gnoffs가 이미 GPU 메모리에 있으므로 이 함수는 GPU에서 실행됩니다. 입력 배열 meas는 함수가 실행되기 전에 gpuArray로 변환됩니다.

GPU에서 MATLAB 작업 공간으로 수정된 결과를 가져옵니다.

results = gather(corrected);

다음과 같이 MATLAB 함수를 정의할 수 있습니다.

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

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              

gather를 사용하여 GPU에서 MATLAB 작업 공간으로 데이터를 가져옵니다.

d = gather(o2);

함수 myfun.m은 난수 R을 생성하고 사용합니다.

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

arrayfun을 사용하여 gpuArray 입력 변수로 이 함수를 실행하면 함수가 GPU에서 실행됩니다. X의 크기는 생성할 임의 요소의 수를 결정합니다. 다음 코드는 GPU의 myfun에 gpuArray 행렬 G를 전달합니다.

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

G는 4×4 gpuArray이므로 myfunR에 대해 16개의 임의 값 스칼라 요소를 생성하는데, 이는 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에서의 난수 생성에 대한 자세한 내용은 Random Number Streams on a GPU 항목을 참조하십시오.

입력 배열로, 스칼라, 벡터, 행렬 또는 다차원 배열로 지정됩니다. GPU에서 실행하려면 arrayfun에 대해 gpuArray 입력 배열 인수가 적어도 하나 이상 있어야 합니다. CPU 메모리에 저장된 각 배열은 함수가 실행되기 전에 gpuArray로 변환됩니다. 동일한 배열로 arrayfun을 여러 번 호출하려는 경우, 해당 배열을 gpuArray로 변환하는 것이 더 효율적입니다.

데이터형: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical

출력 인수

모두 축소

출력 배열로, gpuArray로 반환됩니다.

  • GPU에서 특정 함수를 실행하기 위해 처음으로 arrayfun을 호출할 때에는 GPU 실행을 위한 함수를 설정하기 위해 약간의 오버헤드 시간이 발생합니다. 동일한 함수를 사용한 arrayfun의 후속 호출은 더 빠르게 실행될 수 있습니다.

  • 입력 배열의 비한원소 차원은 서로 일치해야 합니다. 즉, 인수 A1,...,An의 대응하는 차원은 서로 같거나 1이어야 합니다. 입력 배열의 차원이 한원소(즉, 1)이면 arrayfun은 한원소 확장을 사용합니다. 실제 계산에서 배열은 나머지 배열 중 가장 큰 차원과 일치하도록 한원소 차원을 따라 복제됩니다. 입력 배열의 차원이 한원소이고 다른 인수 배열의 대응하는 차원이 0인 경우, arrayfun은 실제 계산에서 한원소 차원을 0으로 줄입니다.

    출력 배열 B의 각 차원은 크기가 0이 아니라면 입력 배열에서 가장 큰 차원과 크기가 같아야 하고, 그렇지 않으면 0이어야 합니다. 다음 코드는 크기가 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와 같은 배열 생성 함수는 크기 사양을 지원하지 않습니다. 난수로 구성된 배열에는 각 요소에 대한 독립적인 스트림이 있습니다.

  • MATLAB의 arrayfun과 마찬가지로 행렬 지수 거듭제곱, 곱셈 및 나눗셈(^, *, /, \)은 요소별 계산만 수행합니다.

  • 입력 배열이나 출력 배열의 크기나 형태를 변경하는 연산(cat, reshape 등)은 지원되지 않습니다.

  • 읽기 전용 인덱싱(subsref)은 지원되며, 중첩 함수 내에서 부모(바깥쪽) 함수 작업 공간의 변수에 대한 액세스도 지원됩니다. GPU에서 실행되기 전에 함수에 존재하는 변수를 인덱싱할 수 있습니다. 중첩 함수 내에서 이러한 변수의 할당이나 subsasgn 인덱싱은 지원되지 않습니다. 지원되는 사용법에 대한 예제는 Stencil Operations on a GPU 항목을 참조하십시오.

  • 익명 함수는 부모 함수 작업 공간에 액세스할 수 없습니다.

  • 지원되는 함수를 오버로드하는 것은 허용되지 않습니다.

  • 코드는 스크립트를 호출할 수 없습니다.

  • 할당되지 않은 계산 결과를 저장할 ans 변수가 없습니다. 모든 계산 결과를 변수에 명시적으로 할당하십시오.

  • 영구 변수 또는 전역 변수, parfor, spmd, switch, try/catch와 같은 언어 기능은 지원되지 않습니다.

  • P 코드 파일에는 gpuArray 데이터로 arrayfun을 호출하는 코드를 포함할 수 없습니다.

버전 내역

R2010b에 개발됨