<p>Under Windows and Mac the Intel GPU drivers include OpenCL support; however, on
Linux OpenCL on Intel GPUs is implemented through an open source project called 
<a href="http://www.freedesktop.org/wiki/Software/Beignet/">Beignet</a> 
(pronnounced like "ben yay", a type of French pastry akin to a what we would 
call a "fritter" in English). Below I have written a step-by-step guide
on how you can get Beignet running on an Ubuntu 14.10 system which has an
Intel 3rd, 4th, or fifth generation Intel processor.</p>

<p>There are several little caveats which need to be discussed up front. Foremost
the Beignet project supports the following hardware:</p>

<ul>
<li>3rd Generation Intel Core Processors</li>
<li>Intel “Bay Trail” platforms with Intel HD Graphics</li>
<li>4th Generation Intel Core Processors (requires a kernel patch be applied for shared memory!)</li>
<li>5th Generation Intel Core Processors "Broadwell".</li>
</ul>

<p>There are also a few noteworthy issues of which you should be aware:</p>

<ul>
<li><p>If your computer is running a Linux kernel in the 3.15 or 3.16 branch, you 
will need to disable some register whitelist functionality every time you 
reboot your system. This can be accomplished by running 
<code>echo 0 &gt; /sys/module/i915/parameters/enable_cmd_parser</code> as root.</p></li>
<li><p>4th Generation Intel Processors (i.e. i3/5/7-4xxx) require a kernel patch
for shared/local memory to function.</p></li>
<li><p>There is no double precision support</p></li>
<li><p>OpenGL-OpenCL interop via <code>cl_khr_gl_sharing</code> is hopelessly broken.</p></li>
</ul>

<p>There are additional release notes that can be found on the 
<a href="http://www.freedesktop.org/wiki/Software/Beignet/">Beignet</a> project page.</p>

<h2>Installing prerequisites</h2>

<pre><code>sudo apt-get install build-essential g++ cmake 
sudo apt-get install clang libclang-3.5-dev libclang-dev libclang1
</code></pre>

<p>Note, if you are on a Ubuntu 14.04 system, you should install <code>libclang-3.4-dev</code>
instead then run <code>update-alternatives</code> to point <code>llvm-link</code> and <code>llvm-as</code> to
the correct version. The latter can be accomplished using the following commands:</p>

<pre><code>sudo update-alternatives --install /usr/bin/llvm-link llvm-link /usr/bin/llvm-link-3.4 34
sudo update-alternatives --install /usr/bin/llvm-as llvm-as /usr/bin/llvm-as-3.4 34
</code></pre>

<p>If you want to use the standard OpenCL ICD loader, you will also need to
install these packages:</p>

<pre><code>sudo apt-get install opencl-headers ocl-icd-dev ocl-icd-libopencl1
</code></pre>

<p>I would also recomment you install the <code>clinfo</code> program so that you can verify
that your installation is successful:</p>

<pre><code>sudo apt-get install clinfo
</code></pre>

<h2>Round 1: checkout and compile Beignet</h2>

<pre><code>git clone git://anongit.freedesktop.org/beignet
cd beignet
git checkout Release_v1.0.0
mkdir build
cd build
cmake ..
</code></pre>

<p>During the CMake stage, ensure the following items are found otherwise the
library will not compile with the required components:</p>

<ul>
<li>OCL ICD header file</li>
</ul>

<p>If everything went fine, go ahead and compile the source and install the library</p>

<pre><code>make
</code></pre>

<p>(Note, you can do make -jN with N > 1 to do a parallel build.)<br />
Next we verify that Beignet is functioning correctly on your hardware by running
unit tests. These can be found in the <code>utest</code> folder. The unit tests require
some enviornmental variables be set prior to invocation:</p>

<pre><code>cd utests
cat setenv.sh
[copy all of the export commands, run them in your shell]
./utest_run
</code></pre>

<p>If a significant fraction of the unit tests fail and you have a 3.15 or 3.16
kernel, you need to disable register whitelisting using a command similar to the
following:</p>

<pre><code>sudo su
echo 0 &gt; /sys/module/i915/parameters/enable_cmd_parser
exit
</code></pre>

<p>and try re-running the tests. Please note that you will <em>always</em> need to run
this command after you reboot your system. The Beignet release notes mention
there is a kernel patch to fix this issue.</p>

<p>If most of the tests pass, but those that involve local memory (~20-30 of
the tests) fail, you will need to apply the <a href="#kernel-patch">kernel patch</a>
listed below.</p>

<p>If all was well, install Beignet to your system:</p>

<pre><code>sudo make install
</code></pre>

<p>You can see a list of installed software in the <code>install_manifest.txt</code> file
in the build directory.</p>

