Как использовать шаблоны C ++ в ядрах OpenCL?

Я новичок в OpenCL.

У меня есть алгоритм, использующий шаблоны. Он хорошо работал с распараллеливанием OpenMP, но теперь объем данных вырос, и единственный способ их обработать - это переписать их для использования OpenCL. Я легко могу использовать MPI для создания кластера, но GPU в стиле Tesla намного дешевле кластера :)

Есть ли способ использовать шаблоны C ++ в ядре OpenCL?

Можно ли как-то расширить шаблоны компилятором C ++ или каким-либо инструментом и после этого использовать так измененную функцию ядра?

РЕДАКТИРОВАТЬ. Идея обходного пути состоит в том, чтобы каким-то образом сгенерировать C99-совместимый код из кода C ++ из шаблона.

Я нашел следующее о Комо:

Comeau C ++ 4.3.3 - это полноценный и полноценный компилятор, который выполняет полную проверку синтаксиса, полную семантическую проверку, полную проверку ошибок и все другие обязанности компилятора. Входной код C ++ транслируется во внутренние деревья компилятора и таблицы символов, не похожие на C ++ или C. Кроме того, он генерирует внутреннюю частную промежуточную форму. Но вместо использования проприетарного генератора внутреннего кода Comeau C ++ 4.3.3 генерирует C-код в качестве своего вывода. Помимо технических преимуществ C ++, аспекты создания C продуктов, таких как Comeau C ++ 4.3.3, рекламировались как причина успеха C ++, поскольку его можно было использовать на большом количестве платформ благодаря общедоступности компиляторов C.

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


person flashnik    schedule 16.12.2010    source источник
comment
Я не думаю, что это возможно напрямую для OpenCL (в отличие от CUDA, который имеет некоторую поддержку шаблонов через nvcc), но я хотел бы, чтобы меня доказали, что он ошибается.   -  person Bart    schedule 17.12.2010
comment
AFAIK это невозможно напрямую, но я надеюсь найти обходной путь, возможно, с использованием некоторых этапов компиляции для генерации C99-совместимого кода, который затем будет обрабатываться обычным способом.   -  person flashnik    schedule 17.12.2010
comment
Теперь я вижу, что подобный вопрос задавался раньше с некоторыми интересными ответами: stackoverflow .com / questions / 1139793 /   -  person Bart    schedule 17.12.2010
comment
Wekk, честно говоря, я видел это до того, как задал этот вопрос, но с тех пор, как этот ответ был разработан, OpenCL был разработан, и, возможно, может появиться продукт, который может решить эту проблему. Также мне непонятно, как использовать Comeau для решения, потому что у меня не так много опыта в C ++, как у этого TS.   -  person flashnik    schedule 17.12.2010
comment
Эта тема поучительна: gcc.gnu.org/ml/gcc/2009 -02 / msg00061.html   -  person Mike    schedule 17.12.2010
comment
Нет, эта тема не особо помогает. Там сказано, что OpnCL требует компиляции среды выполнения, и это не противоречит моей идее подготовить код C ++ ПЕРЕД компиляцией среды выполнения.   -  person flashnik    schedule 18.12.2010


Ответы (6)


Есть старый способ эмуляции шаблонов на чистом языке C. Он основан на включении одного файла несколько раз (без включения защиты). Поскольку OpenCL имеет полнофункциональный препроцессор и позволяет включать файлы, этот трюк можно использовать.

Вот хорошее объяснение: http://arnold.uthar.net/index.php?n=Work.TemplatesC

Это по-прежнему намного сложнее, чем шаблоны C ++: код должен быть разделен на несколько частей, и вы должны явно создать экземпляр каждого экземпляра шаблона. Кроме того, похоже, что вы не можете делать некоторые полезные вещи, такие как реализация факториала в качестве рекурсивного шаблона.

Пример кода

Применим идею к OpenCL. Предположим, что мы хотим вычислить обратный квадратный корень с помощью итерации Ньютона-Рафсона (как правило, это не очень хорошая идея). Однако тип с плавающей запятой и количество итераций могут различаться.

Прежде всего, нам понадобится вспомогательный заголовок ("templates.h"):

#ifndef TEMPLATES_H_
#define TEMPLATES_H_

#define CAT(X,Y,Z) X##_##Y##_##Z   //concatenate words
#define TEMPLATE(X,Y,Z) CAT(X,Y,Z)

