It used to be that portable OpenCL applications required shipping source code for the parallel kernels with the application. In this way, the kernel source code could be compiled for any device at any time in the future. Bad news from an IP protection point of view! The alternative was to pre-compile the kernels thus bloating applications and limiting the devices the OpenCL application could use. The Standard Portable Intermediate Representation (SPIR) is a portable encoding of the kernels in LLVM IR. Simplistically, LLVM is like a portable, generic intermediate (or assembly language). It can generate relocatable machine code at compile-time or link-time or even binary machine code at run-time. The SPIR™ 2.0 provisional specification that provides a non-source encoding, and binary level portability, for OpenCL™ 2.0 device programs. (Note that Intel has confirmed that Broadwell’s GPU will offer support for OpenCL 2.0, including shared virtual memory.)
OpenCL 2.0 is a wonderful extension to the earlier specification that lets host and device kernels directly share complex, pointer-containing data structures such as trees and linked lists, providing significant programming flexibility and eliminating costly data transfers between host and devices.
SPIR 2.0 includes new functionality to fully support new features released in OpenCL C 2.0, including:
- Generic address space – where functions can be written without specifying a named address space for arguments, especially useful for those arguments that are declared to be a pointer to a type, eliminating the need for multiple functions to be written for each named address space used in an application;
- Device side kernel enqueue – where device kernels can enqueue kernels to the same device with no host interaction, enabling flexible work scheduling paradigms and avoiding the need to transfer execution control and data between the device and host, often significantly offloading host processor bottlenecks;
- C++11 atomics – a subset of C11 atomics and synchronization operations to enable assignments in one work-item to be visible to other work-items in a work-group, across work-groups executing on a device or for sharing data between the OpenCL device and host;
- Pipes – memory objects that store data organized as a FIFO. OpenCL 2.0 provides built-in functions for kernels to read from or write to a pipe, providing straightforward programming of pipe data structures that can be highly optimized by OpenCL implementers.
Following is from the SPIR 2.0 FAQ:
Enable third-party code generation targeting OpenCL platforms without going through OpenCL C:
For example, a compiler for an alternative device language (not OpenCL C) can generate SPIR and have it run on any OpenCL backend that supports the cl_khr_spir extension. There is no need to generate OpenCL C as an intermediate. The alternative language could be many things, such as an established language (like FORTRAN), an exotic domain specific language, or a single source programming environment with automatic code partitioning. However, the language semantics must be mappable to SPIR and satisfy the constraints of OpenCL target systems.
A developer can ship an OpenCL application without exposing their device program source at any point in the flow.
The standard OpenCL compilation model provides device program source text to the clCreateProgramWithSource API.
Shipping a SPIR IR instance in bitcode format gives them legal protections they would otherwise not have. (This is not cryptographically strong protection, but instead it is similar to DMCA style protection whereby obfuscation is enough to prove intent if IP reverse engineering is discovered.)
The alternative is to ship device-specific (and sometimes driver-specific) binaries. This can imply a combinatorial explosion in the number of device binaries an application developer would have to prepare and ship.
Compatibility across vendors, and forward compatibility to newer devices:
An application that uses a valid SPIR IR instance should be runnable on any OpenCL platform supporting the cl_khr_spir extension and the matching SPIR version. (A single platform/device combination could support more than one version of SPIR IR; see the CL_DEVICE_SPIR_VERSIONS device query.) The SPIR IR instance could have been generated by any tool, provided it is valid SPIR IR.
For more information: