我在.cl
文件中编写了一个OpenCL内核。它会尝试#include
多个标题。
它的编译失败,因为包含的头文件“找不到”。
我知道clBuildProgram
可以使用-I dir
选项,它将目录dir
添加到要搜索头文件的目录列表中。
在khronus网站论坛中,这篇文章http://www.khronos.org/message_boards/viewtopic.php?f=37&t=2535讨论了这个问题。
他们建议使用clCreateProgramWithSource
来指定所有来源(包括.h文件)。
我对此问题有疑问:
clBuildProgram
与clCreateProgramWithSource
,如上所述)clCreateProgramWithSource
,编译器如何知道要包含哪些内容?我的意思是,哪个来源代表哪个包含文件名?clBuildProgram
并且有几个包含文件的目录,我该如何指定它们?答案 0 :(得分:8)
OpenCL 要求您使用clCreateProgramWithSource()
后跟clBuildProgram()
。
ClCreateProgramWithSource()
创建并返回cl_program
个对象。
cl_program
对象输入clBuildProgram()
。
clBuildProgram()
允许您指定包含包含文件的编译器选项
目录。在您的情况下,对于头文件包含,它将类似于字符串:
-I myincludedir1 -I myincludedir2 ...
使用的编译器是您正在使用的 OpenCL SDK 中的内部OpenCL编译器。所以,如果你 正在使用 AMD的SDK ,将使用属于 OpenCL SDK 的 AMD OpenCL编译器。同样适用于 Nvidia 或英特尔。
检查所有 OpenCL 函数调用的OpenCL状态代码非常重要。
这是clCreateProgramWithSource()
和clBuildProrgam()
必须的
任何编译器错误或消息。还有一个完整的其他位代码可供编写
获取消息的大小,然后自己检索消息。
答案 1 :(得分:2)
使用带有一定数量的包含和代码长度的-I时,Nvidia OpenCL设备驱动程序存在错误。 AMD和英特尔没有这个问题。我的解决方案是在运行时将所有.cl文件连接成一个大文件。这样做的缺点是,在调试代码时,错误的行号对应于连接的.cl文件,而不是单独的.cl文件。
我怀疑Nvidia会解决这个问题。他们不再关心OpenCL了。
答案 2 :(得分:0)
还有一个肮脏的伎俩:你应该模仿包括你自己(即手动合并之类的东西)。编码并不十分清楚,但如果您的OpenCL编译器不支持(或支持错误的)-I
指令,则它可以正常工作。这种方法并不完美(例如,您丢失了语法高亮显示),但可以帮助旧的或错误的OpenCL编译器。
这种可能性的一个简单例子:
std::string load_file(const std::string &file_name, int max_size = 0x100000)
{
FILE *fp = fopen(file_name.c_str(), "rb");
if (!fp)
{
// print some error or throw exception here
return std::string();
}
char *source = new char[max_size];
size_t source_size = fread(source, 1, max_size, fp);
fclose(fp);
if (!source_size)
{
delete[] source;
// print some error or throw exception here
return std::string();
}
std::string result(source);
delete[] source;
return result;
}
// errors checks are omitted for simplification
std::string full_source = load_file("header.h");
full_source += load_file("source.cl");
const char *source_ptr = full_source.c_str();
size_t source_size = full_source.size();
cl_int_status = CL_SUCCESS;
cl_program program = clCreateProgramWithSource(context, 1,
(const char **)&source_ptr, (const size_t *)&source_size, &ret);
// check status for CL_SUCCESS here
// now you have your program (include + source)