Qt 在DLL中使用CUDA函数,declspec(dllexport)可以工作,但结果奇怪吗?

Qt 在DLL中使用CUDA函数,declspec(dllexport)可以工作,但结果奇怪吗?,qt,dll,cuda,dllexport,Qt,Dll,Cuda,Dllexport,我在一段CUDA代码中遇到了一个奇怪的问题。它使用msvc community 2015和Windows 10中的nvcc编译成DLL。我用的是CUDA8。正在使用Qt5开发调用dll的应用程序。 应用程序相当大且复杂:使用Qt、CUDA、VTK、HDF5。这一切似乎都是可行的,应用程序运行并做它应该做的事情,但以一种重复的方式失败,这似乎没有任何意义。下面的示例函数似乎重现了类似的错误 我正在使用以下工具编译dll: nvcc -m64 -arch=sm_20 -o fdm1_cuda.dl

我在一段CUDA代码中遇到了一个奇怪的问题。它使用msvc community 2015和Windows 10中的nvcc编译成DLL。我用的是CUDA8。正在使用Qt5开发调用dll的应用程序。 应用程序相当大且复杂:使用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   : 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下运行它。

问题已解决。 这是代码中的内核elsewher访问超出边界的数组[-1]。 我与cudaGetLastError的错误检查不正确。如果我在每个CUDAGetLaster错误之前执行cudaDeviceSynchronize,它会报告我丢失的错误


谢谢。

遇到的非法内存访问是指内核问题。当内核访问超出范围的内存时,可能会发生这种类型的错误,但在实际检查运行时API是否存在错误之前,无法检测到这种错误。由于您在此处发布的代码根本没有显示任何内核代码,因此该错误不能源于您发布的任何内容。一种可能性是,它发生在应用程序中的其他地方,您实际上有一个CUDA内核调用,您在这里看到错误,因为您在这里进行错误检查。另一种可能是堆栈损坏。
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