我的理解是SPIR二进制文件应该是LLVM bitcode,而SPIR IR是LLVM IR的子集。此外,SPIR与设备无关。我尝试使用llvm-dis命令对我从clGetProgramInfo获取的二进制文件使用CL_PROGRAM_BINARIES作为参数,但它告诉我“无效的bitcode签名”。 llvm-bcanalyzer返回“顶层无效记录”。
我可以采用相反的方式使用Clang将我的OpenCL内核转换为LLVM IR或LLVM bitcode。但是,bitcode文件大小约小10倍,所以我很确定它与我的SPIR二进制文件不一样。
为了完成,我的GPU确实有 cl_khr_spir 扩展名。
答案 0 :(得分:2)
你是正确的,SPIR 1.2 是LLVM IR的一个子集(特别是LLVM 3.2)。请注意,最新版本的SPIR(称为SPIR-V)是不派生自LLVM IR,并且是一个独立的,从头开始的中间表示。
使用llvm-dis
是反汇编基于LLVM的SPIR二进制文件的正确方法。由于SPIR 1.2源自LLVM 3.2,因此只能保证适用于llvm-dis
的LLVM 3.2版本。在实践中,我发现这对于较新版本的LLVM仍然可以正常工作,但并不能保证这种情况始终如此。
虽然您的设备支持cl_khr_spir
扩展名,但当您从CL_PROGRAM_BINARIES
查询clGetProgramInfo
时,不需要它实际返回SPIR二进制文件。许多平台将返回本机二进制文件(例如x86或本机GPU ISA)或其他一些中间表示(这可能是LLVM无法将您的二进制文件识别为基于LLVM的原因)。没有通过OpenCL运行时API检索SPIR二进制文件的标准化机制。
使用clang
将OpenCL C内核编译为LLVM IR / SPIR 1.2是获取LLVM bitcode文件的最佳方式,然后可以使用llvm-dis
对其进行反汇编。一些供应商(例如英特尔)也使用其OpenCL SDK提供离线编译器,这些SDK提供专用命令/工具来执行此操作。