From: 이한종/On-Device Lab(SR)/Engineer/삼성전자 Date: Fri, 25 Oct 2019 08:00:25 +0000 (+0900) Subject: [android] Introduce android_benchmark_app (#8380) X-Git-Tag: submit/tizen/20191205.083104~579 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fee701d84870ba95fd47d0382c3253a4346c1ef4;p=platform%2Fcore%2Fml%2Fnnfw.git [android] Introduce android_benchmark_app (#8380) * [android] Introduce android_benchmark_app This commit introduces an Android benchmark app for easy testing with an actual Android visual app rather than running on shell. The app contains minimal UI which consist of 2 buttons and few text views to show results. Signed-off-by: Hanjoung Lee * Fixes --- diff --git a/Makefile.template b/Makefile.template index a120398..fcb24ea 100644 --- a/Makefile.template +++ b/Makefile.template @@ -61,6 +61,22 @@ ifeq ($(TARGET_OS),android) OPTIONS+= -DNDK_DIR=$(NDK_DIR) endif +ifneq ($(ANDROID_BUILD_TOOLS_DIR),) + OPTIONS+= -DANDROID_BUILD_TOOLS_DIR=$(ANDROID_BUILD_TOOLS_DIR) +endif + +ifneq ($(ANDROID_SDK_DIR),) + OPTIONS+= -DANDROID_SDK_DIR=$(ANDROID_SDK_DIR) +endif + +ifneq ($(TFLITE_MODEL_PATH),) + OPTIONS+= -DTFLITE_MODEL_PATH=$(TFLITE_MODEL_PATH) +endif + +ifneq ($(ANDROID_BOOST_ROOT),) + OPTIONS+= -DANDROID_BOOST_ROOT=$(ANDROID_BOOST_ROOT) +endif + ifeq ($(PARALLEL_BUILD),1) # Get number of processors (linux only for now) ifeq ($(HOST_OS),linux) diff --git a/infra/nnfw/cmake/CfgOptionFlags.cmake b/infra/nnfw/cmake/CfgOptionFlags.cmake index 80736e8..8f53ba2 100644 --- a/infra/nnfw/cmake/CfgOptionFlags.cmake +++ b/infra/nnfw/cmake/CfgOptionFlags.cmake @@ -36,6 +36,7 @@ option(ENVVAR_NEURUN_CONFIG "Use environment variable for neurun configuration" # Default build configuration for contrib # option(BUILD_ANDROID_TFLITE "Enable android support for TensorFlow Lite" OFF) +option(BUILD_ANDROID_BENCHMARK_APP "Enable Android Benchmark App" OFF) option(BUILD_BENCHMARK_ACL "Build ARM Compute Library Benchmarks" OFF) option(BUILD_DETECTION_APP "Build detection example app" OFF) option(BUILD_LABS "Build lab projects" OFF) diff --git a/infra/nnfw/cmake/options/options_arm64-android.cmake b/infra/nnfw/cmake/options/options_arm64-android.cmake index 3064866..392375c 100644 --- a/infra/nnfw/cmake/options/options_arm64-android.cmake +++ b/infra/nnfw/cmake/options/options_arm64-android.cmake @@ -5,6 +5,7 @@ option(BUILD_ARMCOMPUTE "Build ARM Compute from the downloaded source" OFF) # tensorflow-lite does not build BuiltinOpResolver but JNI lib need it # Related Issue : #1403 option(BUILD_ANDROID_TFLITE "Enable android support for TensorFlow Lite" ON) +option(BUILD_ANDROID_BENCHMARK_APP "Enable Android Benchmark App" ON) option(DOWNLOAD_NEON2SSE "Download NEON2SSE library source" OFF) # Need boost library option(BUILD_RUNTIME_NNAPI_TEST "Build Runtime NN API Generated Test" OFF) diff --git a/runtimes/contrib/android_benchmark_app/AndroidManifest.xml b/runtimes/contrib/android_benchmark_app/AndroidManifest.xml new file mode 100644 index 0000000..f0b967c --- /dev/null +++ b/runtimes/contrib/android_benchmark_app/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + diff --git a/runtimes/contrib/android_benchmark_app/CMakeLists.txt b/runtimes/contrib/android_benchmark_app/CMakeLists.txt new file mode 100644 index 0000000..8e9d3c7 --- /dev/null +++ b/runtimes/contrib/android_benchmark_app/CMakeLists.txt @@ -0,0 +1,97 @@ +if(NOT BUILD_ANDROID_BENCHMARK_APP) + return() +endif(NOT BUILD_ANDROID_BENCHMARK_APP) + +if(NOT ANDROID) + message(STATUS "Sample app is disabled as non-Android build") + return() +endif() + +if(NOT DEFINED ANDROID_BUILD_TOOLS_DIR) + message(STATUS "Sample app is disabled as ANDROID_BUILD_TOOLS_DIR is not defined") + return() +endif() + +if(NOT DEFINED ANDROID_SDK_DIR) + message(STATUS "Sample app is disabled as ANDROID_SDK_DIR is not defined") + return() +endif() + +if(NOT DEFINED TFLITE_MODEL_PATH) + message(STATUS "Sample app is disabled as TFLITE_MODEL_PATH is not defined") + return() +endif() + +nnas_find_package(ARMCompute REQUIRED) + +if(NOT CORE_LIBRARY OR NOT RUNTIME_LIBRARY) + message(STATUS "Sample app is disabled as ARM Compute Library is missing") + return() +endif() + +get_filename_component(TFLITE_MODEL_FILENAME ${TFLITE_MODEL_PATH} NAME) + +set(ANDROID_API_VERSION 27) +set(ANDROID_PLATFORM_DIR ${ANDROID_SDK_DIR}/platforms/android-${ANDROID_API_VERSION}) + +set(GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/gen) +set(OBJ_DIR ${CMAKE_CURRENT_BINARY_DIR}/obj) +set(PKG_DIR ${CMAKE_CURRENT_BINARY_DIR}/pkg) +set(LIB_DIR ${PKG_DIR}/lib/arm64-v8a) +set(ASSETS_DIR ${PKG_DIR}/assets) +set(SRC_LIST ${CMAKE_CURRENT_BINARY_DIR}/src.list) + +if (ANDROID_BOOST_ROOT) + set(BOOST_ROOT ${ANDROID_BOOST_ROOT}) +endif (ANDROID_BOOST_ROOT) + +nnas_find_package(Boost REQUIRED) + +add_library(android_benchmark_native SHARED cpp/ndk_main.cpp) +target_compile_definitions(android_benchmark_native PRIVATE MODEL_NAME="${TFLITE_MODEL_FILENAME}") +target_include_directories(android_benchmark_native PRIVATE ${NNAS_EXTERNALS_DIR}/tensorflow) +target_include_directories(android_benchmark_native PRIVATE ${Boost_INCLUDE_DIRS}) +target_link_libraries(android_benchmark_native nnfw_lib_tflite) +target_link_libraries(android_benchmark_native nnfw_lib_misc) +target_link_libraries(android_benchmark_native log) + +nnfw_find_package(FlatBuffersSource REQUIRED) +target_include_directories(android_benchmark_native PUBLIC ${FlatBuffersSource_DIR}/include .) + +add_custom_target(android-benchmark-apk ALL + COMMAND ${CMAKE_COMMAND} -E remove_directory ${GEN_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${GEN_DIR} + COMMAND ${ANDROID_BUILD_TOOLS_DIR}/aapt package -m -J ${GEN_DIR} + -M ${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml + -S ${CMAKE_CURRENT_SOURCE_DIR}/res + -I ${ANDROID_PLATFORM_DIR}/android.jar + COMMAND ${CMAKE_COMMAND} -E remove_directory ${OBJ_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${OBJ_DIR} + COMMAND ${CMAKE_COMMAND} -E remove -f ${SRC_LIST} + COMMAND find ${CMAKE_CURRENT_SOURCE_DIR}/java -name '*.java' >> ${SRC_LIST} + COMMAND find ${GEN_DIR} -name '*.java' >> ${SRC_LIST} + COMMAND javac -d ${OBJ_DIR} -source 1.7 -target 1.7 -bootclasspath "${JAVA_HOME}/jre/lib/rt.jar" + -classpath ${ANDROID_PLATFORM_DIR}/android.jar @${SRC_LIST} + COMMAND ${CMAKE_COMMAND} -E remove_directory ${PKG_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${PKG_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${ASSETS_DIR} + COMMAND ${CMAKE_COMMAND} -E copy ${TFLITE_MODEL_PATH} ${ASSETS_DIR}/model.tflite + COMMAND ${ANDROID_BUILD_TOOLS_DIR}/dx --dex --output=${PKG_DIR}/classes.dex ${OBJ_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_DIR} + COMMAND ${CMAKE_COMMAND} -E copy ${CORE_LIBRARY} ${LIB_DIR} + COMMAND ${CMAKE_COMMAND} -E copy ${RUNTIME_LIBRARY} ${LIB_DIR} + COMMAND ${CMAKE_COMMAND} -E copy $ ${LIB_DIR} + COMMAND ${CMAKE_COMMAND} -E copy $ ${LIB_DIR} + COMMAND ${CMAKE_COMMAND} -E copy $ ${LIB_DIR} + COMMAND ${CMAKE_COMMAND} -E copy $ ${LIB_DIR} + COMMAND ${CMAKE_COMMAND} -E copy $ ${LIB_DIR} + COMMAND ${CMAKE_COMMAND} -E copy $ ${LIB_DIR} + COMMAND ${CMAKE_COMMAND} -E echo ${ANDROID_BUILD_TOOLS_DIR}/aapt package -f -0 tflite -M ${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml -S ${CMAKE_CURRENT_SOURCE_DIR}/res/ -I ${ANDROID_PLATFORM_DIR}/android.jar -F ${CMAKE_CURRENT_BINARY_DIR}/android-benchmark.unsigned.pkg ${PKG_DIR} + COMMAND ${ANDROID_BUILD_TOOLS_DIR}/aapt package -f + -0 tflite + -M ${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml + -S ${CMAKE_CURRENT_SOURCE_DIR}/res/ + -I ${ANDROID_PLATFORM_DIR}/android.jar + -F ${CMAKE_CURRENT_BINARY_DIR}/android-benchmark.unsigned.pkg + ${PKG_DIR} + DEPENDS android_benchmark_native neurun neurun_backend_acl_cl neurun_backend_acl_neon neurun_backend_cpu) diff --git a/runtimes/contrib/android_benchmark_app/README.md b/runtimes/contrib/android_benchmark_app/README.md new file mode 100644 index 0000000..d53a56c --- /dev/null +++ b/runtimes/contrib/android_benchmark_app/README.md @@ -0,0 +1,58 @@ +# Android Benchmark App + +An Android sample app that run `.tflite` and measure performance. + +You can run with two engines. + +- Tensorflow Lite Interpreter +- NN API Delegate (neurun) + +## Build + +In addition to arm64-Android build, you need to specify more parameters. + +- `ANDROID_BUILD_TOOLS_DIR` : Android `build-tools` directory (You may find it in Android SDK directory) +- `ANDROID_SDK_DIR` : Android SDK directory +- `TFLITE_MODEL_PATH` : A model to run (Only one model can be packed) +- `ANDROID_BOOST_ROOT` : Boost library root path + - This repo should contain `lib` and `include` directory + - How to build Boost for Android - Build with [this repo](https://github.com/moritz-wundke/Boost-for-Android) + +Example: + +```bash +make TARGET_ARCH=arm64 \ + CROSS_BUILD=1 \ + BUILD_TYPE=RELEASE \ + NDK_DIR=/home/hanjoung/ws/android-tools/r20/ndk \ + EXT_ACL_FOLDER=/home/hanjoung/ws/temp/arm_compute-v19.05-bin-android/lib/android-arm64-v8a-neon-cl \ + ANDROID_BUILD_TOOLS_DIR=/home/hanjoung/ws/android-tools/sdk/build-tools/27.0.3/ \ + ANDROID_SDK_DIR=/home/hanjoung/ws/android-tools/sdk \ + TFLITE_MODEL_PATH=/Users/hanjoung/ws/ghent/STAR/nnfw/tests/framework/cache/MODELS/mobilenet/mobilenet_v1_0.25_128.tflite \ + ANDROID_BOOST_ROOT=/home/hanjoung/ws/gh/moritz-wundke/Boost-for-Android/build/out/arm64-v8a +``` + +And you will get `obj/contrib/android_benchmark_app/android-benchmark.unsigned.pkg`. This is an unsigned Android app package. + +## Sign APK + +Before installing the package you probably need to sign the package. + +- `apksigner` : This is in `build-tools` directory +- Your keystore : How-to is TBD + +```bash +apksigner sign \ + --ks ~/.android/debug.keystore \ + --in Product/arm64-android.release/obj/contrib/android_benchmark_app/android-benchmark.unsigned.pkg \ + --out tflbench.apk +``` + +You should enter the keystore password. Then you will get `tflbench.apk`. + +## Install APK + +```bash +adb install tflbench.apk +adb uninstall com.ndk.tflbench # To uninstall +``` diff --git a/runtimes/contrib/android_benchmark_app/cpp/ndk_main.cpp b/runtimes/contrib/android_benchmark_app/cpp/ndk_main.cpp new file mode 100644 index 0000000..f2ca131 --- /dev/null +++ b/runtimes/contrib/android_benchmark_app/cpp/ndk_main.cpp @@ -0,0 +1,228 @@ +#include "ndk_main.h" + +#include "tensorflow/lite/kernels/register.h" +#include "tensorflow/lite/model.h" + +#include "tflite/Assert.h" +#include "tflite/Session.h" +#include "tflite/InterpreterSession.h" +#include "tflite/NNAPISession.h" +#include "tflite/ext/kernels/register.h" + +#include "misc/benchmark.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +using namespace tflite; +using namespace tflite::ops::builtin; + +static StderrReporter error_reporter; + +static std::unique_ptr model; + +inline void setText(JNIEnv *env, jobject thisObj, const std::string &message) +{ + jclass thisClass = env->GetObjectClass(thisObj); + jmethodID setTextMethod = env->GetMethodID(thisClass, "setText", "(Ljava/lang/String;)V"); + + assert(setTextMethod != nullptr); + + env->CallVoidMethod(thisObj, setTextMethod, env->NewStringUTF(message.c_str())); +} + +inline void setTitle(JNIEnv *env, jobject thisObj, const std::string &message) +{ + jclass thisClass = env->GetObjectClass(thisObj); + jmethodID setTextMethod = env->GetMethodID(thisClass, "setTitle", "(Ljava/lang/String;)V"); + + assert(setTextMethod != nullptr); + + env->CallVoidMethod(thisObj, setTextMethod, env->NewStringUTF(message.c_str())); + + // Clear message + setText(env, thisObj, ""); +} + +inline void setText(JNIEnv *env, jobject thisObj, const std::stringstream &ss) +{ + setText(env, thisObj, ss.str()); +} + +inline std::unique_ptr loadModel(JNIEnv *env, jobject thisObj, + jobject model_buffer) +{ + const char *model_base = static_cast(env->GetDirectBufferAddress(model_buffer)); + jlong model_size = env->GetDirectBufferCapacity(model_buffer); + + return FlatBufferModel::BuildFromBuffer(model_base, static_cast(model_size), + &error_reporter); +} + +struct Activity +{ + virtual ~Activity() = default; + + virtual void prepare(void) const = 0; + virtual void run(void) const = 0; + virtual void teardown(void) const = 0; +}; + +struct LiteActivity final : public Activity +{ +public: + LiteActivity(nnfw::tflite::Session &sess) : _sess(sess) + { + // DO NOTHING + } + +public: + void prepare(void) const override { _sess.prepare(); } + void run(void) const override { _sess.run(); } + void teardown(void) const override { _sess.teardown(); } + +private: + nnfw::tflite::Session &_sess; +}; + +struct SimpleActivity final : public Activity +{ +public: + SimpleActivity(const std::function &fn) : _fn{fn} + { + // DO NOTHING + } + +public: + void prepare(void) const override {} + void run(void) const override { _fn(); } + void teardown(void) const override {} + +private: + std::function _fn; +}; + +inline void runBenchmark(JNIEnv *env, jobject thisObj, Activity &act) +{ + auto runTrial = [&](void) { + std::chrono::milliseconds elapsed(0); + + act.prepare(); + nnfw::misc::benchmark::measure(elapsed) << [&](void) { act.run(); }; + act.teardown(); + + return elapsed; + }; + + // Warm-up + for (uint32_t n = 0; n < 3; ++n) + { + auto elapsed = runTrial(); + + std::stringstream ss; + ss << "Warm-up #" << n << " takes " << elapsed.count() << "ms" << std::endl; + setText(env, thisObj, ss); + } + + // Measure + using namespace boost::accumulators; + + accumulator_set> acc; + + for (uint32_t n = 0; n < 100; ++n) + { + auto elapsed = runTrial(); + + std::stringstream ss; + ss << "Iteration #" << n << " takes " << elapsed.count() << "ms" << std::endl; + setText(env, thisObj, ss); + + acc(elapsed.count()); + } + + std::stringstream ss; + ss << "Average is " << mean(acc) << "ms" << std::endl; + ss << "Min is " << min(acc) << "ms" << std::endl; + ss << "Max is " << max(acc) << "ms" << std::endl; + setText(env, thisObj, ss); +} + +JNIEXPORT void JNICALL Java_com_ndk_tflbench_MainActivity_runInterpreterBenchmark( + JNIEnv *env, jobject thisObj, jobject model_buffer) +{ + setTitle(env, thisObj, "Running Interpreter Benchmark"); + + auto model = loadModel(env, thisObj, model_buffer); + assert(model != nullptr); + + nnfw::tflite::BuiltinOpResolver resolver; + InterpreterBuilder builder(*model, resolver); + + std::unique_ptr interpreter; + + TFLITE_ENSURE(builder(&interpreter)); + + interpreter->SetNumThreads(-1); + + nnfw::tflite::InterpreterSession sess(interpreter.get()); + LiteActivity act{sess}; + runBenchmark(env, thisObj, act); +} + +static void runNNAPIBenchmark(JNIEnv *env, jobject thisObj, jobject model_buffer) +{ + auto model = loadModel(env, thisObj, model_buffer); + assert(model != nullptr); + + nnfw::tflite::BuiltinOpResolver resolver; + InterpreterBuilder builder(*model, resolver); + + std::unique_ptr interpreter; + + TFLITE_ENSURE(builder(&interpreter)); + + nnfw::tflite::NNAPISession sess(interpreter.get()); + LiteActivity act{sess}; + runBenchmark(env, thisObj, act); +} + +JNIEXPORT void JNICALL Java_com_ndk_tflbench_MainActivity_runNNAPIBenchmark(JNIEnv *env, + jobject thisObj, + jobject model_buffer) +{ + setTitle(env, thisObj, "Running NNAPI Benchmark"); + + try + { + runNNAPIBenchmark(env, thisObj, model_buffer); + } + catch (const std::exception &ex) + { + std::stringstream ss; + ss << "Caught an exception " << ex.what(); + setText(env, thisObj, ss); + } +} + +JNIEXPORT jstring JNICALL Java_com_ndk_tflbench_MainActivity_getModelName(JNIEnv *env, + jobject thisObj) +{ + return env->NewStringUTF(MODEL_NAME); +} + +#define TF_ENSURE(e) \ + { \ + if (!(e).ok()) \ + { \ + throw std::runtime_error{"'" #e "' FAILED"}; \ + } \ + } diff --git a/runtimes/contrib/android_benchmark_app/cpp/ndk_main.h b/runtimes/contrib/android_benchmark_app/cpp/ndk_main.h new file mode 100644 index 0000000..8de39ce --- /dev/null +++ b/runtimes/contrib/android_benchmark_app/cpp/ndk_main.h @@ -0,0 +1,92 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_ndk_tflbench_MainActivity */ + +#ifndef _Included_com_ndk_tflbench_MainActivity +#define _Included_com_ndk_tflbench_MainActivity +#ifdef __cplusplus +extern "C" { +#endif +#undef com_ndk_tflbench_MainActivity_BIND_ABOVE_CLIENT +#define com_ndk_tflbench_MainActivity_BIND_ABOVE_CLIENT 8L +#undef com_ndk_tflbench_MainActivity_BIND_ADJUST_WITH_ACTIVITY +#define com_ndk_tflbench_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L +#undef com_ndk_tflbench_MainActivity_BIND_ALLOW_OOM_MANAGEMENT +#define com_ndk_tflbench_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L +#undef com_ndk_tflbench_MainActivity_BIND_AUTO_CREATE +#define com_ndk_tflbench_MainActivity_BIND_AUTO_CREATE 1L +#undef com_ndk_tflbench_MainActivity_BIND_DEBUG_UNBIND +#define com_ndk_tflbench_MainActivity_BIND_DEBUG_UNBIND 2L +#undef com_ndk_tflbench_MainActivity_BIND_EXTERNAL_SERVICE +#define com_ndk_tflbench_MainActivity_BIND_EXTERNAL_SERVICE -2147483648L +#undef com_ndk_tflbench_MainActivity_BIND_IMPORTANT +#define com_ndk_tflbench_MainActivity_BIND_IMPORTANT 64L +#undef com_ndk_tflbench_MainActivity_BIND_NOT_FOREGROUND +#define com_ndk_tflbench_MainActivity_BIND_NOT_FOREGROUND 4L +#undef com_ndk_tflbench_MainActivity_BIND_WAIVE_PRIORITY +#define com_ndk_tflbench_MainActivity_BIND_WAIVE_PRIORITY 32L +#undef com_ndk_tflbench_MainActivity_CONTEXT_IGNORE_SECURITY +#define com_ndk_tflbench_MainActivity_CONTEXT_IGNORE_SECURITY 2L +#undef com_ndk_tflbench_MainActivity_CONTEXT_INCLUDE_CODE +#define com_ndk_tflbench_MainActivity_CONTEXT_INCLUDE_CODE 1L +#undef com_ndk_tflbench_MainActivity_CONTEXT_RESTRICTED +#define com_ndk_tflbench_MainActivity_CONTEXT_RESTRICTED 4L +#undef com_ndk_tflbench_MainActivity_MODE_APPEND +#define com_ndk_tflbench_MainActivity_MODE_APPEND 32768L +#undef com_ndk_tflbench_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING +#define com_ndk_tflbench_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L +#undef com_ndk_tflbench_MainActivity_MODE_MULTI_PROCESS +#define com_ndk_tflbench_MainActivity_MODE_MULTI_PROCESS 4L +#undef com_ndk_tflbench_MainActivity_MODE_NO_LOCALIZED_COLLATORS +#define com_ndk_tflbench_MainActivity_MODE_NO_LOCALIZED_COLLATORS 16L +#undef com_ndk_tflbench_MainActivity_MODE_PRIVATE +#define com_ndk_tflbench_MainActivity_MODE_PRIVATE 0L +#undef com_ndk_tflbench_MainActivity_MODE_WORLD_READABLE +#define com_ndk_tflbench_MainActivity_MODE_WORLD_READABLE 1L +#undef com_ndk_tflbench_MainActivity_MODE_WORLD_WRITEABLE +#define com_ndk_tflbench_MainActivity_MODE_WORLD_WRITEABLE 2L +#undef com_ndk_tflbench_MainActivity_RECEIVER_VISIBLE_TO_INSTANT_APPS +#define com_ndk_tflbench_MainActivity_RECEIVER_VISIBLE_TO_INSTANT_APPS 1L +#undef com_ndk_tflbench_MainActivity_DEFAULT_KEYS_DIALER +#define com_ndk_tflbench_MainActivity_DEFAULT_KEYS_DIALER 1L +#undef com_ndk_tflbench_MainActivity_DEFAULT_KEYS_DISABLE +#define com_ndk_tflbench_MainActivity_DEFAULT_KEYS_DISABLE 0L +#undef com_ndk_tflbench_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL +#define com_ndk_tflbench_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L +#undef com_ndk_tflbench_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL +#define com_ndk_tflbench_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L +#undef com_ndk_tflbench_MainActivity_DEFAULT_KEYS_SHORTCUT +#define com_ndk_tflbench_MainActivity_DEFAULT_KEYS_SHORTCUT 2L +#undef com_ndk_tflbench_MainActivity_RESULT_CANCELED +#define com_ndk_tflbench_MainActivity_RESULT_CANCELED 0L +#undef com_ndk_tflbench_MainActivity_RESULT_FIRST_USER +#define com_ndk_tflbench_MainActivity_RESULT_FIRST_USER 1L +#undef com_ndk_tflbench_MainActivity_RESULT_OK +#define com_ndk_tflbench_MainActivity_RESULT_OK -1L +/* + * Class: com_ndk_tflbench_MainActivity + * Method: getModelName + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_ndk_tflbench_MainActivity_getModelName(JNIEnv *, jobject); + +/* + * Class: com_ndk_tflbench_MainActivity + * Method: runInterpreterBenchmark + * Signature: (Ljava/nio/MappedByteBuffer;)V + */ +JNIEXPORT void JNICALL Java_com_ndk_tflbench_MainActivity_runInterpreterBenchmark(JNIEnv *, jobject, + jobject); + +/* + * Class: com_ndk_tflbench_MainActivity + * Method: runNNAPIBenchmark + * Signature: (Ljava/nio/MappedByteBuffer;)V + */ +JNIEXPORT void JNICALL Java_com_ndk_tflbench_MainActivity_runNNAPIBenchmark(JNIEnv *, jobject, + jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/runtimes/contrib/android_benchmark_app/java/com/ndk/tflbench/MainActivity.java b/runtimes/contrib/android_benchmark_app/java/com/ndk/tflbench/MainActivity.java new file mode 100644 index 0000000..14bf239 --- /dev/null +++ b/runtimes/contrib/android_benchmark_app/java/com/ndk/tflbench/MainActivity.java @@ -0,0 +1,110 @@ +package com.ndk.tflbench; + +import android.app.Activity; +import android.os.Bundle; +import android.content.Intent; +import android.view.View; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.TextView; +import android.widget.Button; +import android.net.Uri; +import android.content.res.AssetFileDescriptor; +import android.content.res.AssetManager; +import android.graphics.Bitmap; +import android.os.SystemClock; +import android.os.Trace; +import android.util.Log; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.PriorityQueue; +import java.util.Vector; + +public class MainActivity extends Activity { + + static { + System.loadLibrary("android_benchmark_native"); + } + + private void setModel(final String message) { + final TextView textView = (TextView)findViewById(R.id.model_label); + runOnUiThread(new Runnable() { + @Override + public void run() { textView.setText(message); } + }); + } + + private void setTitle(final String message) { + final TextView textView = (TextView)findViewById(R.id.title_label); + runOnUiThread(new Runnable() { + @Override + public void run() { textView.setText(message); } + }); + } + + private void setText(final String message) { + final TextView textView = (TextView)findViewById(R.id.message_label); + runOnUiThread(new Runnable() { + @Override + public void run() { textView.setText(message); } + }); + } + + private MappedByteBuffer buffer; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + setModel(getModelName()); + + // Load Tensorflow Lite model + try + { + AssetManager assets = getAssets(); + AssetFileDescriptor fileDescriptor = assets.openFd("model.tflite"); + FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor()); + FileChannel fileChannel = inputStream.getChannel(); + final long startOffset = fileDescriptor.getStartOffset(); + final long declaredLength = fileDescriptor.getDeclaredLength(); + + buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength); + } catch (IOException e) { + Log.e("MYAPP", "exception", e); + } + + Button btn_interp = (Button)findViewById(R.id.button_interp); + btn_interp.setOnClickListener(new Button.OnClickListener() { + @Override public void onClick(View view) { + new Thread(new Runnable() { + @Override + public void run() { runInterpreterBenchmark(buffer); } + }).start(); + } + }); + + Button btn_nnapi = (Button)findViewById(R.id.button_nnapi); + btn_nnapi.setOnClickListener(new Button.OnClickListener() { + @Override public void onClick(View view) { + new Thread(new Runnable() { + @Override + public void run() { runNNAPIBenchmark(buffer); } + }).start(); + } + }); + } + + public native String getModelName(); + public native void runInterpreterBenchmark(MappedByteBuffer buffer); + public native void runNNAPIBenchmark(MappedByteBuffer buffer); +} diff --git a/runtimes/contrib/android_benchmark_app/res/drawable-hdpi/ic_launcher.png b/runtimes/contrib/android_benchmark_app/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..96a442e Binary files /dev/null and b/runtimes/contrib/android_benchmark_app/res/drawable-hdpi/ic_launcher.png differ diff --git a/runtimes/contrib/android_benchmark_app/res/drawable-mdpi/ic_launcher.png b/runtimes/contrib/android_benchmark_app/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..359047d Binary files /dev/null and b/runtimes/contrib/android_benchmark_app/res/drawable-mdpi/ic_launcher.png differ diff --git a/runtimes/contrib/android_benchmark_app/res/drawable-xhdpi/ic_launcher.png b/runtimes/contrib/android_benchmark_app/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..71c6d76 Binary files /dev/null and b/runtimes/contrib/android_benchmark_app/res/drawable-xhdpi/ic_launcher.png differ diff --git a/runtimes/contrib/android_benchmark_app/res/drawable-xxhdpi/ic_launcher.png b/runtimes/contrib/android_benchmark_app/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..4df1894 Binary files /dev/null and b/runtimes/contrib/android_benchmark_app/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/runtimes/contrib/android_benchmark_app/res/layout/activity_main.xml b/runtimes/contrib/android_benchmark_app/res/layout/activity_main.xml new file mode 100644 index 0000000..5519525 --- /dev/null +++ b/runtimes/contrib/android_benchmark_app/res/layout/activity_main.xml @@ -0,0 +1,38 @@ + + +