From 6b7218e641b071f4160bc7cd9fb796d69f8878dd Mon Sep 17 00:00:00 2001 From: Yuan Shuai Date: Fri, 8 May 2020 16:17:34 +0800 Subject: [PATCH] [DOC] Enhance opencl docs for releasev2.6.0. (#3569) * ehance opencl docs for releasev2.6.0. --- docs/demo_guides/opencl.md | 139 +++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 67 deletions(-) diff --git a/docs/demo_guides/opencl.md b/docs/demo_guides/opencl.md index e255038575..3e7e49fc96 100644 --- a/docs/demo_guides/opencl.md +++ b/docs/demo_guides/opencl.md @@ -2,53 +2,57 @@ Lite支持在Android系统上运行基于OpenCL的程序,目前支持Ubuntu环境下armv8、armv7的交叉编译。 -## 编译 +## 1. 编译 -### 编译环境 +### 1.1 编译环境 1. Docker 容器环境; 2. Linux(推荐 Ubuntu 16.04)环境。 详见 **源码编译指南-环境准备** 章节。 -### 编译Paddle-Lite OpenCL库范例 +### 1.2 编译Paddle-Lite OpenCL库范例 -注:以android-armv8-opencl的目标、Docker容器的编译开发环境为例,CMake3.10,android-ndk-r17c位于`/opt/`目录下。 +注:以android/armv7/opencl的目标、Docker容器的编译开发环境为例,CMake3.10,android-ndk-r17c位于`/opt/`目录下。 -#### 针对 Lite 用户的编译命令(无单元测试,有编译产物) +#### 针对 Lite 用户的编译命令(无单元测试,有编译产物,适用于benchmark) -- `arm_os`: `[android]`,目前不支持linux; +- `with_opencl`: `[ON | OFF]`,编译OpenCL必选; - `arm_abi`: `[armv7 | armv8]`; -- `arm_lang`: `[gcc]`,目前不支持clang; -- `build_extra`: `[OFF | ON]`,编译全量op和kernel,体积会大,编译时间长; +- `toolchain`: `[gcc | clang]`; +- `build_extra`: `[OFF | ON]`,编译全量op和kernel,包含控制流NLP相关的op和kernel体积会大,编译时间长; - `build_cv`: `[OFF | ON]`,编译arm cpu neon实现的的cv预处理模块; -- `android_stl`: `[c++_shared | c++_static]`,paddlelite的库以何种方式链接`android_stl`,选择`c++_shared`得到的动态库体积更小,但使用时候记得上传paddlelite所编译版本(armv7或armv8)一致的`libc++_shared.so`(来自Android-NDK); -注:调用`./lite/tools/build.sh`执行编译。 +- `android_stl`: `[c++_shared | c++_static | gnu_static | gnu_shared]`,paddlelite的库以何种方式链接`android_stl`,选择`c++_shared`得到的动态库体积更小,但使用时候记得上传paddlelite所编译版本(armv7或armv8)一致的`libc++_shared.so`。默认使用`c++_static`。 ```bash -# 假设当前位于处于Lite源码根目录下 +###################################### +# 假设当前位于处于Lite源码根目录下 # +###################################### -# 导入NDK_ROOT变量,注意检查您的安装目录若与本示例不同 +# 导入NDK_ROOT变量,注意检查NDK安装目录若与本示例是否不同 export NDK_ROOT=/opt/android-ndk-r17c # 删除上一次CMake自动生成的.h文件 rm ./lite/api/paddle_use_kernels.h rm ./lite/api/paddle_use_ops.h -# 根据指定编译参数编译 -./lite/tools/build.sh \ - --arm_os=android \ - --arm_abi=armv8 \ - --arm_lang=gcc \ - --build_extra=OFF \ - --build_cv=OFF \ - --android_stl=c++_shared \ - opencl +# 设置编译参数并开始编译 +./lite/tools/build_android.sh \ + --arm_abi=armv7 \ + --toolchain=clang \ + --with_cv=OFF \ + --with_log=OFF \ + --with_extra=OFF \ + --with_opencl=ON + +# 注:编译帮助请执行: ./lite/tools/build_android.sh help ``` +注:该方式的编译产物中的`demo/cxx/mobile_light`适用于做benchmark,该过程不会打印开发中加入的log,注意需要提前转好模型。关于使用,详见下文**运行示例1: 编译产物demo示例**。 + #### 针对 Lite 开发者的编译命令(有单元测试,编译产物) -注:调用`./lite/tools/ci_build.sh`执行编译,该命令会编译armv7和armv8的opencl库。虽然有编译产物,但因编译单元测试,编译产物包体积可能较大,不推荐使用。 +注:调用`./lite/tools/ci_build.sh`执行编译,该命令会编译armv7和armv8的opencl库。虽然有编译产物,但因编译单元测试,编译产物包体积可能较大,生产环境不推荐使用。 ```bash # 假设当前位于处于Lite源码根目录下 @@ -70,13 +74,13 @@ rm ./lite/api/paddle_use_ops.h 注:如果要调试cl kernel,假设已经完成上述脚本编译(已生成cmake文件)。调试只需要修改`./lite/backends/opencl/cl_kernel/`下对应的kernel文件,保存后在项目根目录执行`python ./lite/tools/cmake_tools/gen_opencl_code.py ./lite/backends/opencl/cl_kernel ./lite/backends/opencl/opencl_kernels_source.cc`,该命令会自动将修改后,再切到build目录下执行`make publish_inference`或者你要编译的单测的可执行文件名,cl kernel文件的内容会随着编译自动打包到产物包如 .so 中或者对应单测可执行文件中。 -### 编译产物说明 +### 1.3 编译产物说明 -编译产物位于`build.lite.android.armv8.gcc.opencl`下的`inference_lite_lib.android.armv8.opencl`文件夹内,这里仅罗列关键产物: +编译产物位于`build.lite.android.armv8.gcc.opencl`下的`inference_lite_lib.android.armv8.opencl`文件夹内,根据编译参数不同,文件夹名字会略有不同。这里仅罗列关键产物: - `cxx`:该目录是编译目标的C++的头文件和库文件; - `demo`:该目录包含了两个demo,用来调用使用`libpaddle_api_full_bundled.a`和`libpaddle_api_light_bundled.a`,分别对应`mobile_full`和`mobile_light`文件夹。编译对应的demo仅需在`mobile_full`或`mobile_light`文 - - `mobile_full`:使用cxx config,可直接加载fluid模型,若使用OpenCL需要在`mobilenetv1_full_api.cc`代码里开启`DEMO_USE_OPENCL`的宏,详细见代码注释; + - `mobile_full`:使用cxx config,可直接加载fluid模型,若使用OpenCL需要在`mobilenetv1_full_api.cc`代码里开启`DEMO_USE_OPENCL`的宏,详细见该文件的代码注释; - `mobile_light`:使用mobile config,只能加载`model_optimize_tool`优化过的模型。 注:`opencl`实现的相关kernel已经打包到动态库中。 @@ -119,47 +123,48 @@ rm ./lite/api/paddle_use_ops.h -## 运行示例 - -下面以android、ARMv8、gcc的环境为例,介绍3个示例,分别如何在手机上执行基于OpenCL的ARM GPU推理过程。 +## 2. 运行示例 -### 运行示例1: 编译产物demo示例 +下面以android的环境为例,介绍3个示例,分别如何在手机上执行基于OpenCL的ARM GPU推理过程。 -```bash -###################################################################### -# 编译mobile_light的demo # -###################################################################### -# 步骤: # -# 0.确保编译Paddle-Lite时编译了OpenCL; # -# 1.编译model_optimize_tool并对模型优化, `targets`参数为`opencl`; # -# 2.在产物目录`demo/cxx/mobile_light`下编译`mobile_light`的demo; # -# 3.上传demo, 模型文件到手机; # -# 4.运行demo得到预期结果. # -###################################################################### -# 在/data/local/tmp目录下创建OpenCL文件目录 -adb shell mkdir -p /data/local/tmp/opencl +### 2.1 运行示例1: 编译产物demo示例和benchmark -# use model_optimize_tool to optimize model -./build.model_optimize_tool/lite/api/model_optimize_tool \ - --model_dir=./build.lite.android.armv8.gcc.opencl/install/mobilenet_v1/ \ - --optimize_out_type=naive_buffer \ - --optimize_out=./build.lite.android.armv8.gcc.opencl/install/mobilenet_v1/mobilenetv1_opt \ - --valid_targets=opencl +需要提前用模型优化工具opt转好模型(下面假设已经转换好模型,且模型名为`mobilenetv1_opencl_fp32_opt_releasev2.6_b8234efb_20200423.nb`)。编译脚本为前文**针对 Lite 用户的编译命令(无单元测试,有编译产物,适用于benchmark)**。 -adb shell mkdir /data/local/tmp/opencl/mobilenet_v1/ -chmod +x ./build.lite.android.armv8.gcc.opencl/inference_lite_lib.android.armv8.opencl/demo/cxx/mobile_light/mobilenetv1_light_api -adb push ./build.lite.android.armv8.gcc.opencl/inference_lite_lib.android.armv8.opencl/demo/cxx/mobile_light/mobilenetv1_light_api /data/local/tmp/opencl/ -adb push ./build.lite.android.armv8.gcc.opencl/install/mobilenet_v1/mobilenetv1_opt.nb /data/local/tmp/opencl/ - -# use mobile_light run mobilenet_v1 -adb shell "export GLOG_v=1; \ - /data/local/tmp/opencl/mobilenetv1_light_api \ - /data/local/tmp/opencl/mobilenetv1_opt.nb" +```bash +################################# +# 假设当前位于build.xxx目录下 # +################################# + +# prepare enviroment on phone +adb shell mkdir -p /data/local/tmp/opencl/ + +# build demo +cd inference_lite_lib.android.armv7.opencl/demo/cxx/mobile_light/ +make +cd - + +# push executable binary, library to device +adb push inference_lite_lib.android.armv7.opencl/demo/cxx/mobile_light/mobilenetv1_light_api /data/local/tmp/opencl/ +adb shell chmod +x /data/local/tmp/opencl/mobilenetv1_light_api +adb push inference_lite_lib.android.armv7.opencl/cxx/lib/libpaddle_light_api_shared.so /data/local/tmp/opencl/ + +# push model with optimized(opt) to device +adb push ./mobilenetv1_opencl_fp32_opt_releasev2.6_b8234efb_20200423.nb /data/local/tmp/opencl/ + +# run demo on device +adb shell "export LD_LIBRARY_PATH=/data/local/tmp/opencl/; \ + /data/local/tmp/opencl/mobilenetv1_light_api \ + /data/local/tmp/opencl/mobilenetv1_opencl_fp32_opt_releasev2.6_b8234efb_20200423.nb \ + 1 3 224 224 \ + 100 10 0" # round=100, warmup=10, print_output_tensor=0 ``` -**注:** `GLOG_v`是指定需要显示VLOG的日志级别,默认为0。权重参数会在第一次运行时加载,所以第一次执行时间略长。一般将warmup的值设为10,repeats值设为多次。 +**注:** 权重参数会在第一次运行时加载,所以第一次执行时间略长。一般将warmup的值设为10,repeats值设为多次。 + +### 2.2 运行示例2: test_mobilenetv1单元测试 -### 运行示例2: test_mobilenetv1单元测试 +编译脚本为前文**针对 Lite 开发者的编译命令(有单元测试,编译产物)**。 - **运行文件准备** @@ -181,27 +186,27 @@ adb push build.lite.android.armv8.gcc.opencl/lite/api/test_mobilenetv1 /data/loc adb shell chmod +x /data/local/tmp/opencl/test_mobilenetv1 adb shell "export GLOG_v=1; \ - /data/local/tmp/opencl-image/test_mobilenetv1 \ - --model_dir=/data/local/tmp/opencl-image/mobilenetv1_fluid/ \ + /data/local/tmp/opencl/test_mobilenetv1 \ + --model_dir=/data/local/tmp/opencl/mobilenetv1_fluid/ \ --warmup=10 \ --repeats=100" ``` -### 运行示例3: test_layout_opencl单元测试 +### 2.3 运行示例3: test_layout_opencl单元测试 + +编译脚本为前文**针对 Lite 开发者的编译命令(有单元测试,编译产物)**。 ```bash adb shell mkdir -p /data/local/tmp/opencl +adb push build.lite.android.armv8.gcc.opencl/lite/kernels/opencl/test_layout_opencl /data/local/tmp/opencl/ adb shell chmod +x /data/local/tmp/opencl/test_layout_opencl adb shell "export GLOG_v=4; \ /data/local/tmp/opencl/test_layout_opencl" ``` -### 如何在Code中使用 - -见运行示例1的demo代码: +## 3. 如何在Code中使用 -1. [./lite/demo/cxx/mobile_light/mobilenetv1_light_api.cc](https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/lite/demo/cxx/mobile_light/mobilenetv1_light_api.cc); -2. [./lite/demo/cxx/mobile_full/mobilenetv1_full_api.cc](https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/lite/demo/cxx/mobile_full/mobilenetv1_full_api.cc). +即编译产物`demo/cxx/mobile_light`目录下的代码,在线版参考GitHub仓库[./lite/demo/cxx/mobile_light/mobilenetv1_light_api.cc](https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/lite/demo/cxx/mobile_light/mobilenetv1_light_api.cc); 注:这里给出的链接会跳转到线上最新develop分支的代码,很可能与您本地的代码存在差异,建议参考自己本地位于`lite/demo/cxx/`目录的代码,查看如何使用。 -- GitLab