android - 在新的 Android Studio 中使用 OpenCL

标签 android android-studio opencl android-gradle-plugin build.gradle

我正在尝试编写一个使用 OpenCL 1.2(不用于分发,因此通用访问不是问题)进行计算的简短应用程序。但是,OpenCL 在 Android 上给我带来了一些麻烦。我的电脑上有 libopencl.so 文件和 AMD SDK 的 1.2 header 。问题是:我该如何正确使用它们?

我应该在 gradle(最新版本)构建文件的哪个位置指定它,或者有人可以推荐一个好地方让我转向阅读这个吗?或者,我需要从理论上了解什么才能自己弄清楚 - 正确链接到 OpenCL 库需要什么?

我已经尝试过这里提到的答案: Android Studio fatal error: CL/cl.h No such file or directory

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion = 21
        buildToolsVersion ="22.0.1"

        defaultConfig.with {
            applicationId = "com.example.thing"
            minSdkVersion.apiLevel = 14
            targetSdkVersion.apiLevel = 14
        }
    }
    /*
     * native build settings
     */
    android.ndk {
        moduleName = "otherThing"

        ldLibs += "log"
        ldLibs += "android"
        //cFlags "~/OpenCL1-2HeaderFiles"
    }
    android.buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles  += file('proguard-rules.txt')
        }
    }

    android.productFlavors {
        create("arm") {
            ndk.abiFilters += "armeabi"
        }
        create("arm7") {
            ndk.abiFilters += "armeabi-v7a"
        }
        create("arm8") {
            ndk.abiFilters += "arm64-v8a"
        }
        create("x86") {
            ndk.abiFilters += "x86"
        }
        create("x86-64") {
            ndk.abiFilters += "x86_64"
        }
        create("mips") {
            ndk.abiFilters += "mips"
        }
        create("mips-64") {
            ndk.abiFilters += "mips64"
        }
        create("all")
    }
}

谢谢

最佳答案

这是一个相当复杂的过程。我会尽量保持简洁。

  1. 要在 Android 上运行您的应用程序,AMD 的 libopencl.so 将无法运行。 OpenCL 库必须与您的设备兼容。对于 Android armv7 设备,您需要芯片供应商提供的 OpenCL 库,并使用 armv7 工具链编译。要在 Intel Atom 设备上运行,您需要由芯片供应商提供的库,并针对 x86_32 arch 进行编译。

基本上,对于您的问题,您有两种方法:

[方法 1] 从您拥有的设备中获取 libOpenCL.so 或 libGLES_mali.so 或 libPVROCL.so。以上库名称分别对应 Adreno、Mali 和 PowerVR GPU。使用这些库来编译您的代码。

[方法 2] 在您的 native 代码中,使用 dlopen 打开 OpenCL 库,然后使用 dlsym 将 clBlaBla API 映射到您自己的名称。例如,您可以将 clGetDeviceInfo 映射到 myCLGetDeviceInfo。然后,在您自己的 native 代码中,您可以改为调用 myClGetDeviceInfo。这种方式要求您知道设备上 opencl 库的路径。例如,在 Adreno GPU 上,该位置为/system/vendor/lib/libOpenCL.so。有关更多详细信息,请阅读另一篇文章。 Does Android support OpenCL?

方法 2 更通用和优雅。如果您清楚地知道您的应用程序将在哪些设备上运行,则方法 1 更简单、更快捷。例如,如果您清楚地知道您的应用仅用于在 adreno gpus 上进行测试,那么您可以简单地从您的测试设备中获取 libOpenCL.so。然后使用它来链接您的应用程序。此链接显示了如何执行此操作,并提供了示例代码。你可以从那里开始。

在使用Android studio方面。我只能这样评论:如果您了解在 Android 上编译 OpenCL 应用程序的要求。使用 Android studio 编译和直接使用 ndk-build 编译没有区别。语法可以一对一地从一个映射到另一个。

我个人的经验,写了很多Android.mk文件,慢慢习惯了。所以就算现在我用Android Studio来开发。您链接的文章中的方法实际上是正确的。

但是,我仍然像往常一样使用 ndk-build 来编译我的 native 代码。那样的话,我可以完全控制那里发生的事情,而且我感觉更舒服。获得 .so native 库后,我将其放入 src/main 下的 jniLibs 文件夹中(您的文件夹结构可能不同)。 jniLibs 是 Android Studio 将在其中查找 native 库的默认文件夹。也可以在gradle脚本中指定自己的文件夹(网上一大堆文章,搜索gradle ndk)。当然,以上所有操作都是通过一个脚本完成的(ndk-build,将库复制到某个文件夹)。一旦我拥有所有这些,我就会使用 Android Studio 构建应用程序。通常情况下,您不会同时调试 JAVA 代码和更改 native 代码,因此执行上述操作完全可以并且很舒服。如果你想自动化所有这些,你可以要求 gradle 在构建应用程序之前启动你编写的 ndk 构建脚本。或者你可以让 gradle 按照你喜欢的方式运行 ndk-build 命令(这实际上被很多开发人员使用)。

希望对您有所帮助。欢迎进一步讨论。

关于android - 在新的 Android Studio 中使用 OpenCL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31611790/

相关文章:

android - 如何在android中动态地在gridview中添加复选框

java - 如何使用 ListView 删除 Android Studio 显示中的重复联系人

Android Studio 将多个项目导入到一个项目中

kernel - OpenCL-为什么使用READ_ONLY或WRITE_ONLY缓冲区

compilation - 如何用内核编译opencl项目

buffer - clEnqueueMapBuffer 和 clEnqueueWriteBuffer 有什么区别

android - 使用流作为 API 调用的返回类型

java - EditText 中的 ClickableSpan 到文本末尾调用 click() 到行尾

java - 如何更改android studio中的编码

android - 如何让特定的调用响铃而其他调用静音?