在編寫OpenCL代碼時,爲了方便起見,我們更喜歡將kernel源代碼放在單獨的文件中(一般爲*.cl)。這各做的缺點在於,程序需要在運行時動態讀入文件中的代碼爲字符串,然後再傳遞給OpenCL的RT編譯、執行。因此,在可執行文件之外,我們還需要單獨分發*.cl文件。
下面,我們介紹一種簡單的技巧,將*.cl文件在編譯時靜態的包含在可執行文件中。
- 首先,將所有源代碼由”STRINGFY()”括起來。
文件samefile.cl
中
STRINGIFY(
... // Lots of OpenCL code
)
- 然後,在C/C++文件中,定義第一步用到的宏“STRINGFY()”,通過”include” 預編譯命令將cl文件做爲字符串(可能會很長)導入。
在文件 somefile.cpp
中
#define STRINGIFY(src) #src
inline const char* Kernels() {
static const char* kernels =
#include "somefile.cl"
;
return kernels;
}
這樣kernel代碼就被靜態的編譯到可執行文件中,無需單獨分必。在需要用到kernel函數進行計算時,只需要將返回的字符串(這裏爲”Kernels“)傳遞給OpenCL相應的函數進行處理即可。
當然,我們可以同時添加更多的文件,只要每個cl文件都被”STRINGFY“括起來。C++編譯器會自動完成字符串的拼接。
inline const char* Kernels() {
static const char* kernels =
#include "utility_functions.cl"
#include "somefile.cl"
;
return kernels;
}
- 對於較多短的kernel代碼,我們也可以直接在cpp源文件中將其字符串化。
#define STRINGIFY(src) #src
static const char*
Kernel = STRINGIFY(
// kernel definition
);