время компиляции
чание: этот вопрос не имеет никакого отношения к 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, но я бы хотел, чтобы она там работала) ... Как я могу минимально помассировать ее, чтобы она работала во всех компиляторах?
Таким образом, я хотел бы, чтобы стандартная техника включала содержимое файла в виде строковой константы 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, так как у него нет директив препроцессора внутри макроса), и не слишком большая нагрузка, по крайней мере, в моем контексте (то есть, это не так). t мешает подсветке синтаксиса / редактированию файлов OpenCL). Одной из особенностей подходов препроцессора, подобных этому, является то, что, поскольку смежные строки объединяются, вы можете написать
inline const char* Kernels() {
static const char* kernels =
#include "utility_functions.cl"
#include "somefile.cl"
;
return kernels;
}
и пока макрос STRINGIFY находится в обоих.cl
файлы, строки объединяются, что позволяет вам модульно кодировать ваш OpenCL.