DLL,__ declspec(dllexport)中的CUDA函数有效,但结果奇怪吗?

时间:2017-12-06 18:36:47

标签: qt dll cuda dllexport

我遇到了一段CUDA代码的奇怪问题。它使用msvc社区2015和Windows 10中的nvcc编译成DLL。我使用CUDA 8.调用dll的应用程序正在使用Qt5开发。 应用程序相当庞大和复杂:使用Qt,CUDA,VTK,HDF5。这一切似乎都有效,应用程序运行并执行它应该做的事情,但是以可重现的方式失败,似乎没有任何意义。下面的示例函数似乎重现了类似的错误。

我用:

编译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 

如果我更改了一些我认为与应用程序中其他地方无关的内容(在运行时更改模型的大小),我会得到:

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上运行此应用程序,没有任何重大问题。我现在正试图让它在Windows下运行。

1 个答案:

答案 0 :(得分:1)

问题解决了。 在访问数组[-1]超出范围的代码中,它是一个内核。 我用cudaGetLastError检查错误是不正确的。如果我在每个cudaGetLastError之前执行cudaDeviceSynchronize,它会报告我错过的错误。

感谢。