2016-04-22 18 views
1

私はグローバルメモリをゼロにする単純なCUDAプログラムで遊んでいます。以下はデバイスコードと同様にホストコードです:CUDAアドレス範囲外

#include <stdio.h> 

__global__ void kernel(float *data, int width) { 
    int x = blockDim.x * blockIdx.x + threadIdx.x; 
    int y = blockDim.y * blockIdx.y + threadIdx.y; 

    if (x > (width-1)) { 
     printf("x = %d\n", x); 
     printf("blockDim.x = %d\n", blockDim.x); 
     printf("blockIdx.x = %d\n", blockIdx.x); 
     printf("threadIdx.x = %d\n", threadIdx.x); 
    } 

    if (y > (width-1)) { 
     printf("y = %d\n", y); 
     printf("blockDim.y = %d\n", blockDim.y); 
     printf("blockIdx.y = %d\n", blockIdx.y); 
     printf("threadIdx.y = %d\n", threadIdx.y); 
    } 

    data[y * width + x] = 0.0; 
} 

int main(void) { 
    const int MATRIX_SIZE = 256; 
    float *data, *dataGPU; 
    int sizeOfMem; 
    int x = MATRIX_SIZE; 
    int y = MATRIX_SIZE; 

    cudaDeviceReset(); 
    cudaDeviceSynchronize(); 

    sizeOfMem = sizeof(float) * x * y; 

    data = (float *)malloc(sizeOfMem); 
    cudaMalloc((void **)&dataGPU, sizeOfMem); 

    cudaMemcpy(dataGPU, data, sizeOfMem, cudaMemcpyHostToDevice); 

    //int threads = 256; 
    //int blocks = ((x * y) + threads - 1)/threads; 

    dim3 threads(16, 16); 
    dim3 blocks(x/16, y/16); 

    kernel<<<blocks, threads>>>(dataGPU, MATRIX_SIZE); 
    cudaThreadSynchronize(); 

    cudaMemcpy(data, dataGPU, sizeOfMem, cudaMemcpyDeviceToHost); 

    cudaFree(dataGPU); 

    free(data); 

    return 0; 
} 

私はCUDA-memcheckと私のコードを実行するときに境界エラーメッセージのうちのアドレスを受信し続けます。しかし、これは私が作成した行列の大きさが128以上の場合のみです。 128より小さい次元の場合、エラーはそれほど頻繁ではありません(エラーはほとんどありません)。カーネル機能にprintステートメントが含まれていることに気付くかもしれません。これらのステートメントは、エラーメッセージが表示されたときにのみ出力されます。なぜなら、xとyは決してwidth-1より大きいはずがないからです。この場合、255となります。以下は、私はCUDA-memcheckから受信したエラーメッセージです:

========= CUDA-MEMCHECK 
    ========= Invalid __global__ write of size 4 
    =========  at 0x00000298 in kernel(float*, int) 
    =========  by thread (3,10,0) in block (15,1,0) 
    =========  Address 0x2300da6bcc is out of bounds 
    =========  Saved host backtrace up to driver entry point at kernel launch time 
    =========  Host Frame:/usr/lib64/nvidia/libcuda.so.1 (cuLaunchKernel + 0x2c5) [0x472225] 
    =========  Host Frame:./test_reg_memory [0x16c41] 
    =========  Host Frame:./test_reg_memory [0x31453] 
    =========  Host Frame:./test_reg_memory [0x276d] 
    =========  Host Frame:./test_reg_memory [0x24f0] 
    =========  Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x21b15] 
    =========  Host Frame:./test_reg_memory [0x25cd] 
    ========= 
    y = 2074 
    blockDim.y = 16 
    blockIdx.y = 1 
    threadIdx.y = 10 

この出力は、私は数学をすれば、

y = blockDim.y * blockIdx.y + threadIdx.y = 16 * 1 + 10 = 26 (not 2074) 

私はCUDAを見ていくつかの時間を費やしているので、私には意味がありません。プログラミングフォーラム、そして何も助けに見えなかった。私が読み込んだスレッドが1つあり、レジスタのメモリが壊れている可能性があることを示しています。しかし、スレッドを開始したものは、別のGPUでこの問題を抱えています。スレッドは少し関係がありませんが、私はリンクをとにかく含めました。 I以下

https://devtalk.nvidia.com/default/topic/498784/memory-corruption-on-a-fermi-class-gpu-error-only-on-fermis-program-works-on-non-fermis-/?offset=6

NVCCのバージョンが含まれています。

nvcc: NVIDIA (R) Cuda compiler driver 
Copyright (c) 2005-2015 NVIDIA Corporation 
Built on Tue_Aug_11_14:27:32_CDT_2015 
Cuda compilation tools, release 7.5, V7.5.17 

また、ここで私が使用しているGPUがあります。

Device 0: "GeForce GT 640" 
CUDA Driver Version/Runtime Version 8.0/7.5 
CUDA Capability Major/Minor version number: 3.0 

私が間違っている可能性があることをCUDA経験のある人なら誰でも知ることができますか?

+1

投稿したコードは正しく動作し、cuda-memcheckでエラーが発生しません。本当にあなたが投稿したコードが、あなたがSOの質問からコピー・ペーストしてコンパイルして実行すると、cuda-memcheckエラーが出ることは確実ですか? – talonmies

+0

cudaMallocは成功しますか? –

+0

@RegisPortalez:cudaMallocが失敗した場合、cuda-memcheckはエラーを報告します。投稿された出力にそのようなエラーはありません。 – talonmies

答えて

0

この問題は特定のシステムに限定されており、何らかのハードウェアの問題が原因で発生しているようです。コード自体は問題なく、別のシステムに変更すると正常に動作することが確認されました。

[この回答は、CUDAタグの未回答のキューから質問を得るためにコメントから集められ、コミュニティのwikiエントリとして追加されました]。