Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
d95d66cb
P
Paddle
项目概览
PaddlePaddle
/
Paddle
大约 2 年 前同步成功
通知
2325
Star
20933
Fork
5424
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1423
列表
看板
标记
里程碑
合并请求
543
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1,423
Issue
1,423
列表
看板
标记
里程碑
合并请求
543
合并请求
543
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
d95d66cb
编写于
9月 06, 2017
作者:
T
Travis CI
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Deploy to GitHub Pages:
d924a658
上级
97c432ee
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
532 addition
and
4 deletion
+532
-4
develop/doc_cn/_sources/howto/dev/new_op_cn.md.txt
develop/doc_cn/_sources/howto/dev/new_op_cn.md.txt
+6
-1
develop/doc_cn/_sources/howto/dev/use_eigen_cn.md.txt
develop/doc_cn/_sources/howto/dev/use_eigen_cn.md.txt
+146
-0
develop/doc_cn/howto/dev/new_op_cn.html
develop/doc_cn/howto/dev/new_op_cn.html
+6
-2
develop/doc_cn/howto/dev/use_eigen_cn.html
develop/doc_cn/howto/dev/use_eigen_cn.html
+373
-0
develop/doc_cn/objects.inv
develop/doc_cn/objects.inv
+0
-0
develop/doc_cn/searchindex.js
develop/doc_cn/searchindex.js
+1
-1
未找到文件。
develop/doc_cn/_sources/howto/dev/new_op_cn.md.txt
浏览文件 @
d95d66cb
...
...
@@ -169,6 +169,8 @@ class MulKernel : public framework::OpKernel {
`MulKernel`需要重写`Compute`接口,该接口参数为`const framework::ExecutionContext& context`, `ExecutionContext`相比`InferShapeContext`增加了设备类型,同样可获取到输入输出和属性参数,`Compute`函数里写具体实现时。
注意,不同设备(CPU、GPU)共享一个Op定义,是否则共享同一个`OpKernel`,取决于`Compute`调用的函数是否支持不同设备。`MulOp`的CPU、GPU实现共享同一个`Kernel`,`OpKernel`不共享的例子可以参考[`OnehotCrossEntropyOpKernel`](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/cross_entropy_op.h#L43)。
为了使得`OpKernel`的计算过程书写较为简单,CPU、GPU的代码可以复用,我们通常借助Eigen unsupported Tensor模块来实现。关于在paddle中如何使用Eigen库,请参考对应的使用[文档](https://github.com/PaddlePaddle/Paddle/blob/develop/doc/howto/dev/use_eigen_cn.md)
到此前向Op实现完成,需要在`.cc`文件中注册该op和kernel。反向Op类的定义和Kernel定义与前向Op类似,这里不再重复。但注意,反向Op没有`ProtoMaker`。
...
...
@@ -188,9 +190,12 @@ REGISTER_OP_CPU_KERNEL(mul_grad,
- `REGISTER_OP_WITHOUT_GRADIENT` : 用于注册没有反向的Op。
- `REGISTER_OP_CPU_KERNEL` :注册`ops::MulKernel`类,并特化模板参数为`paddle::platform::CPUPlace`和`float`类型,同理,注册`ops::MulKernel`类。
在 `.cu`文件中注册GPU Kernel。
在 `.cu`文件中注册GPU Kernel。
请注意,如果GPU Kernel的实现是基于Eigen unsupported模块,那么在 `.cu`的最前面请加上宏定义 `#define EIGEN_USE_GPU`
```c++
// if use Eigen unsupported module before include head files
#define EIGEN_USE_GPU
namespace ops = paddle::operators;
REGISTER_OP_GPU_KERNEL(mul, ops::MulKernel<paddle::platform::GPUPlace, float>);
REGISTER_OP_GPU_KERNEL(mul_grad,
...
...
develop/doc_cn/_sources/howto/dev/use_eigen_cn.md.txt
0 → 100644
浏览文件 @
d95d66cb
## 在Paddle中如何使用Eigen
神经网络本质上是一个计算图,计算需要的数据存放在`Tensor`中,而计算过程是由`Operartor`来描述的。在执行时,`Operator`调用对应`OpKernel`中的`Compute`接口,实现对`Tensor`的操作。
### Eigen Tensor模块
Eigen Tensor模块对element-wise计算提供了强大的支持,并且书写一份代码,可以同时在CPU、GPU执行。但Eigen Tensor是一个正在开发中的模块,因此可能测试不够完备,文档较少。
关于Eigen Tensor模块的详细介绍请参考[文档1](https://github.com/RLovelett/eigen/blob/master/unsupported/Eigen/CXX11/src/Tensor/README.md) 和[文档2](https://bitbucket.org/eigen/eigen/src/default/unsupported/Eigen/CXX11/src/Tensor/README.md)
### paddle::framework::Tensor
Paddle Tensor定义在framework目录下,其主要接口如下:
```cpp
class Tensor {
public:
/*! Return a pointer to mutable memory block. */
template <typename T>
inline T* data();
/**
* @brief Return a pointer to mutable memory block.
* @note If not exist, then allocation.
*/
template <typename T>
inline T* mutable_data(platform::Place place);
/**
* @brief Return a pointer to mutable memory block.
*
* @param[in] dims The dimensions of the memory block.
* @param[in] place The place of the memory block.
*
* @note If not exist, then allocation.
*/
template <typename T>
inline T* mutable_data(DDim dims, platform::Place place);
/*! Resize the dimensions of the memory block. */
inline Tensor& Resize(const DDim& dims);
/*! Return the dimensions of the memory block. */
inline const DDim& dims() const;
private:
/*! holds the memory block if allocated. */
std::shared_ptr<Placeholder> holder_;
/*! points to dimensions of memory block. */
DDim dim_;
};
```
`Placeholder`的作用是延迟分配内存,即我们可以先定义一个Tensor,然后使用Resize接口设置Tensor的大小,最后再调用mutable_data接口分配实际的内存。
```cpp
paddle::framework::Tensor t;
paddle::platform::CPUPlace place;
// set size first
t.Resize({2, 3});
// allocate memory on CPU later
t.mutable_data(place);
```
### paddle::framework::Tensor使用样例
下面以AddOp为例说明Tensor的使用过程:
- InferShape
在运行神经网络计算图时,我们先调用每个`Operator`的`InferShape`接口,根据输入Tensor的大小来设置输出Tensor的大小,`Resize`接口会被调用。
```cpp
void InferShape(const framework::InferShapeContext &ctx) const override {
PADDLE_ENFORCE_EQ(ctx.Input<Tensor>("X")->dims(),
ctx.Input<Tensor>("Y")->dims(),
"Two input of Add Op's dimension must be same.");
ctx.Output<Tensor>("Out")->Resize(ctx.Input<Tensor>("X")->dims());
}
```
- Run
`Operator`的`Run`接口最终会调用对应`OpKernel`的`Compute`接口,在这时真正的分配内存,`mutable_data`接口会被调用。
```cpp
void Compute(const framework::ExecutionContext& context) const override {
auto* input0 = context.Input<Tensor>("X");
auto* input1 = context.Input<Tensor>("Y");
auto* output = context.Output<Tensor>("Out");
output->mutable_data<T>(context.GetPlace());
auto x = EigenVector<T>::Flatten(*input0);
auto y = EigenVector<T>::Flatten(*input1);
auto z = EigenVector<T>::Flatten(*output);
auto place = context.GetEigenDevice<Place>();
z.device(place) = x + y;
}
```
### paddle::framework::Tensor到EigenTensor的转换
如上一小节所示,在具体的计算中,我们需要先把输入Tensor和输出Tensor转换为Eigen支持的格式。我们在[eigen.h](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/framework/eigen.h)中提供了一些全局函数用来实现paddle::framework::Tensor到EigenTensor/EigenMatrix/EigenVector/EigenScalar的转换。
以EigenTensor为例,做一个介绍
```cpp
Tensor t;
float* p = t.mutable_data<float>(make_ddim({1, 2, 3}), platform::CPUPlace());
for (int i = 0; i < 1 * 2 * 3; i++) {
p[i] = static_cast<float>(i);
}
EigenTensor<float, 3>::Type et = EigenTensor<float, 3>::From(t);
```
From是EigenTensor模板提供的一个接口,可以实现从paddle::framework::Tensor到对EigenTensor的转换。由于Tensor的rank是模板参数,因此在转换时需要显示的指定。
在Eigen中,不同rank的Tensor是不同类型,Vector是rank为1的Tensor。需要额外注意的是,EigenVector<T>::From方法是把paddle中的一维Tensor转为Eigen的一维Tensor,在这里用EigenVector来表示;而EigenVector<T>::Flatten方法是把paddle中的一个Tensor进行reshape操作,压扁成为Eigen的一维Tensor,类型仍然为EigenVector。
更多的转换方法请参考eigen_test.cc中的[单元测试](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/framework/eigen_test.cc)。
### 实现计算
当需要完成计算时,我们需要等式左边的EigenTensor调用device接口。在这里需要注意的是,这里的EigenTensor之间的运算只是改变了原有Tensor中的数据,而不会改变原有Tensor的shape信息。
```cpp
auto x = EigenVector<T>::Flatten(*input0);
auto y = EigenVector<T>::Flatten(*input1);
auto z = EigenVector<T>::Flatten(*output);
auto place = context.GetEigenDevice<Place>();
z.device(place) = x + y;
```
在这段代码中,input0/input1/output可以是任意维度的Tensor。我们调用了EigenVector的Flatten接口,把任意维度的Tensor转为了一维的EigenVector。而在计算结束之后,input0/input1/output的原有shape信息不变。如果想改变原有Tensor的shape信息,可以调用Resize接口进行改变。
由于Eigen Tensor模块的文档较少,我们可以参考TensorFlow的[kernels](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/kernels)模块下的相关`OpKernel`的计算代码。
develop/doc_cn/howto/dev/new_op_cn.html
浏览文件 @
d95d66cb
...
...
@@ -335,6 +335,7 @@ Kernel实现 | CPU、GPU共享Kernel在<code class="docutils literal"><spa
</ul>
<p><code
class=
"docutils literal"
><span
class=
"pre"
>
MulKernel
</span></code>
需要重写
<code
class=
"docutils literal"
><span
class=
"pre"
>
Compute
</span></code>
接口,该接口参数为
<code
class=
"docutils literal"
><span
class=
"pre"
>
const
</span>
<span
class=
"pre"
>
framework::ExecutionContext
&
</span>
<span
class=
"pre"
>
context
</span></code>
,
<code
class=
"docutils literal"
><span
class=
"pre"
>
ExecutionContext
</span></code>
相比
<code
class=
"docutils literal"
><span
class=
"pre"
>
InferShapeContext
</span></code>
增加了设备类型,同样可获取到输入输出和属性参数,
<code
class=
"docutils literal"
><span
class=
"pre"
>
Compute
</span></code>
函数里写具体实现时。
</p>
<p>
注意,不同设备(CPU、GPU)共享一个Op定义,是否则共享同一个
<code
class=
"docutils literal"
><span
class=
"pre"
>
OpKernel
</span></code>
,取决于
<code
class=
"docutils literal"
><span
class=
"pre"
>
Compute
</span></code>
调用的函数是否支持不同设备。
<code
class=
"docutils literal"
><span
class=
"pre"
>
MulOp
</span></code>
的CPU、GPU实现共享同一个
<code
class=
"docutils literal"
><span
class=
"pre"
>
Kernel
</span></code>
,
<code
class=
"docutils literal"
><span
class=
"pre"
>
OpKernel
</span></code>
不共享的例子可以参考
<a
class=
"reference external"
href=
"https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/cross_entropy_op.h#L43"
><code
class=
"docutils literal"
><span
class=
"pre"
>
OnehotCrossEntropyOpKernel
</span></code></a>
。
</p>
<p>
为了使得
<code
class=
"docutils literal"
><span
class=
"pre"
>
OpKernel
</span></code>
的计算过程书写较为简单,CPU、GPU的代码可以复用,我们通常借助Eigen unsupported Tensor模块来实现。关于在paddle中如何使用Eigen库,请参考对应的使用
<a
class=
"reference external"
href=
"https://github.com/PaddlePaddle/Paddle/blob/develop/doc/howto/dev/use_eigen_cn.md"
>
文档
</a></p>
<p>
到此前向Op实现完成,需要在
<code
class=
"docutils literal"
><span
class=
"pre"
>
.cc
</span></code>
文件中注册该op和kernel。反向Op类的定义和Kernel定义与前向Op类似,这里不再重复。但注意,反向Op没有
<code
class=
"docutils literal"
><span
class=
"pre"
>
ProtoMaker
</span></code>
。
</p>
</div>
<div
class=
"section"
id=
"operator"
>
...
...
@@ -352,8 +353,11 @@ Kernel实现 | CPU、GPU共享Kernel在<code class="docutils literal"><spa
<li><code
class=
"docutils literal"
><span
class=
"pre"
>
REGISTER_OP_WITHOUT_GRADIENT
</span></code>
: 用于注册没有反向的Op。
</li>
<li><code
class=
"docutils literal"
><span
class=
"pre"
>
REGISTER_OP_CPU_KERNEL
</span></code>
:注册
<code
class=
"docutils literal"
><span
class=
"pre"
>
ops::MulKernel
</span></code>
类,并特化模板参数为
<code
class=
"docutils literal"
><span
class=
"pre"
>
paddle::platform::CPUPlace
</span></code>
和
<code
class=
"docutils literal"
><span
class=
"pre"
>
float
</span></code>
类型,同理,注册
<code
class=
"docutils literal"
><span
class=
"pre"
>
ops::MulKernel
</span></code>
类。
</li>
</ul>
<p>
在
<code
class=
"docutils literal"
><span
class=
"pre"
>
.cu
</span></code>
文件中注册GPU Kernel。
</p>
<div
class=
"highlight-c++"
><div
class=
"highlight"
><pre><span></span><span
class=
"k"
>
namespace
</span>
<span
class=
"n"
>
ops
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
paddle
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
operators
</span><span
class=
"p"
>
;
</span>
<p>
在
<code
class=
"docutils literal"
><span
class=
"pre"
>
.cu
</span></code>
文件中注册GPU Kernel。请注意,如果GPU Kernel的实现是基于Eigen unsupported模块,那么在
<code
class=
"docutils literal"
><span
class=
"pre"
>
.cu
</span></code>
的最前面请加上宏定义
<code
class=
"docutils literal"
><span
class=
"pre"
>
#define
</span>
<span
class=
"pre"
>
EIGEN_USE_GPU
</span></code></p>
<div
class=
"highlight-c++"
><div
class=
"highlight"
><pre><span></span><span
class=
"c1"
>
// if use Eigen unsupported module before include head files
</span>
<span
class=
"cp"
>
#define EIGEN_USE_GPU
</span>
<span
class=
"k"
>
namespace
</span>
<span
class=
"n"
>
ops
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
paddle
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
operators
</span><span
class=
"p"
>
;
</span>
<span
class=
"n"
>
REGISTER_OP_GPU_KERNEL
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
mul
</span><span
class=
"p"
>
,
</span>
<span
class=
"n"
>
ops
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
MulKernel
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
paddle
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
platform
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
GPUPlace
</span><span
class=
"p"
>
,
</span>
<span
class=
"kt"
>
float
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
);
</span>
<span
class=
"n"
>
REGISTER_OP_GPU_KERNEL
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
mul_grad
</span><span
class=
"p"
>
,
</span>
<span
class=
"n"
>
ops
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
MulGradKernel
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
paddle
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
platform
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
GPUPlace
</span><span
class=
"p"
>
,
</span>
<span
class=
"kt"
>
float
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
);
</span>
...
...
develop/doc_cn/howto/dev/use_eigen_cn.html
0 → 100644
浏览文件 @
d95d66cb
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!-->
<html
class=
"no-js"
lang=
"en"
>
<!--<![endif]-->
<head>
<meta
charset=
"utf-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<title>
在Paddle中如何使用Eigen
—
PaddlePaddle 文档
</title>
<link
rel=
"stylesheet"
href=
"../../_static/css/theme.css"
type=
"text/css"
/>
<link
rel=
"index"
title=
"索引"
href=
"../../genindex.html"
/>
<link
rel=
"search"
title=
"搜索"
href=
"../../search.html"
/>
<link
rel=
"top"
title=
"PaddlePaddle 文档"
href=
"../../index.html"
/>
<link
rel=
"stylesheet"
href=
"https://cdn.jsdelivr.net/perfect-scrollbar/0.6.14/css/perfect-scrollbar.min.css"
type=
"text/css"
/>
<link
rel=
"stylesheet"
href=
"../../_static/css/override.css"
type=
"text/css"
/>
<script>
var
_hmt
=
_hmt
||
[];
(
function
()
{
var
hm
=
document
.
createElement
(
"
script
"
);
hm
.
src
=
"
//hm.baidu.com/hm.js?b9a314ab40d04d805655aab1deee08ba
"
;
var
s
=
document
.
getElementsByTagName
(
"
script
"
)[
0
];
s
.
parentNode
.
insertBefore
(
hm
,
s
);
})();
</script>
<script
src=
"../../_static/js/modernizr.min.js"
></script>
</head>
<body
class=
"wy-body-for-nav"
role=
"document"
>
<header
class=
"site-header"
>
<div
class=
"site-logo"
>
<a
href=
"/"
><img
src=
"../../_static/images/PP_w.png"
></a>
</div>
<div
class=
"site-nav-links"
>
<div
class=
"site-menu"
>
<a
class=
"fork-on-github"
href=
"https://github.com/PaddlePaddle/Paddle"
target=
"_blank"
><i
class=
"fa fa-github"
></i>
Fork me on Github
</a>
<div
class=
"language-switcher dropdown"
>
<a
type=
"button"
data-toggle=
"dropdown"
>
<span>
English
</span>
<i
class=
"fa fa-angle-up"
></i>
<i
class=
"fa fa-angle-down"
></i>
</a>
<ul
class=
"dropdown-menu"
>
<li><a
href=
"/doc_cn"
>
中文
</a></li>
<li><a
href=
"/doc"
>
English
</a></li>
</ul>
</div>
<ul
class=
"site-page-links"
>
<li><a
href=
"/"
>
Home
</a></li>
</ul>
</div>
<div
class=
"doc-module"
>
<ul>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../../getstarted/index_cn.html"
>
新手入门
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../index_cn.html"
>
进阶指南
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../../api/index_cn.html"
>
API
</a></li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../../faq/index_cn.html"
>
FAQ
</a></li>
</ul>
<div
role=
"search"
>
<form
id=
"rtd-search-form"
class=
"wy-form"
action=
"../../search.html"
method=
"get"
>
<input
type=
"text"
name=
"q"
placeholder=
"Search docs"
/>
<input
type=
"hidden"
name=
"check_keywords"
value=
"yes"
/>
<input
type=
"hidden"
name=
"area"
value=
"default"
/>
</form>
</div>
</div>
</div>
</header>
<div
class=
"main-content-wrap"
>
<nav
class=
"doc-menu-vertical"
role=
"navigation"
>
<ul>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../../getstarted/index_cn.html"
>
新手入门
</a><ul>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../../getstarted/build_and_install/index_cn.html"
>
安装与编译
</a><ul>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../../getstarted/build_and_install/docker_install_cn.html"
>
PaddlePaddle的Docker容器使用方式
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../../getstarted/build_and_install/cmake/build_from_source_cn.html"
>
PaddlePaddle的编译选项
</a></li>
</ul>
</li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../../getstarted/concepts/use_concepts_cn.html"
>
基本使用概念
</a></li>
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../index_cn.html"
>
进阶指南
</a><ul>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../usage/cmd_parameter/index_cn.html"
>
设置命令行参数
</a><ul>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../usage/cmd_parameter/use_case_cn.html"
>
使用案例
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../usage/cmd_parameter/arguments_cn.html"
>
参数概述
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../usage/cmd_parameter/detail_introduction_cn.html"
>
细节描述
</a></li>
</ul>
</li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../usage/cluster/cluster_train_cn.html"
>
运行分布式训练
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../usage/k8s/k8s_basis_cn.html"
>
Kubernetes 简介
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../usage/k8s/k8s_cn.html"
>
Kubernetes单机训练
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../usage/k8s/k8s_distributed_cn.html"
>
Kubernetes分布式训练
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"build_cn.html"
>
编译PaddlePaddle和运行单元测试
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"write_docs_cn.html"
>
如何贡献/修改文档
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"contribute_to_paddle_cn.html"
>
如何贡献代码
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../deep_model/rnn/index_cn.html"
>
RNN相关模型
</a><ul>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../deep_model/rnn/rnn_config_cn.html"
>
RNN配置
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../deep_model/rnn/recurrent_group_cn.html"
>
Recurrent Group教程
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../deep_model/rnn/hierarchical_layer_cn.html"
>
支持双层序列作为输入的Layer
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../deep_model/rnn/hrnn_rnn_api_compare_cn.html"
>
单双层RNN API对比介绍
</a></li>
</ul>
</li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../optimization/gpu_profiling_cn.html"
>
GPU性能分析与调优
</a></li>
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../../api/index_cn.html"
>
API
</a><ul>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../../api/v2/model_configs.html"
>
模型配置
</a><ul>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../../api/v2/config/activation.html"
>
Activation
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../../api/v2/config/layer.html"
>
Layers
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../../api/v2/config/evaluators.html"
>
Evaluators
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../../api/v2/config/optimizer.html"
>
Optimizer
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../../api/v2/config/pooling.html"
>
Pooling
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../../api/v2/config/networks.html"
>
Networks
</a></li>
<li
class=
"toctree-l3"
><a
class=
"reference internal"
href=
"../../api/v2/config/attr.html"
>
Parameter Attribute
</a></li>
</ul>
</li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../../api/v2/data.html"
>
数据访问
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"../../api/v2/run_logic.html"
>
训练与应用
</a></li>
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"../../faq/index_cn.html"
>
FAQ
</a></li>
</ul>
</nav>
<section
class=
"doc-content-wrap"
>
<div
role=
"navigation"
aria-label=
"breadcrumbs navigation"
>
<ul
class=
"wy-breadcrumbs"
>
<li>
在Paddle中如何使用Eigen
</li>
</ul>
</div>
<div
class=
"wy-nav-content"
id=
"doc-content"
>
<div
class=
"rst-content"
>
<div
role=
"main"
class=
"document"
itemscope=
"itemscope"
itemtype=
"http://schema.org/Article"
>
<div
itemprop=
"articleBody"
>
<div
class=
"section"
id=
"paddleeigen"
>
<span
id=
"paddleeigen"
></span><h1>
在Paddle中如何使用Eigen
<a
class=
"headerlink"
href=
"#paddleeigen"
title=
"永久链接至标题"
>
¶
</a></h1>
<p>
神经网络本质上是一个计算图,计算需要的数据存放在
<code
class=
"docutils literal"
><span
class=
"pre"
>
Tensor
</span></code>
中,而计算过程是由
<code
class=
"docutils literal"
><span
class=
"pre"
>
Operartor
</span></code>
来描述的。在执行时,
<code
class=
"docutils literal"
><span
class=
"pre"
>
Operator
</span></code>
调用对应
<code
class=
"docutils literal"
><span
class=
"pre"
>
OpKernel
</span></code>
中的
<code
class=
"docutils literal"
><span
class=
"pre"
>
Compute
</span></code>
接口,实现对
<code
class=
"docutils literal"
><span
class=
"pre"
>
Tensor
</span></code>
的操作。
</p>
<div
class=
"section"
id=
"eigen-tensor"
>
<span
id=
"eigen-tensor"
></span><h2>
Eigen Tensor模块
<a
class=
"headerlink"
href=
"#eigen-tensor"
title=
"永久链接至标题"
>
¶
</a></h2>
<p>
Eigen Tensor模块对element-wise计算提供了强大的支持,并且书写一份代码,可以同时在CPU、GPU执行。但Eigen Tensor是一个正在开发中的模块,因此可能测试不够完备,文档较少。
</p>
<p>
关于Eigen Tensor模块的详细介绍请参考
<a
class=
"reference external"
href=
"https://github.com/RLovelett/eigen/blob/master/unsupported/Eigen/CXX11/src/Tensor/README.md"
>
文档1
</a>
和
<a
class=
"reference external"
href=
"https://bitbucket.org/eigen/eigen/src/default/unsupported/Eigen/CXX11/src/Tensor/README.md"
>
文档2
</a></p>
</div>
<div
class=
"section"
id=
"paddle-framework-tensor"
>
<span
id=
"paddle-framework-tensor"
></span><h2>
paddle::framework::Tensor
<a
class=
"headerlink"
href=
"#paddle-framework-tensor"
title=
"永久链接至标题"
>
¶
</a></h2>
<p>
Paddle Tensor定义在framework目录下,其主要接口如下:
</p>
<div
class=
"highlight-cpp"
><div
class=
"highlight"
><pre><span></span><span
class=
"k"
>
class
</span>
<span
class=
"nc"
>
Tensor
</span>
<span
class=
"p"
>
{
</span>
<span
class=
"k"
>
public
</span><span
class=
"o"
>
:
</span>
<span
class=
"cm"
>
/*! Return a pointer to mutable memory block. */
</span>
<span
class=
"k"
>
template
</span>
<span
class=
"o"
>
<
</span><span
class=
"k"
>
typename
</span>
<span
class=
"n"
>
T
</span><span
class=
"o"
>
>
</span>
<span
class=
"kr"
>
inline
</span>
<span
class=
"n"
>
T
</span><span
class=
"o"
>
*
</span>
<span
class=
"n"
>
data
</span><span
class=
"p"
>
();
</span>
<span
class=
"cm"
>
/**
</span>
<span
class=
"cm"
>
* @brief Return a pointer to mutable memory block.
</span>
<span
class=
"cm"
>
* @note If not exist, then allocation.
</span>
<span
class=
"cm"
>
*/
</span>
<span
class=
"k"
>
template
</span>
<span
class=
"o"
>
<
</span><span
class=
"k"
>
typename
</span>
<span
class=
"n"
>
T
</span><span
class=
"o"
>
>
</span>
<span
class=
"kr"
>
inline
</span>
<span
class=
"n"
>
T
</span><span
class=
"o"
>
*
</span>
<span
class=
"n"
>
mutable_data
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
platform
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
Place
</span>
<span
class=
"n"
>
place
</span><span
class=
"p"
>
);
</span>
<span
class=
"cm"
>
/**
</span>
<span
class=
"cm"
>
* @brief Return a pointer to mutable memory block.
</span>
<span
class=
"cm"
>
*
</span>
<span
class=
"cm"
>
* @param[in] dims The dimensions of the memory block.
</span>
<span
class=
"cm"
>
* @param[in] place The place of the memory block.
</span>
<span
class=
"cm"
>
*
</span>
<span
class=
"cm"
>
* @note If not exist, then allocation.
</span>
<span
class=
"cm"
>
*/
</span>
<span
class=
"k"
>
template
</span>
<span
class=
"o"
>
<
</span><span
class=
"k"
>
typename
</span>
<span
class=
"n"
>
T
</span><span
class=
"o"
>
>
</span>
<span
class=
"kr"
>
inline
</span>
<span
class=
"n"
>
T
</span><span
class=
"o"
>
*
</span>
<span
class=
"n"
>
mutable_data
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
DDim
</span>
<span
class=
"n"
>
dims
</span><span
class=
"p"
>
,
</span>
<span
class=
"n"
>
platform
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
Place
</span>
<span
class=
"n"
>
place
</span><span
class=
"p"
>
);
</span>
<span
class=
"cm"
>
/*! Resize the dimensions of the memory block. */
</span>
<span
class=
"kr"
>
inline
</span>
<span
class=
"n"
>
Tensor
</span><span
class=
"o"
>
&
</span>
<span
class=
"n"
>
Resize
</span><span
class=
"p"
>
(
</span><span
class=
"k"
>
const
</span>
<span
class=
"n"
>
DDim
</span><span
class=
"o"
>
&
</span>
<span
class=
"n"
>
dims
</span><span
class=
"p"
>
);
</span>
<span
class=
"cm"
>
/*! Return the dimensions of the memory block. */
</span>
<span
class=
"kr"
>
inline
</span>
<span
class=
"k"
>
const
</span>
<span
class=
"n"
>
DDim
</span><span
class=
"o"
>
&
</span>
<span
class=
"n"
>
dims
</span><span
class=
"p"
>
()
</span>
<span
class=
"k"
>
const
</span><span
class=
"p"
>
;
</span>
<span
class=
"k"
>
private
</span><span
class=
"o"
>
:
</span>
<span
class=
"cm"
>
/*! holds the memory block if allocated. */
</span>
<span
class=
"n"
>
std
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
shared_ptr
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
Placeholder
</span><span
class=
"o"
>
>
</span>
<span
class=
"n"
>
holder_
</span><span
class=
"p"
>
;
</span>
<span
class=
"cm"
>
/*! points to dimensions of memory block. */
</span>
<span
class=
"n"
>
DDim
</span>
<span
class=
"n"
>
dim_
</span><span
class=
"p"
>
;
</span>
<span
class=
"p"
>
};
</span>
</pre></div>
</div>
<p><code
class=
"docutils literal"
><span
class=
"pre"
>
Placeholder
</span></code>
的作用是延迟分配内存,即我们可以先定义一个Tensor,然后使用Resize接口设置Tensor的大小,最后再调用mutable_data接口分配实际的内存。
</p>
<div
class=
"highlight-cpp"
><div
class=
"highlight"
><pre><span></span><span
class=
"n"
>
paddle
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
framework
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
Tensor
</span>
<span
class=
"n"
>
t
</span><span
class=
"p"
>
;
</span>
<span
class=
"n"
>
paddle
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
platform
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
CPUPlace
</span>
<span
class=
"n"
>
place
</span><span
class=
"p"
>
;
</span>
<span
class=
"c1"
>
// set size first
</span>
<span
class=
"n"
>
t
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
Resize
</span><span
class=
"p"
>
({
</span><span
class=
"mi"
>
2
</span><span
class=
"p"
>
,
</span>
<span
class=
"mi"
>
3
</span><span
class=
"p"
>
});
</span>
<span
class=
"c1"
>
// allocate memory on CPU later
</span>
<span
class=
"n"
>
t
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
mutable_data
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
place
</span><span
class=
"p"
>
);
</span>
</pre></div>
</div>
</div>
<div
class=
"section"
id=
"paddle-framework-tensor"
>
<span
id=
"id1"
></span><h2>
paddle::framework::Tensor使用样例
<a
class=
"headerlink"
href=
"#paddle-framework-tensor"
title=
"永久链接至标题"
>
¶
</a></h2>
<p>
下面以AddOp为例说明Tensor的使用过程:
</p>
<ul
class=
"simple"
>
<li>
InferShape
</li>
</ul>
<p>
在运行神经网络计算图时,我们先调用每个
<code
class=
"docutils literal"
><span
class=
"pre"
>
Operator
</span></code>
的
<code
class=
"docutils literal"
><span
class=
"pre"
>
InferShape
</span></code>
接口,根据输入Tensor的大小来设置输出Tensor的大小,
<code
class=
"docutils literal"
><span
class=
"pre"
>
Resize
</span></code>
接口会被调用。
</p>
<div
class=
"highlight-cpp"
><div
class=
"highlight"
><pre><span></span><span
class=
"kt"
>
void
</span>
<span
class=
"nf"
>
InferShape
</span><span
class=
"p"
>
(
</span><span
class=
"k"
>
const
</span>
<span
class=
"n"
>
framework
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
InferShapeContext
</span>
<span
class=
"o"
>
&
</span><span
class=
"n"
>
ctx
</span><span
class=
"p"
>
)
</span>
<span
class=
"k"
>
const
</span>
<span
class=
"k"
>
override
</span>
<span
class=
"p"
>
{
</span>
<span
class=
"n"
>
PADDLE_ENFORCE_EQ
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
ctx
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
Input
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
Tensor
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
(
</span><span
class=
"s"
>
"
X
"
</span><span
class=
"p"
>
)
</span><span
class=
"o"
>
-
>
</span><span
class=
"n"
>
dims
</span><span
class=
"p"
>
(),
</span>
<span
class=
"n"
>
ctx
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
Input
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
Tensor
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
(
</span><span
class=
"s"
>
"
Y
"
</span><span
class=
"p"
>
)
</span><span
class=
"o"
>
-
>
</span><span
class=
"n"
>
dims
</span><span
class=
"p"
>
(),
</span>
<span
class=
"s"
>
"
Two input of Add Op
'
s dimension must be same.
"
</span><span
class=
"p"
>
);
</span>
<span
class=
"n"
>
ctx
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
Output
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
Tensor
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
(
</span><span
class=
"s"
>
"
Out
"
</span><span
class=
"p"
>
)
</span><span
class=
"o"
>
-
>
</span><span
class=
"n"
>
Resize
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
ctx
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
Input
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
Tensor
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
(
</span><span
class=
"s"
>
"
X
"
</span><span
class=
"p"
>
)
</span><span
class=
"o"
>
-
>
</span><span
class=
"n"
>
dims
</span><span
class=
"p"
>
());
</span>
<span
class=
"p"
>
}
</span>
</pre></div>
</div>
<ul
class=
"simple"
>
<li>
Run
</li>
</ul>
<p><code
class=
"docutils literal"
><span
class=
"pre"
>
Operator
</span></code>
的
<code
class=
"docutils literal"
><span
class=
"pre"
>
Run
</span></code>
接口最终会调用对应
<code
class=
"docutils literal"
><span
class=
"pre"
>
OpKernel
</span></code>
的
<code
class=
"docutils literal"
><span
class=
"pre"
>
Compute
</span></code>
接口,在这时真正的分配内存,
<code
class=
"docutils literal"
><span
class=
"pre"
>
mutable_data
</span></code>
接口会被调用。
</p>
<div
class=
"highlight-cpp"
><div
class=
"highlight"
><pre><span></span><span
class=
"kt"
>
void
</span>
<span
class=
"nf"
>
Compute
</span><span
class=
"p"
>
(
</span><span
class=
"k"
>
const
</span>
<span
class=
"n"
>
framework
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
ExecutionContext
</span><span
class=
"o"
>
&
</span>
<span
class=
"n"
>
context
</span><span
class=
"p"
>
)
</span>
<span
class=
"k"
>
const
</span>
<span
class=
"k"
>
override
</span>
<span
class=
"p"
>
{
</span>
<span
class=
"k"
>
auto
</span><span
class=
"o"
>
*
</span>
<span
class=
"n"
>
input0
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
context
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
Input
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
Tensor
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
(
</span><span
class=
"s"
>
"
X
"
</span><span
class=
"p"
>
);
</span>
<span
class=
"k"
>
auto
</span><span
class=
"o"
>
*
</span>
<span
class=
"n"
>
input1
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
context
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
Input
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
Tensor
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
(
</span><span
class=
"s"
>
"
Y
"
</span><span
class=
"p"
>
);
</span>
<span
class=
"k"
>
auto
</span><span
class=
"o"
>
*
</span>
<span
class=
"n"
>
output
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
context
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
Output
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
Tensor
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
(
</span><span
class=
"s"
>
"
Out
"
</span><span
class=
"p"
>
);
</span>
<span
class=
"n"
>
output
</span><span
class=
"o"
>
-
>
</span><span
class=
"n"
>
mutable_data
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
T
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
context
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
GetPlace
</span><span
class=
"p"
>
());
</span>
<span
class=
"k"
>
auto
</span>
<span
class=
"n"
>
x
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
EigenVector
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
T
</span><span
class=
"o"
>
>
::
</span><span
class=
"n"
>
Flatten
</span><span
class=
"p"
>
(
</span><span
class=
"o"
>
*
</span><span
class=
"n"
>
input0
</span><span
class=
"p"
>
);
</span>
<span
class=
"k"
>
auto
</span>
<span
class=
"n"
>
y
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
EigenVector
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
T
</span><span
class=
"o"
>
>
::
</span><span
class=
"n"
>
Flatten
</span><span
class=
"p"
>
(
</span><span
class=
"o"
>
*
</span><span
class=
"n"
>
input1
</span><span
class=
"p"
>
);
</span>
<span
class=
"k"
>
auto
</span>
<span
class=
"n"
>
z
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
EigenVector
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
T
</span><span
class=
"o"
>
>
::
</span><span
class=
"n"
>
Flatten
</span><span
class=
"p"
>
(
</span><span
class=
"o"
>
*
</span><span
class=
"n"
>
output
</span><span
class=
"p"
>
);
</span>
<span
class=
"k"
>
auto
</span>
<span
class=
"n"
>
place
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
context
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
GetEigenDevice
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
Place
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
();
</span>
<span
class=
"n"
>
z
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
device
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
place
</span><span
class=
"p"
>
)
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
x
</span>
<span
class=
"o"
>
+
</span>
<span
class=
"n"
>
y
</span><span
class=
"p"
>
;
</span>
<span
class=
"p"
>
}
</span>
</pre></div>
</div>
</div>
<div
class=
"section"
id=
"paddle-framework-tensoreigentensor"
>
<span
id=
"paddle-framework-tensoreigentensor"
></span><h2>
paddle::framework::Tensor到EigenTensor的转换
<a
class=
"headerlink"
href=
"#paddle-framework-tensoreigentensor"
title=
"永久链接至标题"
>
¶
</a></h2>
<p>
如上一小节所示,在具体的计算中,我们需要先把输入Tensor和输出Tensor转换为Eigen支持的格式。我们在
<a
class=
"reference external"
href=
"https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/framework/eigen.h"
>
eigen.h
</a>
中提供了一些全局函数用来实现paddle::framework::Tensor到EigenTensor/EigenMatrix/EigenVector/EigenScalar的转换。
</p>
<p>
以EigenTensor为例,做一个介绍
</p>
<div
class=
"highlight-cpp"
><div
class=
"highlight"
><pre><span></span><span
class=
"n"
>
Tensor
</span>
<span
class=
"n"
>
t
</span><span
class=
"p"
>
;
</span>
<span
class=
"kt"
>
float
</span><span
class=
"o"
>
*
</span>
<span
class=
"n"
>
p
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
t
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
mutable_data
</span><span
class=
"o"
>
<
</span><span
class=
"kt"
>
float
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
make_ddim
</span><span
class=
"p"
>
({
</span><span
class=
"mi"
>
1
</span><span
class=
"p"
>
,
</span>
<span
class=
"mi"
>
2
</span><span
class=
"p"
>
,
</span>
<span
class=
"mi"
>
3
</span><span
class=
"p"
>
}),
</span>
<span
class=
"n"
>
platform
</span><span
class=
"o"
>
::
</span><span
class=
"n"
>
CPUPlace
</span><span
class=
"p"
>
());
</span>
<span
class=
"k"
>
for
</span>
<span
class=
"p"
>
(
</span><span
class=
"kt"
>
int
</span>
<span
class=
"n"
>
i
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"mi"
>
0
</span><span
class=
"p"
>
;
</span>
<span
class=
"n"
>
i
</span>
<span
class=
"o"
>
<
</span>
<span
class=
"mi"
>
1
</span>
<span
class=
"o"
>
*
</span>
<span
class=
"mi"
>
2
</span>
<span
class=
"o"
>
*
</span>
<span
class=
"mi"
>
3
</span><span
class=
"p"
>
;
</span>
<span
class=
"n"
>
i
</span><span
class=
"o"
>
++
</span><span
class=
"p"
>
)
</span>
<span
class=
"p"
>
{
</span>
<span
class=
"n"
>
p
</span><span
class=
"p"
>
[
</span><span
class=
"n"
>
i
</span><span
class=
"p"
>
]
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"k"
>
static_cast
</span><span
class=
"o"
>
<
</span><span
class=
"kt"
>
float
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
i
</span><span
class=
"p"
>
);
</span>
<span
class=
"p"
>
}
</span>
<span
class=
"n"
>
EigenTensor
</span><span
class=
"o"
>
<
</span><span
class=
"kt"
>
float
</span><span
class=
"p"
>
,
</span>
<span
class=
"mi"
>
3
</span><span
class=
"o"
>
>
::
</span><span
class=
"n"
>
Type
</span>
<span
class=
"n"
>
et
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
EigenTensor
</span><span
class=
"o"
>
<
</span><span
class=
"kt"
>
float
</span><span
class=
"p"
>
,
</span>
<span
class=
"mi"
>
3
</span><span
class=
"o"
>
>
::
</span><span
class=
"n"
>
From
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
t
</span><span
class=
"p"
>
);
</span>
</pre></div>
</div>
<p>
From是EigenTensor模板提供的一个接口,可以实现从paddle::framework::Tensor到对EigenTensor的转换。由于Tensor的rank是模板参数,因此在转换时需要显示的指定。
</p>
<p>
在Eigen中,不同rank的Tensor是不同类型,Vector是rank为1的Tensor。需要额外注意的是,EigenVector
<T>
::From方法是把paddle中的一维Tensor转为Eigen的一维Tensor,在这里用EigenVector来表示;而EigenVector
<T>
::Flatten方法是把paddle中的一个Tensor进行reshape操作,压扁成为Eigen的一维Tensor,类型仍然为EigenVector。
</p>
<p>
更多的转换方法请参考eigen_test.cc中的
<a
class=
"reference external"
href=
"https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/framework/eigen_test.cc"
>
单元测试
</a>
。
</p>
</div>
<div
class=
"section"
id=
""
>
<span
id=
"id2"
></span><h2>
实现计算
<a
class=
"headerlink"
href=
"#"
title=
"永久链接至标题"
>
¶
</a></h2>
<p>
当需要完成计算时,我们需要等式左边的EigenTensor调用device接口。在这里需要注意的是,这里的EigenTensor之间的运算只是改变了原有Tensor中的数据,而不会改变原有Tensor的shape信息。
</p>
<div
class=
"highlight-cpp"
><div
class=
"highlight"
><pre><span></span><span
class=
"k"
>
auto
</span>
<span
class=
"n"
>
x
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
EigenVector
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
T
</span><span
class=
"o"
>
>
::
</span><span
class=
"n"
>
Flatten
</span><span
class=
"p"
>
(
</span><span
class=
"o"
>
*
</span><span
class=
"n"
>
input0
</span><span
class=
"p"
>
);
</span>
<span
class=
"k"
>
auto
</span>
<span
class=
"n"
>
y
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
EigenVector
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
T
</span><span
class=
"o"
>
>
::
</span><span
class=
"n"
>
Flatten
</span><span
class=
"p"
>
(
</span><span
class=
"o"
>
*
</span><span
class=
"n"
>
input1
</span><span
class=
"p"
>
);
</span>
<span
class=
"k"
>
auto
</span>
<span
class=
"n"
>
z
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
EigenVector
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
T
</span><span
class=
"o"
>
>
::
</span><span
class=
"n"
>
Flatten
</span><span
class=
"p"
>
(
</span><span
class=
"o"
>
*
</span><span
class=
"n"
>
output
</span><span
class=
"p"
>
);
</span>
<span
class=
"k"
>
auto
</span>
<span
class=
"n"
>
place
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
context
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
GetEigenDevice
</span><span
class=
"o"
>
<
</span><span
class=
"n"
>
Place
</span><span
class=
"o"
>
>
</span><span
class=
"p"
>
();
</span>
<span
class=
"n"
>
z
</span><span
class=
"p"
>
.
</span><span
class=
"n"
>
device
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
place
</span><span
class=
"p"
>
)
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
x
</span>
<span
class=
"o"
>
+
</span>
<span
class=
"n"
>
y
</span><span
class=
"p"
>
;
</span>
</pre></div>
</div>
<p>
在这段代码中,input0/input1/output可以是任意维度的Tensor。我们调用了EigenVector的Flatten接口,把任意维度的Tensor转为了一维的EigenVector。而在计算结束之后,input0/input1/output的原有shape信息不变。如果想改变原有Tensor的shape信息,可以调用Resize接口进行改变。
</p>
<p>
由于Eigen Tensor模块的文档较少,我们可以参考TensorFlow的
<a
class=
"reference external"
href=
"https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/kernels"
>
kernels
</a>
模块下的相关
<code
class=
"docutils literal"
><span
class=
"pre"
>
OpKernel
</span></code>
的计算代码。
</p>
</div>
</div>
</div>
</div>
<footer>
<hr/>
<div
role=
"contentinfo"
>
<p>
©
Copyright 2016, PaddlePaddle developers.
</p>
</div>
Built with
<a
href=
"http://sphinx-doc.org/"
>
Sphinx
</a>
using a
<a
href=
"https://github.com/snide/sphinx_rtd_theme"
>
theme
</a>
provided by
<a
href=
"https://readthedocs.org"
>
Read the Docs
</a>
.
</footer>
</div>
</div>
</section>
</div>
<script
type=
"text/javascript"
>
var
DOCUMENTATION_OPTIONS
=
{
URL_ROOT
:
'
../../
'
,
VERSION
:
''
,
COLLAPSE_INDEX
:
false
,
FILE_SUFFIX
:
'
.html
'
,
HAS_SOURCE
:
true
,
SOURCELINK_SUFFIX
:
"
.txt
"
,
};
</script>
<script
type=
"text/javascript"
src=
"../../_static/jquery.js"
></script>
<script
type=
"text/javascript"
src=
"../../_static/underscore.js"
></script>
<script
type=
"text/javascript"
src=
"../../_static/doctools.js"
></script>
<script
type=
"text/javascript"
src=
"../../_static/translations.js"
></script>
<script
type=
"text/javascript"
src=
"https://cdn.bootcss.com/mathjax/2.7.0/MathJax.js"
></script>
<script
type=
"text/javascript"
src=
"../../_static/js/theme.js"
></script>
<script
src=
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
integrity=
"sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin=
"anonymous"
></script>
<script
src=
"https://cdn.jsdelivr.net/perfect-scrollbar/0.6.14/js/perfect-scrollbar.jquery.min.js"
></script>
<script
src=
"../../_static/js/paddle_doc_init.js"
></script>
</body>
</html>
\ No newline at end of file
develop/doc_cn/objects.inv
浏览文件 @
d95d66cb
无法预览此类型文件
develop/doc_cn/searchindex.js
浏览文件 @
d95d66cb
因为 它太大了无法显示 source diff 。你可以改为
查看blob
。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录