0

GPUで同時にランダムに生成された数値を使用して、これらの各並列配列の100個の要素を初期化しようとしています。しかし、私のルーチンはさまざまな乱数を生成していません。Visual Studioでコードをデバッグすると、配列内の要素ごとに1つの番号が表示されます。このコードの目的は、CImg FilledTrianglesルーチンを最適化して、可能な場合はGPUを使用することです。

何が間違っているので、どうすれば修正できますか?これが私のコードです:

__global__ void initCurand(curandState* state, unsigned long seed)
    int idx = threadIdx.x + blockIdx.x * blockDim.x;
    curand_init(seed, idx, 0, &state[idx]);
    __syncthreads();
}

/*
 * CUDA kernel that will execute 100 threads in parallel
*/

__global__ void initializeArrays(float* posx, float* posy,float* rayon, float* veloc, float* opacity
                                ,float * angle, unsigned char** color, int height, int width, curandState* state){

    int idx = threadIdx.x + blockIdx.x * blockDim.x;

    curandState localState = state[idx];
    __syncthreads();

    posx[idx] = (float)(curand_uniform(&localState)*width);
    posy[idx] = (float)(curand_uniform(&localState)*height);
    rayon[idx] = (float)(10 + curand_uniform(&localState)*50);
    angle[idx] = (float)(curand_uniform(&localState)*360);
    veloc[idx] = (float)(curand_uniform(&localState)*20 - 10);
    color[idx][0] = (unsigned char)(curand_uniform(&localState)*255);
    color[idx][1] = (unsigned char)(curand_uniform(&localState)*255);
    color[idx][2] = (unsigned char)(curand_uniform(&localState)*255);
    opacity[idx] = (float)(0.3 + 1.5*curand_uniform(&localState));
}

これらのカーネルを準備して呼び出すホストコードは次のとおりです。グリッド内の1つのブロックに(要素ごとに)100個のスレッドを作成しようとしています。

 // launch grid of threads
      dim3 dimBlock(100);
      dim3 dimGrid(1);

      initCurand<<<dimBlock,dimGrid>>>(devState, unsigned(time(nullptr)));
      // synchronize the device and the host
    cudaDeviceSynchronize();
     initializeArrays<<<dimBlock, dimGrid>>>(d_posx, d_posy, d_rayon, d_veloc, d_opacity, d_angle,d_color, img0.height(), img0.width(), devState);

予備知識:

  // Define random properties (pos, size, colors, ..) for all triangles that will be displayed.
    float posx[100], posy[100], rayon[100], angle[100], veloc[100], opacity[100];
    // Define the same properties but for the device
    float* d_posx;
    float* d_posy;
    float* d_rayon;
    float* d_angle;
    float* d_veloc;
    float* d_opacity;
    //unsigned char d_color[100][3];
    unsigned char** d_color;
    curandState* devState;
    cudaError_t err;

    // allocate memory on the device for the device arrays
    err = cudaMalloc((void**)&d_posx, 100 * sizeof(float));
    err = cudaMalloc((void**)&d_posy, 100 * sizeof(float));
    err = cudaMalloc((void**)&d_rayon, 100 * sizeof(float));
    err = cudaMalloc((void**)&d_angle, 100 * sizeof(float));
    err = cudaMalloc((void**)&d_veloc, 100 * sizeof(float));
    err = cudaMalloc((void**)&d_opacity, 100 * sizeof(float));
    err = cudaMalloc((void**)&devState, 100*sizeof(curandState));
    errCheck(err);
    size_t pitch;
    //allocated the device memory for source array  
    err = cudaMallocPitch(&d_color, &pitch, 3 * sizeof(unsigned char),100);

結果の取得:

// get the populated arrays back to the host for use
     err = cudaMemcpy(posx,d_posx, 100 * sizeof(float), cudaMemcpyDeviceToHost);
     err = cudaMemcpy(posy,d_posy, 100 * sizeof(float), cudaMemcpyDeviceToHost);
     err = cudaMemcpy(rayon,d_rayon, 100 * sizeof(float), cudaMemcpyDeviceToHost);
     err = cudaMemcpy(veloc,d_veloc, 100 * sizeof(float), cudaMemcpyDeviceToHost);
     err = cudaMemcpy(opacity,d_opacity, 100 * sizeof(float), cudaMemcpyDeviceToHost);
     err = cudaMemcpy(angle,d_angle, 100 * sizeof(float), cudaMemcpyDeviceToHost);
     err = cudaMemcpy2D(color,pitch,d_color,100, 100 *sizeof(unsigned char),3, cudaMemcpyDeviceToHost);
4

1 に答える 1

1

間違いなく、これから変更を加える必要があります。

err = cudaMalloc((void**)&devState, 100*sizeof(float));

これに:

err = cudaMalloc((void**)&devState, 100*sizeof(curandState));

コードをcuda-memcheckで実行した場合、これを発見したはずです。これが原因で、initCurandカーネルには範囲外のアクセスがたくさんありました。

また、すべてのcuda呼び出しとすべてのカーネル起動でエラーチェックを実行する必要があります。color[][]配列の操作が台無しになっているため、2番目のカーネル呼び出しが失敗していると思います。

通常、で配列を作成するときはcudaMallocPitch、pitchパラメータを使用して配列にアクセスする必要があります。Cには実際の配列幅に関する固有の知識がないため、Cの二重添え字配列自体は機能しません。

次の変更を加えることで修正できました。

__global__ void initializeArrays(float* posx, float* posy,float* rayon, float* veloc, float* opacity,float * angle, unsigned char* color, int height, int width, curandState* state, size_t pitch){

    int idx = threadIdx.x + blockIdx.x * blockDim.x;

    curandState localState = state[idx];
    __syncthreads();

    posx[idx] = (float)(curand_uniform(&localState)*width);
    posy[idx] = (float)(curand_uniform(&localState)*height);
    rayon[idx] = (float)(10 + curand_uniform(&localState)*50);
    angle[idx] = (float)(curand_uniform(&localState)*360);
    veloc[idx] = (float)(curand_uniform(&localState)*20 - 10);
    color[idx*pitch] = (unsigned char)(curand_uniform(&localState)*255);
    color[(idx*pitch)+1] = (unsigned char)(curand_uniform(&localState)*255);
    color[(idx*pitch)+2] = (unsigned char)(curand_uniform(&localState)*255);
    opacity[idx] = (float)(0.3 + 1.5*curand_uniform(&localState));
}

 initializeArrays<<<dimBlock, dimGrid>>>(d_posx, d_posy, d_rayon, d_veloc, d_opacity, d_angle,d_color, img0.height(), img0.width(), devState, pitch);

unsigned char* d_color;

これらの変更により、見つけたエラーを排除することができ、コードはさまざまなランダムな値を吐き出しました。すべての値を調べたわけではありませんが、それで始めることができます。

于 2013-03-06T04:46:04.053 に答える