OpenCL

Open Computing Language (OpenCL) is a framework for writing programs that execute across heterogeneous computing platforms (CPUs, GPUs, DSPs, FPGAs, ASICs, ...).

Overview
The point of this article is to deal with Gentoo implementation and quirks so the overview will be short. For a better overview of the theoretical aspects, see the OpenCL wikipedia article.

OpenCL presents itself as a library with a simple interface:
 * standardized API headers (eg. #include CL/cl.h) for C and C++
 * the OpenCL library (eg. libOpenCL.so)

The standard is made to provide many OpenCL platforms on one system, and each platform can see various devices. Each device has a certain compute characteristics (number of compute units, optimal vector size, memory limits, ...). The OpenCL standard allows to load OpenCL kernels which are pieces of C99-like code that is JIT-compiled by the OpenCL implementations (most of them rely on LLVM to work), and execute these kernels on the target hardware. Functions are provided to compile the kernels, load them, transfer data back and forth from the target devices, etc.

Hardware vendors can benefit from this standard by implementing the OpenCL primitives for their hardware.

Installing an OpenCL implementation means adding a library implementing the OpenCL API, and a reference to the library path in the ICD (Installable Client Driver) database, as a file in /etc/OpenCL/vendors.

There is an ICD loader which can be provided by a generic loader or one of the implementations. For most uses of OpenCL one of these must be selected using eselect opencl.

The OpenCL host and device API calls, the memory hierarchy are standard, but it doesn't mean that code which is portable to different implementations will be efficient on all of them. Often, code has to be tested on one implementation to eliminate issues. See the implementation validation and implementation tuning sections..

Implementations on Linux
Here are upstream projects that provide an implementation of OpenCL.


 * pocl is an OpenSource, LLVM-based OpenCL implementation for the CPU which is not necessarily the fastest, but is educational
 * mesa has a WIP implementation which works on some GPU
 * AMD provides its AMD APP SDK which contains an OpenCL library
 * nVidia provides its CUDA toolkit which contains an OpenCL library
 * Intel, on Linux, has an implementation for CPU devices, and another for GPU devices ("Beignet")

The implementations will be developed in further subsections.

ICD
The package provides a layer of indirection to enable different OpenCL implementations, and also provides the OpenCL.pc pkg-config descriptor.

pocl
As of 2015-03-15:


 * the package is available in portage.

Mesa (clover)
As of 2016, installing with the opencl USE flag will get you an OpenCL 1.1 installation that works on almost all AMD GPUs. For a full least of features see the GalliumCompute Matrix.

Intel - CPU
The Intel CPU SDK is provided by the which is in portage.

As of 2014-09-15:


 * Use version 2.* if the 4.* dies on you.

Intel - GPU
The GPU implementation from Intel is Beignet. Beignet supports Ivy Bridge and later processors.

The package is available in portage.

Linux kernels 3.15 and 3.16 may require the following workaround:

AMD
The driver is provided by the package, which is maintained in the Science overlay.

nVidia
The driver is provided by the package which is in portage.

Implementation Validation
An implementation (especially the experimental ones) can be checked by running test suites such as:


 * piglit: Open Source OpenGL/OpenCL test suite. Check GalliumCompute for simple piglit tests

Implementation Tuning
The main vendors will provide some form of advanced documentation to use their hardware to the maximum:


 * nVidia: For developers targetting nVidia hardware, nVidia provides a Best Practices Guide.
 * AMD: For developers targetting AMD hardware, AMD provides an Optimization Guide.
 * Beignet: For developers targetting the opensource OpenCL implementation for Intel GPU hardware, the Beignet projects provide a brief optimization guide

Some characteristics are not straightforward to find, and benchmarks are one way to find out.

TODO detail

LLVM DLL Hell
LLVM is starting to become a central library, and it is used by most of the implementations. If the user/implementer is not careful, linkage issues can occur (symbol collisions, constructors getting called multiple times and not handled, etc.). This is something that can be noticed with many implementations also.

TODO example