2016-09-13 3 views
0

いくつかの標準的なテンソルフロー層(https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/kernels/maxpooling_op_gpu.cu.ccなど)、ForwardおよびBackwardパスの一部としてコードCUDA_1D_KERNEL_LOOP(index、nthreads) ...Tensorflow:CUDA_1D_KERNEL_LOOP(index、nthreads)オペレータでのインデックスの意味

ここの「インデックス」は、何とかボトムフィーチャマップの座標に関係していると思いますが、その正確な意味は分かりません。

答えて

3

CUDA_1D_KERNEL_LOOP(i, n)は、tensorflow/core/util/cuda_kernel_helper.hで定義されたプリプロセッサマクロです。これは、Tensorflowコードベース内の多くのCudaカーネルで使用される汎用コントロールフローステートメントを提供します。

ステートメントは、通常、カーネル内の配列の要素を反復処理するために使用されます。引数iは制御変数の名前であり、引数nは制御文の停止条件です。 Cudaカーネルは並列スレッドで起動されます。各スレッドは通常、配列要素のサブセットで動作します。マクロは、目的の配列要素にアクセスするためのいくつかの便利さを提供します。あなたにリンクしている例では

CUDA_1D_KERNEL_LOOP(index, nthreads)は以下のように解釈される:従って

for (int index = blockIdx.x * blockDim.x + threadIdx.x; index < nthreads; index += blockDim.x * gridDim.x) 

index後続のコード・ブロックに入る前に宣言しCUDA_1D_KERNEL_LOOP内で初期化されます。 indexの正確な意味は、コードブロック内での使用方法によって異なります。

0

私がこのマクロを最初に読んだときに私が困惑したことは、「なぜこれはループですか、既に並列化されているカーネル内ではありませんか?答えは、GPUが実際にサポートするスレッドよりも多くのスレッドがある場合、ループがケースを処理するということです。

たとえば、並列化されたベクトルの追加を行い、GPUの場合、ブロックごとに512スレッドを使用し、最大4096ブロックのスケジューリングを行うと決めました(これらはCaffe2のデフォルトパラメータです)。つまり、最大2097152スレッドのスケジューリングのみが可能です。ベクトルに実際に4M要素があるとします。今では要素ごとに実際にスレッドを割り当てることはできません。したがって、各スレッドは、ベクトル内の複数の要素を合計する必要があります。これがこのループの目的です。

ここでは、仕事のスケジュール設定の仕方を正確に示す小さな例です。 blockDim.x == 2,gridDim.x == 2,nthreads == 7とする。次に、GPUスレッドを(blockIdx.x, threadIdx.x)と指定した場合、ベクトル上で次の処理を行うように割り当てます。[(0,0), (0,1), (1,0), (1,1), (0,0), (0,1), (1,0)]特に、グリッドサイズに応じて、使用できるGPUスレッドは4つしかないことがわかります。したがって threadIdx.x == 0の場合、indexは、BOTH 04のベクトル要素の処理を処理します。