1

I'd like to do something like this:

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

The goal is to give the user an ability to pass different functors (with same base-type) to operate on some set of data contained in thrust's vector.

I tried to achieve this result in two ways.

First I tried to derive my functor class from thrust::unary_function and defined operator() in my functor class with signature like this:

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

This one didn't work because (as I suspect) unary_function itself doesn't have the () operator defined so when I passed my object by de-referencing a pointer of type unary_function* compiler couldn't find the operator definition (virtual or regular) so it produced error:

Error 3 error : call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type

Once this approach proved to be invalid, I tried to make my own base class (let's call it BaseFunctor, like in the first example) but this time added

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

This served as a base class for the other class - let's call it MyFunctor in which I overloaded this operator. Then I tried to pass it to thrust::transform like in my first example, which resulted in some fatal error (couldn't even catch an exception).

Is there a way to apply this kind of polymorphism to functors in thrust?

I could probably template my class that utilizes that functor to have T* as a member instead of (for example) BaseFunctor* which would lead to the result I want but then I'd have no control over what the user passes, I also wouldn't know if the passed type implements desired functionality and I would have no way to enforce this. I know I can use specialization but it'd kind of kill the original purpose (to give user freedom of creating his own functor).

user2521472
  • 137
  • 11
  • 4
    This isn't going to work because the functor's vtable will not be copied correctly from host to device. But even if it could, you wouldn't want to dispatch a virtual function every time you evaluate the functor. The function objects used in each evaluation are copies of the original and all have the same type, so all those dispatches are redundant. You should consider a solution which hoists the virtual function dispatch outside of the functor into the code which invokes the Thrust algorithm. – Jared Hoberock Jan 24 '15 at 00:04
  • @JaredHoberock So basically do something like my template solution in my first post? Not sure if I got this right. Could you please provide at least some abstract example of this? To be more precise - what do you mean by "consider a solution which hoists the virtual function dispatch outside of the functor into the code which invokes the Thrust algorithm"? – user2521472 Jan 26 '15 at 13:19
  • 1
    [Here's a worked example](http://stackoverflow.com/questions/22988244/polymorphism-and-derived-classes-in-cuda-cuda-thrust/23476510?s=1|2.6593#23476510) of "standard" object polymorphism in thrust. If your selection of what the virtual function will do is based on the object (what I am referring to as standard object polymorphism), then it can work if the objects are created in device code. Your question is unclear. You want a user-selectable functor? I don't think you need to use virtual functions for this. You might be interested in [this](http://stackoverflow.com/questions/23391914). – Robert Crovella Feb 01 '15 at 15:24

1 Answers1

1

This isn't going to work because the functor's vtable will not be copied correctly from host to device. But even if it could, you wouldn't want to dispatch a virtual function every time you evaluate the functor. The function objects used in each evaluation are copies of the original and all have the same type, so all those dispatches are redundant. You should consider a solution which hoists the virtual function dispatch outside of the functor into the code which invokes the Thrust algorithm.

[This answer added as a community wiki entry from comments to get the question off the unanswered list]

talonmies
  • 70,661
  • 34
  • 192
  • 269