# Testing OpenCL-based packages on Travis CI

**URL:** https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403
**Category:** GPU
**Tags:** testing
**Created:** [November 18, 2016, 7:00am UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403 "2016-11-18T07:00:46Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [November 18, 2016, 7:00am UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403/1 "2016-11-18T07:00:47Z")

</div>

My [ImageQuilting.jl](https://github.com/juliohm/ImageQuilting.jl) package has a big chunk of uncovered code because I am not sure what dependencies I should install on Travis CI before testing its GPU features. After a lot of effort refactoring and playing around with optional dependencies, I managed to have a working test suite on my local machine that includes extra tests whenever `OpenCL.jl` and `CLFFT.jl` are installed.

I am opening this thread to ask you for your help in designing a minimal `.travis.yml` that takes care of setting up the environment for `OpenCL.jl` and `CLFFT.jl`. Something along these lines:

```bash
language: julia

os:
  - linux
  - osx

before_install:
  - if [$TRAVIS_OS_NAME = "linux"]; then
      sudo apt-get -qq update
      sudo apt-get install pocl
      ... # what else?
    fi;
  - if [$TRAVIS_OS_NAME = "osx"]; then
      # Is POCL installed by default in OSX?
      # what else?
    fi;

script:
  - if [[-a .git/shallow]]; then git fetch --unshallow; fi
  - julia -e 'Pkg.add("OpenCL"); Pkg.add("CLFFT")'
  - julia --check-bounds=yes -e 'Pkg.clone(pwd()); Pkg.build("ImageQuilting"); Pkg.test("ImageQuilting"; coverage=true)'

after_sucess:
  - # etc

```

I tried to borrow code from `.travis.yml` files in those packages, but they install many other things that I am not sure are necessary for my test goals. Can we build a solution together for future reference?

---

<div class="post-metadata">

### Author: ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)
#### Post date: [November 18, 2016, 7:54am UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403/2 "2016-11-18T07:54:53Z")

</div>

On OSX you don’t need to install OpenCL since Apple is providing a implementation.

Now as you have experienced under Linux on Travis the situation is a bit more complicated… There are at least three OpenCL CPU implementations that we can use.

1. AMD [http://developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk/](http://developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk/)
2. Intel [Intel® SDK for OpenCL™ Applications](https://software.intel.com/en-us/intel-opencl)
3. POCL [http://portablecl.org/](http://portablecl.org/)

The first two are a pain to install on Travis and _POCL_ is good enough for testing purposes. All three implementations vary in small ways and for OpenCL.jl we have been seeing differences in correctness and locally I try to test against as many implementations as possible. The main question is what version of POCL is available on Travis, it needs to be fairly recent in order to work well with OpenCL.jl\*

If you want to use packages like _CLFFT.jl_ you will have to install their dependencies manually, or add _deps/build.jl_ scripts to them. The latter would be beneficial in general.

I don’t have a good general solution for this yet, but the steps we could pursue is:

1. Add a build script for necessary dependencies to all CL\* packages
2. Provide a script in OpenCL.jl that sets up a compatible version of POCL on Linux

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [November 18, 2016, 5:37pm UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403/3 "2016-11-18T17:37:15Z")

</div>

Thank you for the clear answer @vchuravy, I fully support the two steps you proposed.

What is a recent enough version of POCL? I can compare it to what Travis provides and then we can work together on writing the script.

In addition to the `OpenCL.jl` dependencies, can you confirm that `libfftw3-dev` is the only extra library required by `CLFFT.jl`?

---

<div class="post-metadata">

### Author: ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)
#### Post date: [November 19, 2016, 12:10am UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403/4 "2016-11-19T00:10:08Z")

</div>

> [@juliohm](#):
>
> In addition to the OpenCL.jl dependencies, can you confirm that libfftw3-dev is the only extra library required by CLFFT.jl?

CLFFT requires [GitHub - clMathLibraries/clFFT: a software library containing FFT functions written in OpenCL](https://github.com/clMathLibraries/clFFT) which is the C-library and I think libfftw3 is only needed if you want to test `clFFT` itself.

For pocl the minimal version is `0.10`, but `0.13` would be best.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [November 19, 2016, 1:52am UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403/5 "2016-11-19T01:52:44Z")

</div>

Oh, that is true, got confused with the names, fftw3 and clFFT are different things. Please let me know if you have plans to work on the deps/build.jl for OpenCL.jl, you are much more familiar with it than I am.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [December 4, 2016, 9:14pm UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403/6 "2016-12-04T21:14:32Z")

</div>

@vchuravy I am reading the `BinDeps` specification to try write a `build.jl` script for `OpenCL.jl`. How should we choose a specific driver implementation for the user when multiple implementations are available (e.g. beignet, intel, POCL)? Can we specify our preferences and let the user customize it at runtime if he needs a specific library?

I need some sort of skeleton to start adding build steps gradually:

```julia
using BinDeps

libopencl = library_dependency("libopencl", aliases=[""], os=...)

# there are multiple providers out there even for a single OS (e.g. Arch Linux)
provides(Pacman, "opencl-nvidia", libopencl)
# Beignet is available in AUR
# POCL is yet another choice

if is_apple()
# Do we need to do anything?
end

if is_windows()
# I am afraid of this one
end

```

---

<div class="post-metadata">

### Author: ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)
#### Post date: [December 5, 2016, 1:04am UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403/7 "2016-12-05T01:04:22Z")

</div>

The problem is that what opencl provider to use is depended on the hardware used. I think what we can reasonably do is to make sure that we pick up any existing installation of a hardware specific library and use that and if we don’t find any print a big warning and then install POCL.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [December 5, 2016, 2:33am UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403/8 "2016-12-05T02:33:29Z")

</div>

I understand @vchuravy, this is definitely part of the problem. Do you have a suggestion for a `build.jl` skeleton? I just need pseudocode like:

```julia
if NVIDIA
# dependencies = A, B, C
end

if AMD
# dependencies = D, E, F
end

if Intel
# dependencies = G, H, I
end

# find providers and fallback to POCL if none is found
provider(...)

```

We could actually prompt the user to select between different drivers when they are available for a specific OS and Graphics card. But we need to start somewhere simple…

---

<div class="post-metadata">

### Author: ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)
#### Post date: [December 5, 2016, 3:10am UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403/9 "2016-12-05T03:10:43Z")

</div>

If I remember BinDeps correctly, we should be able to do:

```julia
using BinDeps

libopencl = library_dependency("libopencl", aliases=[""], os=...)

# All these packages provide a version of OpenCL (and AFAIK this is a or)
provides(Pacman,["opencl-nvidia","beignet", "opencl-amd", "opencl-catalyst", "pocl"],[libopencl])
# Do this for apt-get and YUM
....
# Sources...
# add a Source build step that does cmake and make following http://portablecl.org/docs/html/install.html#configure-build
# A bonus would be to use the LLVM that comes with Julia

```

For apple we should need to do anything since they ship OpenCL and I wouldn’t bother with Windows for now (until somebody complains loudly).

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [December 5, 2016, 3:19am UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403/10 "2016-12-05T03:19:10Z")

</div>

@vchuravy what about always build POCL from source, use it as the default and let the user pick something else at runtime with a `OpenCL.jl` configurable variable like `OPENCL_DRIVER`?

---

<div class="post-metadata">

### Author: ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)
#### Post date: [December 5, 2016, 11:21am UTC](https://discourse.julialang.org/t/testing-opencl-based-packages-on-travis-ci/403/11 "2016-12-05T11:21:40Z")

</div>

That might work. Especially if we would do

1. Check if OpenCL is installed
2. If not install POCL
3. Print warning and notice
