メインコンテンツ

arrayfun

関数を GPU 上の配列内の各要素に適用する

説明

メモ

この関数の動作は MATLAB® 関数 arrayfun と似ていますが、関数の評価が CPU ではなく GPU で行われる点で異なります。まだ GPU 上にない必要なデータは GPU メモリに移動されます。評価のために渡された MATLAB 関数がコンパイルされてから GPU で実行されます。すべての出力引数は gpuArray オブジェクトとして返されます。

B = arrayfun(func,A) は、関数 funcgpuArray A の各要素に適用してから、func の出力を連結して gpuArray B の出力を生成します。BA と同じサイズであり、B(i,j,...) = func(A(i,j,...)) です。入力引数 func は、1 つの入力引数を受け入れ、スカラーを返す MATLAB 関数の関数ハンドルです。func は、A の要素数と同じ回数呼び出されます。

B = arrayfun(func,A1,...,An) は、B(i,j,...) = func(A1(i,j,...),...,An(i,j,...)) となるように func を配列 A1,...,An の要素に適用します。関数 func は、n 個の入力引数を受け入れてスカラーを返さなければなりません。A1,...,An のサイズは一致するか、互換性がなければなりません。

[B1,...,Bm] = arrayfun(func,___) は、関数 funcm 個の出力値を返す場合に複数の出力配列 B1,...,Bm を返します。func は異なるデータ型をもつ出力引数を返すことができますが、func の各呼び出しにおいて、各出力のデータ型は同じでなければなりません。

すべて折りたたむ

関数 cal を定義します。関数 cal は、測定データの配列にゲインとオフセットの補正を適用します。この関数は、rawdata 配列の各要素に gain 係数と offset を適用する際に、要素単位の演算のみを実行します。

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

測定データの配列を作成します。

meas = 1:4
meas = 1×4

     1     2     3     4

ゲイン データとオフセット データを含む配列を作成します。

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

GPU でキャリブレーション関数を実行します。この関数は、入力引数 gn および offs が既に GPU 配列であり、したがって GPU メモリ上に格納されているため GPU で実行されます。関数が実行される前に、入力配列 measgpuArray オブジェクトに変換されます。

corrected = arrayfun(@cal,meas,gn,offs)
corrected =

    1.0021    1.9889    2.9874    4.0129

要素単位の演算を GPU でほんの数回実行しても、コードが高速化される可能性はほとんどありません。arrayfun の実行速度が入力配列のサイズに応じてどのように変化するかを示す例については、arrayfun を使用した、要素単位の MATLAB 関数の GPU におけるパフォーマンス改善を参照してください。

要素単位の演算を複数の入力に適用し、複数の出力を返す関数を定義します。

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

gpuArray 入力データを作成し、この関数を 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              

乱数 R を作成して使用する関数を定義します。

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

GPU で関数を実行します。G は 4 行 4 列の gpuArray オブジェクトであるため、arrayfunmyRandfun 関数を 16 回適用し、16 個の異なる乱数スカラー値 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

入力引数

すべて折りたたむ

入力配列の要素に適用する関数。関数ハンドルとして指定します。

  • func はスカラー値を返さなければなりません。

  • 各出力引数について、func は呼び出されるたびに同じクラスの値を返さなければなりません。

  • func は数値または logical の入力データを受け入れなければなりません。

  • func は MATLAB 言語で記述された関数のハンドルでなければなりません。func を MEX 関数のハンドルとして指定することはできません。

  • func を静的メソッドまたはクラス コンストラクター メソッドとして指定することはできません。

func には、以下の 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, if
for
return
switch, case, otherwise
while

配列を作成する関数 (InfNaNonesrandrandirandnzeros など) は、サイズ指定を入力引数としてサポートしていません。代わりに、生成される配列のサイズは、関数の入力変数のサイズによって決まります。入力変数または出力変数の要求を満たす十分な数の配列要素が生成されます。クラスと like の両方の構文を使用して、データ型を指定できます。以下の例で、配列作成関数でサポートされる構文を示します。

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

func 内で randrandi および randn を使用して乱数を生成する場合、各要素は異なるサブストリームから生成されます。GPU での乱数発生の詳細については、GPU 上の乱数ストリームを参照してください。

func 内で switch, case, otherwise を使用する場合、ケース式は数値と logical 値のみをサポートします。

入力配列。スカラー、ベクトル、行列または多次元配列として指定します。arrayfun を GPU 上で実行するには、少なくとも 1 つの入力配列の引数が gpuArray でなければなりません。CPU メモリに格納された各配列は、関数が評価される前に gpuArray に変換されます。同じ配列を指定して arrayfun を複数回呼び出す場合、その配列を gpuArray に変換するとより効率的になります。

データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical

出力引数

すべて折りたたむ

出力配列。gpuArray として返されます。

制限

  • A1,...,An のサイズは一致するか、互換性がなければなりません。出力配列 B のサイズは、A1,...,An のサイズによって異なります。詳細については、基本的な演算で互換性のある配列サイズを参照してください。

  • arrayfun によりサポートされている演算は厳密に要素単位であり、各要素の各計算は他の要素と独立して実行されるため、一定の制約が適用されます。

    • 入出力配列の形状やサイズは変更できません。

    • rand などの配列作成関数は、サイズ指定をサポートしていません。乱数の配列は、要素ごとに独立したストリームを有しています。

  • arrayfun での出力配列 B の要素の計算順序を指定したり、特定の順序で計算される要素に依存したりすることはできません。

  • MATLAB の arrayfun と同様に、行列のべき乗、乗算および除算 (^*/\) では要素単位の計算のみが実行されます。

  • 入出力配列 (catreshape など) のサイズまたは形状を変更する演算はサポートされていません。

  • 読み取り専用のインデックス付け (subsref) と、入れ子関数の中から親 (外側) 関数ワークスペースの変数へのアクセスがサポートされています。GPU で関数を評価する前に、その関数内にある変数にインデックスを付けることができます。入れ子関数の中からこのような変数を代入したりそれを subsasgn インデックス化することは、サポートされません。サポートされている使用法の例は、GPU でのステンシル演算を参照してください。

  • 無名関数はその親関数のワークスペースにはアクセスできません。

  • サポートされている関数のオーバーロードは許可されません。

  • コードからスクリプトを呼び出すことはできません。

  • 代入されていない計算結果を格納する ans 変数はありません。必ずすべての計算結果を明示的に変数に代入します。

  • サポートされていない言語機能として、永続変数またはグローバル変数、parforspmdtry および catch が挙げられます。

ヒント

  • GPU で特定の関数を呼び出すために最初に arrayfun を呼び出す時点では、GPU 実行のための関数の設定に若干のオーバーヘッド時間が発生します。同じ関数を指定したその後の arrayfun の呼び出しでは、処理速度が向上します。

拡張機能

すべて展開する

バージョン履歴

R2010b で導入

すべて展開する