<h2>Verify <code>Beignet</code> is installed</h2>

<p>In a terminal run the <code>clinfo</code> program. You should see something like this:</p>

<pre><code>$ clinfo
...      
Platform Name:              Intel Gen OCL Driver
Number of devices:          1
Device Type:                CL_DEVICE_TYPE_GPU
...
Name:                       Intel(R) HD Graphics Haswell GT2 Desktop
Vendor:                     Intel
Device OpenCL C version:    OpenCL C 1.2 beignet 0.9.1
Driver version:             0.9.1
Profile:                    FULL_PROFILE
Version:                    OpenCL 1.2 beignet 0.9.1
Extensions:                 cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store cl_khr_icd
</code></pre>

<p>Take note that the Intel OpenCL driver is loaded for a GPU device using
<code>beignet</code>. This indicates the Installable Client Driver (ICD) is correctly
installed. Also note the extensions listed.</p>

<h2>Applying the kernel patch to enable OpenCL shared local memory.</h2>

<p>If you are using Beignet on a 4th generation Intel processor, you will need
to apply a kernel patch to enable shared/local memory. This is a fairly lengthy
process that will require at least 70 GB of hard disk space and perhaps an
hour of compilation time if the build is executed in parallel.</p>

<p>In the next few paragraphs I'll walk you through how you can apply the kernel
patch. I have based my instructions on the 
[kernel compliation instructions for Ubuntu] (https://help.ubuntu.com/community/Kernel/Compile). 
Instructions for different OSes will be significantly different</p>

<p>Install prerequisites:</p>

<pre><code>sudo apt-get build-dep linux-image-`uname -r`
</code></pre>

<p>Make a working directory for the kernel somewhere and download the source</p>

<pre><code>mkdir kernel
cd kernel
apt-get source linux-image-`uname -r`
</code></pre>

<p>Next we see if we can automatically apply the patch. First download the
patch:</p>

<pre><code>wget https://01.org/sites/default/files/disable-batchbuffer-security.patch
</code></pre>

<p>Now <code>cd</code> into the kernel directory:</p>

<pre><code>cd linux-3.13.0
</code></pre>

<p>Check some details about the patch</p>

<pre><code>git apply --stat ../disable-batchbuffer-security.patch
</code></pre>

<p>Try automatically applying the patch:</p>

<pre><code>git apply --check ../disable-batchbuffer-security.patch
</code></pre>

<p>If it automatically applies with no errors, just apply it:</p>

<pre><code>git apply ../disable-batchbuffer-security.patch
</code></pre>

<p>If it did not work (as was the case on my system), the change is fairly
simple. Open the <code>drivers/gpu/drm/i915/i915_gem_execbuffer.c</code> file in an
editor:</p>

<pre><code>gedit drivers/gpu/drm/i915/i915_gem_execbuffer.c
</code></pre>

<p>In the <code>i915_gem_do_execbuffer</code> function, find the following code:</p>

<pre><code>flags = 0;
if (args-&gt;flags &amp; I915_EXEC_SECURE) {
    if (!file-&gt;is_master || !capable(CAP_SYS_ADMIN))
        return -EPERM;
</code></pre>

<p>And add the line <code>flags |= I915_DISPATCH_SECURE;</code> as follows:</p>

<pre><code>flags = 0;
flags |= I915_DISPATCH_SECURE;
if (args-&gt;flags &amp; I915_EXEC_SECURE) {
    if (!file-&gt;is_master || !capable(CAP_SYS_ADMIN))
        return -EPERM;
</code></pre>

<p>This was inserted on line 998 for me. Save the file. Now we need to compile and
install the modified kernel.</p>

<p>Now we build the new kernel. Run the following commands from within the kernel
source directory:</p>

<pre><code>fakeroot debian/rules clean
DEB_BUILD_OPTIONS=parallel=8 fakeroot debian/rules binary-headers binary-generic
</code></pre>

<p>This will build some Debian packages and place them in the directory <em>above</em>
the kernel source root.</p>

<p>After the kernel has compiled, install it:</p>

<pre><code>cd ../ (or go back into the kernel directory)
sudo dpkg -i linux-headers-3.16.0-29-generic_3.16.0-29.54_amd64.deb 
sudo dpkg -i linux-image-3.16.0-29-generic_3.16.0-29.54_amd64.deb
</code></pre>

<p>(you might have to change the numeric kernel version to match what you compiled)
Now add the kernel to the boot options:</p>

<pre><code>sudo update-grub
sudo reboot
</code></pre>

<p>Now go back and re-run the Beignet unit test framework from above. With any
luck everything will work fine.</p>
