繁体   English   中英

如何使用模板正确定义函数

[英]how to properly define functions with templates

当我尝试构建程序时,我无法理解为什么会得到未解析的外部符号。 我有3个文件。 让我们说

main.cpp
file.cu
headerfile.h

我在main.cpp文件的main函数中定义了这两个const变量:

const uint             N = 1048576;
const uint          base = 1024;

我还定义了headerfile.h所需的函数:

template <const uint N, const uint base>
void F1(
    float2 *d_S_x,
    float2 *d_S_y,
    bool *S_yy,
    CCP *dev_CP,
    uint batchSize,
    uint batchLength
);

和其他人一样:

...
extern "C" uint bitonicSort(
    float2 *d_P_out,
    float2 *d_P_in,
    uint batchSize,
    uint arrayLength,
    uint dir,
    uint xy
);
...

我必须使用模板,因为变量Nbase将用于在设备上分配共享内存,所以我需要有const变量。 F1函数就像file.cu的接口函数,我将在其中启动我的内核。 现在从main.cpp我正常调用F1

F1 <N,base> ( d_S_x, d_S_y, d_S_yy, dev_CP, batchsize, batchLength);

我从F1内部启动了一些内核(或错误BF显示的其他函数),如:

MinReduction <N, base> <<< 1, base >>>(dev_CP);

.h文件中函数的定义是否有问题? 我想我错过了使用extern和模板的东西吗? 错误是:

Error 4 error LNK1120: 2 unresolved externals E:\D....exe
Error 3 error LNK2001: unresolved external symbol "void __cdecl BF<1048576,1024>(struct float2 *,struct CCP *)" (??$BruteForce@$0BAAAAA@$0EAA@@@YAXPAUfloat2@@PAUCCP@@@Z) E:\...main.obj
Error 2 error LNK2001: unresolved external symbol "void __cdecl F1<1048576,1024>(struct float2 *,struct float2 *,bool *,struct CCP *,unsigned int,unsigned int)" (??$closest_pair@$0BAAAAA@$0EAA@@@YAXPAUfloat2@@0PA_NPAUCCP@@II@Z) E:\..main.obj

如果不在headerfile.h中,我应该在哪里定义函数? 据我所知,Extern告诉编译器你没有声明一个新变量,而是引用一个在别处声明的变量。 但是定义extern和模板不起作用吗? 任何帮助,将不胜感激。 提前致谢。

在模板实例化时,所有显式特化声明必须是可见的。

从您的(不完整)帖子中,您似乎有以下(简化)方案:

main.cu file

const int             N = 1048576;
const int          base = 1024;

#include "test.cuh"

int main() {

    F1<N,base>();

    return 0;
}

test.cuh file

template<const int N, const int base> void F1();

test.cu file

template<int N, int base> void F1() { }

此结构将提供以下错误消息

error LNK2001: unresolved external symbol "void __cdecl F1<1048576,1024>(void)" (??$F1@$0BAAAAA@$0EAA@@@YAXXZ)

原因是在main.cu文件的F1<N,base>调用中发生的隐式特化在定义F1的转换单元( test.cu文件)中不可见。

你应该使用类似的东西

const int             N = 1048576;
const int          base = 1024;

template<int N, int base> void F1() { };

int main() {

    F1<N,base>();

    return 0;
}

在这种情况下,隐式特化F1<N,base>(); 发生在main.cu文件中的是在定义F1的同一转换单元中。

您的问题与CUDA无关,是在C ++中使用模板的问题。 您可能希望查看本指南以获取更多即时信息。

虽然JackOLantern的答案非常相关,但让我们更具体的CUDA:我想知道你是否真的需要这两个模板变量。

  • 您将'base'作为块大小传递,这意味着您已经有一些不承担其值的行为。 那么,对于代码的某些部分提前“知道”它是否如此重要?
  • 至于N,我不知道你用它是什么,但1,048,576 = 2 ^ 20有点太完美了。 我想知道 - 你不能让它成为常数吗? 或者将其作为枚举值传递给内核?

所以,你可能会为自己创造问题......(或者你可能没有,但在你的情况下其他人可能会这样做)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM