我开始编写模拟并决定尝试使用更加反对的方法。因此,我还决定在CUDA内核中使用模板参数,该参数指示模拟的空间维度。问题是,由于在头文件中实现模板函数的限制,我不得不使用一种复杂的方法来保持内核包装器可以从.cpp源文件中调用。
我的方法是重载2和3维的包装函数。然后我有一个包装类的类,它处理初始化和管理内核资源。不幸的是,由于我提到的限制,我必须保留两个模板类成员,即
struct kernelWrapper{
KernelWrapper(Simulation<2> *simulation):
d_(2),
simulation2d_(simulation)
{}
KernelWrapper(Simulation<3> *simulation):
d_(3),
simulation3d_(simulation)
{}
process(void){ //wrapper function for kernel launching
switch(d_){
case 2:
kernel<2><<<..., ...>>>(...);
break;
}
case 3:
kernel<3><<<..., ...>>>(...);
break;
}
default:
break;
}
int d_;
union{
Simulation<2> *simulation2d_;
Simulation<3> *simulation3d_;
};
union{
Lattice<2> *lattice2d_d;
Lattice<3> *lattice3d_d;
};
};
因此我想知道你是否知道一种更好的方法来实现我正在尝试做的事情,即为模板CUDA内核创建一个包装器。
更新:我想在发布上述帖子后再添加一个我发现的解决方案。如C++ faq(第13-15点)所示,可以将模板实现放在源文件中并显式实例化所需的模板,即在我的情况下为2和3维。使用C ++ 11,可以更进一步,在模板定义中引入关键字extern
以节省一些编译/链接时间,同时解释here。
答案 0 :(得分:3)
问题是,由于实施模板的限制 函数在头文件中,我不得不使用复杂的方法 保持使.cpp源文件可以调用内核包装。
在.cpp
中编写模板声明代码是合法的 kernelWrapper
是否在.hpp或.cpp中,您应该有一个类似于
template<int d_>
struct kernelWrapper
{
KernelWrapper(Simulation<d_> *simulation) : simulation_(simulation)
{}
process(void)
{
kernel<d_><<<..., ...>>>(...);
}
Simulation<d_>* simulation_;
Lattice<d_>* lattice2d_;
};
同时避免使用switch / case选择内核,使用类似:
int const max_dimension = 4;
template<int static_dimension>
void select_kernel(int dynamic_dimension)
{
if(dynamic_dimension == static_dimension)
{
call_kernel<static_dimension>();
}
select_kernel<static_dimension+1>(dynamic_dimension);
}
template<>
void select_kernel<max_dimension>(int dynamic_dimension)
{
// error message
}
void select_kernel(int dynamic_dimension)
{
select_kernel<1>(dynamic_dimension);
}
如果这种选择频繁,那么不使用模板会很有意义。