Thrust中的虚方法调用

时间:2015-01-23 23:58:32

标签: c++ oop cuda polymorphism thrust

我想做这样的事情:

BaseFunctor* f = new MyFunctor();
thrust::transform(it1,it2,MyFunctor);

目标是让用户能够传递不同的函子(具有相同的基本类型)来操作推力向量中包含的一些数据集。

我试图以两种方式实现这个结果。

首先,我尝试从thrust :: unary_function派生我的仿函数类,并在我的仿函数类中定义了operator(),其签名如下:

__host__ __device__  int operator()(const MyType& x) const

这个没有用,因为(我怀疑)unary_function本身并没有定义()运算符所以当我通过取消引用unary_function类型的指针来传递我的对象时*编译器不能&#39 ; t找到运算符定义(虚拟或常规),以便产生错误:

  

错误3错误:没有适当的operator()或转换函数调用类类型的对象到指针到函数类型

一旦这种方法被证明是无效的,我试着创建自己的基类(让我们称之为BaseFunctor,就像在第一个例子中一样),但这次添加了

__host__ __device__ virtual int operator()(const MyType& x) const

这是另一个类的基类 - 让我们称之为MyFunctor,我在其中重载了这个运算符。 然后我尝试将它传递给push :: transform,就像在我的第一个例子中一样,这导致了一些致命的错误(甚至无法捕获异常)。

有没有办法将这种多态性应用于推力中的仿函数?

我可以模拟我的类使用该仿函数将T *作为成员而不是(例如)BaseFunctor *,这将导致我想要的结果但是我无法控制用户的内容传递,我也不知道传递的类型是否实现了所需的功能,我也无法强制执行此操作。我知道我可以使用专业化,但它有点扼杀了最初的目的(让用户自由创建自己的仿函数)。

1 个答案:

答案 0 :(得分:1)

这不会起作用,因为仿函数的vtable不会在主机之间正确复制。但即使可以,每次评估仿函数时,您也不会想要发送虚函数。每个评估中使用的函数对象都是原始的副本,并且都具有相同的类型,因此所有这些调度都是多余的。你应该考虑一个解决方案,它将函数外部的虚函数调度提升到调用Thrust算法的代码中。

[此答案作为社区维基条目添加,从评论中删除未答复列表中的问题]

相关问题