2013-01-24 84 views
5

我已经在.cl文件中编写了OpenCL内核。它试图#include几个标题。包含头文件到OpenCL .cl文件

其编译失败,因为包含的头文件是“未找到”。 我知道clBuildProgram可以采取-I dir选项,它将目录dir添加到要搜索的头文件的目录列表。

在khronus网站论坛中,这篇文章http://www.khronos.org/message_boards/viewtopic.php?f=37&t=2535谈到了这个问题。

他们建议使用clCreateProgramWithSource它指定所有源(包括.h文件)。

我有一个关于这个问题一个问题:

  1. 哪种选择更好? (clBuildProgramclCreateProgramWithSource,如上所述)
  2. 如果我使用clCreateProgramWithSource编译器如何知道要包含什么?我的意思是,哪个来源代表哪个包含文件名?
  3. 如果我使用clBuildProgram并且有几个包含文件的目录,我该如何指定它们?

回答

5

的OpenCL需要使用clCreateProgramWithSource()其次clBuildProgram()

ClCreateProgramWithSource()创建并返回一个cl_program对象。

cl_program对象输入clBuildProgram()

clBuildProgram()允许您指定编译器选项,其中包括包含文件 目录。在你的情况下,头文件还包括,它会是这样的字符串:

-I myincludedir1 -I myincludedir2 ... 

使用的编译器是内部OpenCL编译OpenCL的SDK您使用。所以,如果你 使用AMD的SDK,则AMD OpenCL编译那是他们的OpenCL的SDK的一部分将被使用。同样适用于NvidiaIntel

其重要的是检查所有OpenCL状态码OpenCL函数调用。 这是强制要求clCreateProgramWithSource()clBuildProrgam()得到 任何编译器错误或消息。还有一个完整的其他位代码来编写 以获取消息的大小,然后自己检索消息。

2

Nvidia OpenCL设备驱动程序在使用-I时包含一定数量的包含和代码长度时会出现错误。 AMD和英特尔没有这个问题。我的解决方案是在运行时将所有.cl文件连接成一个大文件。这样做的缺点是,在调试代码时,错误的行号对应于concatenated .cl文件,而不是单个的.cl文件。

我怀疑Nvidia会永远解决这个问题。他们不再关心OpenCL了。

+0

AMD APP与-I问题也从我的经验(它根本不工作),但英特尔处理它完美。 – Thomas

+0

这很有趣。我虽然我在CPU上测试过它。我没有AMD GPU,所以我无法在GPU上进行测试。也许这是一个GPU与CPU的问题? – 2013-03-10 07:18:53

+0

不,我在Windows下的两个设备下试过,编译器似乎并不处理相对包含路径。基本上,我的编译器命令行中有“-I cl /”,我的内核整齐排列在cl /目录下,虽然在Intel/Linux下工作正常,但AMD不会有任何问题,无论如何我尝试的是,我发现的唯一解决方案是在#include指令中对每个.cl文件的*绝对路径*进行硬编码,或将我的cl /文件夹添加到系统$ PATH。这可能是我的安装,但是我的Linux系统并没有像我的Linux系统那样维护。 – Thomas

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)