未验证 提交 bc15d7ef 编写于 作者: Y Yuan Shuai 提交者: GitHub

[DOC][OPENCL] Fix opencl demo (#2492)

* [LITE][OPENCL] fix v2.1.0 opencl doc
上级 c36d7b1e
...@@ -232,52 +232,9 @@ adb shell /data/local/tmp/opencl/test_layout_opencl ...@@ -232,52 +232,9 @@ adb shell /data/local/tmp/opencl/test_layout_opencl
# 如何在Code中使用 # 如何在Code中使用
见运行示例1的demo代码:
注意:推荐用户首先参考前文中提到的编译产物`demo`中的使用方法。 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).
下面对单测中的代码进行讲解,Lite支持对ARM CPU和ARM GPU的混调执行,具体描述如下:
注:这里给出的链接会跳转到线上最新develop分支的代码,很可能与您本地的代码存在差异,建议参考自己本地位于`lite/demo/cxx/`目录的代码,查看如何使用。
- 设置Lite推断执行的有效Places,使其包含ARM CPU(kARM)和ARM GPU(kOpenCL);
- 确保GPU(kOpenCL)在第一位,位置代表Places的重要性和kernel选择有直接关系。
通过以上设置,Lite在推断执行过程中如果发现某一Op存在着基于OpenCL的实现,其会优先选择使用该实现执行Op的计算过程。若发现某一Op没有基于OpenCL实现的Kernel,其会自动选择执行基于ARM CPU的实现。
代码示例(来自`lite/api/mobilenetv1_test.cc`):
```cpp
// 初始化预测实例、CPU线程数、CPU策略
DeviceInfo::Init();
DeviceInfo::Global().SetRunMode(LITE_POWER_HIGH, FLAGS_threads);
lite::Predictor predictor;
// 设置Lite推断执行的硬件信息Places为{kOpenCL, kARM}
std::vector<Place> valid_places({
Place({TARGET(kOpenCL), PRECISION(kFP16), DATALAYOUT(kNHWC)}),
Place({TARGET(kOpenCL), PRECISION(kFP16), DATALAYOUT(kNCHW)}),
Place({TARGET(kOpenCL), PRECISION(kFloat), DATALAYOUT(kNHWC)}),
Place({TARGET(kOpenCL), PRECISION(kFloat), DATALAYOUT(kNCHW)}),
Place({TARGET(kARM), PRECISION(kFloat)})
});
// 根据Place构建模型
predictor.Build(model_dir, "", "", valid_places);
// 设置模型的输入
auto* input_tensor = predictor.GetInput(0);
input_tensor->Resize(DDim(std::vector<DDim::value_type>({1, 3, 224, 224})));
auto* data = input_tensor->mutable_data<float>();
auto item_size = input_tensor->dims().production();
for (int i = 0; i < item_size; i++) {
data[i] = 1;
}
// 执行模型推断
predictor.Run();
// 获取模型的预测结果tensor
// 下面展示如何取出第一个输入tensor,及其维度,元素个数,指针
auto* out0_tensor = predictor.GetOutput(0);
auto out0_dims = out0_tensor->dims();
auto out0_item_size = out0_tensor->dims().production();
auto* out0_pointer = out0_tensor->data<float>();
```
...@@ -22,9 +22,9 @@ Lite支持在Android系统上运行基于OpenCL的程序,目前支持Ubuntu环 ...@@ -22,9 +22,9 @@ Lite支持在Android系统上运行基于OpenCL的程序,目前支持Ubuntu环
|--arm_abi|代表体系结构类型,支持armv8和armv7|默认为`armv8`即arm64-v8a;`armv7`即armeabi-v7a| |--arm_abi|代表体系结构类型,支持armv8和armv7|默认为`armv8`即arm64-v8a;`armv7`即armeabi-v7a|
|--arm_lang|代表编译目标文件所使用的编译器|默认为gcc,支持 gcc和clang两种| |--arm_lang|代表编译目标文件所使用的编译器|默认为gcc,支持 gcc和clang两种|
### 编译范例 ### 编译Paddle-Lite OpenCL库范例
注:以Docker容器环境为例,CMake3.10,android-ndk-r17c位于`/opt/`目录下。 注:以android-armv8-opencl的目标、Docker容器的编译开发环境为例,CMake3.10,android-ndk-r17c位于`/opt/`目录下。
```bash ```bash
# 假设当前位于处于Lite源码根目录下 # 假设当前位于处于Lite源码根目录下
...@@ -44,10 +44,75 @@ rm ./lite/api/paddle_use_ops.h ...@@ -44,10 +44,75 @@ rm ./lite/api/paddle_use_ops.h
build_test_arm_opencl build_test_arm_opencl
``` ```
## 运行示例准备 编译产物位于`build.lite.android.armv8.gcc.opencl`下的`inference_lite_lib.android.armv8.opencl`文件夹内,这里仅罗列关键产物:
下面以android、ARMv8、gcc的环境为例,介绍如何在手机上执行基于OpenCL的ARM GPU推理过程。 - `cxx`:该目录是编译目标的C++的头文件和库文件;
**注意:** 以下命令均在Lite源码根目录下运行。 - `demo`:该目录包含了两个demo,用来调用使用`libpaddle_api_full_bundled.a``libpaddle_api_light_bundled.a`,分别对应`mobile_full``mobile_light`文件夹。编译对应的demo仅需在`mobile_full``mobile_light`文件夹下执行`make`命令即可:
- `mobile_full`:使用cxx config,可直接加载fluid模型,若使用OpenCL需要在`mobilenetv1_full_api.cc`代码里开启`DEMO_USE_OPENCL`的宏,详细见代码注释;
- `mobile_light`:使用mobile config,只能加载`model_optimize_tool`优化过的模型;
- `opencl`:该目录存放opencl实现的相关kernel。
```bash
.
|-- cxx
| |-- include
| | |-- paddle_api.h
| | |-- paddle_image_preprocess.h
| | |-- paddle_lite_factory_helper.h
| | |-- paddle_place.h
| | |-- paddle_use_kernels.h
| | |-- paddle_use_ops.h
| | `-- paddle_use_passes.h
| `-- lib
| |-- libpaddle_api_full_bundled.a
| |-- libpaddle_api_light_bundled.a
| |-- libpaddle_full_api_shared.so
| `-- libpaddle_light_api_shared.so
|-- demo
| `-- cxx
| |-- Makefile.def
| |-- README.md
| |-- include
| | |-- paddle_api.h
| | |-- paddle_lite_factory_helper.h
| | |-- paddle_place.h
| | |-- paddle_use_kernels.h
| | |-- paddle_use_ops.h
| | `-- paddle_use_passes.h
| |-- mobile_full
| | |-- Makefile
| | `-- mobilenetv1_full_api.cc
| `-- mobile_light
| |-- Makefile
| `-- mobilenetv1_light_api.cc
`-- opencl
`-- cl_kernel
|-- buffer
| |-- depthwise_conv2d_kernel.cl
| |-- elementwise_add_kernel.cl
| |-- fc_kernel.cl
| |-- im2col_kernel.cl
| |-- layout_kernel.cl
| |-- mat_mul_kernel.cl
| |-- pool_kernel.cl
| `-- relu_kernel.cl
|-- cl_common.h
`-- image
|-- channel_add_kernel.cl
|-- elementwise_add_kernel.cl
|-- pool_kernel.cl
`-- relu_kernel.cl
```
调用`libpaddle_api_full_bundled.a``libpaddle_api_light_bundled.a`见下一部分运行示例。
## 运行示例
下面以android、ARMv8、gcc的环境为例,介绍3个示例,分别如何在手机上执行基于OpenCL的ARM GPU推理过程。
**注意:** 以下命令均在Lite源码根目录下运行。在3个示例前,下面这段命令都先要执行用来准备环境:
```bash ```bash
# 在/data/local/tmp目录下创建OpenCL文件目录 # 在/data/local/tmp目录下创建OpenCL文件目录
...@@ -61,7 +126,62 @@ adb push lite/backends/opencl/cl_kernel/buffer/* /data/local/tmp/opencl/cl_kerne ...@@ -61,7 +126,62 @@ adb push lite/backends/opencl/cl_kernel/buffer/* /data/local/tmp/opencl/cl_kerne
adb push lite/backends/opencl/cl_kernel/image/* /data/local/tmp/opencl/cl_kernel/image/ adb push lite/backends/opencl/cl_kernel/image/* /data/local/tmp/opencl/cl_kernel/image/
``` ```
### 运行示例1: test_mobilenetv1 ### 运行示例1: 编译产物demo示例
```bash
######################################################################
# 编译mobile_full的demo #
######################################################################
# 步骤: #
# 0.确保编译Paddle-Lite时编译了OpenCL; #
# 1.编辑`mobilenetv1_full_api.cc`代码, 开启`DEMO_USE_OPENCL`的宏; #
# 2.在产物目录`demo/cxx/mobile_full`下编译`mobile_full`的demo; #
# 3.上传demo, 模型, opencl kernel文件到手机; #
# 4.运行demo得到预期结果. #
######################################################################
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_full/mobilenetv1_full_api
adb push ./build.lite.android.armv8.gcc.opencl/inference_lite_lib.android.armv8.opencl/demo/cxx/mobile_full/mobilenetv1_full_api /data/local/tmp/opencl/
adb push ./build.lite.android.armv8.gcc.opencl/install/mobilenet_v1/* /data/local/tmp/opencl/mobilenet_v1
# use mobile_full run mobilenet_v1
# `GLOG_v` is log level
adb shell "export GLOG_v=0; \
/data/local/tmp/opencl/mobilenetv1_full_api \
--model_dir=/data/local/tmp/opencl/mobilenet_v1 \
--optimized_model_dir=/data/local/tmp/opencl/full_api_opt_model"
######################################################################
# 编译mobile_light的demo #
######################################################################
# 步骤: #
# 0.确保编译Paddle-Lite时编译了OpenCL; #
# 1.编译model_optimize_tool并对模型优化, `targets`参数为`opencl`; #
# 2.在产物目录`demo/cxx/mobile_light`下编译`mobile_light`的demo; #
# 3.上传demo, 模型, opencl kernel文件到手机; #
# 4.运行demo得到预期结果. #
######################################################################
# 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/ \
--valid_targets=opencl
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/* /data/local/tmp/opencl/mobilenet_v1
# use mobile_light run mobilenet_v1
adb shell "export GLOG_v=5; \
/data/local/tmp/opencl/mobilenetv1_light_api \
--model_dir=/data/local/tmp/opencl/"
```
### 运行示例2: test_mobilenetv1单元测试
- **运行文件准备** - **运行文件准备**
...@@ -93,7 +213,7 @@ adb shell /data/local/tmp/opencl/test_mobilenetv1 \ ...@@ -93,7 +213,7 @@ adb shell /data/local/tmp/opencl/test_mobilenetv1 \
**注意:** 因为权重参数均会在Op Kernel第一次运行时进行加载,所以第一次的执行时间会略长。一般将warmup的值设为1,repeats值设为多次。 **注意:** 因为权重参数均会在Op Kernel第一次运行时进行加载,所以第一次的执行时间会略长。一般将warmup的值设为1,repeats值设为多次。
### 运行示例2: test_layout_opencl ### 运行示例3: test_layout_opencl单元测试
- **运行文件准备** - **运行文件准备**
...@@ -112,46 +232,9 @@ adb shell /data/local/tmp/opencl/test_layout_opencl ...@@ -112,46 +232,9 @@ adb shell /data/local/tmp/opencl/test_layout_opencl
# 如何在Code中使用 # 如何在Code中使用
Lite支持对ARM CPU和ARM GPU的混调执行,具体描述如下: 见运行示例1的demo代码:
- 设置Lite推断执行的有效Places,使其包含ARM CPU(kARM)和ARM GPU(kOpenCL);
- 确保GPU(kOpenCL)在第一位,位置代表Places的重要性和kernel选择有直接关系。
通过以上设置,Lite在推断执行过程中如果发现某一Op存在着基于OpenCL的实现,其会优先选择使用该实现执行Op的计算过程。若发现某一Op没有基于OpenCL实现的Kernel,其会自动选择执行基于ARM CPU的实现。
代码示例(来自`lite/api/mobilenetv1_test.cc`):
```cpp 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);
// 初始化预测实例、CPU线程数、CPU策略 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).
DeviceInfo::Init();
DeviceInfo::Global().SetRunMode(LITE_POWER_HIGH, FLAGS_threads);
lite::Predictor predictor;
// 设置Lite推断执行的硬件信息Places为{kOpenCL, kARM} 注:这里给出的链接会跳转到线上最新develop分支的代码,很可能与您本地的代码存在差异,建议参考自己本地位于`lite/demo/cxx/`目录的代码,查看如何使用。
std::vector<Place> valid_places({
Place({TARGET(kOpenCL), PRECISION(kFloat)}),
Place({TARGET(kARM), PRECISION(kFloat)})
});
// 根据Place构建模型
predictor.Build(model_dir, "", "", valid_places);
// 设置模型的输入
auto* input_tensor = predictor.GetInput(0);
input_tensor->Resize(DDim(std::vector<DDim::value_type>({1, 3, 224, 224})));
auto* data = input_tensor->mutable_data<float>();
auto item_size = input_tensor->dims().production();
for (int i = 0; i < item_size; i++) {
data[i] = 1;
}
// 执行模型推断
predictor.Run();
// 获取模型的预测结果tensor
// 下面展示如何取出第一个输入tensor,及其维度,元素个数,指针
auto* out0_tensor = predictor.GetOutput(0);
auto out0_dims = out0_tensor->dims();
auto out0_item_size = out0_tensor->dims().production();
auto* out0_pointer = out0_tensor->data<float>();
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册