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)
# 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)
# 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)
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.ndk.tflbench" >
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.ndk.tflbench.MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
--- /dev/null
+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 $<TARGET_FILE:android_benchmark_native> ${LIB_DIR}
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:neurun> ${LIB_DIR}
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:neurun_backend_acl_cl> ${LIB_DIR}
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:arm_compute_ex> ${LIB_DIR}
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:neurun_backend_acl_neon> ${LIB_DIR}
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:neurun_backend_cpu> ${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)
--- /dev/null
+# 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
+```
--- /dev/null
+#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 <boost/accumulators/accumulators.hpp>
+#include <boost/accumulators/statistics/stats.hpp>
+#include <boost/accumulators/statistics/mean.hpp>
+#include <boost/accumulators/statistics/min.hpp>
+#include <boost/accumulators/statistics/max.hpp>
+
+#include <cassert>
+#include <chrono>
+#include <sstream>
+
+#include <android/log.h>
+
+using namespace tflite;
+using namespace tflite::ops::builtin;
+
+static StderrReporter error_reporter;
+
+static std::unique_ptr<FlatBufferModel> 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<FlatBufferModel> loadModel(JNIEnv *env, jobject thisObj,
+ jobject model_buffer)
+{
+ const char *model_base = static_cast<char *>(env->GetDirectBufferAddress(model_buffer));
+ jlong model_size = env->GetDirectBufferCapacity(model_buffer);
+
+ return FlatBufferModel::BuildFromBuffer(model_base, static_cast<size_t>(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<void(void)> &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<void(void)> _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<double, stats<tag::mean, tag::min, tag::max>> 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> 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> 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"}; \
+ } \
+ }
--- /dev/null
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* 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
--- /dev/null
+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);
+}
--- /dev/null
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <Button android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/button_interp"
+ android:text="Run Interp benchmark"/>
+
+ <Button android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/button_nnapi"
+ android:text="Run NNAPI benchmark"/>
+
+ <TextView android:text=""
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/model_label"
+ android:layout_centerHorizontal="true"
+ android:textSize="16dp"/>
+
+ <TextView android:text=""
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/title_label"
+ android:layout_centerHorizontal="true"
+ android:textSize="16dp"/>
+
+ <TextView android:text=""
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/message_label"
+ android:layout_centerHorizontal="true"
+ android:textSize="16dp"/>
+
+</LinearLayout>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <style name="AppTheme" parent="android:Theme.Material.Light">
+ </style>
+</resources>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">T/F Lite Benchmark</string>
+
+</resources>