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