#endif

Затем мы пишем шаблонную функцию в "NewtonRaphsonRsqrt.cl":

#include "templates.h"

real TEMPLATE(NewtonRaphsonRsqrt, real, iters) (real x, real a) {
    int i;
    for (i = 0; i<iters; i++) {
        x *= ((real)1.5 - (0.5*a)*x*x);
    }
    return x;
}

Создайте экземпляр этого шаблона в основном файле .cl следующим образом:

#define real float
#define iters 2
#include "NewtonRaphsonRsqrt.cl"  //defining NewtonRaphsonRsqrt_float_2

#define real double
#define iters 3
#include "NewtonRaphsonRsqrt.cl"  //defining NewtonRaphsonRsqrt_double_3

#define real double
#define iters 4
#include "NewtonRaphsonRsqrt.cl"  //defining NewtonRaphsonRsqrt_double_4

А потом можно использовать это так:

double prec = TEMPLATE(NewtonRaphsonRsqrt, double, 4) (1.5, 0.5);
float approx = TEMPLATE(NewtonRaphsonRsqrt, float, 2) (1.5, 0.5);
person stgatilov    schedule 16.07.2013
comment
+1 (хотя было бы даже лучше включить описание того, как это работает, прямо здесь, в посте) - person jogojapan; 16.07.2013
comment
@jogojapan, я добавил пример кода (в OpenCL). Теперь ответ более замкнутый. - person stgatilov; 16.07.2013

Я написал экспериментальный инструмент преобразования исходного кода C ++ в OpenCL C. Инструмент компилирует исходный код C ++ (даже некоторый STL) в байт-код LLVM и использует модифицированную версию серверной части LLVM 'C' для дизассемблирования байтового кода в OpenCL 'C'.

См. http://dimitri-christodoulou.blogspot.com/2013/12/writing-opencl-kernels-in-c.html.

Например, этот код, использующий std :: enable_if C ++ 11, может быть преобразован в OpenCL 'C', а затем выполнен на графическом процессоре:

#include <type_traits>

template<class T>
T foo(T t, typename std::enable_if<std::is_integral<T>::value >::type* = 0)
{
    return 1;
}

template<class T>
T foo(T t, typename std::enable_if<std::is_floating_point<T>::value >::type* = 0)
{
    return 0;
}

extern "C" void _Kernel_enable_if_int_argument(int* arg0, int* out)
{
    out[0] = foo(arg0[0]);
}
person Dimitri    schedule 01.01.2014

Вы можете взглянуть на VexCL, который использует шаблоны выражений для генерации ядер OpenCL. Вы можете получить некоторые идеи о том, как заставить OpenCL хорошо работать с шаблонами.

Еще одна библиотека, над которой активно ведется работа, - это Boost.Compute, который является слоем поверх OpenCL, позволяющим использовать общие Код C ++.

Общая идея состоит в том, чтобы создать ядро ​​как строку C более или менее и передать ее среде выполнения OpenCL для компиляции и выполнения.

person ipapadop    schedule 28.06.2013

Если вы действительно настроены сделать это, вы можете перенаправить свой компилятор C ++ на создание NVidia PTX (и Clang, скорее всего, скоро сможет это сделать). Но таким образом вы привяжете свой код к оборудованию NVidia.

Другой способ - реализовать собственный бэкэнд для LLVM, основанный на текущем CBE, который будет генерировать чистый код OpenCL вместо C.

person SK-logic    schedule 18.12.2010

Обратите внимание, что новый стандарт SYCL Khronos имеет встроенную поддержку шаблонов C ++ в OpenCL.

person Ruyk    schedule 19.10.2017

PyOpenCL теперь использует Mako в качестве механизма шаблонов. http://www.makotemplates.org/

person Chad Brewbaker    schedule 07.05.2011
comment
При чем здесь шаблоны C ++? - person Ben Voigt; 07.05.2011
comment
Алгоритмы не используют шаблоны, а их реализации. Учитывая это, а также тот факт, что C ++ и OpenCL расширяют C в разных направлениях (тем самым гарантируя, что реализация OP должна быть в некоторой степени изменена), разумно предложить альтернативный механизм шаблонов, который оказался полезным для создания OpenCL и может предложить аналогичный уровень гибкости. - person user57368; 07.05.2011