OpenCL on the Nexus 10, A Simple Example

>> Saturday, February 23, 2013

It's taken a while, but I finished coding an Android app that uses OpenCL to access the Mali GPU on the Nexus 10. It's not exciting, but here's the code for the top-level Activity:

public class TestNdkActivity extends Activity {

  static {
    System.load("/system/vendor/lib/egl/libGLES_mali.so");
    System.loadLibrary("TestNDK");
  }

  private native int getNumDevices();

  public void onCreate(Bundle b) {
    super.onCreate(b);
    setContentView(R.layout.testndk);
    TextView tv = (TextView)findViewById(R.id.tv);
    tv.setText("Number of connected devices: " + getNumDevices());
  }
}

To execute, the application needs two shared libraries: libGLES_mali.so and libTestNDK.so. The first can be found in the /system/vendor/lib/egl directory on the Nexus 10. The second is compiled by ndk-build using the following makefile (Android.mk):
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE      := TestNDK
LOCAL_C_INCLUDES  := $(LOCAL_PATH)/../include
LOCAL_LDLIBS      := $(LOCAL_PATH)/../external/libGLES_mali.so
LOCAL_SRC_FILES   := test_ndk.c
LOCAL_ARM_MODE    := arm

include $(BUILD_SHARED_LIBRARY)

To get the compilation to work, I put a copy of libGLES_mali.so in the project's 'external' directory. I also copied the $MALI_SDK/include/CL folder into the project's 'include' directory. There must be a better way to do this.

Here's my simple JNI code (test_ndk.c). It finds the first OpenCL platform and returns the number of available devices.
#include <CL/cl.h>
#include "test_ndk.h"

JNIEXPORT jint JNICALL Java_com_testndk_TestNdkActivity_getNumDevices
  (JNIEnv *env, jobject obj) {

    cl_platform_id platform;
    cl_device_id device;
    cl_uint num_devices;

    clGetPlatformIDs(1, &platform, NULL);
    clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1, NULL, &num_devices);
    return num_devices;
}

When I run the app, the TextView tells me that one device is connected. I'll try to get a more interesting example working in the next few days. For now, I'm content.

7 comments:

rahul February 23, 2013 at 7:43 PM  

Thanks for your post! I believe a somewhat similar hack has also been discovered to work on the Nexus 4 (the library name is obviously different). Will post details if I can confirm.

Matthew Scarpino February 23, 2013 at 7:56 PM  

If you can find a similar project, that would be great. There has to be a better way to construct Android-OpenCL applications.

Anonymous,  February 26, 2013 at 5:08 PM  

Hey Matt, you don't need to do all this work. The stubs file is in the sdk. I don't know why but you don't need the: System.load("/system/vendor/lib/egl/libGLES_mali.so");

just use your System.loadLibrary("TestNDK");
it seems it will local the openlib for you if you use the stubs.

you will be up and running in 15 min.

J.

Anonymous,  February 26, 2013 at 5:11 PM  

I meant to say "it seems it will load the OpenCL lib for you when you load your TestNDK file if you compile your library linking to the stubs."

and by sdk I mean the Mail OpenCL SDK

Matthew Scarpino February 26, 2013 at 6:01 PM  

That's a good point, but I decided I'd rather build against the library that would be linked to the executable.

My main problem was that, because I'm limited to Windows at the moment, I couldn't get absolute path names to work in Android.mk. That's why I had to create the "external" and "include" folders. I'll get this fixed.

Wayne Margot March 2, 2013 at 2:24 PM  

err.. any chance this can morph in to a file which the hoi polloi can dl and install with one click...? :/

Matthew Scarpino March 3, 2013 at 10:32 PM  

Nothing's ever that simple, but I've uploaded an OpenCL test app to Google Play. Alas, it's not there yet.

I uploaded the source code for the app to https://github.com/mattscar/opencl_device_test.

Post a Comment

  © Blogger template Werd by Ourblogtemplates.com 2009

Back to TOP