From 5d04a13078398303608fd74c57681891382ffec5 Mon Sep 17 00:00:00 2001 From: wangliu Date: Fri, 8 Jun 2018 17:14:09 +0800 Subject: [PATCH] add jni interface --- CMakeLists.txt | 18 +++++-- src/common/log.h | 22 +++++++++ src/jni/paddle_mobile_jni.cpp | 93 +++++++++++++++++++++++++++++++++++ src/jni/paddle_mobile_jni.h | 51 +++++++++++++++++++ 4 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 src/jni/paddle_mobile_jni.cpp create mode 100644 src/jni/paddle_mobile_jni.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 989f96e311..aa4895227c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.0) project(paddle-mobile) -option(DEBUGING "enable debug mode" OFF) +option(DEBUGING "enable debug mode" ON) option(USE_OPENMP "openmp support" OFF) option(USE_EXCEPTION "use std exception" OFF) @@ -11,10 +11,13 @@ else() set(CMAKE_BUILD_TYPE Release) endif () - if(DEBUGING) message(STATUS "debuging") add_definitions(-DPADDLE_MOBILE_DEBUG) + if(ANDROID) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -llog") + endif() + else() message(STATUS "releasing") add_definitions(-fvisibility=hidden -fvisibility-inlines-hidden) @@ -49,6 +52,12 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build) file(GLOB_RECURSE PADDLE_MOBILE_CC src/*.cc src/*.cpp src/*.c) file(GLOB_RECURSE PADDLE_MOBILE_H src/*.h) +if (NOT ANDROID) +list(REMOVE_ITEM PADDLE_MOBILE_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/jni/*.cpp) +list(REMOVE_ITEM PADDLE_MOBILE_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/jni/*.h) +list(REMOVE_ITEM PADDLE_MOBILE_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/operators/math/math_func_neon.h) +endif () + include_directories(src/) if(USE_OPENMP) @@ -118,10 +127,11 @@ else () add_definitions(-DTRANSPOSE_OP) endif() + add_library(paddle-mobile SHARED ${PADDLE_MOBILE_CC} ${PADDLE_MOBILE_H}) -if(DEBUGING) +#if(DEBUGING) add_subdirectory(test) -endif() +#endif() diff --git a/src/common/log.h b/src/common/log.h index 052fb7df2b..0be2bb79fc 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -20,11 +20,33 @@ limitations under the License. */ #include #include #endif +#ifdef ANDROID +#include +#endif namespace paddle_mobile { #ifdef PADDLE_MOBILE_DEBUG +#ifdef ANDROID + +extern const char *ANDROID_LOG_TAG; + +#define LOGI(...) \ + __android_log_print(ANDROID_LOG_INFO, ANDROID_LOG_TAG, __VA_ARGS__); \ + printf(__VA_ARGS__) +#define LOGW(...) \ + __android_log_print(ANDROID_LOG_WARNING, ANDROID_LOG_TAG, __VA_ARGS__); \ + printf(__VA_ARGS__) +#define LOGD(...) \ + __android_log_print(ANDROID_LOG_DEBUG, ANDROID_LOG_TAG, __VA_ARGS__); \ + printf(__VA_ARGS__) +#define LOGE(...) \ + __android_log_print(ANDROID_LOG_ERROR, ANDROID_LOG_TAG, __VA_ARGS__); \ + printf(__VA_ARGS__) + +#endif + enum LogLevel { kNO_LOG, kLOG_ERROR, diff --git a/src/jni/paddle_mobile_jni.cpp b/src/jni/paddle_mobile_jni.cpp new file mode 100644 index 0000000000..f663b78fd4 --- /dev/null +++ b/src/jni/paddle_mobile_jni.cpp @@ -0,0 +1,93 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. 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. */ + +#ifdef ANDROID + +#include "paddle_mobile_jni.h" +#ifdef __cplusplus +extern "C" { +#endif +namespace paddle_mobile { +namespace jni { +using framework::DDim; +using framework::Program; +using framework::Tensor; +using paddle_mobile::CPU; +using std::string; + +extern const char *ANDROID_LOG_TAG = + "paddle_mobile LOG built on " __DATE__ " " __TIME__; +static Executor *shared_executor_instance = nullptr; + +// toDo mutex lock +// static std::mutex shared_mutex; + +Executor *getExecutorInstance(const Program p, int batch_size, + bool use_optimize) { + if (nullptr == shared_executor_instance) { + shared_executor_instance = new Executor(p, batch_size, use_optimize); + } + return shared_executor_instance; +} + +string jstring2cppstring(JNIEnv *env, jstring jstr) { + const char *cstr = env->GetStringUTFChars(jstr, 0); + string cppstr(cstr); + env->ReleaseStringUTFChars(jstr, cstr); + return cppstr; +} + +JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_load(JNIEnv *env, + jclass thiz, + jstring modelPath) { + paddle_mobile::Loader loader; + bool optimize = true; + auto program = loader.Load(jstring2cppstring(env, modelPath), optimize); + shared_executor_instance = getExecutorInstance(program, 1, optimize); + return shared_executor_instance != nullptr ? JNI_TRUE : JNI_FALSE; +} + +JNIEXPORT jfloatArray JNICALL Java_com_baidu_paddle_PML_predictImage( + JNIEnv *env, jclass thiz, jfloatArray buf) { + jfloatArray result = NULL; + int count = 0; + float *dataPointer = nullptr; + if (nullptr != buf) { + dataPointer = env->GetFloatArrayElements(buf, NULL); + } + framework::Tensor input; + framework::DDim ddim = framework::make_ddim({1, 3, 224, 224}); + input.Resize(ddim); + auto input_ptr = input.mutable_data(); + for (int i = 0; i < framework::product(ddim); i++) { + input_ptr[i] = dataPointer[i]; + } + auto output = shared_executor_instance->Predict(input); + count = output->numel(); + result = env->NewFloatArray(count); + env->SetFloatArrayRegion(result, 0, count, output->data()); + return result; +} + +JNIEXPORT void JNICALL Java_com_baidu_paddle_PML_clear(JNIEnv *env, + jclass thiz) {} + +} // namespace jni +} // namespace paddle_mobile + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/jni/paddle_mobile_jni.h b/src/jni/paddle_mobile_jni.h new file mode 100644 index 0000000000..a262d4070c --- /dev/null +++ b/src/jni/paddle_mobile_jni.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. 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. */ + +#pragma once +#ifdef ANDROID +#include +#include "common/log.h" +#include "framework/tensor.h" +#include "io/io.h" + +#ifdef __cplusplus +extern "C" { +#endif +namespace paddle_mobile { +namespace jni { +/** + * load model & params of the net for android + */ +JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_load(JNIEnv *env, + jclass thiz, + jstring modelPath); + +/** + * object detection for anroid + */ +JNIEXPORT jfloatArray JNICALL Java_com_baidu_paddle_PML_predictImage( + JNIEnv *env, jclass thiz, jfloatArray buf); + +/** + * clear data of the net when destroy for android + */ +JNIEXPORT void JNICALL Java_com_baidu_paddle_PMLL_clear(JNIEnv *env, + jclass thiz); +} // namespace jni +} // namespace paddle_mobile +#ifdef __cplusplus +} +#endif + +#endif -- GitLab