Примечание: этот вопрос не имеет ничего общего с OpenCL как таковым ... проверьте последний абзац для краткого изложения моего вопроса.Но, чтобы обеспечить некоторую предысторию:
Я пишу некоторый код C ++, который использует OpenCL.Мне нравится хранить исходные тексты для моих ядер OpenCL в их собственных файлах, чтобы облегчить кодирование и сопровождение (в отличие от непосредственного встраивания исходных текстов в виде строковых констант в связанный код C ++).Это неизбежно приводит к вопросу о том, как загрузить их в среду выполнения OpenCL, как только наступит время для распространения двоичных файлов - в идеале, источник OpenCL включен в двоичный файл, так что двоичный файл не должен находиться в определенном месте.в некоторой структуре каталогов, чтобы знать, где находится исходный код OpenCL.
Я хотел бы включить файлы OpenCL в качестве строковых констант где-нибудь, и желательно без использования дополнительных шагов сборки или внешних инструментов (для кросс-компилятора/ кроссплатформенность простота использования ... т.е. нет до xxd
и тому подобное).Я думал, что наткнулся на технику, основанную на втором ответе в этом обсуждении, например:
#define STRINGIFY(src) #src
inline const char* Kernels() {
static const char* kernels = STRINGIFY(
#include "kernels/util.cl"
#include "kernels/basic.cl"
);
return kernels;
}
Обратите внимание, что я предпочел бы не вставлять макрос STRINGIFY
в моем коде OpenCL, если это вообще возможно (как это было сделано в вышеупомянутом вопросе SO).Теперь это прекрасно работает на компиляторе Clang / LLVM, но GCC умирает ужасной смертью (появляется «Неопределенный список аргументов, вызывающий макрос STRINGIFY» и различные синтаксические «ошибки», связанные с содержимым файлов .cl).Итак, очевидно, что этот точный метод не применим в компиляторах (я не пробовал MSVC, но я бы хотел, чтобы он там тоже работал) ... Как я мог бы минимально помассировать его, чтобы он работал в компиляторах?1013 * Подводя итог, хотелось бы, чтобы стандартная техника включала содержимое файла в виде строковой константы C / C ++ без вызова внешних инструментов или загрязнения файлов посторонним кодом.Идеи?
РЕДАКТИРОВАТЬ : Как указал Potatoswatter, поведение вышеописанного не определено, поэтому действительно метод препроцессора кросс-компиляции, который не включает в себя касание файлов, которые будутСтроковый код, вероятно, не возможен (первый человек, который выяснит отвратительный хак, который выполняет для большинства / всех компиляторов, получает очки ответа).Для любопытных я закончил делать то, что было предложено во втором ответе здесь ... то есть я добавил макрос STRINGIFY
непосредственно в файлы OpenCL, которые я включал:
В somefile.cl
:
STRINGIFY(
... // Lots of OpenCL code
)
В somefile.cpp
:
#define STRINGIFY(src) #src
inline const char* Kernels() {
static const char* kernels =
#include "somefile.cl"
;
return kernels;
}
Это работает в компиляторах, в которых я пробовал (Clang и GCC, так каку него нет директив препроцессора внутри макроса), и это не слишком большая нагрузка, по крайней мере, в моем контексте (т. е. это не мешает подсветке синтаксиса / редактированию файлов OpenCL).Одной из особенностей подходов препроцессора, подобных этому, является то, что, поскольку смежные строки объединяются, вы можете записать
inline const char* Kernels() {
static const char* kernels =
#include "utility_functions.cl"
#include "somefile.cl"
;
return kernels;
}
, и пока макрос STRINGIFY находится в обоих файлах .cl
, строки объединяются, что позволяетвам, чтобы модулировать свой код OpenCL.