Skip to content

Commit

Permalink
Merge pull request #68 from EthicalML/android-example
Browse files Browse the repository at this point in the history
Added android example and upgraded build configurations
  • Loading branch information
axsaucedo authored Oct 4, 2020
2 parents 68b9554 + 76882d8 commit 0ca2b8e
Show file tree
Hide file tree
Showing 52 changed files with 3,687 additions and 265 deletions.
1 change: 1 addition & 0 deletions .ccls
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
-I/c/Users/axsau/Programming/lib/vcpkg/installed/x64-linux/include/
-I./src/include/
-I./single_include/
-I./vk_ndk_wrapper_include/
-I./test/compiled_shaders_include/

18 changes: 15 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.17.0)
cmake_minimum_required(VERSION 3.4.1)
project(kompute VERSION 0.3.0)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 14)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_VERBOSE_MAKEFILE on)
Expand All @@ -11,15 +11,27 @@ option(KOMPUTE_OPT_BUILD_TESTS "Enable if you want to build tests" 0)
option(KOMPUTE_OPT_BUILD_DOCS "Enable if you want to build documentation" 0)
option(KOMPUTE_OPT_BUILD_SHADERS "Enable if you want to re-build all shader files" 0)
option(KOMPUTE_OPT_BUILD_SINGLE_HEADER "Enable if you want to build the single header file" 0)
option(KOMPUTE_OPT_INSTALL "Enable if you want to enable installation" 1)
option(KOMPUTE_OPT_ENABLE_SPDLOG "Extra compile flags for Kompute, see docs for full list" 0)
option(KOMPUTE_OPT_ANDOID_BUILD "Enable android compilation flags required" 0)
# TODO: Add on docs
option(KOMPUTE_OPT_DISABLE_VK_DEBUG_LAYERS "Explicitly disable debug layers even on debug" 0)

set(KOMPUTE_EXTRA_CXX_FLAGS "" CACHE STRING "Extra compile flags for Kompute, see docs for full list")

if(KOMPUTE_OPT_ENABLE_SPDLOG)
set(KOMPUTE_EXTRA_CXX_FLAGS "${KOMPUTE_EXTRA_CXX_FLAGS} -DKOMPUTE_ENABLE_SPDLOG=1")
endif()

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG=1 ${KOMPUTE_EXTRA_CXX_FLAGS}")
if(KOMPUTE_OPT_ANDOID_BUILD)
set(KOMPUTE_EXTRA_CXX_FLAGS "${KOMPUTE_EXTRA_CXX_FLAGS} -DVK_USE_PLATFORM_ANDROID_KHR")
endif()

if(KOMPUTE_OPT_DISABLE_VK_DEBUG_LAYERS)
set(KOMPUTE_EXTRA_CXX_FLAGS "${KOMPUTE_EXTRA_CXX_FLAGS} -DKOMPUTE_DISABLE_VK_DEBUG_LAYERS=1")
endif()

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG=1 ${KOMPUTE_EXTRA_CXX_FLAGS} -DUSE_DEBUG_EXTENTIONS")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DRELEASE=1 ${KOMPUTE_EXTRA_CXX_FLAGS}")

# Allow scripts to call main kompute Makefile
Expand Down
Binary file added docs/images/android-editor.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/android-kompute.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions examples/android/android-simple/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.idea
.DS_Store
.gradle
build
*.iml
*~
local.properties
.externalNativeBuild
.cxx
.cdep
cdep.sha256
31 changes: 31 additions & 0 deletions examples/android/android-simple/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

<table>
<tr>


<td width="70%">
<h1>Vulkan Kompute Android</h1>
<h3>Example Running Logistic Regression with Vulkan Kompute in Android Phones</h3>

<p>
This example provides an end to end example that can be run using android studio.

The example uses the Kompute build in the relative folder to build the respective binaries for android.

The build structure provides a range of options to build in different Android hardware. This example was tested in various emulators including Pixel 2, and a physical Samsung S7 phone.
</p>
<img src="https://raw.githubusercontent.com/EthicalML/vulkan-kompute/android-example/docs/images/android-editor.jpg">

</td>


<td width="30%">
<img src="https://raw.githubusercontent.com/EthicalML/vulkan-kompute/android-example/docs/images/android-kompute.jpg">
</td>

</tr>
</table>




71 changes: 71 additions & 0 deletions examples/android/android-simple/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 29
ndkVersion '21.2.6472646'

defaultConfig {
applicationId "com.ethicalml.kompute"
minSdkVersion 23
targetSdkVersion 29
versionCode = 1
versionName = "0.0.1"
externalNativeBuild {
cmake {
abiFilters "armeabi-v7a", 'arm64-v8a', 'x86', 'x86_64'
arguments '-DANDROID_TOOLCHAIN=clang',
'-DANDROID_STL=c++_static',
'-DKOMPUTE_OPT_ANDOID_BUILD=1',
'-DKOMPUTE_OPT_INSTALL=0',
'-DKOMPUTE_OPT_BUILD_SINGLE_HEADER=1',
'-DKOMPUTE_OPT_DISABLE_VK_DEBUG_LAYERS=1',
'-DKOMPUTE_EXTRA_CXX_FLAGS=-DKOMPUTE_VK_API_MINOR_VERSION=0'
}
}
}

