2017-12-06 6 views
0

私はCUDAコードを使って奇妙な問題に遭遇しました。これは、msvcコミュニティ2015とnvccをWindows 10で使用してDLLにコンパイルされます。私はCUDA 8を使用しています.Dllを呼び出すアプリケーションはQt5で開発されています。 アプリケーションはかなり大きく、複雑です:Qt、CUDA、VTK、HDF5を使用しています。それはすべて動作するように見える、アプリが実行され、それが仮定されているが、再現可能な方法で失敗する意味がないようです。以下の関数例は、同様のエラーを再現しているようです。DLL内のCUDA関数、__declspec(dllexport)は動作しますが奇妙な結果はありますか?

私は、DLLをコンパイルしています:この機能は、メインコードと同じ問題を呈しているようだ

nvcc -m64 -arch=sm_20 -o fdm1_cuda.dll -Xcompiler "/LD /D_USRDLL /D_WINDLL" fdm1_cuda.cu 

extern "C" __declspec(dllexport) void fdm1_funnyproblemchecker(){ 

    cudaError_t errorcode; 
    float *a_host; 
    float *b_host; 
    float *a_device; 
    int num, i; 

    num=10; 

    a_host = (float *)malloc(sizeof(float)*num); 
    if(a_host) printf("Result check, allocate host memory a: success\n"); 
    if(!a_host) printf("Result check, allocate host memory a: failed!\n"); 
    for(i=0;i<num;i++) a_host[i] = (float)i; 
    for(i=0;i<num;i++) printf("%6.3f ", a_host[i]); 
    printf("\n"); 

    b_host = (float *)malloc(sizeof(float)*num); 
    if(b_host) printf("Result check, allocate host memory b: success\n"); 
    if(!b_host) printf("Result check, allocate host memory b: failed!\n"); 


    errorcode = cudaSuccess; 
    cudaMalloc((void **) &a_device, sizeof(float)*num); 
    errorcode = cudaGetLastError(); 
    printf("Result check, allocate device memory: %s\n", cudaGetErrorString(errorcode)); 

    errorcode = cudaSuccess; 
    cudaMemcpy(a_device, a_host, num*sizeof(float), cudaMemcpyHostToDevice); 
    errorcode = cudaGetLastError(); 
    printf("Result check, copy host to device : %s\n", cudaGetErrorString(errorcode)); 

    errorcode = cudaSuccess; 
    cudaMemcpy(b_host, a_device, num*sizeof(float), cudaMemcpyDeviceToHost); 
    errorcode = cudaGetLastError(); 
    printf("Result check, copy device to host : %s\n", cudaGetErrorString(errorcode)); 

    for(i=0;i<num;i++) printf("%6.3f ", b_host[i]); 
    printf("\n"); 

    fflush(stdout); 

    cudaFree(a_device); 
    free(a_host); 
    free(b_host); 

} 

時には、これからの出力は次のとおりです。

Result check, allocate host memory a: success 
0.000 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 9.000 
Result check, allocate host memory b: success 
Result check, allocate device memory: no error 
Result check, copy host to device : no error 
Result check, copy device to host : no error 
0.000 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 9.000 

私がアプリケーションの他の場所に関連しているとは思わないものを変更した場合(moのサイズを変更するデルは実行時に)、私はこれを得る:

Result check, allocate host memory a: success 
0.000 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 9.000 
Result check, allocate host memory b: success 
Result check, allocate device memory: no error 
Result check, copy host to device : an illegal memory access was encountered 
Result check, copy device to host : an illegal memory access was encountered 
0.000 0.000 0.000 0.000 0.000 0.000 0.000 270355481144287188484096.000 74936693461279934656588472647680.000 0.000 

したがって、cudaMemcpyの障害があります。 これは、ホストmallocの問題、cudaMallocの問題、またはdllから実行されている問題かどうかはわかりません。 誰かが私がここで行方不明を見ることができますか?

私はこのアプリケーションをLinuxやMacで実行しており、大きな問題はなく動的ライブラリを使用しています。私は今、窓の下でそれを取得しようとしています。

+1

"不正なメモリアクセスが発生しました"は、カーネルの問題を指しています。カーネルがメモリ範囲外にアクセスすると、このタイプのエラーが発生する可能性がありますが、実際にランタイムAPIでエラーをチェックするまで検出されません。ここに掲示されたコードはカーネルコードが一切表示されていないため、投稿したものでエラーが発生していない可能性があります。 1つの可能性は、実際にCUDAカーネルコールを持っているアプリケーションのどこか他の場所で発生していることです。ここでエラーチェックを行っているため、ここでエラーが表示されています。別の可能性は、スタックの破損です。 –

答えて

1

問題を解決しました。 境界外の配列[-1]にアクセスするコード内の別のカーネルでした。 私のcudaGetLastErrorによるエラーチェックが正しくありませんでした。各cudaGetLastErrorの前にcudaDeviceSynchronizeを実行すると、エラーが報告されていました。

ありがとうございました。

関連する問題