C++ 由于错误,Ptx程序集中止

C++ 由于错误,Ptx程序集中止,c++,cuda,ptx,C++,Cuda,Ptx,我曾尝试在MS Visual Studio 2012中为C/CUDA 5.5上的乘法CSR矩阵和向量编写程序,但遇到ptx错误。 我的代码列表: __global__ void multKernelSymm(double* s, double* u, double* val, int* rowPtr, int* colInd) { int l = 0, jl, i; int idx = blockDim.x*blockIdx.x; l =

我曾尝试在MS Visual Studio 2012中为C/CUDA 5.5上的乘法CSR矩阵和向量编写程序,但遇到ptx错误。 我的代码列表:

__global__ void multKernelSymm(double* s, double* u, double* val, int* rowPtr, int* colInd)
    {
        int l = 0, jl, i;
        int idx = blockDim.x*blockIdx.x;

        l = rowPtr[idx] - 1;
        for ( i = 0; i < (rowPtr[idx + 1] - rowPtr[idx]); i++){
            jl = colInd[l] - 1;
            s[idx] = s[idx] + val[l] * u[jl];
            l+=1;
        }

        l = 0;
        l = rowPtr[idx] - 1;
        for (int i = 0; i < (rowPtr[idx + 1] - rowPtr[idx]); i++){
            jl = colInd[l] - 1;
            if(jl > idx)
                atomicAdd(&s[jl], val[l] * u[idx]);
                //s[jl] = s[jl] + val[l] * u[idx];
            l+=1;
        }


    }

    __device__ double atomicAdd(double* address, double val)
    {
         unsigned long long int* address_as_ull =
         (unsigned long long int*)address;
         unsigned long long int old = *address_as_ull, assumed;
         do {
            assumed = old;
            old = atomicCAS(address_as_ull, assumed, __double_as_longlong(val + __longlong_as_double(assumed)));
         } while (assumed != old);
         return __longlong_as_double(old);
    }

我能修好它吗?

我通过做3个更改来编译您的代码:

  • 如@PaulR所示,在调用自定义的
    atomicAdd
    函数时,删除
    double
    关键字
  • atomicAdd
    的第一个参数应该是指向要更新的地址(要向其中添加值的地址)的指针,而不是在该地址传递值。因此,您的函数调用应该如下所示:

    atomicAdd(&(s[jl]), val[l] * u[idx]);
    
  • 最后,将自定义
    atomicAdd
    函数的声明和定义移动到内核定义之前


  • 通过这些更改,我可以编译您的代码

    这甚至可以编译吗?你期望什么
    双原子加法(s[jl],val[l]*u[idx])待办事项?如
    双原子添加()我使用了CUDA编程指南中的示例。但原子和
    \uuuuuLonglong\uuDouble
    \uuuDouble\uuLonglong
    未定义。我还用float而不是double编写了程序的变体(因为CUDA中本机存在float atomicAdd();
    ),但它也未定义。你没有抓住要点-语法甚至无效。@PaulR,可能是,但我复制了《编程指南》中的double atomicAdd函数,函数(我在上面编写的)未定义。可能我需要使用更多的标题,而不仅仅是
    cuda_runtime.h
    ?你仍然没有抓住要点-关键字
    double
    不应该出现-看起来你只是复制和粘贴了函数定义,而没有真正理解你在做什么。提示:您希望将
    atomicAdd()
    的结果存储在哪里?谢谢您,我已经修复了它。但是我仍然没有定义
    atomicCAS
    \u longlong\u as\u double
    。我最好的猜测是您在visual studio中有一个配置不正确的项目。您正在编译.cpp文件而不是.cu文件,或者您没有找到添加
    -arch=sm_20
    开关的正确位置。作为测试,您可以从提供的一个cuda示例项目开始,确保您可以编译其中一个,然后将代码添加到该项目中。除了添加
    -arch=sm_20
    开关外,还应删除任何其他开关(
    sm_10
    )等,因为它们会导致错误。示例工作正常。我试图在项目的CUDA属性中指定
    sm_20,compute_20
    ,但它不起作用。另外,我在前面读到过,
    -arch=sm_20`等于添加
    sm_20
    compute_20
    ,而不是
    sm_10,compute_10
    。我真的编译了.cu文件。我添加了vs命令。将默认值更改为sm_20时获得的此命令。如果我使用默认设置-我只是得到一些未定义的函数。这是一种不同于您所描述的错误。我看不到任何关于
    atomicCAS
    \uuu longlong\u的内容是未定义的。您需要重新配置VS以显示发出的命令的所有输出,以便我们可以看到PTXA报告的确切问题。有VS设置来控制控制台窗口中显示的输出级别。
    
    atomicAdd(&(s[jl]), val[l] * u[idx]);