在Android Studio上使用OpenCL

在尝试了很多的方法后,终于可以在Android Studio上使用OpenCL,现在记录一下过程。

判断手机是否支持OpenCL的方法

  1. 下载aida64,在设备里查看是否有OpenCL设备
  2. 下载Opencl-z,如果支持,通过此软件可以查看到platform和device

在native-lib中使用Opencl

  1. git clone [email protected]:GaussRieman/libopencl-stub.git
  2. 在Android.mk中添加一个static library
    include $(CLEAR VARS)
    LOCAL_MODULE := libopenclstub
    LOCAL_C_INCLUDES := path/to/libopencl-stub/include
    LOCAL_SRC_FILES := path/to/libopencl.c
    LOCAL_CFLAGS := -fPIC -o2
    include $(BUILD_STATIC_LIBRARY)
  3. 在native-lib中添加对stub库的静态链接
    LOCAL_STATIC_LIBRARIES += libopenclstub
  4. 在native-lib中添加对CL头文件的支持
    LOCAL_C_INCLUDES += path/to/libopencl-stub/include/CL/
  5. 在cpp或c中包含CL头文件就可以使用了

有兴趣的深入一下,为什么要用stub

很多人会参考一篇文章,里面提到了这个原因,因为google是不公开支持opencl的,所以NDK中并不会有libOpenCL.so,这个库都是放在各个厂家的库中,比较常见的位置是"system/vendor/lib64/libOpenCL.so",但是如果你将这个库adb pull到host,然后作为一个动态库放到Android Studio中使用,在运行时会报错找不到“libc++.so”:

03-21 17:07:51.502 31234 31234 W linker  : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible for the namespace "classloader-namespace" - the access is temporarily granted as a workaround for http://b/26394120

这是因为libOpenCL.so会调用libc++.so,以及libcutils.so,这些依赖可以通过下面的命令找到。

aarch64-linux-android-readelf -dW libOpenCL.so

根据参考的博客里面的方法,将所需的动态库全部pull出来,当做app的私有库来加载,的确可以解决编译的问题,但是在使用clGetPlatforms时,会找不到可用的platform。如果是开发一个底层库,在不知道vendor的情况下,只能将adrno, mali等GPU全部拷出来,一层层的依赖,甚至会涉及到libbase.so。。。不是一个好的办法。

另一种方式是上面提到的,使用stub,将libOpenCL.so动态加载,libopencl.c主要就是帮我们完成适配平台和封装接口的工作,它主要用到dlopen和dlsym,前者用来加载vendor支持的CL动态库,后者用来映射接口。

再扯一点题外话,google不支持OpenCL, Khronos小组也推出了Vulkan,所以CL地位很尴尬,目前在第三方库中使用OpenCL最好的就是使用stub,万一哪天google把dlopen也关了,那就真的没得玩了。。。

参考

  1. https://blog.csdn.net/wjskeepmaking/article/details/70080315
  2. https://github.com/GaussRieman/libopencl-stub

你可能感兴趣的:(算法工程与架构)