包括 OpenCL .cl 文件的标头
include headers to OpenCL .cl file
我在.cl
文件中编写了一个 OpenCL 内核。 它尝试#include
多个标头。
它的编译失败,因为"找不到"包含的头文件。我知道clBuildProgram
可以采用-I dir
选项,该选项将目录dir
添加到要搜索头文件的目录列表中。
在khronus网站论坛中,这篇文章 http://www.khronos.org/message_boards/viewtopic.php?f=37&t=2535 讨论了这个问题。
他们建议使用指定所有来源(包括.h文件)的clCreateProgramWithSource
。
我对这个问题有一个问题:
- 哪个选项更好?(
clBuildProgram
与clCreateProgramWithSource
,如上所述) - 如果我使用
clCreateProgramWithSource
编译器如何知道要包含的内容?我的意思是,哪个来源代表哪个包含的文件名? - 如果我使用
clBuildProgram
并且有多个包含文件的目录,如何指定它们?
OpenCL 要求您使用clCreateProgramWithSource()
后跟 clBuildProgram()
。
ClCreateProgramWithSource()
创建并返回一个cl_program
对象。
该cl_program
对象被输入到clBuildProgram()
中。
clBuildProgram()
允许您指定包含包含文件的编译器选项目录。 在您的情况下,对于头文件包含,它将类似于字符串:
-I myincludedir1 -I myincludedir2 ...
使用的编译器是您正在使用的 OpenCL SDK 中的内部 OpenCL 编译器。所以如果你正在使用AMD的SDK,将使用作为其OpenCL SDK一部分的AMD OpenCL编译器。英伟达或英特尔也是如此。
检查所有 OpenCL 函数调用的 OpenCL 状态代码非常重要。这对于clCreateProgramWithSource()
和clBuildProrgam()
是强制性的任何编译器错误或消息。 还有一整段其他位代码要写获取消息的大小,然后检索消息本身。
Nvidia OpenCL 设备驱动程序在使用具有一定数量的包含和代码长度的 -I 时存在错误。 AMD和英特尔没有这个问题。 我的解决方案是在运行时将所有 .cl 文件连接成一个大文件。 这样做的缺点是,在调试代码中,错误的行号对应于已处理的 .cl 文件,而不是单个 .cl 文件。
我怀疑英伟达永远不会解决这个问题。 他们不再关心OpenCL。
肮脏的技巧:你应该模仿包括你自己(即手动合并之类的东西)。编码不是很清楚,但如果 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)
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- CMake OpenCL:无法读取内核文件
- 英特尔 OpenCL SDK - 头文件在哪里
- AMD OpenCL 致命错误:CL/cl.hpp:没有这样的文件或目录
- 使用OpenCL 2.0 c++绑定头文件的链接器错误
- c++中包含相对路径的OpenCL头文件问题
- Opencl内核文件没有完全加载
- 没有外部内核文件的openCL
- 使用nvcc的可执行程序比使用gcc/g++和OpenCL的可执行文件大
- 编译 OpenCL 文件时LNK2019许多错误
- 包括 OpenCL .cl 文件的标头
- 如何将OpenCL内核文件(.cl)编译为llvm IR文件
- 如果从二进制文件加载,OpenCL将导致CL_INVALID_COMMAND_QUEUE