11

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

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

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

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

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

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

3 回答 3

10

OpenCL要求您使用clCreateProgramWithSource()后跟clBuildProgram().

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

cl_program对象被输入到clBuildProgram().

clBuildProgram()允许您指定包含包含文件目录的编译器选项。在您的情况下,对于头文件包含,它将类似于字符串:

-I myincludedir1 -I myincludedir2  ...

使用的编译器是您正在使用的OpenCL SDK中的内部 OpenCL 编译器。因此,如果您使用AMD 的 SDK,将使用作为其OpenCL SDK一部分的AMD OpenCL 编译器。同样适用于NvidiaIntel

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

于 2013-01-24T21:28:54.373 回答
4

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

我怀疑英伟达会解决这个问题。他们不再关心 OpenCL。

于 2013-03-09T20:58:04.527 回答
1

还有一个更肮脏的技巧:你应该模仿 include 你自己(即像手动合并的东西)。编码不是很清楚,但如果您的 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)
于 2015-11-19T09:45:13.360 回答