2017-12-06 11 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에서 오류를 확인할 때까지는 감지 할 수 없습니다. 여기에 게시 된 코드는 커널 코드가 전혀 표시되어 있지 않으므로 게시 한 항목에서 오류가 발생하지 않았을 수 있습니다. 한 가지 가능성은 실제로 응용 프로그램에서 CUDA 커널 호출이있는 다른 곳에서 발생하고 있으며 여기에서 오류 검사를하고 있기 때문에 여기에 오류가 표시됩니다. 또 다른 가능성은 스택 손상입니다. –

답변

1

문제가 해결되었습니다. 범위 밖의 배열 [-1]에 액세스하는 코드의 다른 부분이었습니다. cudaGetLastError로 내 오류 검사가 잘못되었습니다. 각 cudaGetLastError 앞에 cudaDeviceSynchronize를 수행하면 오류가보고됩니다.

감사합니다.