包含OpenCL .cl文件的标头

时间:2013-01-24 13:49:49

标签: c++ header include opencl

我在.cl文件中编写了一个OpenCL内核。它会尝试#include多个标题。

它的编译失败,因为包含的头文件“找不到”。 我知道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并且有几个包含文件的目录,我该如何指定它们?

3 个答案:

答案 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)