ドキュメンテーション センター

  • 評価版
  • 製品アップデート

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

GPU における要素単位での MATLAB コードの実行

MATLAB コードと gpuArray オブジェクト

MATLAB 計算を GPU 上で 実行するためのオプションがあります。

  • GPU でデータを転送または作成し、得られた gpuArray を、gpuArray をサポートするよう拡張された組み込み関数への入力として使用します。入力としての gpuArray をサポートする関数の詳細およびリストは、「gpuArray をサポートする組み込み関数」を参照してください。

  • GPU で、要素単位の演算を行う独自の MATLAB 関数を実行できます。

どちらのソリューションを採用するかは、必要な関数が gpuArray をサポートするよう拡張されているかどうか、および GPU との間のデータ転送がパフォーマンスに及ぼす影響によって決まります。

GPU での MATLAB 関数の実行

MATLAB 関数を GPU で実行するには、その MATLAB 関数の関数ハンドルを最初の入力引数に指定して、arrayfun または bsxfun を呼び出します。

result = arrayfun(@myFunction, arg1, arg2);

2 番目以降の引数では、MATLAB 関数への入力が指定されます。これらの入力引数は、ワークスペース データや gpuArray とすることができます。入力引数のいずれかが gpuArray の場合、関数は GPU で実行されて gpuArray を返します (どの入力も gpuArray ではない場合、arrayfun および bsxfun は CPU で実行されます)。

    メモ:    arrayfunbsxfun は、GPU での要素単位の演算のみをサポートします。

使用可能なオプションについての説明は、arrayfun および bsxfun のリファレンス ページを参照してください。

例: MATLAB コードの実行

次の例では、小さな関数で測定データの配列に補正データを適用しています。ファイル myCal.m で定義されている関数は次のとおりです。

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

この関数は、rawdata 配列の各要素にゲイン係数とオフセットを適用する際に、要素単位の演算のみを実行します。

ノミナル測定値を作成します。

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

この関数では、ゲインとオフセットを rawdata と同じサイズの配列にすることができ、個々の測定値に一意の補正を適用できます。通常は、各アプリケーションに転送せずに済むよう補正データは GPU 上に保持します。

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

GPU でキャリブレーション関数を実行します。

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

これは、入力引数 gn および offs が既に GPU メモリ上に格納されているため GPU で実行されます。

補正された結果を GPU から MATLAB ワークスペースに取得します。

results = gather(corrected);

サポートされている MATLAB コード

arrayfun または bsxfun に渡される関数には、以下の 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
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
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
xor


+
-
.*
./
.\
.^
==
~=
<
<=
>
>=
&
|
~
&&
||
以下のスカラー拡張バージョン:
*
/
\
^
分岐命令:
break
continue
else
elseif
for
if
return
while

GPU での乱数の生成

GPU で実行するために arrayfun または bsxfun に渡す関数には、乱数発生器関数 randrandi および randn を含めることができます。ただし、GPU では、MATLAB でサポートされるこれらの関数の完全な機能まではサポートされていません。

GPU で実行される arrayfun および bsxfun では、以下の形式による乱数行列の生成がサポートされます。

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')

乱数の生成では、配列サイズは指定しません。代わりに、生成される乱数値の数は関数に対する入力変数のサイズによって決まります。実質的に、任意の入力変数や出力変数に必要な十分な数の乱数要素が生成されます。

たとえば、関数 myfun.m に、乱数行列 R の生成と使用を組み込んだ以下のコードを含めるとします。

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

arrayfun を使用し、gpuArray である入力変数を指定してこの関数を実行すると、関数は GPU で実行されます。この場合、R の乱数要素の数は X のサイズによって決まるため、指定の必要はありません。次のコードでは、gpuArray 行列 G を GPU 上の myfun に渡しています。

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

G は 4 行 4 列の gpuArray であるため、myfunR の 16 個の乱数値スカラー要素を、G の要素の計算ごとに 1 つずつ生成します。

GPU での arrayfun および bsxfun による乱数発生では、「gpuArray の乱数ストリームの制御」で説明された、gpuArray による乱数発生と同じグローバル ストリームを使用します。GPU での乱数発生についての詳細と、GPU と CPU での発生の比較は、「乱数ストリームの制御」を参照してください。

制限

以下の制限が、arrayfunbsxfun が GPU で評価する関数内のコードに適用されます。

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

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

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

  • 入れ子関数は MATLAB ワークスペースの変数、つまり、GPU での arrayfun の評価以前から MATLAB に存在している変数には、読み取り専用アクセスしかできません。

  • MATLAB ワークスペースの変数に対し、subsref のインデックス付けはサポートされていますが、subsasgn のインデックス付けはサポートされていません。

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

  • すべての倍精度計算は IEEE 準拠ですが、単精度計算はハードウェア上の制限により IEEE 準拠ではありません。

  • サポートされているデータ型変換は singledoubleint8uint8int16uint16int32uint32 および logical です。

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

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

  • randrandi または randn で乱数行列を生成する場合、行列のサイズを指定する必要はなく、行列の各要素には独自の乱数ストリームが設定されます。

この情報は役に立ちましたか?