当使用cos时,Cuda从__device__函数返回错误的值

时间:2015-01-17 02:48:51

标签: c memory-management cuda nvidia cosine

我试图在nvidia GPU上运行此代码并返回奇怪的值。它由两个模块main.cuexmodul.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
  • 当我将1.0中的exmodul.cu更改为大于的数字时 1.0000009530.999999999999999945,它返回正确 结果
  • 当我更改1.1中的exmodul.cu时,除了值1.0之外,它也会失败。
  • 行为并不依赖于同一模块中的常量2.0
  • 当我使用其他功能代替cos sinexp时,它可以正常使用。
  • 使用double q = cos(1.1);无效。
  • 当我将函数extFunc()复制到模块main.cu时,它可以正常工作。
  • 如果我在*gd=1.0;中取消注释main.cu,则会返回正确的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

你知道出了什么问题吗?

谢谢,Lukas


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();

1 个答案:

答案 0 :(得分:2)

我能够在受支持的配置(CUDA 6.5,CentOS 6.2,K40)上重现有问题的行为。

当我从CUDA 6.5切换到CUDA 7 RC时,问题就消失了。

此问题在旧配置(CUDA 5.5,CentOS 6.2,M2070)上似乎也无法重现

我建议切换到CUDA 7 RC来解决这个问题。我怀疑编译过程中已经修复了一个潜在的错误。