编译 OpenCL 应用程序和使用可用编译器选项的正确方法

Posted

技术标签:

【中文标题】编译 OpenCL 应用程序和使用可用编译器选项的正确方法【英文标题】:Proper way of compiling OpenCL applications and using available compiler options 【发布时间】:2017-04-05 18:07:48 【问题描述】:

我是 OpenCL 方面的新手。

编译 OpenCL 项目的最佳方法是什么?

    使用受支持的编译器(GCCClang):

    当我们使用编译器时 像gccclang,我们如何控制这些选项?他们是 必须在源代码中设置,或者,同样是正常的 编译流程我们可以在命令行上传递它们。查看Khornos-Manual-1.2,有几个optionscl_int clBuildProgram 提供优化。 :

    gcc|clang -O3 -I<INCLUDES> OpenCL_app.c -framework OpenCL OPTION -lm
    

    其实,我试过这个并收到一个错误:

    gcc: error: unrecognized command line option '<OPTION>'
    

    或者,使用openclc:

    我见过有人使用openclc 编译器使用 Makefile。

我想知道哪种方法最好(如果 实际上有两种不同的方式),以及我们如何控制 使用不同的编译时选项。

【问题讨论】:

您的意思是之前完成的另一个内核编译的二进制输出吗?它缩短了编译时间,尤其是对于 fpgas。你在第一个问题中问什么?是否需要添加其他 C 程序的头文件? @huseyintugrulbuyukisik。我的问题很笼统。编译opencl应用程序(主机+内核)的正确方法是什么。是使用 gcc/llvm 和 opencl 库还是使用 openclc。 您需要包含来自操作系统的 opencl lib-dll 文件,以便 C++ 绑定工作和编译。 opencl 内核编译只需给 cl 程序和 cl 内核对象一个字符串并在运行时而不是编译时编译即可完成。如果你有二进制文件,那么你可以从一开始就准备好 opencl。如果安装了 gpu 驱动程序,您可以在某些文件夹中找到它们,但我不记得了。 那么openclc有什么用呢? 它在您的程序之外编译,因此您可以使用它的结果文件在您的程序中运行内核,而无需进行 opencl 编译。例如,我没有使用它,因此在我的计算机中编译 3 个设备需要 10-20 秒(在运行时),因为我将内核程序作为字符串和 opencl.dll 提供了必要的函数,它在我想要的时候编译那个字符串,但一个 fpga 需要几个小时来编译,所以他们预先编译一次并发布它,这样用户就不用等待几个小时来计算 【参考方案1】:

您可能知道,但重申这一点很重要。 OpenCL 标准包含两件事:

    OpenCL C 语言和编程模型(我认为最近的标准包括一些 C++) 用于管理设备的 OpenCL 主机库

gccclang 是 OpenCL 项目主机端的编译器。因此,将无法使用主机编译器为 OpenCL 设备代码编译提供编译器选项,因为它们甚至不知道任何 OpenCL。 除了clang 之外,还有一个接受 OpenCL 设备代码的标志,即包含内核的 .cl 文件。这样您就可以使用clang 并提供标志和选项(如果我没记错的话),但现在您将拥有 llvm IR 或SPIR 输出而不是设备可执行对象。然后,您可以使用设备的运行时环境(opencl 驱动程序)将SPIR 对象加载到设备。 您可以查看以下链接:

Using Clang to compile kernels

Llvm IR generation

SPIR

其他选择是使用您的目标平台提供的工具。每个声称支持 opencl 的供应商都应该有一个运行时环境。通常,他们有单独的 CLI 工具来编译 OpenCL 设备代码。在您的情况下(我猜)您有来自 Apple 的驱动程序,因此您有 openclc

Intel CLI as an example

现在是您的主要问题(编译 opencl 的最佳方法)。这取决于你想做什么。你没有具体说明你有什么样的要求,所以我不得不推测。

如果您想在没有宿主程序的情况下进行离线编译,上述注意事项将对您有所帮助。否则,您必须使用 OpenCL 库并为您的内核进行在线编译,这对于需要可移植性的产品通常是首选。因为如果您在程序开始时编译所有内核,您可以直接使用提供的环境,而无需为每个目标平台提供库。

因此,如果你有一个 OpenCL 项目,你必须决定如何编译。如果您真的想使用通用标志并且不依赖第三方工具。我建议你有一个类来构建你的内核并提供你想要的标志。

【讨论】:

感谢您的完整回答@Vermulo。您能否为我的其他问题提供提示:***.com/questions/43417757/…【参考方案2】:

...我们如何控制这些选项?它们是否必须在源代码中设置,或者像正常的编译流程一样我们可以在命令行中传递它们。

可以在源代码中设置选项。例如:

const char options[] = "-cl-finite-math-only -cl-no-signed-zeros"; /* 构建程序 */ err = clBuildProgram(program, 1, &device, options, NULL, NULL);

我从未见过在命令行中指定 opencl 选项,我不知道这是否可行。

【讨论】:

谢谢@Sergio。如果 OpenCL 提供了一些可以在编译时控制的环境,那就太好了,否则你应该每次都在源代码中修改 options[]

以上是关于编译 OpenCL 应用程序和使用可用编译器选项的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

是否所有与 OpenCL 优化相关的选项都默认为 false?

FPGA opencl编译aocx报错!

OpenCL 编译器之间的语法差异 [关闭]

用于编译大型 ASP .NET 应用程序的可用选项

OpenCL(英特尔平台)显示构建错误(-11),状态为 0

Metal并行计算以及Metal程序的命令行编译