The Standard Portable Intermediate Representation (SPIR) is a portable encoding of device programs. SPIR 1.2 is an encoding of OpenCL C device programs in LLVM IR.
SPIR 1.2 defines how any OpenCL C (version 1.2) device program can be encoded in LLVM (version 3.2).
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.
IP protection:
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.
The reference SPIR flow is as follows:
At development time:
At runtime:
The development time activities in the above flow are called SPIR Generation, and the runtime activities are called SPIR consumption.
Khronos standardizes (provides specifications and conformance tests for) two things:
Khronos does not define the process for translating a program from any source language into SPIR.
Generation:
Processing:
Consumption:
Khronos specifications themselves are copyrighted by The Khronos Group Inc., and are restrictively licensed. (See the specification document preamble for details.)
You may use or implement the functionality in the SPIR IR or OpenCL specifications, free of charge.
To claim conformance to the specifications, you must follow the process defined in the Khronos Adopters program.
As always, check the full legal terms and conditions for any Khronos specification, Adopters Agreement, or any software or hardware implementations you plan to use.
Use the patched Clang 3.2 from the Khronos Github account to translate valid OpenCL C (version 1.2) into SPIR 1.2.
Khronos group members are contributing all patches to Clang trunk. As of January 2014, most of the support is already included in Clang trunk, but there are some pieces missing.
See previous answer. The only holdup is review of the remaining patches.
Ask on the Clang developer email list.
Yes. It's very likely (but not required) that you will want to base your work on a recent version of LLVM and perhaps Clang.
Use the Verifier module. It is an LLVM pass that checks validity with respect to the SPIR IR specification.
As of January 2014, it is known to be incomplete. The intent is to continue to improve it.
Optimization or transformation of an LLVM module that is also a valid SPIR IR instance is beyond the scope of any Khronos specfication.
However, it is the responsibility of the transformation to (a) preserve program semantics according to LLVM rules, (b) preserve OpenCL semantics as expressed in SPIR IR, and (c) result in valid SPIR IR; if these are also goals of the transform.
A conformant OpenCL implementation that supports standard extension cl_khr_spir can load and run a SPIR IR instance. See the OpenCL extension specification for version 1.2, 2.0 or later for details on the runtime APIs for doing so.
In particular, an OpenCL platform would list cl_khr_spir in its response to the CL_PLATFORM_EXTENSIONS query. Also, the CL_DEVICE_SPIR_VERSIONS lists which versions of SPIR IR are supported by a particular device, e.g. 1.2 2.0.
It is up to vendors to describe what extensions their OpenCL implementations support. Khronos does not maintain a list. (Yet...?)
Khronos does not control what you do with a SPIR instance.
However, the Khronos Adopters Program defines the conformance process and criteria for SPIR consumption (the cl_khr_spir extension to OpenCL).
SPIR 1.2 supports all features of OpenCL 1.2 device programs.
Secondarily, OpenCL 1.2 is the first version of OpenCL to define the cl_khr_spir runtime API to load SPIR instances.
The following projects are known to use SPIR:
Project | Description | Project owner |
---|---|---|
Clang 3.2 patched | OpenCL C 1.2 to SPIR compiler | Khronos Group Inc |
SPIR Tools | SPIR module verifier, etc. | Khronos Group Inc |
PGI OpenACC | OpenACC to SPIR compiler | Portland Group Inc |
C++AMP compiler | Multicoreware Inc |
The OpenCL cl_khr_spir runtime API extension assumes you can deliver a binary SPIR IR instance to the clCreateProgramWithBinary API.
The target environment may impose additional requirements before such an application can execute. For example, a target environment may require application pre-verification and cryptographically strong application signing. See the definition of Deployment Ecosystem in the Glossary below.
For OpenCL targets, the conformance process ensures that SPIR 1.2 instances can be loaded and executed by an OpenCL platform which supports the cl_khr_spir extension and which includes "1.2" in its reply to the CL_DEVICE_SPIR_VERSIONS device query. (The target platform might not even include any part of LLVM in its tool flow, let alone a specific version.)
The broader question is whether an LLVM 3.2 IR bitcode can be loaded and processed by an LLVM toolchain that is much newer than LLVM 3.2. For example, LLVM 3.4 encodes function attributes differently than LLVM 3.2 does. Khronos members (such as Intel) are contributing tests and fixes to the LLVM trunk to attempt to preserve the ability for newer LLVM versions to load LLVM 3.2 bitcodes. This is an ongoing process, and at some point the LLVM community may decide to break backward compatibility in a fundamental and hard-to-fix way.