我试图使用VisualStudio2019在CUDA的一个pow函数中使用函数__device__。
__device__ double Len(double a, double b)
{
return pow(a, 2) + pow(b, 2);
}然而,当我试图构建解决方案时,它总是给我这个错误。
“x64/Debug/kernel.cu.obj”中对“_Z3powdi”的未定义引用错误
只有当我将2更改为2.0时,它才能工作。我认为这可能是使用非整数值作为参数的函数的正确格式,但是当我在普通的C++代码中尝试它时,它与整数2一起正常工作。
这个问题的原因是什么?我该怎么解决呢?
备注:
#include <math.h>,但是它给出了同样的错误。发布于 2020-11-14 04:15:39
自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;
}这样编译时不会出现错误。
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.40219.01 for x64)的CUDA 9.2Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29112 for x64)在Windows 10上的应用我编译的版本和调试版本如下(用于调试生成的大括号中的参数):
nvcc -o pow_dbl_int.exe {-g -G} pow_dbl_int.cu
运行时的可执行文件将产生以下输出:
len = 2.5000000000000000e+01如果这个示例程序没有像前面所示的命令行正确编译,我会怀疑MSVS安装或CUDA安装有什么问题。在我的实践中,我发现通常情况下,首先安装MSVS,然后安装CUDA,这样当安装时,CUDA可以正确地集成到MSVS中。
由于OP显然安装了几天前才在(二零二零年十一月十日)上发布的MSVS版本,主机编译器头文件和CUDA头文件之间也可能存在不兼容性,这就是为什么CUDA历来对受支持的主机编译器版本进行严格检查的原因(不确定现在是否如此)。我注意到微软已经发布了MSVS 2019 16.8.1,发布日期为2020年11月12日。
正如多个注释和CUDA最佳做法指南中所指出的,只需乘以就可以更容易地完成平方,并且不需要调用pow()。
发布于 2020-11-15 07:13:12
更新:我将所有的pow(float)更改为powf(float),问题就解决了。如果您可以修改代码,我建议修改它们,而不是坚持旧版本。
在VS 16.8更新之后,我的cuda项目也遇到了一些构建问题。回到16.7.8之后,问题就解决了。
发布于 2021-01-12 15:35:09
注意:我不是C++开发人员,所以如果我在胡说八道,或者我的解决方案不好的话,请原谅我。
在我们的C++/CLI项目中将MSVC C++工具集更新为v142 (19.28)后,我们也遇到了同样的问题。此问题仅在运行时调用Optix函数时出现。
我们的kernel.cu从CUDA数学API中调用不存在的函数,尽管intellisense建议它调用std函数。我不知道发生了什么,也不知道为什么,但现在起作用了。
在CUDA数学API中,有两个pow函数:
我所做的只是简单地将整数转换为double (static_cast<double>(3)),然后在另一个带有浮动参数的调用中,将调用从pow更改为powf。
https://stackoverflow.com/questions/64797767
复制相似问题