diff --git a/examples/android/android-simple/app/build.gradle b/examples/android/android-simple/app/build.gradle index 8d2abc372..0ecee901b 100644 --- a/examples/android/android-simple/app/build.gradle +++ b/examples/android/android-simple/app/build.gradle @@ -1,4 +1,6 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' Properties properties = new Properties() properties.load(project.rootProject.file('local.properties').newDataInputStream()) @@ -6,12 +8,13 @@ def ndkDir = properties.getProperty('ndk.dir') def valLayerBinDir = "${ndkDir}/sources/third_party/vulkan/src/build-android/jniLibs" android { - compileSdkVersion 26 + compileSdkVersion 29 + ndkVersion '21.2.6472646' defaultConfig { applicationId "com.ethicalml.kompute.examples.android" minSdkVersion 26 - targetSdkVersion 26 + targetSdkVersion 29 versionCode = 1 versionName = "0.0.1" externalNativeBuild { @@ -26,29 +29,57 @@ android { } } } + + buildFeatures { + viewBinding true + } + buildTypes { + release { + minifyEnabled = false + proguardFiles getDefaultProguardFile('proguard-android.txt'), + 'proguard-rules.pro' + } + } externalNativeBuild { cmake { - path 'src/main/jni/CMakeLists.txt' + path 'src/main/cpp/CMakeLists.txt' } } sourceSets { main { jniLibs { - // Must have ndk-r12 or better which including layer binaries - srcDirs = ["${valLayerBinDir}"] + // Must have ndk-r12 or better which including layer binaries + srcDirs = ["${valLayerBinDir}"] } } } - buildTypes { - release { - minifyEnabled = false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + flavorDimensions 'cpuArch' + productFlavors { + arm8 { + dimension 'cpuArch' + ndk { + abiFilters 'arm64-v8a', 'armeabi-v7a' + } } - } + x86_64 { + dimension 'cpuArch' + ndk { + abiFilters 'x86_64', 'x86' + } + } + universal { + dimension 'cpuArch' + // include all default ABIs. with NDK-r16, it is: + // armeabi-v7a, arm64-v8a, x86, x86_64 + } + } } dependencies { + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/examples/android/android-simple/app/src/main/AndroidManifest.xml b/examples/android/android-simple/app/src/main/AndroidManifest.xml index c15080377..58826d222 100755 --- a/examples/android/android-simple/app/src/main/AndroidManifest.xml +++ b/examples/android/android-simple/app/src/main/AndroidManifest.xml @@ -5,23 +5,35 @@ android:versionCode="1" android:versionName="1.0"> - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/android/android-simple/app/src/main/jni/CMakeLists.txt b/examples/android/android-simple/app/src/main/cpp/CMakeLists.txt similarity index 81% rename from examples/android/android-simple/app/src/main/jni/CMakeLists.txt rename to examples/android/android-simple/app/src/main/cpp/CMakeLists.txt index 8c3ea439f..0b3948088 100644 --- a/examples/android/android-simple/app/src/main/jni/CMakeLists.txt +++ b/examples/android/android-simple/app/src/main/cpp/CMakeLists.txt @@ -6,14 +6,14 @@ set(ANDROID_APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue) set(VK_ANDROID_COMMON_DIR ${ANDROID_NDK}/sources/third_party/vulkan/src/common) set(VK_ANDROID_INCLUDE_DIR ${ANDROID_NDK}/sources/third_party/vulkan/src/include) -# build native_app_glue as a static lib -include_directories(${ANDROID_APP_GLUE_DIR}) -add_library(app-glue STATIC - ${ANDROID_APP_GLUE_DIR}/android_native_app_glue.c) +## build native_app_glue as a static lib +#include_directories(${ANDROID_APP_GLUE_DIR}) +#add_library(app-glue STATIC +# ${ANDROID_APP_GLUE_DIR}/android_native_app_glue.c) # build vulkan app add_library(kompute_android SHARED - main.cpp) + KomputeJniNative.cpp) include_directories( ${VK_ANDROID_COMMON_DIR} @@ -29,7 +29,7 @@ set(CMAKE_SHARED_LINKER_FLAGS target_link_libraries(kompute_android kompute - app-glue +# app-glue log kompute_vk_ndk_wrapper android) \ No newline at end of file diff --git a/examples/android/android-simple/app/src/main/cpp/KomputeJniNative.cpp b/examples/android/android-simple/app/src/main/cpp/KomputeJniNative.cpp new file mode 100644 index 000000000..85a780fb3 --- /dev/null +++ b/examples/android/android-simple/app/src/main/cpp/KomputeJniNative.cpp @@ -0,0 +1,111 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//#undef DEBUG +//#define RELEASE 1 + +#include +//#include +//#include +//#include +//#include +//#include + +#include +#include + +//#include "kompute/Kompute.hpp" + + +// Functions interacting with Android native activity +void android_main(struct android_app* state); +void terminate(void); +void handle_cmd(android_app* app, int32_t cmd); + + +// Android log function wrappers +static const char* kTAG = "Vulkan-Tutorial01"; +#define LOGI(...) \ + ((void)__android_log_print(ANDROID_LOG_INFO, kTAG, __VA_ARGS__)) +#define LOGW(...) \ + ((void)__android_log_print(ANDROID_LOG_WARN, kTAG, __VA_ARGS__)) +#define LOGE(...) \ + ((void)__android_log_print(ANDROID_LOG_ERROR, kTAG, __VA_ARGS__)) + + +JNIEXPORT jstring JNICALL +Java_com_ethicalml_kompute_examples_android_KomputeJni_stringFromJNI(JNIEnv *env, jobject thiz) { +#if defined(__arm__) + #if defined(__ARM_ARCH_7A__) + #if defined(__ARM_NEON__) + #if defined(__ARM_PCS_VFP) + #define ABI "armeabi-v7a/NEON (hard-float)" + #else + #define ABI "armeabi-v7a/NEON" + #endif + #else + #if defined(__ARM_PCS_VFP) + #define ABI "armeabi-v7a (hard-float)" + #else + #define ABI "armeabi-v7a" + #endif + #endif + #else + #define ABI "armeabi" + #endif +#elif defined(__i386__) +#define ABI "x86" +#elif defined(__x86_64__) +#define ABI "x86_64" +#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */ +#define ABI "mips64" +#elif defined(__mips__) +#define ABI "mips" +#elif defined(__aarch64__) +#define ABI "arm64-v8a" +#else +#define ABI "unknown" +#endif + + + LOGI("Initialising vulkan"); +// if (!InitVulkan()) { +// LOGE("Vulkan is unavailable, install vulkan and re-start"); +// return false; +// } +// +// LOGI("Creating manager"); +// +// kp::Manager mgr; +// +// auto tensorA = mgr.buildTensor({0,1,2}); +// auto tensorB = mgr.buildTensor({0,1,2}); +// auto tensorC = mgr.buildTensor({1,2,3}); +// +// LOGI("Result before:"); +// for(const float & i : tensorC->data()) { +// LOGI("%f ", i); +// } +// +// mgr.evalOpDefault>({tensorA, tensorB, tensorC}); +// mgr.evalOpDefault({tensorC}); +// +// LOGI("Result after:"); +// for(const float & i : tensorC->data()) { +// LOGI("%f ", i); +// } + + return (*env).NewStringUTF("Hello from JNI ! Compiled with ABI "); +} + diff --git a/examples/android/android-simple/app/src/main/java/com/ethicalml/kompute/examples/android/KomputeJni.kt b/examples/android/android-simple/app/src/main/java/com/ethicalml/kompute/examples/android/KomputeJni.kt new file mode 100755 index 000000000..d3b1261aa --- /dev/null +++ b/examples/android/android-simple/app/src/main/java/com/ethicalml/kompute/examples/android/KomputeJni.kt @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.ethicalml.kompute.examples.android + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.ethicalml.kompute.examples.android.databinding.ActivityHelloJniBinding + +class KomputeJni : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + /* + * Retrieve our TextView and set its content. + * the text is retrieved by calling a native + * function. + */ + val binding = ActivityHelloJniBinding.inflate(layoutInflater) + setContentView(binding.root) + binding.helloTextview.text = stringFromJNI() + } + + /* + * A native method that is implemented by the + * 'hello-jni' native library, which is packaged + * with this application. + */ + external fun stringFromJNI(): String? + + /* + * This is another native method declaration that is *not* + * implemented by 'hello-jni'. This is simply to show that + * you can declare as many native methods in your Java code + * as you want, their implementation is searched in the + * currently loaded native libraries only the first time + * you call them. + * + * Trying to call this function will result in a + * java.lang.UnsatisfiedLinkError exception ! + */ + external fun unimplementedStringFromJNI(): String? + + companion object { + /* + * this is used to load the 'hello-jni' library on application + * startup. The library has already been unpacked into + * /data/data/com.example.hellojni/lib/libhello-jni.so + * at the installation time by the package manager. + */ + init { + System.loadLibrary("kompute_android") + } + } +} + diff --git a/examples/android/android-simple/app/src/main/jni/main.cpp b/examples/android/android-simple/app/src/main/jni/main.cpp deleted file mode 100644 index 3946ce5e2..000000000 --- a/examples/android/android-simple/app/src/main/jni/main.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2016 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#undef DEBUG -#define RELEASE 1 - -#include -#include -#include -#include -#include -#include - -#include "kompute/Kompute.hpp" - - -// Android log function wrappers -static const char* kTAG = "Vulkan-Tutorial01"; -#define LOGI(...) \ - ((void)__android_log_print(ANDROID_LOG_INFO, kTAG, __VA_ARGS__)) -#define LOGW(...) \ - ((void)__android_log_print(ANDROID_LOG_WARN, kTAG, __VA_ARGS__)) -#define LOGE(...) \ - ((void)__android_log_print(ANDROID_LOG_ERROR, kTAG, __VA_ARGS__)) - - -// We will call this function the window is opened. -// This is where we will initialise everything -bool initialized_ = false; -bool initialize(android_app* app); - -// Functions interacting with Android native activity -void android_main(struct android_app* state); -void terminate(void); -void handle_cmd(android_app* app, int32_t cmd); - -// typical Android NativeActivity entry function -void android_main(struct android_app* app) { - app->onAppCmd = handle_cmd; - - int events; - android_poll_source* source; - do { - if (ALooper_pollAll(initialized_ ? 1 : 0, nullptr, &events, - (void**)&source) >= 0) { - if (source != NULL) source->process(app, source); - } - } while (app->destroyRequested == 0); -} - -bool initialize(android_app* app) { - - LOGI("Initialising vulkan"); - if (!InitVulkan()) { - LOGE("Vulkan is unavailable, install vulkan and re-start"); - return false; - } - - LOGI("Creating manager"); - - kp::Manager mgr; - - auto tensorA = mgr.buildTensor({0,1,2}); - auto tensorB = mgr.buildTensor({0,1,2}); - auto tensorC = mgr.buildTensor({1,2,3}); - - LOGI("Result before:"); - for(const float & i : tensorC->data()) { - LOGI("%f ", i); - } - - mgr.evalOpDefault>({tensorA, tensorB, tensorC}); - mgr.evalOpDefault({tensorC}); - - LOGI("Result after:"); - for(const float & i : tensorC->data()) { - LOGI("%f ", i); - } - - initialized_ = true; - - return 0; -} - -void terminate(void) { - initialized_ = false; -} - -// Process the next main command. -void handle_cmd(android_app* app, int32_t cmd) { - switch (cmd) { - case APP_CMD_INIT_WINDOW: - // The window is being shown, get it ready. - initialize(app); - break; - case APP_CMD_TERM_WINDOW: - // The window is being hidden or closed, clean it up. - terminate(); - break; - default: - LOGI("event not handled: %d", cmd); - } -} diff --git a/examples/android/android-simple/app/src/main/res/layout/activity_hello_jni.xml b/examples/android/android-simple/app/src/main/res/layout/activity_hello_jni.xml new file mode 100644 index 000000000..18840726a --- /dev/null +++ b/examples/android/android-simple/app/src/main/res/layout/activity_hello_jni.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/examples/android/android-simple/app/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/android/android-simple/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..cde69bccc Binary files /dev/null and b/examples/android/android-simple/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/examples/android/android-simple/app/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/android/android-simple/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..c133a0cbd Binary files /dev/null and b/examples/android/android-simple/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/examples/android/android-simple/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/android/android-simple/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..bfa42f0e7 Binary files /dev/null and b/examples/android/android-simple/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/examples/android/android-simple/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/android/android-simple/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..324e72cdd Binary files /dev/null and b/examples/android/android-simple/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/examples/android/android-simple/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/android/android-simple/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..aee44e138 Binary files /dev/null and b/examples/android/android-simple/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/examples/android/android-simple/app/src/main/res/values-w820dp/dimens.xml b/examples/android/android-simple/app/src/main/res/values-w820dp/dimens.xml new file mode 100644 index 000000000..63fc81644 --- /dev/null +++ b/examples/android/android-simple/app/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/examples/android/android-simple/app/src/main/res/values/colors.xml b/examples/android/android-simple/app/src/main/res/values/colors.xml new file mode 100755 index 000000000..3ab3e9cbc --- /dev/null +++ b/examples/android/android-simple/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #3F51B5 + #303F9F + #FF4081 + diff --git a/examples/android/android-simple/app/src/main/res/values/dimens.xml b/examples/android/android-simple/app/src/main/res/values/dimens.xml new file mode 100755 index 000000000..47c822467 --- /dev/null +++ b/examples/android/android-simple/app/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + diff --git a/examples/android/android-simple/app/src/main/res/values/strings.xml b/examples/android/android-simple/app/src/main/res/values/strings.xml index c899fe132..8ac01a86b 100755 --- a/examples/android/android-simple/app/src/main/res/values/strings.xml +++ b/examples/android/android-simple/app/src/main/res/values/strings.xml @@ -1,4 +1,3 @@ - - Kompute Android Example + KomputeJni diff --git a/examples/android/android-simple/app/src/main/res/values/styles.xml b/examples/android/android-simple/app/src/main/res/values/styles.xml new file mode 100755 index 000000000..5885930df --- /dev/null +++ b/examples/android/android-simple/app/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/examples/android/android-simple/build.gradle b/examples/android/android-simple/build.gradle index 123abac4a..c4c40217e 100644 --- a/examples/android/android-simple/build.gradle +++ b/examples/android/android-simple/build.gradle @@ -1,14 +1,15 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext.kotlin_version = '1.3.72' + repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files + classpath 'com.android.tools.build:gradle:4.0.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/examples/android/android-simple/gradle.properties b/examples/android/android-simple/gradle.properties index 1d3591c8a..7fa14279e 100644 --- a/examples/android/android-simple/gradle.properties +++ b/examples/android/android-simple/gradle.properties @@ -11,8 +11,10 @@ # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx10248m -XX:MaxPermSize=256m # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file +# org.gradle.parallel=true +android.useAndroidX=true \ No newline at end of file diff --git a/examples/android/android-simple/gradle/wrapper/gradle-wrapper.properties b/examples/android/android-simple/gradle/wrapper/gradle-wrapper.properties index 14819fe99..12582e2e7 100644 --- a/examples/android/android-simple/gradle/wrapper/gradle-wrapper.properties +++ b/examples/android/android-simple/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/single_include/kompute/Kompute.hpp b/single_include/kompute/Kompute.hpp index ec04fde88..3d8f327ba 100755 --- a/single_include/kompute/Kompute.hpp +++ b/single_include/kompute/Kompute.hpp @@ -9,8 +9,8 @@ //#define USE_DEBUG_EXTENTIONS #ifdef VK_USE_PLATFORM_ANDROID_KHR -#include -#include +//#include +//#include #include // VK_NO_PROTOTYPES required before vulkan import but after wrapper.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a1d2fd24b..02c792cf8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,19 +29,19 @@ file(GLOB kompute_CPP ) if(KOMPUTE_OPT_ANDOID_BUILD) - set(ANDROID_APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue) + #set(ANDROID_APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue) set(VK_ANDROID_COMMON_DIR ${ANDROID_NDK}/sources/third_party/vulkan/src/common) set(VK_ANDROID_PATCH_DIR ${PROJECT_SOURCE_DIR}/vk_ndk_wrapper_include/) set(VK_ANDROID_INCLUDE_DIR ${ANDROID_NDK}/sources/third_party/vulkan/src/include) include_directories( - ${ANDROID_APP_GLUE_DIR} + #${ANDROID_APP_GLUE_DIR} ${VK_ANDROID_COMMON_DIR} ${VK_ANDROID_PATCH_DIR} ${VK_ANDROID_INCLUDE_DIR}) - add_library(android_app_glue STATIC - ${ANDROID_APP_GLUE_DIR}/android_native_app_glue.c) + #add_library(android_app_glue STATIC + # ${ANDROID_APP_GLUE_DIR}/android_native_app_glue.c) add_library(kompute_vk_ndk_wrapper STATIC ${PROJECT_SOURCE_DIR}/vk_ndk_wrapper_include/kompute_vk_ndk_wrapper.cpp) @@ -79,7 +79,7 @@ endif() if(KOMPUTE_OPT_ANDOID_BUILD) target_link_libraries( kompute - android_app_glue + #android_app_glue kompute_vk_ndk_wrapper log android diff --git a/src/include/kompute/Core.hpp b/src/include/kompute/Core.hpp index 3b4d1129c..3bdab7411 100644 --- a/src/include/kompute/Core.hpp +++ b/src/include/kompute/Core.hpp @@ -9,8 +9,8 @@ //#define USE_DEBUG_EXTENTIONS #ifdef VK_USE_PLATFORM_ANDROID_KHR -#include -#include +//#include +//#include #include // VK_NO_PROTOTYPES required before vulkan import but after wrapper.hpp