buildFeatures {
viewBinding true
}
buildTypes {
release {
minifyEnabled = false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path 'src/main/cpp/CMakeLists.txt'
}
}

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"
}
17 changes: 17 additions & 0 deletions examples/android/android-simple/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${ANDROID_SDK}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
21 changes: 21 additions & 0 deletions examples/android/android-simple/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ethicalml.kompute">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".KomputeJni">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
<!-- END_INCLUDE(manifest) -->
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions examples/android/android-simple/app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
cmake_minimum_required(VERSION 3.4.1)

add_subdirectory(../../../../../../../ ${CMAKE_CURRENT_BINARY_DIR}/kompute_build)

set(VK_ANDROID_INCLUDE_DIR ${ANDROID_NDK}/sources/third_party/vulkan/src/include)

add_library(kompute-jni SHARED
KomputeJniNative.cpp
KomputeModelML.cpp)

include_directories(
${VK_ANDROID_COMMON_DIR}
${VK_ANDROID_INCLUDE_DIR}
../../../../../../../single_include/
../../../../../../../vk_ndk_wrapper_include/)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 \
-DVK_USE_PLATFORM_ANDROID_KHR=1 \
-DKOMPUTE_DISABLE_VK_DEBUG_LAYERS=1")

target_link_libraries(kompute-jni
# Libraries from kompute build
kompute
kompute_vk_ndk_wrapper
# Libraries from android build
log
android)
114 changes: 114 additions & 0 deletions examples/android/android-simple/app/src/main/cpp/KomputeJniNative.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// 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 <android/log.h>
#include <unistd.h>

#include <string.h>
#include <jni.h>

#include "kompute/Kompute.hpp"

#include "KomputeModelML.hpp"

#ifndef KOMPUTE_VK_INIT_RETRIES
#define KOMPUTE_VK_INIT_RETRIES 5
#endif

static std::vector<float> jfloatArrayToVector(JNIEnv *env, const jfloatArray & fromArray) {
float *inCArray = env->GetFloatArrayElements(fromArray, NULL);
if (NULL == inCArray) return std::vector<float>();
int32_t length = env->GetArrayLength(fromArray);

std::vector<float> outVector(inCArray, inCArray + length);
return outVector;
}

static jfloatArray vectorToJFloatArray(JNIEnv *env, const std::vector<float> & fromVector) {
jfloatArray ret = env->NewFloatArray(fromVector.size());
if (NULL == ret) return NULL;
env->SetFloatArrayRegion(ret, 0, fromVector.size(), fromVector.data());
return ret;
}

extern "C" {

JNIEXPORT jboolean JNICALL
Java_com_ethicalml_kompute_KomputeJni_initVulkan(JNIEnv *env, jobject thiz) {

SPDLOG_INFO("Initialising vulkan");

uint32_t totalRetries = 0;

while (totalRetries < KOMPUTE_VK_INIT_RETRIES) {
SPDLOG_INFO("VULKAN LOAD TRY NUMBER: %u", totalRetries);
if(InitVulkan()) {
break;
}
sleep(1);
totalRetries++;
}

return totalRetries < KOMPUTE_VK_INIT_RETRIES;
}


JNIEXPORT jfloatArray JNICALL
Java_com_ethicalml_kompute_KomputeJni_kompute(
JNIEnv *env,
jobject thiz,
jfloatArray xiJFloatArr,
jfloatArray xjJFloatArr,
jfloatArray yJFloatArr) {

SPDLOG_INFO("Creating manager");

std::vector<float> xiVector = jfloatArrayToVector(env, xiJFloatArr);
std::vector<float> xjVector = jfloatArrayToVector(env, xjJFloatArr);
std::vector<float> yVector = jfloatArrayToVector(env, yJFloatArr);

KomputeModelML kml;
kml.train(yVector, xiVector, xjVector);

std::vector<float> pred = kml.predict(xiVector, xjVector);

return vectorToJFloatArray(env, pred);
}

JNIEXPORT jfloatArray JNICALL
Java_com_ethicalml_kompute_KomputeJni_komputeParams(
JNIEnv *env,
jobject thiz,
jfloatArray xiJFloatArr,
jfloatArray xjJFloatArr,
jfloatArray yJFloatArr) {

SPDLOG_INFO("Creating manager");

std::vector<float> xiVector = jfloatArrayToVector(env, xiJFloatArr);
std::vector<float> xjVector = jfloatArrayToVector(env, xjJFloatArr);
std::vector<float> yVector = jfloatArrayToVector(env, yJFloatArr);

KomputeModelML kml;
kml.train(yVector, xiVector, xjVector);

std::vector<float> params = kml.get_params();

return vectorToJFloatArray(env, params);
}

}
Loading

0 comments on commit 0ca2b8e

Please sign in to comment.