2017-03-05 158 views
1

在我的程序中,我必須生成大量的隨機數。因此,我嘗試重用cuRAND狀態,這樣我就只需要初始化它們一次。不幸的是,執行初始化的代碼會產生奇怪的內存訪問錯誤。我花了很多時間調試它,並且只有當我將'curand_init()'的參數'sequence'設置爲一個很大的值(例如30000)或者當參數'seed'變得太大時,錯誤纔會發生。 用下面的代碼我能夠重現錯誤:curand_init()產生內存訪問錯誤

#include <conio.h> 
#include <stdio.h> 
#include <curand.h> 
#include <curand_kernel.h> 
#include "cuda_runtime.h" 
#include "device_launch_parameters.h" 

__global__ void initRnd(unsigned long long seed, curandState* states, int size) 
{ 
    int id = blockIdx.x * blockDim.x + threadIdx.x; 
    if (id < size) { 
     curand_init(seed, id, 0, &states[id]); 
    } 
} 

void handleError(cudaError_t code) 
{ 
    if (code != cudaSuccess) { 
     printf("ERROR: %s (Code: %d) %s %d\n", cudaGetErrorString(code), code, __FILE__, __LINE__); 
     exit(code); 
    } 
} 

int main() 
{ 
    const int size = 3000000; 

    cudaError_t code = cudaSetDevice(0); 
    handleError(code); 

    curandState *data; 
    code = cudaMalloc((void**)&data, size * sizeof(curandState)); 
    handleError(code); 

    const int blockSize = 256; 
    int numOfBlocks = (size + blockSize - 1)/blockSize; 
    dim3 dimGrid(numOfBlocks); 
    dim3 dimBlock(blockSize); 
    initRnd << <dimGrid, dimBlock >> > (time(0), data, size); 
    code = cudaDeviceSynchronize(); 
    handleError(code); 

    code = cudaDeviceReset(); 
    handleError(code); 

    printf("\nPress any key...\n"); 
    _getch(); 
} 

當我運行這個使用CUDA-MEMCHECK它提供unpredictible結果,有時我的計算機崩潰。

的誤差消失當我設置curand_init的序列參數爲0:

curand_init(seed, 0, 0, &states[id]); 

由於其導致具有在所有的線程相同的序列我試圖線程ID添加到種子值:

curand_init(seed+id, 0, 0, &states[id]); 

但是當「身份證」包含高值的錯誤再次出現。

我對cuda編程頗爲陌生,如果我做錯了什麼,或者如果這是cuRAND中的一個錯誤,我應該向NVidia申請,我不確定。

任何人都可以幫忙嗎?

更新:

要檢查這是否是我的程序中的錯誤或某處CUDA中我使用第3.6章的第一個例子。 (「設備API示例」,參見cuRAND Programming Guide)。它也會在cuda-memcheck中產生內存訪問衝突。所以我猜想它可能是cuRAND或內存檢查器中的錯誤。有人可以驗證這一點嗎?有人能夠毫無錯誤地運行cuda-memcheck的例子嗎?

btw:即使使用其他cuRAND生成器(如curandStatePhilox4_32_10_t或curandStateMRG32k3a)也存在此問題。

更新2

這不是CUDA-MEMCHECK,報告虛假錯誤。這是Nsights開啓了memcheck選項。它似乎與cuRAND無關。即使在一些簡單的cuda示例中,Nsight也會報告內存訪問錯誤。對不起,上面的文字中有誤導性的信息。

+1

看來你是在窗戶上。這可能只是用於大尺寸內核網格的WDDM TDR。 –

+0

沒錯。我在窗戶上。但TDR在我的機器上關閉。 –

+1

我在linux/CUDA8/K20x上運行你的代碼。它運行良好,有或沒有'cuda-memcheck'。但是,使用'cuda-memcheck'需要非常長的時間才能運行。 –

回答

1

當我做了更多的調試後,發現curand工作正常。這是產生虛假錯誤消息的nsight調試器。

尤其是,使用選項啓用Cuda Memory Checker已打開。很多時候它會報告cuda-memcheck根本找不到任何東西的錯誤。

此外,它經常報告錯誤失敗的斷言。到目前爲止,我無法弄清楚導致問題的原因。我的代碼中可能存在一個導致這種奇怪行爲的錯誤。

或者我的機器配置有問題。與此同時,我安裝了幾個CUDA的新驅動程序更新。所以CUDA本身似乎不太可能導致問題。

但是,我只是想讓你知道CURAND並沒有引起麻煩。