5

更新: バグが見つかりました。前に投稿したコードは非常に複雑なので、単純化して、問題がある部分だけを残します。

if (number >= dim * num_points)
    return;

しかし、実際にはnum_pointsしかありません。num_pointsスレッドを使用したいので、正しい方法は

if (number >= num_points)
    return;

助けてくれてありがとう。


CPU から GPU にいくつかの C++ コードを書き直しています。そして、コードを以下に貼り付けます。長くなってすみません。問題はこの方法で検出されやすいと思います。

コードでは、すべてのスレッドにマトリックス形式の中間結果が必要なので、これらの中間結果 (d_dir2、d_R、d_Stick、d_PStick など) にデバイス メモリを割り当てます。結果は私が期待したものではないことが判明したので、デバッグするために、次の方法でいくつかの中間結果 R を出力しようとしました。

もし (k == 0)
 {
 results[tmp_int1 + i * dim + j] = R[tmp_int1 + i * dim + j];
 }

その後、C++ で結果を出力します。ただし、結果は毎回異なる値を与えることがわかりました。場合によっては R の正解、PStick の値、R と PStick の組み合わせ、R と 0 の組み合わせ (結果は最初に 0 に初期化されます) を返します。

何が問題を引き起こしたのか非常に混乱しています。何か案が?どうもありがとうございました :)

__global__ void stickvote(const int dim, const int num_points, const int gridx, float Sigma, float* input, float* dir2, float* R, float* Stick, float* PStick, float* results) {
  float threshold = 4 * Sigma;
  float c = (- 16 * log(0.1f) * (sqrt(Sigma) - 1)) / 3.1415926f / 3.1415926f;

  int row = blockIdx.y * blockDim.y + threadIdx.y;
  int col = blockIdx.x * blockDim.x + threadIdx.x;
  int number = row * BLOCK_SIZE * gridx + col;

  if (number >= dim * num_points)  //// The bug is here!
    return;
}


extern "C" void KernelStickVote(int dim, int num_points, float Sigma, float* input, float* results) {
  const int totalpoints = num_points;
  const int totalpoints_input = (dim + 1)* (dim + 1) * num_points;
  const int totalpoints_output = dim * dim * num_points;
  size_t size_input = totalpoints_input * sizeof(float);
  size_t size_output = totalpoints_output * sizeof(float);

  float* d_input;
  cutilSafeCall(cudaMalloc((void**)&d_input, size_input));

  float* d_result;
  cutilSafeCall(cudaMalloc((void**)&d_result, size_output));

  // used to save dir, and calculate dir * dir'
  float* d_dir2;
  cutilSafeCall(cudaMalloc((void**)&d_dir2, dim * num_points * sizeof(float)));

  // used to save R: dim * dim * N
  float* d_R;
  cutilSafeCall(cudaMalloc((void**)&d_R, size_output));

  // used to save Stick: dim * dim * N
  float* d_Stick;
  cutilSafeCall(cudaMalloc((void**)&d_Stick, size_output));

  // used to save Stick: dim * dim * N
  float* d_PStick;
  cutilSafeCall(cudaMalloc((void**)&d_PStick, size_output));

  // Copy input data from host to device
  cudaMemcpy(d_input, input, size_input, cudaMemcpyHostToDevice);

  int totalblock = (totalpoints % BLOCKPOINTS==0 ? totalpoints/BLOCKPOINTS : (int(totalpoints/BLOCKPOINTS) + 1));
  int gridx = (65535 < totalblock ? 65535 : totalblock);
  int gridy = (totalblock % gridx == 0 ? totalblock/gridx : (int(totalblock/gridx)+1) );
  dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
  dim3 dimGrid(gridx, gridy);

  stickvote<<<dimGrid, dimBlock>>>(dim, num_points, gridx, Sigma, d_input, d_dir2, d_R, d_Stick, d_PStick, d_result);
  cudaMemcpy(results, d_result, size_output, cudaMemcpyDeviceToHost);

  cudaFree(d_input);
  cudaFree(d_result);
  cudaFree(d_dir2);
  cudaFree(d_R);
  cudaFree(d_Stick);
  cudaFree(d_PStick);
}
4

1 に答える 1

1

質問の元の投稿者は、さらにコードを単純化し、自分自身をデバッグし、カーネル内のガードステートメントを発見しました:

if (number >= dim * num_points)
    return;

実際、間違っていたし、そうすべきだった

if (number >= num_points)
    return;

これがエラーの原因でした。

この回答は、未回答のキューからこの質問を削除する目的で、コミュニティ wiki の回答として追加されました。

于 2014-06-16T09:20:11.840 に答える