Использование OpenCL в новой Android Studio


Я пытаюсь написать короткое приложение, которое использует OpenCL 1.2 (не для распространения, поэтому Универсальный доступ не является проблемой) для выполнения вычислений. Тем не менее, OpenCL дает мне немного проблем на Android. У меня есть, на моем компьютере, libopencl.so файл и заголовки 1.2 из пакета SDK AMD. Вопрос в том, как правильно их использовать?

Где в файле сборки gradle (новейшая версия) я должен указать это, или кто-то может порекомендовать мне хорошее место, чтобы я мог обратиться, чтобы прочитать об этом? Или, что мне нужно понять теоретически, чтобы я мог понять самостоятельно-что требуется для правильной связи с библиотеками OpenCL?

Я уже пробовал ответ, упомянутый здесь: Android Studio фатальная ошибка: CL/cl.h нет такого файла или каталога

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")
    }
}

Спасибо

2 3

2 ответа:

Это довольно сложный процесс. Я постараюсь быть кратким.

  1. чтобы запустить приложение на Android, libopencl.so от AMD ничего не получится. Библиотека OpenCL должна быть совместима с вашим устройством. Для устройства Android armv7 вам понадобится библиотека OpenCL, предоставленная поставщиком чипов и скомпилированная с помощью ARMv7 toolchain. Чтобы работать на устройстве Intel Atom, вам нужно, чтобы библиотека была предоставлена производителем чипа и была скомпилирована в x86_32 arch.

В основном, для вашего вопрос, у вас есть два пути:

[метод 1] захватите libOpenCL.so или libGLES_mali.so, или libPVROCL.so от устройств, которые у вас есть. Приведенные выше названия lib соответствуют графическим процессорам Adreno, Mali и PowerVR. Используйте эти библиотеки для компиляции кода.

[Метод 2] в собственном коде откройте библиотеку OpenCL с помощью dlopen, а затем с помощью dlsym сопоставьте API clBlaBla с вашим собственным именем. Например, можно сопоставить clgetteviceinfo с myclgetteviceinfo. Затем, в вашем собственном родном код, вы можете вызвать myClGetDeviceInfo вместо этого. Этот способ требует, чтобы вы знали путь к библиотеке opencl на ваших устройствах. Например, на графических процессорах Adreno расположение будет /system / vendor/lib / libOpenCL. so. Подробнее читайте в другом посте. поддерживает ли Android OpenCL?

Метод 2 является более общим и элегантным. Метод 1 проще и быстрее, если вы четко знаете, на каких устройствах будет работать ваше приложение. Например, если вы четко знаете, что ваше приложение предназначено только для тестирования на графических процессорах adreno, тогда вы можете просто захватить libOpenCL.so с вашего тестового устройства. Затем используйте его, чтобы связать ваше приложение. Эта ссылка показывает, как это сделать, и предоставляет пример кода. Вы можете начать оттуда.

С точки зрения использования Android studio. Я могу только прокомментировать это: если вы понимаете требование компиляции приложения OpenCL на Android. Компиляция с помощью Android studio или непосредственно с помощью ndk-build не имеют никакой разницы. Синтаксис может быть один к одному сопоставлен от одного к другому.

Для моего личного опыта, Я написал очень много Android.mk файлы, и я начинаю к этому привыкать. Так что даже если сейчас я использую Android Studio для разработки. Метод в статье, которую вы связали, на самом деле правильный.

Однако я по-прежнему использую ndk-build для компиляции собственного кода, как обычно. Таким образом, я могу полностью контролировать то, что там произошло, и я чувствую себя более комфортно. Как только я получил родную библиотеку .so, я поместил ее в папку jniLibs под src/main (ваша структура папок может быть другой). jnilibs-папка по умолчанию, где Android studio найдет родные библиотеки. Вы также можете указать свою собственную папку в скрипте gradle (тонны статей в интернете, поиск gradle ndk). Конечно, все вышеперечисленные операции выполняются скриптом (ndk-build, копирование библиотеки в какую-то папку). После того, как у меня есть все это, я создаю приложение с помощью Android studio. Как правило, вы не будете отлаживать JAVA-код и изменять машинный код одновременно, поэтому делать все это совершенно нормально и довольно удобно. Если вы хотите автоматизировать все это, вы можно попросить gradle запустить сценарий сборки ndk, который вы написали, прежде чем он соберет приложение. Или вы можете попросить gradle выполнить команду ndk-build так, как вам нравится (это на самом деле используется многими разработчиками).

Надеюсь, это поможет. Любое дальнейшее обсуждение приветствуется.

Большое спасибо за ваш ответ, Роберт! Мне нужно было заставить что-то работать, поэтому я закончил тем, что прошел через устройство, на котором оно установлено, проверив через

static const char *default_so_paths[] = { // Android
                                            "/system/lib/libOpenCL.so", "/system/vendor/lib/libOpenCL.so",
                                            "/system/vendor/lib/egl/libGLES_mali.so",
                                            "/system/vendor/lib/libPVROCL.so",
                                            "/data/data/org.pocl.libs/files/lib/libpocl.so",
                                          // Linux
                                            "/usr/lib/libOpenCL.so",            "/usr/local/lib/libOpenCL.so",
                                            "/usr/local/lib/libpocl.so",
                                            "/usr/lib64/libOpenCL.so", "/usr/lib32/libOpenCL.so",
                                            "libOpenCL.so"
                                          };

А затем отображение API, что я, наверное, видел, как это делается некоторое время назад.

У меня наконец-то все заработало, но я хотел бы поблагодарить вас, как за этот всеобъемлющий ответ, так и за большинство ваших ответов на этом форуме по этой теме. Они все были очень полезны.