単純な Cuda カーネルにあるバグを理解するのに苦労しています。エラーが表示される最小値までカーネルを縮小しました。
ポイントの数を格納するだけの「ポリゴン」クラスがあります。「ポイントを追加する」(カウンターをインクリメントするだけ) 関数があり、ポリゴンの配列内のすべてのポリゴンに 4 つのポイントを追加します。最後に、ループを使用してポイント数を更新する関数を呼び出します。このループで 1new_nbpts++
回呼び出すと、期待どおりの答えが得られます。つまり、すべてのポリゴンに 4 つのポイントがあります。同じループnew_nbpts++
で 2 回目の呼び出しを行うと、ポリゴンのポイント数がガベージ (4194304 ポイント) になり、正しくありません (8 を取得する必要があります)。
私が誤解しているものがあると思います。
完全なカーネル:
#include <stdio.h>
#include <cuda.h>
class Polygon {
public:
__device__ Polygon():nbpts(0){};
__device__ void addPt() {
nbpts++;
};
__device__ void update() {
int new_nbpts = 0;
for (int i=0; i<nbpts; i++) {
new_nbpts++;
new_nbpts++; // calling that a second time screws up my result
}
nbpts = new_nbpts;
}
int nbpts;
};
__global__ void cut_poly(Polygon* polygons, int N)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx>=N) return;
Polygon pol;
pol.addPt();
pol.addPt();
pol.addPt();
pol.addPt();
for (int i=0; i<N; i++) {
pol.update();
}
polygons[idx] = pol;
}
int main(int argc, unsigned char* argv[])
{
const int N = 20;
Polygon p_h[N], *p_d;
cudaError_t err = cudaMalloc((void **) &p_d, N * sizeof(Polygon));
int block_size = 4;
int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);
cut_poly <<< n_blocks, block_size >>> (p_d, N);
cudaMemcpy(p_h, p_d, sizeof(Polygon)*N, cudaMemcpyDeviceToHost);
for (int i=0; i<N; i++)
printf("%d\n", p_h[i].nbpts);
cudaFree(p_d);
return 0;
}