pow 在 CUDA 中的 __device__ 函数内无法正常工作

Abd*_*tef 3 c++ cuda pow

我正在尝试使用 Visual Studio 2019 在 CUDA 中的函数pow内部使用函数。__device__

__device__ double Len(double a, double b)
{
    return pow(a, 2) + pow(b, 2);
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试构建解决方案时,它一直给我这个错误。

错误“x64/Debug/kernel.cu.obj”中对“_Z3powdi”的未定义引用

2仅当我更改为时它才有效2.0。我认为这可能是使用非整数值作为参数的函数的正确格式,但是当我在正常的C++代码中尝试它时,它可以正常使用 integer 2

出现这个问题的原因是什么?我该如何解决这个问题?

笔记:

  1. 前几天还正常,这个错误可能是在最新更新Visual Studio 2019版本16.8.0之后发生的。
  2. 我尝试添加#include <math.h>和删除它,但它给出了相同的错误。

nju*_*ffa 5

自 2008 年左右添加适当的双精度支持以来, CUDA 已pow (double, int)在设备代码中得到支持。至少从 C++98 标准(ISO/IEC 14882 第 26.5 节)开始,这是必需的功能。这是一个包含 OP 功能的完整示例程序,为简洁起见省略了错误检查:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

__device__ double Len(double a, double b)
{
    return pow(a, 2) + pow(b, 2);
}

__global__ void kernel (double a, double b)
{
    printf ("len = %23.16e\n", Len(a, b));
}

int main (void)
{
    kernel<<<1,1>>>(3,4);
    cudaDeviceSynchronize();
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

这编译没有错误

  • Windows 7 上的CUDA 9.2 与 MSVS 2010 ( Microsoft (R) C/C++ Optimizing Compiler Version 16.00.40219.01 for x64)

  • Windows 10 上的CUDA 11.1 与 MSVS 2019 ( Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29112 for x64)

我编译了发布和调试版本,如下所示(大括号中的参数用于调试版本):

nvcc -o pow_dbl_int.exe {-g -G} pow_dbl_int.cu

运行时的可执行文件会产生以下输出:

len =  2.5000000000000000e+01
Run Code Online (Sandbox Code Playgroud)

如果这个示例程序无法使用所示的命令行正确编译,我会怀疑 MSVS 安装或 CUDA 安装出现问题。在我的实践中,我发现先安装 MSVS 然后再安装 CUDA 通常是有利的,这样 CUDA 在安装时可以正确集成到 MSVS 中。

由于OP显然安装了几天前(即2020年11月10日)才发布的MSVS版本,因此主机编译器头文件和CUDA头文件之间也存在不兼容的可能性,这就是CUDA历史上强加的原因严格检查受支持的主机编译器版本(不确定现在是否这样做)。我注意到微软已经发布了MSVS 2019 16.8.1,发布日期为2020年11月12日。

正如多条评论和CUDA 最佳实践指南中所述,只需乘法即可更轻松地完成平方,并且无需调用pow().