0

理解できない何らかの理由で起動に失敗する単純な CUDA カーネルを作成しました。以下に、私のグローバル変数が表示されます。

unsigned int volume[256*256*256];//contains volume data of source
unsigned int target[256*256*256];//contains volume data of target
unsigned int* d_volume=NULL;//source data on device
unsigned int* d_target=NULL;//target data on device

次の機能はカーネルランチャーです。

void launch_kernel(){

cudaMalloc(&d_volume,256*256*256*sizeof(unsigned int));
cudaMemcpy(d_volume, volume, 256*256*256*sizeof(unsigned int),cudaMemcpyHostToDevice);
cudaMalloc(&d_target,256*256*256*sizeof(unsigned int));
cudaMemcpy(d_target, target, 256*256*256*sizeof(unsigned int),cudaMemcpyHostToDevice);
dim3 threads(256,1,1);
dim3 blocks(256,256,1);

simple_kernel<<<blocks,threads>>>(d_volume,d_target);
cudaError_t cudaResult;
cudaResult = cudaGetLastError();
if (cudaResult != cudaSuccess)
{
    cout<<"kernel failed"<<endl;
}
cudaMemcpy(volume, d_volume, 256*256*256*sizeof( int),cudaMemcpyDeviceToHost);
cudaFree(d_volume);
cudaMemcpy(target, d_target 256*256*256*sizeof( int),cudaMemcpyDeviceToHost);
cudaFree(d_target);
}

次のようにカーネルを起動すると、問題がd_target発生しているようです。

simple_kernel<<<blocks,threads>>>(d_volume,d_volume);

それは完全に機能しており (渡す必要がある値をデバイスに渡します)、メッセージは表示されません。なぜそれが起こるのでしょうか?カーネル宣言は以下のとおりです。

 __global__ void simple_kernel(unsigned int* src,unsigned int* tgt){
//i dont think it matters what it is for.
         int x = threadIdx.x;
         int y = blockIdx.x;
         int z = blockIdx.y;
         if(x!=0 || x!=255 || y!=0 || y!=255 || z!=0 || z!=255  ){//in bound of memory allocated
            if( src[x*256*256+y*256+z]==tgt[x*256*256+y*256+z])
                if(tgt[(x+1)*256*256+y*256+z]==1 || tgt[(x-1)*256*256+y*256+z]==1 || tgt[(x-1)*256*256+(y+1)*256+z] ||tgt[(x-1)*256*256+(y-1)*256+z])
                    src[x*256*256+y*256+z]=1;
                else
                    src[x*256*256+y*256+z]=0;
         }

    }
4

1 に答える 1

2

CUDA は、グローバル メモリへの範囲外の読み取りアクセスの場合にもエラーを返すことがあります。この範囲外の読み取りアクセスを次の場所で実行します。
if(tgt[(x+1)*256*256+y*256+z]==1 || ...)たとえば、x = y = z = 255範囲外のチェックを通過します。

範囲外の読み取りアクセス中にカーネルを起動した場合、実際には、配列として
simple_kernel<<<blocks,threads>>>(d_volume,d_volume);
既に割り当てられ、連続して格納されているグローバル メモリにアクセスするため、エラーは発生しません。d_targetd_volumed_target

さらにエラーチェックを行って私の意見を確認するか、cuda-memcheck でプログラムを起動してください。

于 2013-04-06T00:55:27.267 に答える