With an increasing number of OpenCL run-times supporting ingestion of SPIR-V, OpenCL developers may wish to use offline compilation to precompile SPIR-V kernels that can be used portably across multiple OpenCL implementations. Consistently using the same front-end compiler can enhance cross-vendor deployment consistency, while reducing overall compile times and eliminating the need to ship OpenCL C source code. Kernel development may also be more streamlined as compiler error messages don't have to be queried using OpenCL API calls.
A number of open source tools have been developed in recent years that can be used together to compile OpenCL C or C++ for OpenCL kernels into SPIR-V - for example as shown below. An extensive of OpenCL tools and compiler is available in the OpenCL Resource Guide.
Using open source tools for offline compilation of OpenCL kernels into SPIR-V
If you want to try the above flow for yourself, after installing the tools, the set of commands you would use are:
(i) Compiling OpenCL C/C++ for OpenCL file into intermediate LLVM IR formats:
clang -c -target spir -O0 -emit-llvm -o test.bc test.cl (for 32-bit targets)
clang -c -target spir64 -O0 -emit-llvm -o test.bc test.cl (for 64-bit targets)
- to compile C++ for OpenCL source the following flag
-cl-std=clc++needs to be added in the command line of clang invocation.
- In clang releases prior to 13.0, calling most built-in functions requires an extra flag to be passed to clang
-Xclang -finclude-default-header. Refer to the release documentation for more details.
(ii) Converting LLVM IR into SPIR-V.
llvm-spirv test.bc -o test.spv
Note that converting optimized IR is currently unsupported.
(iii) There are several options for optimizing the kernels through this flow. LLVM IR optimization can be undertaken on LLVM IR by reverse-converting from SPIR-V using spirv-llvm, however, the conversion of optimized IR into SPIR-V may sometimes have issues. Alternatively, llvm-opt can be used to optimize SPIR-V modules.
(iv) Linking can be done on LLVM IR level by passing multiple bc files to llvm-link.
llvm-link test1.bc test2.bc -o app.bc
llvm-spirv app.bc -o app.spv
Alternatively, spirv-link can be used:
spirv-link -o app.spv test1.spv test2.spv
(v) Debugging support can be obtained regularly by passing -g to Clang:
clang -c test.cl -target spir -o test.bc -g
(vi) Once the SPIR-V binary is produced, it can be loaded in OpenCL applications using the clCreateProgramWithIL API call.