Альтернативный способ шаблона структуры со статической функцией-членом в CUDA?

0

В C++ я часто использую статические функции, инкапсулированные в шаблонные структуры, чтобы иметь возможность указывать шаблон функции во время компиляции, позволяя различные оптимизации, например, встраивание и т.д. (Кстати, имеет ли это имя?). Пример (довольно надуманный, и, вероятно, есть ошибки, но вы понимаете):

template <int dim>
struct ImplementationA {
    static float compute(float a) {
        // do stuff, e.g.
        return 2*pow(a,dim);
    }
};

template <int dim>
struct ImplementationB {
    static float compute(float a) {
        // do other stuff, e.g.
        return 3*pow(a,dim);
    }
};

template <template <int> class ImplT, int dim> class Test {
    void compute_stuff(float *dst, const float *src, int N) {
        for(int i=0; i<N; i++)
            dst[i] = ImlT<dim>::compute(src[i]);
    }
};

void main() {
    float v1[100];
    float v2[100];

    Test<ImplementationB,3> t;
    t.compute_stuff(v2,v1,N);
}

Однако, если я хочу сделать то же самое в CUDA с compute являющимся ядром, то есть __global__, это невозможно, поскольку у вас не может быть static __global__ функции static __global__ member. Какие у меня есть другие возможности, которые обеспечивают минимальные эксплуатационные издержки? Я использую GCC 4.6, поэтому некоторые функции C++ 11 недоступны.

  • 0
    Как насчет обертывания статической функции-члена C ++ 11 вокруг вызова функции ядра?
  • 0
    @JackOLantern, да, это то, что я в итоге и сделал. Работало просто отлично, но я уверен, что решение jet45 бы также.
Теги:
c++11
templates
cuda

1 ответ

1
Лучший ответ

Вы можете создать класс шаблона с реализацией в методе __device__ и малую функцию __global__ которая просто использует этот класс и вызывает метод:

template <int dim> class ImplementationA
{
public:
    // parameters
    float *dst;
    const float *src;
    int N;

    // implementation
    __device__ void compute()
    {
        float a = src[threadIdx.x];
        // ...
    }
};

// The same for ImplementationB

// global function
template <class Impl>
__global__ void compute(Impl impl)
{
    impl.compute();
}

// call
ImplementationA<3> impl;
impl.src = src;
compute<<<1, 32>>>(impl);
  • 0
    Да, это делает свое дело, но я все еще думаю, что решение @JackOLantern более изящно, так как для пользователя, то есть для класса, использующего различные реализации, все скрыто за структурой.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню