At the beginning, we'll require the namespaces that contain functions for GPU programming. Functions that work with OpenCL are in the uncomplicate.clojurecl.core namespace of the ClojureCL library.

( require ' [ uncomplicate.clojurecl.core :refer :all ] ' [ uncomplicate.clojurecl.info :refer :all ] )

nil

Although most concepts of OpenCL are similar to what we've seen with CUDA, the environment setup is a bit more detailed. That's because OpenCL does not support only GPU's, and only from one vendor, but multiple hardware devices from multiple vendors. It has to offer a choice of drivers and supported versions, at the same time.

The entry point is the concept of platform. The platforms function returns a sequence of platforms available on the system:

( map name-info ( platforms ) )

AMD Accelerated Parallel Processing

My machine reports one platform: AMD.

( def amd-platform ( first ( platforms ) ) )

#'user/amd-platform

Different platforms support different versions of OpenCL standard, and some additional vendor-specific extensions. Each platform can be used to access the appropriate hardware. What devices do I have on AMD's platform?

( map name-info ( devices amd-platform ) )

Hawaii Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz

Now I know that there is one Hawaii GPU's (R9 290X) and one CPU that can be accessed through AMD's platform. Let's grab the handle of the first device:

( def my-amd-gpu ( first ( devices amd-platform ) ) )

What is the type of this object and how does it look like?

my-amd-gpu

#object[uncomplicate.clojurecl.internal.impl.CLDevice 0x3f393c1e "#CLDevice[0x7f34a472bfb0]"]

Having the handle of the device, we can proceed in a fashion similar to the Hello CUDA tutorial.