Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle-Lite
提交
5b108807
P
Paddle-Lite
项目概览
PaddlePaddle
/
Paddle-Lite
通知
332
Star
4
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
271
列表
看板
标记
里程碑
合并请求
78
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle-Lite
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
271
Issue
271
列表
看板
标记
里程碑
合并请求
78
合并请求
78
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
5b108807
编写于
10月 29, 2019
作者:
Y
Yuan Shuai
提交者:
GitHub
10月 29, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[DOC] Fix opencl doc (#2266)
* Fix opencl doc
上级
1f9a75a1
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
96 addition
and
47 deletion
+96
-47
_all_pages/develop/opencl.md
_all_pages/develop/opencl.md
+96
-47
未找到文件。
_all_pages/develop/opencl.md
浏览文件 @
5b108807
...
...
@@ -3,46 +3,50 @@ layout: post
title
:
基于OpenCL的ARM GPU预测
---
Lite支持在Android系统上运行基于OpenCL的程序,目前
提供armv8和
armv7的交叉编译。
Lite支持在Android系统上运行基于OpenCL的程序,目前
支持Ubuntu环境下armv8、
armv7的交叉编译。
## 编译
-
编译环境: 使用基于
`paddle/fluid/lite/tools/Dockerfile.mobile`
生成docker镜像。
-
cmake编译选项介绍
*
`ARM_TARGET_OS`
代表目标操作系统, 目前仅支持android, 亦为默认值。
*
`ARM_TARGET_ARCH_ABI`
代表体系结构类型,支持输入armv8和armv7。其中,armv8等效于arm64-v8a,亦为默认值;armv7等效于 armeabi-v7a。
*
`ARM_TARGET_LANG`
代表编译目标文件所使用的编译器, 默认为gcc,支持 gcc和clang两种。
-
参考示例
### 编译环境
1.
Docker 容器环境;
2.
Linux(推荐 Ubuntu 16.04)环境。
详见
[
**源码编译指南-环境准备** 章节
](
./source_compile.md
)
### 编译选项
|参数|介绍|值|
|--------|--------|--------|
|--arm_os|代表目标操作系统|目前仅支持且默认为
`android`
|
|--arm_abi|代表体系结构类型,支持armv8和armv7|默认为
`armv8`
即arm64-v8a;
`armv7`
即armeabi-v7a|
|--arm_lang|代表编译目标文件所使用的编译器|默认为gcc,支持 gcc和clang两种|
### 编译范例
注:以Docker容器环境为例,CMake3.10,android-ndk-r17c位于
`/opt/`
目录下。
```
bash
# 假设处于Lite源码根目录下
mkdir
-p
build_opencl
&&
cd
build_opencl
cmake ..
\
-DLITE_WITH_OPENCL
=
ON
\
-DWITH_GPU
=
OFF
\
-DWITH_MKL
=
OFF
\
-DWITH_LITE
=
ON
\
-DLITE_WITH_CUDA
=
OFF
\
-DLITE_WITH_X86
=
OFF
\
-DLITE_WITH_ARM
=
ON
\
-DLITE_WITH_LIGHT_WEIGHT_FRAMEWORK
=
ON
\
-DWITH_TESTING
=
ON
\
-DARM_TARGET_OS
=
"android"
-DARM_TARGET_ARCH_ABI
=
"armv8"
-DARM_TARGET_LANG
=
"gcc"
# 注意:在编译其他目标对象前,需要先执行如下命令完成OpenCL所需头文件的下载和生成
make opencl_clhpp
# 接着,用户可以选择完整编译
make lite_compile_deps
-j4
# 或者选择只编译某一目标文件,例如test_mobilenetv1
make test_mobilenetv1
-j4
```
# 假设当前位于处于Lite源码根目录下
# 导入NDK_ROOT变量,注意检查您的安装目录若与本示例不同
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/ci_build.sh
\
--arm_os
=
android
\
--arm_abi
=
armv8
\
--arm_lang
=
gcc
\
build_test_arm_opencl
```
下面以MobileNetV1为例,介绍如何在手机上执行基于OpenCL的ARM GPU推理过程。
## 运行示例准备
下面以android、ARMv8、gcc的环境为例,介绍如何在手机上执行基于OpenCL的ARM GPU推理过程。
**注意:**
以下命令均在Lite源码根目录下运行。
```
bash
...
...
@@ -50,50 +54,88 @@ make test_mobilenetv1 -j4
adb shell
mkdir
-p
/data/local/tmp/opencl
adb shell
mkdir
-p
/data/local/tmp/opencl/cl_kernel/buffer
adb shell
mkdir
-p
/data/local/tmp/opencl/cl_kernel/image
# 将OpenCL的kernels文件推送到/data/local/tmp/opencl目录下
adb push lite/opencl/cl_kernel/cl_common.h /data/local/tmp/opencl/cl_kernel/
adb push lite/opencl/cl_kernel/buffer/
*
/data/local/tmp/opencl/cl_kernel/buffer/
adb push lite/opencl/cl_kernel/image/
*
/data/local/tmp/opencl/cl_kernel/image/
adb push lite/backends/opencl/cl_kernel/cl_common.h /data/local/tmp/opencl/cl_kernel/
adb push lite/backends/opencl/cl_kernel/buffer/
*
/data/local/tmp/opencl/cl_kernel/buffer/
adb push lite/backends/opencl/cl_kernel/image/
*
/data/local/tmp/opencl/cl_kernel/image/
```
### 运行示例1: test_mobilenetv1
-
**运行文件准备**
```
bash
# 将mobilenet_v1的模型文件推送到/data/local/tmp/opencl目录下
adb shell
mkdir
-p
/data/local/tmp/opencl/mobilenet_v1
adb push build_opencl/third_party/install/mobilenet_v1/
*
/data/local/tmp/opencl/mobilenet_v1/
# 将OpenCL测试程序(如test_mobilenetv1)推送到/data/local/tmp/opencl目录下
adb push build_opencl/lite/api/test_mobilenetv1 /data/local/tmp/opencl
adb push build.lite.android.armv8.gcc.opencl/third_party/install/mobilenet_v1/
*
/data/local/tmp/opencl/mobilenet_v1/
# 将OpenCL单元测试程序test_mobilenetv1,推送到/data/local/tmp/opencl目录下
adb push build.lite.android.armv8.gcc.opencl/lite/api/test_mobilenetv1 /data/local/tmp/opencl
```
-
**执行OpenCL推理过程**
使用如下命令运行OpenCL程序。其中,
`--cl_path`
指定了OpenCL的kernels文件即cl
\_
kernel所在目录,
`--modle_dir`
指定了模型文件所在目录。
使用如下命令运行OpenCL程序。其中:
-
`--cl_path`
指定了OpenCL的kernels文件即cl
\_
kernel所在目录;
-
`--modle_dir`
指定了模型文件所在目录。
```
bash
adb shell /data/local/tmp/opencl/test_mobilenetv1
--cl_path
=
/data/local/tmp/opencl
--model_dir
=
/data/local/tmp/opencl/mobilenet_v1
--warmup
=
1
--repeats
=
1
adb shell
chmod
+x /data/local/tmp/opencl/test_mobilenetv1
adb shell /data/local/tmp/opencl/test_mobilenetv1
\
--cl_path
=
/data/local/tmp/opencl
\
--model_dir
=
/data/local/tmp/opencl/mobilenet_v1
\
--warmup
=
1
\
--repeats
=
1
```
**注意:**
因为权重参数均会在Op Kernel第一次运行时进行加载,所以第一次的执行时间会略长。一般将warmup的值设为1,repeats值设为多次。
### 运行示例2: test_layout_opencl
-
**运行文件准备**
```
bash
# 将OpenCL单元测试程序test_layout_opencl,推送到/data/local/tmp/opencl目录下
adb push build.lite.android.armv8.gcc.opencl/lite/kernels/opencl/test_layout_opencl /data/local/tmp/opencl/
```
-
**执行OpenCL推理过程**
```
bash
adb shell
chmod
+x /data/local/tmp/opencl/test_layout_opencl
adb shell /data/local/tmp/opencl/test_layout_opencl
```
# 如何在Code中使用
Lite支持对ARM CPU和ARM GPU的混调执行,具体描述如下:
1.
设置Lite推断执行的有效Places,使其包含ARM CPU(kARM)和ARM GPU(kOpenCL);
2.
设置Lite推断执行的偏好Place为ARM GPU(kOpenCL)。
通过以上两步设置,Lite在推断执行过程中如果发现某一Op存在着基于OpenCL的实现,其会优先选择使用该实现执行Op的计算过程。若发现某一Op没有基于OpenCL实现的Kernel,其会自动选择执行基于ARM CPU的实现。
-
设置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}
// 设置Lite推断执行的硬件信息Places为{kOpenCL, kARM}
std
::
vector
<
Place
>
valid_places
({
Place
({
TARGET
(
kOpenCL
),
PRECISION
(
kFloat
)}),
Place
({
TARGET
(
kARM
),
PRECISION
(
kFloat
)})
});
// 根据
有效Places和偏好
Place构建模型
// 根据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
})));
...
...
@@ -102,7 +144,14 @@ auto item_size = input_tensor->dims().production();
for
(
int
i
=
0
;
i
<
item_size
;
i
++
)
{
data
[
i
]
=
1
;
}
// 执行模型推断并获取模型的预测结果
// 执行模型推断
predictor
.
Run
();
auto
*
out
=
predictor
.
GetOutput
(
0
);
// 获取模型的预测结果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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录