Offline compilation of OpenCL kernel source code

Offline Compilation of OpenCL Kernel Sources

Offline compilation of OpenCL kernel source code

Aside from online compilation during application execution, OpenCL kernel sources can be compiled offline into binaries that can be loaded into the drivers using special API calls (e.g. clCreateProgramWithBinary or clCreateProgramWithIL).

In addition to online compilation during application execution, the OpenCL kernel source code can be compiled offline into binaries, which can be loaded into the driver using special API calls such as clCreateProgramWithBinary or clCreateProgramWithIL.

This section describes available open source tools for offline compilation of OpenCL kernels.

This section describes the available open source tools for offline compilation of OpenCL kernels.

Open Source Tools

Open source tools

  • clang is a compiler front-end for the C/C++ family of languages, including OpenCL C and C++ for OpenCL. It can produce executable binaries (e.g. AMDGPU), or portable binaries (e.g. SPIR). It is part of the LLVM compiler infrastructure project, and there is information regarding OpenCL kernel language support and standard headers.
  • clang is a compiler front-end for the C/C++ family of languages, including OpenCL C and C++ for OpenCL. It can generate executable binaries (such as AMDGPU) or portable binaries (such as SPIR). It is part of the LLVM Compiler Infrastructure project and has information about OpenCL kernel language support and standard headers.
  • SPIRV-LLVM Translator provides a library and the llvm-spirv tool for bidirectional translation between LLVM IR and SPIR-V.
  • The SPIRV-LLVM translator provides a library and LLVM-SPIRV tools for bidirectional translation between LLVM-IR and SPIR-V.
  • clspv compiler and clvk runtime layer enable OpenCL applications to be executed with Vulkan drivers.
  • The clspv compiler and clvk runtime layer enable OpenCL applications to execute using the Vulkan driver.
  • SPIR-V Tools provide a set of utilities to process SPIR-V binaries including spirv-opt optimizer, spirv-link linker, spirv-dis /spirv-as (dis-)assembler, and spirv-val validator.
  • SPIR-V tools provide a set of utilities for working with SPIR-V binaries, including the spirv-opt optimizer, spirv-link linker, spirv-dis/spirv-as (dis-) assembler, and spirv-val validator .

Compiling Kernels to SPIR-V

Compile the kernel to SPIR-V

The open source tools can be used to perform full compilation from OpenCL kernel sources into SPIR-V.

Open source tools are available to perform a complete compilation from the OpenCL kernel source code to SPIR-V.

Offline compilation flow for OpenCL kernels into SPIR-V

Offline compilation process from OpenCL kernel to SPIR-V

When tools are used to target OpenCL drivers they operate on OpenCL flavor of SPIR-V and when tools target Vulkan drivers they operate on Vulkan flavor of SPIR-V instead. Some tools can ingest both SPIR-V dialects. However, it is generally not possible to transform or mix the modules of different SPIR-V flavors. For example, it is generally not possible to use spirv-link to link the modules in both OpenCL and Vulkan formats of SPIR-V.

When tools are used against OpenCL drivers, they operate on the OpenCL flavor of SPIR-V, and when tools are used against Vulkan drivers they operate on the Vulkan flavor of SPIR-V. Some tools can use the SPIR-V dialect simultaneously. However, it is usually not possible to convert or mix modules of different SPIR-V flavors. For example, it is generally not possible to link SPIR-V’s OpenCL and Vulkan format modules using spirv linking.

Examples
Example

If you want to try the above compilation flow for yourself, after installing the tools, you can use the following commands.

If you want to try the above compilation process yourself, you can use the following command after installing the tool.

Compile for OpenCL runtime
Compile for OpenCL runtime

(i) Compiling OpenCL C/C++ for OpenCL file into SPIR flavor LLVM IR (for 32 bit targets) formats:

(i) Compile OpenCL C/C++ of OpenCL files to SPIR-style LLVM IR (for 32-bit targets) format:

clang -c -target spir -O0 -emit-llvm -o test.bc test.cl

Using -cl-std changes the language version compiled for.

Using -cl-std changes the compiled language version.

To compile C++ for OpenCL source pass -cl-std=CLC++ or use the file extension .clcpp.

To compile C++ for OpenCL source code, pass -cl std=CLC++ or use the file extension .clcpp.

clang -cl-std=CLC + + -c -target spir -O0 -emit-llvm -o test.bc test.cl
clang -c -target spir -O0 -emit-llvm -o test.bc test.clcpp

If debugging support is needed then the -g flag can be used in the clang invocation:

If debugging support is required, the -g flag can be used in the clang call:

clang -c test.cl -target spir -o test.bc -g

Note: In clang releases up to 12.0, calling most builtin functions requires the extra flags -Xclang -finclude-default-header to be passed to clang. Refer to the release documentation for more details.

Note: In clang versions up to 12.0, calling most built-in functions requires passing the extra flag -Xclang-finclude default header to clang. See the publishing documentation for more details.

(ii) Converting LLVM IR into SPIR-V.

(ii) Convert LLVM IR to SPIR-V.

llvm-spirv test.bc -o test.spv

Note: Converting IR produced with optimization levels other than -O0 is only available as an experimental feature and it is not guaranteed to work. In the majority of cases, the conversion is expected to succeed when optimizations are enabled. Developers are encouraged to file a bug report when issues are encountered. As a workaround when encountering an issue in translating modules obtained with optimizations, generate LLVM IR with optimizations disabled, and then use the stand-alone < strong>spirv-opt tool to optimize at the SPIR-V level.

Note: Converting IRs generated using optimization levels other than -O0 is only available as an experimental feature and is not guaranteed to work. In most cases, with optimization enabled, the conversion is expected to be successful. Developers are encouraged to submit bug reports when encountering problems. When problems are encountered in translating modules obtained through optimization, as a workaround, generate the LLVM IR with optimization disabled and then use the standalone spirv-opt tool to optimize at the SPIR-V level.

(iii) Linking multiple modules can be done on LLVM IR level by passing multiple .bc files to llvm-link.

(iii) Linking of multiple modules can be done at the LLVM IR level by passing multiple .bc files to LLVM linking.

llvm-link test1.bc test2.bc -o app.bc
llvm-spirv app.bc -o app.spv

Alternatively, spirv-link can be used to link SPIR-V modules of the same flavor either OpenCL or Vulkan:

Alternatively, the spirv link can be used to connect SPIR-V modules of the same flavor in OpenCL or Vulkan:

spirv-link -o app.spv test1.spv test2.spv

(iv) Once the SPIR-V binary is produced, it can be loaded in OpenCL applications using the clCreateProgramWithIL API call.

(iv) Once the SPIR-V binary is generated, it can be loaded into an OpenCL application using the clCreateProgramWithIL API call.

Compile for Vulkan runtime
Compile for Vulkan runtime

Compiling OpenCL sources directly to SPIR-V binary format:

Compile OpenCL source code directly into SPIR-V binary format:

clspv test.cl -o test.spv

The SPIR-V binary files can be further optimized or linked using spirv-opt and spirv-link respectively before loading into the Vulkan runtime using vkCreateShaderModule from Vulkan API or (if clvk is used) clCreateProgramWithIL from OpenCL API.

SPIR-V binaries can be further optimized or linked using spirv-opt and spirv-link respectively before loading into the Vulkan runtime using the Vulkan API’s vkCreateShaderModule or (if using clvk) the OpenCL API’s clCreateProgramWithIL.