1

この質問に似た質問が複数あることは承知していますが、何かを間違ってインデックス付けしている可能性があることを除けば、それらから非常に役立つものをまとめることができませんでした。

入力ベクトル A のシーケンシャル アドレッシング リダクションを出力ベクトル B に実行しようとしています。

完全なコードはhttp://pastebin.com/7UGadgjXで入手できますが、これはカーネルです。

__global__ void vectorSum(int *A, int *B, int numElements) {
  extern __shared__ int S[];
  // Each thread loads one element from global to shared memory
  int tid = threadIdx.x;
  int i = blockDim.x * blockIdx.x + threadIdx.x;
  if (i < numElements) {
    S[tid] = A[i];
    __syncthreads();
    // Reduce in shared memory
    for (int t = blockDim.x/2; t > 0; t>>=1) {
      if (tid < t) {
        S[tid] += S[tid + t];
      }
      __syncthreads();
    }
    if (tid == 0) B[blockIdx.x] = S[0];
  }
}

これらはカーネル起動ステートメントです。

// Launch the Vector Summation CUDA Kernel
  int threadsPerBlock = 256;
  int blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock;
  vectorSum<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, numElements);

私が読んだ特定されていない起動エラーは、セグメンテーション違反に似ています。私は nvidia リダクションのドキュメントを綿密にたどり、カーネルを numElements の範囲内に収めようとしましたが、コードがいかに単純であるかを考えると、何か重要なものが欠けているようです。

4

1 に答える 1

3

あなたの問題は、削減カーネルが正しく動作するために動的に割り当てられた共有メモリを必要とすることですが、カーネルの起動では何も指定されていません。その結果、境界外/不正な共有メモリ アクセスが発生し、カーネルが中止されます。

CUDA ランタイム API 構文では、カーネル起動ステートメントに4 つの引数があります。最初の 2 つは、起動のグリッドとブロックの寸法です。後者の 2 つはオプションであり、デフォルト値はありませんが、動的に割り当てられる共有メモリのサイズとストリームを指定します。

これを修正するには、起動コードを次のように変更します。

// Launch the Vector Summation CUDA Kernel
  int threadsPerBlock = 256;
  int blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock;
  size_t shmsz = (size_t)threadsPerBlock * sizeof(int);
  vectorSum<<<blocksPerGrid, threadsPerBlock, shmsz>>>(d_A, d_B, numElements);

[免責事項: コンパイルもテストもされていないブラウザで書かれたコードは、自己責任で使用してください]

これにより、少なくともコードの最も明白な問題が修正されるはずです。

于 2013-06-11T05:46:52.203 に答える