【发布时间】:2015-03-15 17:59:41
【问题描述】:
我正在尝试在 nvidia GPU 上运行此代码,但它返回奇怪的值。它由 main.cu 和 exmodul.cu 两个模块组成(在下面列出)。对于我正在使用的建筑:
nvcc -dc -arch sm_35 main.cu
nvcc -dc -arch sm_35 exmodul.cu
nvcc -arch sm_35 -lcudart -o main main.o exmodul.o
如果我运行它,我会得到奇怪的最后一行!!! gd 必须为 1。
result=0
result=0
result=0
result=0
gd=-0.5
- 当我将
exmodul.cu中的1.0更改为大于1.000000953或下面0.999999999999999945,它返回正确 结果。 - 当我在
exmodul.cu中更改1.1时,除了值1.0之外,它也会失败。 - 行为不依赖于同一模块中的常量
2.0。 - 当我使用另一个函数而不是
cos(如sin或exp)时,它可以正常工作。 - 使用
double q = cos(1.1);无效。 - 当我将函数
extFunc()复制到模块main.cu时,它可以正常工作。 - 如果我在
main.cu中取消注释*gd=1.0;,它会返回正确的1.0。
在 Nvidia GT750M 和 GeForce GTX TITAN Black 上测试。 (在 GT750M 上返回不同的值 gd=6.1232329394368592e-17 但仍然错误)。操作系统:Debian Jessie。
$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2013 NVIDIA Corporation
Built on Thu_Mar_13_11:58:58_PDT_2014
Cuda compilation tools, release 6.0, V6.0.1
你知道出了什么问题吗?
谢谢,卢卡斯
main.cu
#include <stdio.h> // printf
#include "exmodul.h" // extFunc
__global__ void mykernel(double*gd);
void deviceCheck();
int main(int argc, char *argv[])
{
double gd, *d_gd;
cudaMalloc(&d_gd, sizeof(double)); deviceCheck();
mykernel<<<1,1>>>(d_gd); deviceCheck();
cudaMemcpy(&gd, d_gd, sizeof(double), cudaMemcpyDeviceToHost);
deviceCheck();
cudaFree(d_gd); deviceCheck();
fprintf(stderr,"gd=%.17g\n",gd);
return 0;
}
void deviceCheck()
{
cudaError_t result = cudaSuccess;
cudaDeviceSynchronize();
result = cudaGetLastError();
fprintf(stderr,"result=%d\n",result); fflush(stderr);
}
__global__ void mykernel(double *gd)
{
*gd = extFunc();
//*gd=1.0;
__syncthreads();
return;
}
exmodul.cu
#include "exmodul.h"
__device__ double extFunc()
{
double q = 1.1;
q = cos(q);
if(q<2.0) { q = 1.0; }
return q;
}
exmodul.h
__device__ double extFunc();
【问题讨论】:
-
cos() 的返回值范围是 -1 ... +1。所以这一行:'if(q
-
这一行:'printf(stderr,"gd=%.17g\n",gd);'不正确,应该是:'fprintf(stderr,"gd=%.17g\n",gd);' // 注意不同的函数调用 另外,'gd' 中的值始终为 1.0,格式转换没有小数点左侧的字符来打印 1。这就是为什么所有打印值都是 0
-
user3629249:谢谢。不需要包含
math.h,请参阅[1]。我希望它必须返回 q==1 因为-1 < cos <+1,但它不起作用。而且我不知道为什么..fprintf是我在将代码复制到这里时犯的错误。 [1]devtalk.nvidia.com/default/topic/792656/… -
我无法重现该问题,但我在 Windows 上使用 CUDA 6.5。不同 GPU 上返回的不同值表明 CUDA API 调用失败。您的错误检查似乎没有尽可能严格,您可能想尝试直接检查 API 函数的返回状态,一个启动前和启动后的内核错误,如图所示,例如,here。
-
@Luuuucky 根据 NVIDIA 的说法,Debian 是 CUDA 6.0 支持的操作系统吗?如果没有,你就靠你自己了,因为 NVIDIA 尚未验证操作系统的正确 CUDA 操作。您可能想咨询 Debian 特定的论坛或邮件列表。我怀疑问题是您系统的本地问题(安装错误等)。
标签: c memory-management cuda nvidia trigonometry