development_android.md 5.4 KB
Newer Older
R
Ruilong Liu 已提交
1
# Android开发文档
2

W
wangliu 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
用户可通过如下两种方式,交叉编译Android平台上适用的paddle-mobile库:

- 基于Docker容器编译
- 基于Linux交叉编译


## 基于Docker容器编译
### 1. 安装 docker
安装 docker 的方式,参考官方文档 [https://docs.docker.com/install/](https://docs.docker.com/install/)
### 2. 使用 docker 搭建构建环境
首先进入 paddle-mobile 的目录下,执行 `docker build`
以 Linux/Mac 为例 (windows 建议在 'Docker Quickstart Terminal' 中执行)

```
$ docker build -t paddle-mobile:dev - < Dockerfile
```
使用 `docker images` 可以看到我们新建的 image

```
$ docker images
REPOSITORY      TAG     IMAGE ID       CREATED         SIZE
paddle-mobile   dev     33b146787711   45 hours ago    372MB
```
### 3. 使用 docker 构建
进入 paddle-mobile 目录,执行 docker run

```
$ docker run -it --mount type=bind,source=$PWD,target=/paddle-mobile paddle-mobile:dev
root@5affd29d4fc5:/ # cd /paddle-mobile
# 生成构建 android 产出的 Makefile
root@5affd29d4fc5:/ # rm CMakeCache.txt
root@5affd29d4fc5:/ # cmake -DCMAKE_TOOLCHAIN_FILE=tools/toolchains/arm-android-neon.cmake
# 生成构建 linux 产出的 Makefile
root@5affd29d4fc5:/ # rm CMakeCache.txt
root@5affd29d4fc5:/ # cmake -DCMAKE_TOOLCHAIN_FILE=tools/toolchains/arm-linux-gnueabi.cmake
```
### 4. 设置编译选项
可以通过 ccmake 设置编译选项

```
root@5affd29d4fc5:/ # ccmake .
                                                     Page 1 of 1
 CMAKE_ASM_FLAGS
 CMAKE_ASM_FLAGS_DEBUG
 CMAKE_ASM_FLAGS_RELEASE
 CMAKE_BUILD_TYPE
 CMAKE_INSTALL_PREFIX             /usr/local
 CMAKE_TOOLCHAIN_FILE             /paddle-mobile/tools/toolchains/arm-android-neon.cmake
 CPU                              ON
 DEBUGING                         ON
 FPGA                             OFF
 LOG_PROFILE                      ON
 MALI_GPU                         OFF
 NET                              googlenet
 USE_EXCEPTION                    ON
 USE_OPENMP                       OFF
```
修改选项后,按 `c`, `g` 更新 Makefile
### 5. 构建
使用 make 命令进行构建

```
root@5affd29d4fc5:/ # make
```
### 6. 查看构建产出
构架产出可以在 host 机器上查看,在 paddle-mobile 的目录下,build 以及 test/build 下,可以使用 adb 指令或者 scp 传输到 device 上执行

## 基于Linux交叉编译
### 交叉编译环境准备
##### 下载Android NDK

从源码交叉编译paddle-mobile,用户需要提前准备好交叉编译环境。Android平台使用的C/C++交叉编译工具链是[Android NDK](https://developer.android.com/ndk/),用户可以自行前往下载,也可以通过以下命令获取:
W
wangliu 已提交
75
- Mac平台
W
wangliu 已提交
76 77 78 79
```
wget https://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip
unzip android-ndk-r17b-darwin-x86_64.zip

W
wangliu 已提交
80 81 82 83 84
```
- Linux平台
```
wget https://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip
unzip android-ndk-r17b-linux-x86_64.zip
W
wangliu 已提交
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
```

##### 设置环境变量
工程中自带的独立工具链会根据环境变量NDK_ROOT查找NDK,因此需要配置环境变量:

```
export NDK_ROOT = "path to ndk"
```
### 执行编译
在paddle-mobile根目录中,执行以下命令:

```
cd tools
sh build.sh android

```
执行完毕后,生成的so位于build目录中,单测可执行文件位于test/build目录中。
##### Tips:
如果想要获得体积更小的库,可选择编译支持指定模型结构的库。
如执行如下命令:

```
sh build.sh android googlenet
```
会得到一个支持googlnet的体积更小的库。
110

W
wangliu 已提交
111 112
##测试
在编译完成后,我们提供了自动化的测试脚本,帮助用户将运行单测文件所需要的模型及库文件push到Android设备中,执行以下命令:
113

W
wangliu 已提交
114 115 116 117 118
```
cd tools/android-debug-script
sh run_on_android.sh (npm) 可选参数npm,用于选择是否传输模型文件到手机上
```
出现如下提示:
119

W
wangliu 已提交
120 121 122 123 124
```
**** choose OP or NET to test ****
which to test :
```
输入名称即可运行对应的测试文件。
125

W
wangliu 已提交
126 127
##部署
Android应用可通过JNI接口调用底层C/C++,paddle-mobile对外提供的JNI接口如下:
128

129 130
##### 1 load接口  加载模型参数
- 用于加载参数文件分散的模型
W
wangliu 已提交
131
```
132 133 134 135 136 137 138 139
/**
     * Load seperated parameters
     * @param modelDir
     * @return
     */
    public static native boolean load(String modelDir);
```
- 用于加载参数文件合并的模型文件
W
wangliu 已提交
140
```
141 142 143 144 145 146 147
/**
     * Load combined parameters
     * @param modelPath
     * @param paramPath
     * @return
     */
    public static native boolean loadCombined(String modelPath,String paramPath);
148

149
```
W
wangliu 已提交
150
##### 2 predict接口 执行预测
151
- 接受预处理过的RGB数组的predict接口
W
wangliu 已提交
152 153 154 155
```
/**
*@param buf 输入数据
*@return 输出数据
156
JNIEXPORT jfloatArray JNICALL Java_com_baidu_paddle_PML_predictImage(
W
wangliu 已提交
157 158
    JNIEnv *env, jclass thiz, jfloatArray buf);
```
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
- 接受原始yuv数据的predict接口
```
 /**
     *
     * @param buf yuv420格式的字节数组
     * @param imgWidth yuv数据的宽
     * @param imgHeight yuv数据的高
     * @param ddims 输入数据的形状
     * @param meanValues 模型训练时各通道的均值
     * @return
     */

    public static native float[] predictYuv(byte[] buf, int imgWidth, int imgHeight, int[] ddims, float[]meanValues);

```
W
wangliu 已提交
174
##### 3 clear接口 销毁实例、清理内存操作
175

W
wangliu 已提交
176 177 178 179
```
JNIEXPORT void JNICALL Java_com_baidu_paddle_PMLL_clear(JNIEnv *env,
                                                        jclass thiz);
```
180 181