A Tutorial for using OpenCL in ImageJ

Revision as of 06:34, 16 August 2017 by Rueden (talk | contribs) (Migrated from: http://developer.imagej.net/opencl)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This tutorial is meant to help you leverage OpenCL from Java for use with ImageJ.


To use OpenCL from Java in ImageJ we rely on JOCL. JOCL is written on top of a low level JNI API to make using OpenCL a bit easier. The OpenCL code you write can also leverage JOCL to accelerate execution of ImageJ plugins from Java. We have created an OpenCL deconvolution example to demonstrate compute acceleration using OpenCL (both locally and remotely as a binary web service).

Setting up the Development Machine

We set up an Ubuntu based development machine for OpenCL development and testing. OSX 10.6, Windows 64/32, and Linux 64/32 pass the tests and are supported by this package. Here are the steps for setting up Ubuntu:

  • Obtain an ISO for Ubuntu 10.04
  • Install Ubuntu on the target machine.
  • Install g++ with: 
    sudo apt-get install g++
  • Install needed development libs with:
    sudo apt-get install freeglut3-dev
    sudo apt-get install libxi-dev
    sudo apt-get install libxmu-dev

Setting up OpenCL

You will need to install OpenCL for your OpenCL enabled hardware if it does not come installed as part of the OS.

Setting up OpenCL for ATI

If you have ATI GPU hardware, check out these instructions.

Setting up OpenCL for NVidia

For NVidia hardware, install development drivers, CUDA Toolkit, and GPU Computing SDK code samples by following these installation instructions.

Use the wget tool for downloading the three needed install files from NVidia's download site.

wget http://developer.download.nvidia.com/compute/cuda/\
wget http://developer.download.nvidia.com/compute/cuda/\
wget http://developer.download.nvidia.com/compute/cuda/\

Stop the graphical desktop manager by typing:

sudo gdm stop

from the command line.

Install the required files:

sudo sh devdriver_3.2_linux_64_260.19.26.run
sudo sh cudatoolkit_3.2.16_linux_64_ubuntu10.04.run
sh gpucomputingsdk_3.2.16_linux.run

Per the installation instructions, we setup the environment variables (in .bashrc):

export LD_LIBRARY_PATH="/usr/local/cuda/lib:/usr/local/cuda/lib64"
export PATH="/usr/local/cuda/bin"

Test the installation by compiling and running a few of the NVidia provided OpenCL samples by changing directories to:


and running:


We ran into an error and ended up editing the file


by replacing line 169 with:

NVCCFLAGS  += --compiler-options -fpermissive

and re-running:


Change directories to


and run


to check the binary CUDA install.

Build the OpenCL examples by changing directories to


and running:


Change directories to


to run the OpenCL Bandwidth sample using:


Setting up Eclipse and needed plugins on Ubuntu

To configure the development environment, we started by installing the JRE with:

sudo apt-get install openjdk-6-jdk

and downloading Eclipse for J2EE Developers from:


and following the Eclipse installation steps.

We added the SVN plugin to Eclipse by clicking on Help-> Install New Software and adding the SVN adapter site:


Downloading and running the ImageJ OpenCL examples

The ImageJ OpenCL examples can be imported as an Eclipse project by right clicking in the Package Explorer window and choose Import. Select Git project and add the site:


Import the branch and assign a general project name like imagej-opencl.

The folder structure of the source consists of the following:

  • src - Java and OpenCL source files (extension .cl) Notice the files fht.cl and sobel.cl in the src directory. When executed, the Java code in provided in the examples compile these the OpenCL for execution. Note: Runtime compilation of the OpenCL source files allows execution on any potential OpenCL enabled device.
  • sourcedata - (Point Spread Function) PSF and 3D data used as a small sample data set for the FHT3D Example.
  • lib - libraries needed for classes using JOCL, ImageJ, and Hessian 4.0.7

We have included the necessary JOCL native libraries for Windows 32/64, Apple, and Linux 32/64 platforms inside this directory. To use OpenCL from Java in ImageJ we leverage JOCL. JOCL uses JNI to make calls into the OpenCL API. The OpenCL code you write can also leverage JOCL to accelerate execution of ImageJ plugins from Java. Since each OS has different native JOCL native libraries, the runtime environment must be configured such that the Java code can load the needed native libraries.

Understanding platform-specific JOCL native libraries

For these samples, three native libraries are needed: gluegen-rt, jocl, and JOCL-'platform'-'arch'. If you look in the lib folder, you will find -natives-xyz.jar files containing the respective libraries. You need to unzip each of the three jar files and copy the dynamic files (.so, .dylib, or .dll) into the parent directory if they are not already present. Notice the below example where the libgluegen-rt.dylib, libJOCL-apple-x86_64.dylib, and libjocl.dylib files are in the platform specific directory.


Then ensure that the platform specific jar is exported during the project build. For example notice that the JOCL-0-1.4-beta1.jar file is referenced in the project. (To see this menu right click the project and choose Properties -> Java Build Path -> Libraries.)


Finally, ensure that the platform specific files are exported:


Start exploring the examples by viewing the developer comments in the file src/publication/SobelFilterExample.java. Notice the Main() method calls run() which use an awt.Image type as an input parameter. Modify and run the Main() method as a Java application and adjust the VM Arguments (E.g. -Xmx1024m) if needed.

SobelFilter example

Without modification, SobelFilterExample.java loads an image from a web server, process it locally using OpenCL, and displays the results. There is nothing novel about this example. It simply allows runtime testing of several system configuration steps to ensure working configuration of JOCL and OpenCL native libraries. Modify this example to suite your needs, but please ensure proper JOCL and OpenCL configuration before proceeding.

Understanding ImageJ + OpenCL

Working within ImageJ: If developing an ImageJ plugin using OpenCL realize that programmatic control is passed to your plugin inside the PlugIn (or PluginFilter) run() method. An example of this can be found in src.demos.OpenCL_SobelFilter.java. For this plugin to run within ImageJ, the JOCL jars and native libraries respective to the target platform will need to be available by the ImageJ classloader. The supporting JOCL native libraries can be copied into the plug-in directory within ImageJ to allow plugin implementations using OpenCL to reference the native libraries provided by the OpenCL installation.

ImageJ OpenCL: An incremental approach to applying OpenCL

Now that you have demonstrated use of OpenCL from Java and within ImageJ, you may wish to see a compute intensive example demonstrating modification of an existing Java implementation that delegates a portion of its implementation to OpenCL. Take a look at the developer comments in the FHT3D_3D_Deconvolution.java example to see what steps are used for brokering data between Java and OpenCL between steps within an algorithm's implementation.

The approach used to start delegating to OpenCL from an existing Java implementation:

  1. Assess the performance of the existing implementation to identify the most compute intensive region of code
  2. Develop a test data set before and after that region
  3. Write OpenCL code that replaces the compute intensive region
  4. Test to ensure the new OpenCL code generates the same results using the test data
  5. Add conditional delegation logic to handle runtime compute capabilities

OpenCL ImageJ plugins following enterprise java patterns

Finally, some users and academic labs are building "GPU Supercomputers" to expose compute resources to a wide range of applications running locally. In this case, you wish to leverage to look at the FHTEJBService and Iterative_Deconvolve_3D_WS classes for an example on how to remotely serve up the your GPU accelerated resources using open source J2EE technologies.

In this example, Hessian Binary Web Services are used to broker data between the Java consumer and the Hessian Servlet. This approach is only recommended for those labs having sufficient throughput between the client application and the OpenCL/GPU servlet host.

Hosting OpenCL-accelerated algorithms using Oracle's GlassfishV3

Start out with the installation instructions available here.

To set up OpenCL support on Glassfish for deploying the ImageJ/Fiji Java based EJBs, navigate to the system's lib directory (for example: /opt/glassfishv3/glassfish/lib) and install the required jars/native libs.

sudo wget http://jogamp.org/deployment/webstart/jocl-natives-linux-amd64.jar
sudo unzip jocl-natives-linux-amd64.jar
sudo rm -rdf META-INF
sudo rm jocl-natives-linux-amd64.jar
sudo wget http://jogamp.org/deployment/webstart/gluegen-rt-natives-linux-amd64.jar
sudo unzip gluegen-rt-natives-linux-amd64.jar
sudo rm -rdf META-INF/
sudo rm gluegen-rt-natives-linux-amd64.jar

sudo wget http://jocl.org/downloads/JOCL-0.1.4-beta1-bin-linux-x86_64.zip
sudo unzip JOCL-0.1.4-beta1-bin-linux-x86_64.zip
sudo mv JOCL-0.1.4-beta1-bin-linux-x86_64/*.so .
sudo mv JOCL-0.1.4-beta1-bin-linux-x86_64/*.jar .
sudo rm -rdf JOCL-0.1.4-beta1-bin-linux-x86_64
sudo rm JOCL-0.1.4-beta1-bin-linux-x86_64.zip

sudo wget http://jogamp.org/deployment/webstart/gluegen-rt.jar
sudo wget http://jogamp.org/deployment/webstart/gluegen.jar
sudo wget http://jogamp.org/deployment/webstart/jocl.jar

The only other thing needed to get glassfish setup to support JOCL is to login to the admin console, under Common Tasks  › Configuration  › JVM Settings  › Path Settings.

Native Library Path Prefix: /opt/glassfishv3/glassfish/lib