2017-03-05 10 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結果、時には自分のコンピュータがクラッシュを提供します。私は、エラーを再現することができるよ、次のコードで 。

I 0にcurand_initのシーケンスパラメータを設定するとエラーが消える:

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

それは私がシード値にスレッドIDを追加しようとしたすべてのスレッドに同じ配列を有することになるので:

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

しかし、 'id'に高い値が含まれていると、エラーが再び表示されます。

私はかなり斬新なプログラミングです。私が何か間違っていたり、それがcuidのバグでNVidiaにファイルしなければならないと私は気にしません。

誰でも手助けできますか?

更新:

これは私が章3.6から最初の例を使用クーダで私のプログラムまたはどこかのバグであるかどうかをチェックします。 (「デバイスAPIの例」、cuRAND Programming Guideを参照)。また、cuda-memcheckでメモリアクセス違反が発生します。ですから、それはcuRANDのバグかメモリチェッカーのバグだと思います。誰かがこれを確認してもらえますか?誰かがエラーなしでサンプルwhith cuda-memcheckを実行することはできますか?

btw:curandStatePhilox4_32_10_tやcurandStateMRG32k3aなどの他のcuRANDジェネレータでも問題があります。

アップデート2

それは偽のエラーを報告CUDA-memcheckはありません。 memcheckオプションがオンになっているのはNightsです。それはcuRANDから独立しているようです。 Nsightは、いくつかの簡単な例でもメモリアクセスエラーを報告します。上記のテキストに誤解を招くような情報をお送りいただきありがとうございます。

+1

あなたはウィンドウ上にいるようです。これは、カーネルグリッドの大きなサイズのWDDM TDRだけかもしれません。 –

+0

そうです。私は窓の上にいる。しかし、私のマシンではTDRがオフになっています。 –

+1

linux/CUDA8/K20xでコードを実行しました。 'cuda-memcheck'の有無にかかわらずうまく動作します。しかし、 'cuda-memcheck'では、実行するのにとても長い時間がかかります。 –

答えて

1

私がもっと多くのデバッグを行った後、curandはうまく動作することが判明しました。偽のエラーメッセージを生成するのはnsightデバッガです。

特に、を有効にすると、Cudaメモリチェッカーが有効になります。非常に頻繁に、cuda-memcheckが何も見つけない場所でエラーを報告します。

また、falseがアサーションに失敗することがよくあります。今まで私は問題の原因を突き止めることができませんでした。おそらく、私のコードにこの奇妙な動作を引き起こすバグがあります。

また、自分のマシンの設定に問題があります。その間、新しいドライバが付属したCUDAのアップデートをいくつかインストールしました。したがって、CUDA自体が問題を引き起こす可能性は低いようです。

しかし、私は、CURANDが問題を引き起こしていないことをお知らせしたいと思います。

関連する問題