1

I'm writing cuda kernels that can make use of functors, that are passed as a parameter with templates. For example:

template<typename Functor> void myKernel(float arg1, float* arg2, Functor f) {
  // Do stuff that will involve f
}

These functors are defined in a header file that I include in each cpp file, and for each one I have to instantiate all the kernels with all the functors:

template<> myKernel<Add>(float, float*, Add)
template<> myKernel<Sub>(float, float*, Sub)

This is a lot of code duplication, and we have to remember to add a new line for each new functor. Is there a way to define all of this once?

Pafnouti
  • 161
  • 1
  • 1
  • 8
  • A preprocessor macro? – Amit Sep 01 '15 at 21:38
  • Are you aware of explicit instantiation? https://msdn.microsoft.com/en-us/library/by56e477.aspx – Captain Giraffe Sep 01 '15 at 21:44
  • I hope that there is a solution that doesn't involve marcros. – Pafnouti Sep 01 '15 at 21:46
  • It looks like you are defining specializations. Is that a requirement? Can you define one default template implementation instead, and then use implicit instantiation? – jxh Sep 01 '15 at 22:27
  • @jxh To use implicit instantiation I need to have my kernels defined in headers right? This is not an option: the functors are created in the cpp files, then given to the .cu files which are compiled separately. – Pafnouti Sep 01 '15 at 22:34
  • Are you saying you are forbidden from defining a header file that all cpp files can include? – jxh Sep 01 '15 at 22:52

2 Answers2

1

Take a look at extern template declarations.

There are some subtle details about extern templates, especially 14.7.2.10:

Except for inline functions and class template specializations, explicit instantiation declarations have the effect of suppressing the implicit instantiation of the entity to which they refer.

This means that the following will only suppress the instantiation of the non-inline member function f in other translation units, but not for g:

template<typename T> class A {
public:
     void g() {} // inline member function
     void f();
};

template<typename T> void A::f() {} // non-inline
Community
  • 1
  • 1
Jens
  • 9,058
  • 2
  • 26
  • 43
0

Just add the instanciations in the header file, and you won't have to remember to specify them every time.

Vincent Fourmond
  • 3,038
  • 1
  • 22
  • 24