3

私は、Matlab 2011a で CUDA カーネルを起動するために parallel.gpu.CUDAKernel を使用しています。ループ内での後続のカーネル起動によって同じ gpuArray が読み込まれるようにコードを設計しましたが、各起動は gpuArray の一意のセグメントに制限されます。

実行の終わりまでに、配列全体がいっぱいになるはずです。ただし、gather() を使用してメモリをホストに戻すと、最後のカーネル起動によって書き込まれたメモリのみが正しくなります。他のすべては空白です。これは、途中でループから抜け出した場合にも当てはまります。

カーネルの反復を示すフラグを渡すことで、これが実際に当てはまることを確認しました。最初の反復以外の場合、カーネルは何もしません。ただし、後続のカーネルが何もしない場合でも、最初のカーネルによって書き込まれたデータの場所はまだ空です! これは、最初のカーネルを起動した直後にループから抜け出した場合には当てはまりません。

したがって、Matlab がカーネルの起動の間に gpuArray をリセットしているように思えます。そうならないようにする方法はありますか?

4

1 に答える 1

2

feval 呼び出しの出力をキャプチャすれば、これは機能するはずです。次のような単純なカーネルを考えてみましょう:

__global__ void setOneEl( double * array, double val, int element ) {
    array[element] = val;
}

次に、MATLAB で次のコードを実行すると、お望みどおりに動作します。

>> k = parallel.gpu.CUDAKernel('kern.ptx');
>> g = parallel.gpu.GPUArray.zeros(1,10);
>> for ii = 1:2:10, g = k.feval(g, rand, ii); end
>> gather(g)
ans =
         0    0.0975         0    0.2785         0    0.5469         0    0.9575         0    0.9649

通常の MATLAB セマンティクスと一致させるために、gpuArrayオブジェクトは値ベースであるため、gpuArrayインスタンスを変更する場合は、他の MATLAB データ型の場合と同様に、出力値を同じ配列に取り戻さなければなりません。ただし、CUDAKernel.feval呼び出しは結果を同じ変数にキャプチャしていることを認識し、インプレース最適化を使用してコピーの作成を回避できることに注意してください。

于 2012-04-30T07:06:11.800 に答える