【发布时间】:2018-06-20 08:26:29
【问题描述】:
这个问题与 LLVM/clang 有关。
我已经知道如何使用 OpenCL API( clBuildProgram() 和 clGetProgramBuildInfo() )编译 opencl-kernel-file(.cl)
我的问题是:
如何使用 OpenCL 1.2 或更高版本将 opencl-kernel-file(.cl) 编译为 LLVM IR?
换句话说,如何在没有 libclc 的情况下将 opnecl-kernel-file(.cl) 编译为 LLVM IR?
我尝试了各种方法来获取 OpenCL-Kernel-File 的 LLVM-IR。
我首先按照 clang 用户手册进行操作。(https://clang.llvm.org/docs/UsersManual.html#opencl-features) 但它没有运行。
其次,我找到了一种使用 libclc 的方法。
命令是这样的:
clang++ -emit-llvm -c -target -nvptx64-nvidial-nvcl -Dcl_clang_storage_class_specifiers -include /usr/local/include/clc/clc.h -fpack-struct=64 -o "$@".bc "$@" <br>
llvm-link "$@".bc /usr/local/lib/clc/nvptx64--nvidiacl.bc -o "$@".linked.bc <br>
llc -mcpu=sm_52 -march=nvptx64 "$@".linked.bc -o "$@".nvptx.s<br>
此方法运行良好,但由于 libclc 是在 OpenCL 1.1 规范之上构建的,因此它不能用于 OpenCL 1.2 或更高版本的代码,例如使用 printf 的代码。
而且这个方法使用了libclc,它以新函数的形式实现了OpenCL的内置函数。您可以观察到,在结果 opencl 二进制文件的程序集(ptx)中,它直接进入函数调用,而不是将其转换为内联程序集。我担心这会影响 gpu 的行为和性能,例如执行时间。
所以现在我正在寻找一种使用 libclc 替换编译的方法。
作为最后的手段,我正在考虑将 libclc 与 NVPTX 后端和 LLVM 的 AMDGPU 后端一起使用。
但如果已经有其他方法,我想使用它。
(我希望我还没有找到的 OpenCL 前端在 clang 中存在)
我的程序的场景是:
- 有opencl内核源文件(.cl)
- 将文件编译为 LLVM IR
- IR 级流程到 IR
- 编译(使用 llc)IR 到二进制
- 每个 gpu 目标(nvptx, amdgcn..)
- 使用二进制文件,使用 clCreateProgramWithBinary() 运行主机(.c 或带有 lib OpenCL 的 .cpp)
现在,当我将内核源文件编译为 LLVM IR 时,我必须包含 libclc 的标头(上述命令的第一个中的 -include 选项)以编译内置函数。而且我必须在将 IR 编译为二进制文件之前链接 libclc 库
我的环境如下:
- GTX960
- NVIDIA 的二进制文件以 nvptx 格式显示
- 我正在为我的 gpu 使用 sm_52 nvptx。
- Ubuntu Linux 16.04 LTS
- LLVM/Clang 5.0.0
- 如果有其他方法,我愿意更改 LLVM 版本。
感谢您的建议!
【问题讨论】:
-
所以基本上你对 libclc 的唯一问题是对内置函数的调用指令没有内联,对吧?
-
是的。那是我的第一个。另外,我想编译OpenCL 1.2或更高版本的内置函数。
标签: opencl llvm llvm-clang llvm-ir