development_doc.md 6.7 KB
Newer Older
W
wangliu 已提交
1 2
### iOS&Android开发文档

3 4 5 6
# iOS开发文档

## 编译

W
wangliu 已提交
7
```sh
L
liuruilong 已提交
8 9 10 11

# 在 paddle-mobile 目录下:
cd tools

12 13 14 15 16 17 18 19 20
sh build.sh ios

# 如果只想编译某个特定模型的 op, 则需执行以下命令
sh build.sh ios googlenet

# 在这个文件夹下, 你可以拿到生成的 .a 库
cd ../build/release/ios/build

```
L
liuruilong 已提交
21 22 23 24
#### 常见问题:

1. No iOS SDK's found in default search path ...

L
liuruilong 已提交
25
    这个问题是因为 tools/ios-cmake/ios.toolchain.cmake 找不到你最近使用的 iOS SDK 路径, 所以需要自己进行指定, 
L
liuruilong 已提交
26
    以我当前的环境为例: 在 tools/ios-cmake/ios.toolchain.cmake 143行前添加我本地的 iOS SDK 路径: set(CMAKE_IOS_SDK_ROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk")
27

L
liuruilong 已提交
28
## 集成
29 30

```
R
Ruilong Liu 已提交
31
将上一步生成的:
W
wangliu 已提交
32
libpaddle-mobile.a
33

R
Ruilong Liu 已提交
34
/src/ios_io/ 下的
35 36
PaddleMobile.h
```
L
liuruilong 已提交
37 38 39 40 41
拖入工程

#### oc 接口

接口如下:
42 43 44

```
/*
R
Ruilong Liu 已提交
45
	创建对象
46
*/
R
Ruilong Liu 已提交
47
- (instancetype)init;
48 49 50 51 52 53 54 55 56

/*
	load 模型, 开辟内存
*/
- (BOOL)load:(NSString *)modelPath andWeightsPath:(NSString *)weighsPath;

/*
	进行预测, means 和 scale 为训练模型时的预处理参数, 如训练时没有做这些预处理则直接使用 predict
*/
R
Ruilong Liu 已提交
57
- (NSArray *)predict:(CGImageRef)image dim:(NSArray<NSNumber *> *)dim means:(NSArray<NSNumber *> *)means scale:(float)scale;
58 59 60 61

/*
	进行预测
*/
R
Ruilong Liu 已提交
62
- (NSArray *)predict:(CGImageRef)image dim:(NSArray<NSNumber *> *)dim;
63 64 65 66 67 68 69 70 71

/*
	清理内存
*/
- (void)clear;

```


R
Ruilong Liu 已提交
72
# Android开发文档
73

W
wangliu 已提交
74 75 76 77 78 79 80 81 82 83 84 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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
用户可通过如下两种方式,交叉编译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/),用户可以自行前往下载,也可以通过以下命令获取:

```
wget https://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip
unzip android-ndk-r17b-darwin-x86_64.zip

```

##### 设置环境变量
工程中自带的独立工具链会根据环境变量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的体积更小的库。
176

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

W
wangliu 已提交
180 181 182 183 184
```
cd tools/android-debug-script
sh run_on_android.sh (npm) 可选参数npm,用于选择是否传输模型文件到手机上
```
出现如下提示:
185

W
wangliu 已提交
186 187 188 189 190
```
**** choose OP or NET to test ****
which to test :
```
输入名称即可运行对应的测试文件。
191

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

195 196
##### 1 load接口  加载模型参数
- 用于加载参数文件分散的模型
W
wangliu 已提交
197
```
198 199 200 201 202 203 204 205
/**
     * Load seperated parameters
     * @param modelDir
     * @return
     */
    public static native boolean load(String modelDir);
```
- 用于加载参数文件合并的模型文件
W
wangliu 已提交
206
```
207 208 209 210 211 212 213
/**
     * Load combined parameters
     * @param modelPath
     * @param paramPath
     * @return
     */
    public static native boolean loadCombined(String modelPath,String paramPath);
214

215
```
W
wangliu 已提交
216
##### 2 predict接口 执行预测
217
- 接受预处理过的RGB数组的predict接口
W
wangliu 已提交
218 219 220 221
```
/**
*@param buf 输入数据
*@return 输出数据
222
JNIEXPORT jfloatArray JNICALL Java_com_baidu_paddle_PML_predictImage(
W
wangliu 已提交
223 224
    JNIEnv *env, jclass thiz, jfloatArray buf);
```
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
- 接受原始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 已提交
240
##### 3 clear接口 销毁实例、清理内存操作
241

W
wangliu 已提交
242 243 244 245
```
JNIEXPORT void JNICALL Java_com_baidu_paddle_PMLL_clear(JNIEnv *env,
                                                        jclass thiz);
```
246 247