Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
f2442be9
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看板
提交
f2442be9
编写于
9月 14, 2017
作者:
Y
Yibing Liu
浏览文件
操作
浏览文件
下载
差异文件
merge conflicts
上级
36f349e7
30ab4fae
变更
51
隐藏空白更改
内联
并排
Showing
51 changed file
with
1452 addition
and
293 deletion
+1452
-293
.gitignore
.gitignore
+1
-0
cmake/cpplint.cmake
cmake/cpplint.cmake
+2
-2
doc/howto/dev/new_op_cn.md
doc/howto/dev/new_op_cn.md
+13
-36
paddle/framework/lod_tensor.h
paddle/framework/lod_tensor.h
+4
-8
paddle/framework/lod_tensor_test.cc
paddle/framework/lod_tensor_test.cc
+20
-25
paddle/framework/lod_tensor_test.cu
paddle/framework/lod_tensor_test.cu
+2
-4
paddle/framework/operator.cc
paddle/framework/operator.cc
+42
-0
paddle/framework/operator.h
paddle/framework/operator.h
+45
-0
paddle/gserver/layers/MKLDNNConvLayer.cpp
paddle/gserver/layers/MKLDNNConvLayer.cpp
+543
-0
paddle/gserver/layers/MKLDNNConvLayer.h
paddle/gserver/layers/MKLDNNConvLayer.h
+253
-0
paddle/gserver/tests/test_MKLDNN.cpp
paddle/gserver/tests/test_MKLDNN.cpp
+78
-0
paddle/math/MKLDNNMatrix.cpp
paddle/math/MKLDNNMatrix.cpp
+21
-0
paddle/math/MKLDNNMatrix.h
paddle/math/MKLDNNMatrix.h
+25
-0
paddle/operators/CMakeLists.txt
paddle/operators/CMakeLists.txt
+32
-11
paddle/operators/accuracy_op.cc
paddle/operators/accuracy_op.cc
+1
-1
paddle/operators/add_op.cc
paddle/operators/add_op.cc
+2
-1
paddle/operators/concat_op.cc
paddle/operators/concat_op.cc
+1
-1
paddle/operators/concat_op.cu
paddle/operators/concat_op.cu
+0
-19
paddle/operators/cos_sim_op.cc
paddle/operators/cos_sim_op.cc
+7
-5
paddle/operators/elementwise_mul_op.cc
paddle/operators/elementwise_mul_op.cc
+5
-3
paddle/operators/fill_zeros_like_op.cc
paddle/operators/fill_zeros_like_op.cc
+1
-1
paddle/operators/gather_op.cc
paddle/operators/gather_op.cc
+2
-2
paddle/operators/gaussian_random_op.cc
paddle/operators/gaussian_random_op.cc
+1
-1
paddle/operators/lookup_table_op.cc
paddle/operators/lookup_table_op.cc
+3
-2
paddle/operators/mean_op.cc
paddle/operators/mean_op.cc
+2
-2
paddle/operators/minus_op.cc
paddle/operators/minus_op.cc
+1
-1
paddle/operators/mul_op.cc
paddle/operators/mul_op.cc
+7
-3
paddle/operators/onehot_cross_entropy_op.cc
paddle/operators/onehot_cross_entropy_op.cc
+3
-3
paddle/operators/onehot_cross_entropy_op.cu
paddle/operators/onehot_cross_entropy_op.cu
+0
-0
paddle/operators/onehot_cross_entropy_op.h
paddle/operators/onehot_cross_entropy_op.h
+0
-0
paddle/operators/pad_op.cc
paddle/operators/pad_op.cc
+5
-4
paddle/operators/recurrent_op.cc
paddle/operators/recurrent_op.cc
+10
-8
paddle/operators/reshape_op.cc
paddle/operators/reshape_op.cc
+2
-2
paddle/operators/rnn/recurrent_op_utils.cc
paddle/operators/rnn/recurrent_op_utils.cc
+12
-7
paddle/operators/rowwise_add_op.cc
paddle/operators/rowwise_add_op.cc
+3
-3
paddle/operators/scale_op.cc
paddle/operators/scale_op.cc
+1
-1
paddle/operators/scatter_op.cc
paddle/operators/scatter_op.cc
+6
-3
paddle/operators/sequence_avg_pool_op.cc
paddle/operators/sequence_avg_pool_op.cc
+90
-0
paddle/operators/sequence_avg_pool_op.cu
paddle/operators/sequence_avg_pool_op.cu
+25
-0
paddle/operators/sequence_avg_pool_op.h
paddle/operators/sequence_avg_pool_op.h
+81
-0
paddle/operators/sgd_op.cc
paddle/operators/sgd_op.cc
+5
-4
paddle/operators/sigmoid_op.cc
paddle/operators/sigmoid_op.cc
+3
-2
paddle/operators/softmax_op.cc
paddle/operators/softmax_op.cc
+3
-2
paddle/operators/squared_l2_distance_op.cc
paddle/operators/squared_l2_distance_op.cc
+6
-4
paddle/operators/sum_op.cc
paddle/operators/sum_op.cc
+3
-2
paddle/operators/top_k_op.cc
paddle/operators/top_k_op.cc
+2
-2
paddle/operators/uniform_random_op.cc
paddle/operators/uniform_random_op.cc
+1
-1
paddle/pybind/pybind.cc
paddle/pybind/pybind.cc
+10
-50
python/paddle/trainer/config_parser.py
python/paddle/trainer/config_parser.py
+14
-3
python/paddle/v2/framework/tests/test_cross_entropy_op.py
python/paddle/v2/framework/tests/test_cross_entropy_op.py
+9
-7
python/paddle/v2/framework/tests/test_tensor.py
python/paddle/v2/framework/tests/test_tensor.py
+44
-57
未找到文件。
.gitignore
浏览文件 @
f2442be9
...
@@ -22,6 +22,7 @@ cmake-build-*
...
@@ -22,6 +22,7 @@ cmake-build-*
# generated while compiling
# generated while compiling
python/paddle/v2/framework/core.so
python/paddle/v2/framework/core.so
paddle/pybind/pybind.h
CMakeFiles
CMakeFiles
cmake_install.cmake
cmake_install.cmake
paddle/.timestamp
paddle/.timestamp
...
...
cmake/cpplint.cmake
浏览文件 @
f2442be9
...
@@ -26,9 +26,9 @@ set(IGNORE_PATTERN
...
@@ -26,9 +26,9 @@ set(IGNORE_PATTERN
.*ImportanceSampler.*
.*ImportanceSampler.*
.*cblas\\.h.*
.*cblas\\.h.*
.*\\.pb\\.txt
.*\\.pb\\.txt
.*LtrDataProvider.*
.*MultiDataProvider.*
.*MultiDataProvider.*
.*pb.*
)
.*pb.*
.*pybind.h
)
# add_style_check_target
# add_style_check_target
#
#
...
...
doc/howto/dev/new_op_cn.md
浏览文件 @
f2442be9
...
@@ -34,7 +34,7 @@ Kernel实现 | CPU、GPU共享Kernel实现在`.h`文件中,否则,CPU
...
@@ -34,7 +34,7 @@ Kernel实现 | CPU、GPU共享Kernel实现在`.h`文件中,否则,CPU
注册Op | Op注册实现在
`.cc`
文件;Kernel注册CPU实现在
`.cc`
文件中,GPU实现在
`.cu`
文件中
注册Op | Op注册实现在
`.cc`
文件;Kernel注册CPU实现在
`.cc`
文件中,GPU实现在
`.cu`
文件中
实现新的op都添加至目录
[
paddle/operators
](
https://github.com/PaddlePaddle/Paddle/tree/develop/paddle/operators
)
下,文件命名以
`*_op.h`
(如有) 、
`*_op.cc`
、
`*_op.cu`
(如有)结尾。
实现新的op都添加至目录
[
paddle/operators
](
https://github.com/PaddlePaddle/Paddle/tree/develop/paddle/operators
)
下,文件命名以
`*_op.h`
(如有) 、
`*_op.cc`
、
`*_op.cu`
(如有)结尾。
**系统会根据文件名自动构建op和其对应的Python扩展。**
下面以矩阵乘操作,即
[
MulOp
](
https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/mul_op.cc
)
为例来介绍如何写带Kernel的Operator。
下面以矩阵乘操作,即
[
MulOp
](
https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/mul_op.cc
)
为例来介绍如何写带Kernel的Operator。
...
@@ -224,45 +224,15 @@ MulOp(const std::string &type, const framework::VariableNameMap &inputs,
...
@@ -224,45 +224,15 @@ MulOp(const std::string &type, const framework::VariableNameMap &inputs,
### 5. 编译
### 5. 编译
-
简单
**无特殊依赖**
的OP无需修改CMakeList.txt文件。
[
paddle/operators/CMakeLists.txt
](
https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/CMakeLists.txt
)
会自动将
`paddle/operators`
目录下新增的
`*_op.cc`
文件加入编译。
运行下面命令可以进行编译:
-
较为复杂、
**有额外依赖**
的operator仍需要修改
[
paddle/operators/CMakeLists.txt
](
https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/CMakeLists.txt
)
。如,
`mul_op`
依赖
`math_function`
,需要在
`CMakeLists.txt`
中添加如下内容:
```
```
op_library(mul_op SRCS mul_op.cc mul_op.cu DEPS math_function) +
make mul_op
```
```
-
运行下面命令可以进行编译:
```
make mul_op
```
## 绑定Python
## 绑定Python
-
绑定Python
系统会对新增的op自动绑定Python,并链接到生成的lib库中。
在 [`paddle/pybind/pybind.cc
`](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/pybind/pybind.cc) 使用`
USE_OP
`告知编译器需要链接的Op,具体解释参考[代码注释](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/framework/op_registry.h#L81)。
```
USE_OP(mul);
```
如果只实现了CPU版本,则使用`
USE_CPU_ONLY_OP
`:
```
USE_CPU_ONLY_OP(gather);
```
如果OP不带Kernel,则使用`
USE_NO_KENREL_OP
`:
```
USE_NO_KENREL_OP(recurrent);
```
- 生成库
`
paddle/operators
` 目录下新增的 `
*
_op.cc
` 文件会被自动添加链接到生成的lib库中。
## 实现单元测试
## 实现单元测试
...
@@ -367,3 +337,10 @@ make test ARGS="-R test_mul_op -V"
...
@@ -367,3 +337,10 @@ make test ARGS="-R test_mul_op -V"
```
bash
```
bash
ctest
-R
test_mul_op
ctest
-R
test_mul_op
```
```
## 注意事项
-
为每个Op创建单独的
`*_op.h`
(如有)、
`*_op.cc`
和
`*_op.cu`
(如有)。不允许一个文件中包含多个Op,这将会导致编译出错。
-
注册Op时的类型名,需要和该Op的名字一样。即不允许在
`A_op.cc`
里面,注册
`REGISTER_OP(B, ...)`
等,这将会导致单元测试出错。
-
如果Op没有实现GPU Kernel,请不要创建空的
`*_op.cu`
,这将会导致单元测试出错。
-
如果多个Op依赖一些共用的函数,可以创建非
`*_op.*`
格式的文件来存放,如
`gather.h`
文件。
paddle/framework/lod_tensor.h
浏览文件 @
f2442be9
...
@@ -51,18 +51,15 @@ bool operator==(const LoD& a, const LoD& b);
...
@@ -51,18 +51,15 @@ bool operator==(const LoD& a, const LoD& b);
* LoDTensor (Level of details Tensor)
* LoDTensor (Level of details Tensor)
* see https://en.wikipedia.org/wiki/Level_of_details for reference.
* see https://en.wikipedia.org/wiki/Level_of_details for reference.
*/
*/
class
LoDTensor
{
class
LoDTensor
:
public
Tensor
{
public:
public:
LoDTensor
()
{}
LoDTensor
()
{}
LoDTensor
(
const
LoD
&
lod
,
Tensor
*
t
)
:
lod_
(
lod
),
tensor_
(
t
)
{}
void
set_lod
(
const
LoD
&
lod
)
{
lod_
=
lod
;
}
explicit
LoDTensor
(
const
LoD
&
lod
)
:
lod_
(
lod
)
{}
void
set_tensor
(
Tensor
*
tensor
)
{
tensor_
=
tensor
;
}
Tensor
&
tensor
()
{
return
*
tensor_
;
}
void
set_lod
(
const
LoD
&
lod
)
{
lod_
=
lod
;
}
LoD
lod
()
{
return
lod_
;
}
LoD
lod
()
const
{
return
lod_
;
}
/*
/*
* Get a element from LoD.
* Get a element from LoD.
...
@@ -104,7 +101,6 @@ class LoDTensor {
...
@@ -104,7 +101,6 @@ class LoDTensor {
private:
private:
LoD
lod_
;
LoD
lod_
;
Tensor
*
tensor_
;
// not owned
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle
}
// namespace paddle
paddle/framework/lod_tensor_test.cc
浏览文件 @
f2442be9
...
@@ -36,69 +36,64 @@ class LoDTensorTester : public ::testing::Test {
...
@@ -36,69 +36,64 @@ class LoDTensorTester : public ::testing::Test {
ASSERT_EQ
(
lod
.
size
(),
3UL
);
ASSERT_EQ
(
lod
.
size
(),
3UL
);
tensor
.
Resize
({
20
/*batch size*/
,
128
/*dim*/
});
lod_tensor_
.
Resize
({
20
/*batch size*/
,
128
/*dim*/
});
// malloc memory
// malloc memory
tensor
.
mutable_data
<
float
>
(
place
);
lod_tensor_
.
mutable_data
<
float
>
(
place
);
lod_tensor
.
set_lod
(
lod
);
lod_tensor_
.
set_lod
(
lod
);
lod_tensor
.
set_tensor
(
&
tensor
);
}
}
protected:
protected:
platform
::
CPUPlace
place
;
platform
::
CPUPlace
place
;
Tensor
tensor
;
LoDTensor
lod_tensor_
;
LoDTensor
lod_tensor
;
};
};
TEST_F
(
LoDTensorTester
,
NumLevels
)
{
ASSERT_EQ
(
lod_tensor
.
NumLevels
(),
3UL
);
}
TEST_F
(
LoDTensorTester
,
NumLevels
)
{
ASSERT_EQ
(
lod_tensor
_
.
NumLevels
(),
3UL
);
}
TEST_F
(
LoDTensorTester
,
NumElements
)
{
TEST_F
(
LoDTensorTester
,
NumElements
)
{
ASSERT_EQ
(
lod_tensor
.
NumElements
(
0
),
2UL
);
ASSERT_EQ
(
lod_tensor
_
.
NumElements
(
0
),
2UL
);
ASSERT_EQ
(
lod_tensor
.
NumElements
(
1
),
4UL
);
ASSERT_EQ
(
lod_tensor
_
.
NumElements
(
1
),
4UL
);
ASSERT_EQ
(
lod_tensor
.
NumElements
(
2
),
8UL
);
ASSERT_EQ
(
lod_tensor
_
.
NumElements
(
2
),
8UL
);
}
}
TEST_F
(
LoDTensorTester
,
SliceLevels
)
{
TEST_F
(
LoDTensorTester
,
SliceLevels
)
{
// slice 1 level
// slice 1 level
for
(
size_t
level
=
0
;
level
<
3UL
;
++
level
)
{
for
(
size_t
level
=
0
;
level
<
3UL
;
++
level
)
{
LoDTensor
new_lod_tensor
=
lod_tensor
;
LoDTensor
new_lod_tensor
=
lod_tensor
_
;
new_lod_tensor
.
SliceLevels
(
level
,
level
+
1
);
new_lod_tensor
.
SliceLevels
(
level
,
level
+
1
);
ASSERT_EQ
(
new_lod_tensor
.
NumLevels
(),
1UL
);
ASSERT_EQ
(
new_lod_tensor
.
NumLevels
(),
1UL
);
ASSERT_EQ
(
new_lod_tensor
.
NumElements
(
0
),
lod_tensor
.
NumElements
(
level
));
ASSERT_EQ
(
new_lod_tensor
.
NumElements
(
0
),
lod_tensor_
.
NumElements
(
level
));
ASSERT_EQ
(
new_lod_tensor
.
tensor
().
data
<
float
>
(),
ASSERT_EQ
(
new_lod_tensor
.
data
<
float
>
(),
lod_tensor_
.
data
<
float
>
());
lod_tensor
.
tensor
().
data
<
float
>
());
}
}
// slice 2 level
// slice 2 level
for
(
size_t
level
=
0
;
level
<
2UL
;
++
level
)
{
for
(
size_t
level
=
0
;
level
<
2UL
;
++
level
)
{
LoDTensor
new_lod_tensor
=
lod_tensor
;
LoDTensor
new_lod_tensor
=
lod_tensor
_
;
new_lod_tensor
.
SliceLevels
(
level
,
level
+
2
);
new_lod_tensor
.
SliceLevels
(
level
,
level
+
2
);
ASSERT_EQ
(
new_lod_tensor
.
NumLevels
(),
2UL
);
ASSERT_EQ
(
new_lod_tensor
.
NumLevels
(),
2UL
);
ASSERT_EQ
(
new_lod_tensor
.
NumElements
(
0
),
lod_tensor
.
NumElements
(
level
));
ASSERT_EQ
(
new_lod_tensor
.
NumElements
(
0
),
lod_tensor
_
.
NumElements
(
level
));
ASSERT_EQ
(
new_lod_tensor
.
NumElements
(
1
),
lod_tensor
.
NumElements
(
level
+
1
));
ASSERT_EQ
(
new_lod_tensor
.
NumElements
(
1
),
ASSERT_EQ
(
new_lod_tensor
.
tensor
().
data
<
float
>
(),
lod_tensor_
.
NumElements
(
level
+
1
));
lod_tensor
.
tensor
()
.
data
<
float
>
());
ASSERT_EQ
(
new_lod_tensor
.
data
<
float
>
(),
lod_tensor_
.
data
<
float
>
());
}
}
}
}
TEST_F
(
LoDTensorTester
,
SliceInLevel
)
{
TEST_F
(
LoDTensorTester
,
SliceInLevel
)
{
size_t
level
=
0
;
size_t
level
=
0
;
LoDTensor
new_lod_tensor
=
lod_tensor
;
LoDTensor
new_lod_tensor
=
lod_tensor
_
;
new_lod_tensor
.
SliceInLevel
(
level
,
0
,
2
);
new_lod_tensor
.
SliceInLevel
(
level
,
0
,
2
);
EXPECT_EQ
(
new_lod_tensor
.
NumLevels
(),
3UL
);
EXPECT_EQ
(
new_lod_tensor
.
NumLevels
(),
3UL
);
EXPECT_EQ
(
new_lod_tensor
.
NumElements
(
0
),
2UL
);
EXPECT_EQ
(
new_lod_tensor
.
NumElements
(
0
),
2UL
);
EXPECT_EQ
(
new_lod_tensor
.
NumElements
(
1
),
4UL
);
EXPECT_EQ
(
new_lod_tensor
.
NumElements
(
1
),
4UL
);
EXPECT_EQ
(
new_lod_tensor
.
NumElements
(
2
),
8UL
);
EXPECT_EQ
(
new_lod_tensor
.
NumElements
(
2
),
8UL
);
ASSERT_EQ
(
new_lod_tensor
.
tensor
().
data
<
float
>
(),
ASSERT_EQ
(
new_lod_tensor
.
data
<
float
>
(),
lod_tensor_
.
data
<
float
>
());
lod_tensor
.
tensor
().
data
<
float
>
());
level
=
1
;
level
=
1
;
new_lod_tensor
=
lod_tensor
;
new_lod_tensor
=
lod_tensor
_
;
new_lod_tensor
.
SliceInLevel
(
level
,
0
,
2
);
new_lod_tensor
.
SliceInLevel
(
level
,
0
,
2
);
ASSERT_EQ
(
new_lod_tensor
.
NumLevels
(),
2UL
);
ASSERT_EQ
(
new_lod_tensor
.
NumLevels
(),
2UL
);
ASSERT_EQ
(
new_lod_tensor
.
NumElements
(
0
),
2UL
);
ASSERT_EQ
(
new_lod_tensor
.
NumElements
(
0
),
2UL
);
ASSERT_EQ
(
new_lod_tensor
.
NumElements
(
1
),
4UL
);
ASSERT_EQ
(
new_lod_tensor
.
NumElements
(
1
),
4UL
);
ASSERT_EQ
(
new_lod_tensor
.
tensor
().
data
<
float
>
(),
ASSERT_EQ
(
new_lod_tensor
.
data
<
float
>
(),
lod_tensor_
.
data
<
float
>
());
lod_tensor
.
tensor
().
data
<
float
>
());
}
}
}
// namespace framework
}
// namespace framework
...
...
paddle/framework/lod_tensor_test.cu
浏览文件 @
f2442be9
...
@@ -26,18 +26,16 @@ __global__ void test(size_t* a, int size) {
...
@@ -26,18 +26,16 @@ __global__ void test(size_t* a, int size) {
}
}
TEST
(
LoDTensor
,
LoDInGPU
)
{
TEST
(
LoDTensor
,
LoDInGPU
)
{
paddle
::
framework
::
Tensor
tensor
;
paddle
::
framework
::
LoDTensor
lod_tensor
;
paddle
::
framework
::
LoDTensor
lod_tensor
;
paddle
::
platform
::
GPUPlace
place
(
0
);
paddle
::
platform
::
GPUPlace
place
(
0
);
paddle
::
framework
::
LoD
src_lod
;
paddle
::
framework
::
LoD
src_lod
;
src_lod
.
push_back
(
std
::
vector
<
size_t
>
{
0
,
2
,
4
,
6
,
8
,
10
,
12
,
14
});
src_lod
.
push_back
(
std
::
vector
<
size_t
>
{
0
,
2
,
4
,
6
,
8
,
10
,
12
,
14
});
tensor
.
Resize
({
14
,
16
});
lod_
tensor
.
Resize
({
14
,
16
});
tensor
.
mutable_data
<
float
>
(
place
);
lod_
tensor
.
mutable_data
<
float
>
(
place
);
lod_tensor
.
set_lod
(
src_lod
);
lod_tensor
.
set_lod
(
src_lod
);
lod_tensor
.
set_tensor
(
&
tensor
);
CHECK_EQ
(
lod_tensor
.
lod_element
(
0
,
2
),
4
);
CHECK_EQ
(
lod_tensor
.
lod_element
(
0
,
2
),
4
);
CHECK_EQ
(
lod_tensor
.
lod_element
(
0
,
4
),
8
);
CHECK_EQ
(
lod_tensor
.
lod_element
(
0
,
4
),
8
);
...
...
paddle/framework/operator.cc
浏览文件 @
f2442be9
...
@@ -186,6 +186,48 @@ void OperatorBase::GenerateTemporaryNames() {
...
@@ -186,6 +186,48 @@ void OperatorBase::GenerateTemporaryNames() {
}
}
}
}
template
<
>
const
Tensor
*
InferShapeContext
::
Input
<
Tensor
>
(
const
std
::
string
&
name
)
const
{
auto
*
var
=
InputVar
(
name
);
return
var
==
nullptr
?
nullptr
:
GetTensorFromVar
(
var
);
}
template
<
>
const
std
::
vector
<
const
Tensor
*>
InferShapeContext
::
MultiInput
<
Tensor
>
(
const
std
::
string
&
name
)
const
{
auto
names
=
op
().
Inputs
(
name
);
std
::
vector
<
const
Tensor
*>
res
;
res
.
reserve
(
names
.
size
());
std
::
transform
(
names
.
begin
(),
names
.
end
(),
std
::
back_inserter
(
res
),
[
&
](
const
std
::
string
&
sub_name
)
{
auto
var
=
scope_
.
FindVar
(
sub_name
);
return
var
==
nullptr
?
nullptr
:
GetTensorFromVar
(
var
);
});
return
res
;
}
template
<
>
Tensor
*
ExecutionContext
::
Output
<
Tensor
>
(
const
std
::
string
&
name
)
const
{
auto
*
var
=
OutputVar
(
name
);
return
var
==
nullptr
?
nullptr
:
const_cast
<
Tensor
*>
(
GetTensorFromVar
(
var
));
}
template
<
>
std
::
vector
<
Tensor
*>
ExecutionContext
::
MultiOutput
<
Tensor
>
(
const
std
::
string
&
name
)
const
{
auto
names
=
op
().
Outputs
(
name
);
std
::
vector
<
Tensor
*>
res
;
res
.
reserve
(
names
.
size
());
std
::
transform
(
names
.
begin
(),
names
.
end
(),
std
::
back_inserter
(
res
),
[
&
](
const
std
::
string
&
sub_name
)
{
auto
var
=
scope
().
FindVar
(
sub_name
);
return
var
==
nullptr
?
nullptr
:
const_cast
<
Tensor
*>
(
GetTensorFromVar
(
var
));
});
return
res
;
}
void
OpProtoAndCheckerMaker
::
Validate
()
{
void
OpProtoAndCheckerMaker
::
Validate
()
{
validated_
=
true
;
validated_
=
true
;
CheckNoDuplicatedInOutAttrs
();
CheckNoDuplicatedInOutAttrs
();
...
...
paddle/framework/operator.h
浏览文件 @
f2442be9
...
@@ -22,6 +22,7 @@ limitations under the License. */
...
@@ -22,6 +22,7 @@ limitations under the License. */
#include "op_info.h"
#include "op_info.h"
#include "paddle/framework/attribute.h"
#include "paddle/framework/attribute.h"
#include "paddle/framework/framework.pb.h"
#include "paddle/framework/framework.pb.h"
#include "paddle/framework/lod_tensor.h"
#include "paddle/framework/scope.h"
#include "paddle/framework/scope.h"
#include "paddle/framework/tensor.h"
#include "paddle/framework/tensor.h"
#include "paddle/platform/device_context.h"
#include "paddle/platform/device_context.h"
...
@@ -326,11 +327,27 @@ class InferShapeContext {
...
@@ -326,11 +327,27 @@ class InferShapeContext {
return
res
;
return
res
;
}
}
const
Tensor
*
GetTensorFromVar
(
const
Variable
*
var
)
const
{
if
(
var
->
IsType
<
LoDTensor
>
())
{
return
&
var
->
Get
<
LoDTensor
>
();
}
PADDLE_ENFORCE
(
var
->
IsType
<
Tensor
>
(),
"The Input(%s) must be LoDTensor or Tensor."
);
return
&
var
->
Get
<
Tensor
>
();
}
private:
private:
const
OperatorBase
&
op_
;
const
OperatorBase
&
op_
;
const
Scope
&
scope_
;
const
Scope
&
scope_
;
};
};
template
<>
const
Tensor
*
InferShapeContext
::
Input
<
Tensor
>
(
const
std
::
string
&
name
)
const
;
template
<>
const
std
::
vector
<
const
Tensor
*>
InferShapeContext
::
MultiInput
<
Tensor
>
(
const
std
::
string
&
name
)
const
;
template
<
typename
T
>
template
<
typename
T
>
struct
EigenDeviceConverter
;
struct
EigenDeviceConverter
;
...
@@ -363,9 +380,37 @@ class ExecutionContext : public InferShapeContext {
...
@@ -363,9 +380,37 @@ class ExecutionContext : public InferShapeContext {
return
device_context_
;
return
device_context_
;
}
}
// redefine Output function,
// use Variable::Get instead of Variable::GetMutable
template
<
typename
T
>
T
*
Output
(
const
std
::
string
&
name
)
const
{
auto
var
=
OutputVar
(
name
);
return
var
==
nullptr
?
nullptr
:
const_cast
<
T
*>
(
&
var
->
Get
<
T
>
());
}
// redefine MultiOutput function.
// use Variable::Get instead of Variable::GetMutable
template
<
typename
T
>
std
::
vector
<
T
*>
MultiOutput
(
const
std
::
string
&
name
)
const
{
auto
names
=
op
().
Outputs
(
name
);
std
::
vector
<
T
*>
res
;
res
.
reserve
(
names
.
size
());
std
::
transform
(
names
.
begin
(),
names
.
end
(),
std
::
back_inserter
(
res
),
[
&
](
const
std
::
string
&
sub_name
)
{
return
Output
<
T
>
(
sub_name
);
});
return
res
;
}
const
platform
::
DeviceContext
*
device_context_
;
const
platform
::
DeviceContext
*
device_context_
;
};
};
template
<>
Tensor
*
ExecutionContext
::
Output
<
Tensor
>
(
const
std
::
string
&
name
)
const
;
template
<>
std
::
vector
<
Tensor
*>
ExecutionContext
::
MultiOutput
<
Tensor
>
(
const
std
::
string
&
name
)
const
;
class
OpKernel
{
class
OpKernel
{
public:
public:
/**
/**
...
...
paddle/gserver/layers/MKLDNNConvLayer.cpp
0 → 100644
浏览文件 @
f2442be9
/* Copyright (c) 2017 PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include "MKLDNNConvLayer.h"
#include "paddle/math/MathUtils.h"
#include "paddle/utils/Logging.h"
using
namespace
mkldnn
;
// NOLINT
typedef
memory
::
format
format
;
namespace
paddle
{
REGISTER_LAYER
(
mkldnn_conv
,
MKLDNNConvLayer
);
bool
MKLDNNConvLayer
::
init
(
const
LayerMap
&
layerMap
,
const
ParameterMap
&
parameterMap
)
{
if
(
!
MKLDNNLayer
::
init
(
layerMap
,
parameterMap
))
{
return
false
;
}
CHECK_EQ
(
inputLayers_
.
size
(),
1
)
<<
"Only support one input layer yet"
;
CHECK_EQ
(
inputLayers_
.
size
(),
parameters_
.
size
());
CHECK
(
config_
.
shared_biases
())
<<
"Only support shared biases yet"
;
oc_
=
config_
.
num_filters
();
const
ConvConfig
&
conf
=
config_
.
inputs
(
0
).
conv_conf
();
ic_
=
conf
.
channels
();
fw_
=
conf
.
filter_size
();
fh_
=
conf
.
filter_size_y
();
pw_
=
conf
.
padding
();
ph_
=
conf
.
padding_y
();
dw_
=
conf
.
dilation
();
dh_
=
conf
.
dilation_y
();
sw_
=
conf
.
stride
();
sh_
=
conf
.
stride_y
();
gp_
=
conf
.
groups
();
oh_
=
conf
.
output_y
();
ow_
=
conf
.
output_x
();
ih_
=
conf
.
img_size_y
();
iw_
=
conf
.
img_size
();
caffeMode_
=
conf
.
caffe_mode
();
CHECK
(
caffeMode_
)
<<
"Only support caffe mode yet"
;
CHECK
(
dh_
==
1
&&
dw_
==
1
)
<<
"Only support dilation 1 yet"
;
// check group setting
CHECK_EQ
((
oc_
/
gp_
)
*
gp_
,
oc_
)
<<
"group is indivisible for oc"
;
CHECK_EQ
((
ic_
/
gp_
)
*
gp_
,
ic_
)
<<
"group is indivisible for ic"
;
// create weight
size_t
height
=
oc_
/
gp_
;
size_t
width
=
ic_
*
fh_
*
fw_
;
CHECK_EQ
(
parameters_
[
0
]
->
getSize
(),
height
*
width
);
weight_
=
std
::
unique_ptr
<
Weight
>
(
new
Weight
(
height
,
width
,
parameters_
[
0
],
0
));
// create biases
if
(
biasParameter_
.
get
()
!=
NULL
)
{
biases_
=
std
::
unique_ptr
<
Weight
>
(
new
Weight
(
1
,
oc_
,
biasParameter_
));
}
return
true
;
}
void
MKLDNNConvLayer
::
convertWeightsFromPaddle
()
{
if
(
hasInitedWgt_
)
{
return
;
}
CHECK
(
wgtVal_
)
<<
"should have been initialized"
;
// the paddle weight format is oihw or goihw
auto
targetDim
=
wgtVal_
->
getDims
();
auto
srcFmt
=
(
gp_
==
1
)
?
memory
::
format
::
oihw
:
memory
::
format
::
goihw
;
wgtVal_
->
reorderDataFrom
(
wgtVal_
,
srcFmt
,
targetDim
);
hasInitedWgt_
=
true
;
}
void
MKLDNNConvLayer
::
convertWeightsToPaddle
()
{
CHECK
(
wgtVal_
)
<<
"should have been initialized"
;
auto
targetDim
=
wgtVal_
->
getDims
();
auto
dstFmt
=
(
gp_
==
1
)
?
memory
::
format
::
oihw
:
memory
::
format
::
goihw
;
wgtVal_
->
reorderDataTo
(
wgtVal_
,
dstFmt
,
targetDim
);
}
void
MKLDNNConvLayer
::
reshape
(
int
&
bs
,
int
&
ic
,
int
&
ih
,
int
&
iw
,
int
oc
,
int
&
oh
,
int
&
ow
)
{
reshapeInput
(
bs
,
ih
,
iw
);
// cal output sizes
// oc can not be changed
int
fh
=
(
fh_
-
1
)
*
dh_
+
1
;
int
fw
=
(
fw_
-
1
)
*
dw_
+
1
;
oh
=
outputSize
(
ih
,
fh
,
ph_
,
sh_
,
caffeMode_
);
ow
=
outputSize
(
iw
,
fw
,
pw_
,
sw_
,
caffeMode_
);
reshapeOutput
(
oh
,
ow
);
resizeOutput
(
bs
,
oc
*
oh
*
ow
);
printSizeInfo
();
}
void
MKLDNNConvLayer
::
resetFwd
(
std
::
vector
<
primitive
>&
pipeline
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
)
{
resetFwdPD
(
fwdPD_
);
resetFwdBuffers
(
fwdPD_
,
in
,
wgt
,
bias
,
out
);
resetFwdPipeline
(
pipeline
,
fwdPD_
,
in
,
wgt
,
bias
,
out
);
printValueFormatFlow
();
}
void
MKLDNNConvLayer
::
resetBwd
(
std
::
vector
<
primitive
>&
pipeline
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
)
{
std
::
shared_ptr
<
conv_bwdWgt
::
primitive_desc
>
bwdWgtPD
;
std
::
shared_ptr
<
conv_bwdData
::
primitive_desc
>
bwdDataPD
;
resetBwdWgtPD
(
bwdWgtPD
);
resetBwdDataPD
(
bwdDataPD
);
resetBwdBuffers
(
bwdWgtPD
,
bwdDataPD
,
in
,
wgt
,
bias
,
out
);
resetBwdPipeline
(
pipeline
,
bwdWgtPD
,
bwdDataPD
,
in
,
wgt
,
bias
,
out
);
printGradFormatFlow
();
}
void
MKLDNNConvLayer
::
updateInputData
()
{
cpuInVal_
->
setData
(
getInputValue
(
0
,
CPU_DEVICE
)
->
getData
());
}
void
MKLDNNConvLayer
::
updateWeights
(
const
UpdateCallback
&
callback
)
{
weight_
->
getParameterPtr
()
->
incUpdate
(
callback
);
if
(
biases_
&&
biases_
->
getWGrad
())
{
biases_
->
getParameterPtr
()
->
incUpdate
(
callback
);
}
}
void
MKLDNNConvLayer
::
loadConvSettings
(
memory
::
dims
&
wgt
,
memory
::
dims
&
bias
,
memory
::
dims
&
stride
,
memory
::
dims
&
dilation
,
memory
::
dims
&
padL
,
memory
::
dims
&
padR
)
{
wgt
=
(
gp_
==
1
)
?
memory
::
dims
{
oc_
,
ic_
,
fh_
,
fw_
}
:
memory
::
dims
{
gp_
,
oc_
/
gp_
,
ic_
/
gp_
,
fh_
,
fw_
};
bias
=
memory
::
dims
{
oc_
};
stride
=
memory
::
dims
{
sh_
,
sw_
};
padL
=
memory
::
dims
{
ph_
,
pw_
};
padR
=
getPaddingR
();
// note: mkldnn dilation start from 0
dilation
=
memory
::
dims
{
dh_
-
1
,
dw_
-
1
};
}
void
MKLDNNConvLayer
::
resetFwdPD
(
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
)
{
// dims for conv
memory
::
dims
inDims
=
memory
::
dims
{
bs_
,
ic_
,
ih_
,
iw_
};
memory
::
dims
outDims
=
memory
::
dims
{
bs_
,
oc_
,
oh_
,
ow_
};
memory
::
dims
wgtDims
,
biasDims
,
strides
,
dilations
,
padL
,
padR
;
loadConvSettings
(
wgtDims
,
biasDims
,
strides
,
dilations
,
padL
,
padR
);
prop_kind
pk
=
passType_
==
PASS_TEST
?
prop_kind
::
forward_scoring
:
prop_kind
::
forward_training
;
algorithm
algo
=
algorithm
::
convolution_direct
;
padding_kind
padKind
=
padding_kind
::
zero
;
conv_fwd
::
desc
fwdDesc
=
biases_
&&
biases_
->
getW
()
?
conv_fwd
::
desc
(
pk
,
algo
,
MKLDNNMatrix
::
createMemoryDesc
(
inDims
),
MKLDNNMatrix
::
createMemoryDesc
(
wgtDims
),
MKLDNNMatrix
::
createMemoryDesc
(
biasDims
),
MKLDNNMatrix
::
createMemoryDesc
(
outDims
),
strides
,
dilations
,
padL
,
padR
,
padKind
)
:
conv_fwd
::
desc
(
pk
,
algo
,
MKLDNNMatrix
::
createMemoryDesc
(
inDims
),
MKLDNNMatrix
::
createMemoryDesc
(
wgtDims
),
MKLDNNMatrix
::
createMemoryDesc
(
outDims
),
strides
,
dilations
,
padL
,
padR
,
padKind
);
pd
.
reset
(
new
conv_fwd
::
primitive_desc
(
fwdDesc
,
engine_
));
}
void
MKLDNNConvLayer
::
resetFwdBuffers
(
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
)
{
CHECK
(
pd
);
resetInValue
(
pd
,
in
);
resetWgtBiasValue
(
pd
,
wgt
,
bias
);
resetOutValue
(
pd
,
out
);
}
void
MKLDNNConvLayer
::
resetFwdPipeline
(
std
::
vector
<
primitive
>&
pipeline
,
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
)
{
pipeline
.
clear
();
if
(
cvtInVal_
)
{
pipeline
.
push_back
(
*
cvtInVal_
);
}
if
(
bias
)
{
fwd_
.
reset
(
new
conv_fwd
(
*
pd
,
*
in
,
*
wgt
,
*
bias
,
*
out
));
}
else
{
fwd_
.
reset
(
new
conv_fwd
(
*
pd
,
*
in
,
*
wgt
,
*
out
));
}
pipeline
.
push_back
(
*
fwd_
);
if
(
cvtOutVal_
)
{
pipeline
.
push_back
(
*
cvtOutVal_
);
}
}
void
MKLDNNConvLayer
::
resetInValue
(
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
in
)
{
const
MatrixPtr
&
inMat
=
inputLayers_
[
0
]
->
getOutput
().
value
;
in
=
MKLDNNMatrix
::
create
(
inMat
,
pd
->
src_primitive_desc
());
// create buffer and reorder if input value do not match
cpuInVal_
=
nullptr
;
cvtInVal_
=
nullptr
;
if
(
inputIsOnlyMKLDNN
())
{
MKLDNNMatrixPtr
dnnIn
=
std
::
dynamic_pointer_cast
<
MKLDNNMatrix
>
(
inMat
);
CHECK
(
dnnIn
)
<<
"Input should be MKLDNNMatrix"
;
if
(
dnnIn
->
getPrimitiveDesc
()
!=
in
->
getPrimitiveDesc
())
{
CHECK_EQ
(
dnnIn
->
getFormat
(),
format
::
nc
);
CHECK
(
ih_
==
1
&&
iw_
==
1
)
<<
"when input is nc format"
;
// create a new one with nchw format and same data
memory
::
dims
inDims
=
memory
::
dims
{
bs_
,
ic_
,
1
,
1
};
dnnIn
=
MKLDNNMatrix
::
create
(
inMat
,
inDims
,
format
::
nchw
,
engine_
);
CHECK
(
dnnIn
->
getPrimitiveDesc
()
==
in
->
getPrimitiveDesc
());
}
in
=
dnnIn
;
}
else
{
const
MatrixPtr
&
cpuIn
=
getInputValue
(
0
,
CPU_DEVICE
);
memory
::
dims
inDims
=
memory
::
dims
{
bs_
,
ic_
,
ih_
,
iw_
};
cpuInVal_
=
MKLDNNMatrix
::
create
(
cpuIn
,
inDims
,
format
::
nchw
,
engine_
);
if
(
cpuInVal_
->
getPrimitiveDesc
()
!=
in
->
getPrimitiveDesc
())
{
// create new mkldnn matrix
in
=
MKLDNNMatrix
::
create
(
nullptr
,
pd
->
src_primitive_desc
());
cvtInVal_
=
MKLDNNMatrix
::
createReorder
(
cpuInVal_
,
in
);
CHECK
(
cvtInVal_
)
<<
"should not be emptry"
;
}
else
{
in
=
cpuInVal_
;
}
}
}
void
MKLDNNConvLayer
::
resetWgtBiasValue
(
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
)
{
wgt
=
MKLDNNMatrix
::
create
(
weight_
->
getW
(),
pd
->
weights_primitive_desc
());
VLOG
(
MKLDNN_FMTS
)
<<
"Weight value format: "
<<
wgt
->
getFormat
();
bias
=
nullptr
;
if
(
biases_
&&
biases_
->
getW
())
{
bias
=
MKLDNNMatrix
::
create
(
biases_
->
getW
(),
pd
->
bias_primitive_desc
());
}
}
void
MKLDNNConvLayer
::
resetOutValue
(
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
out
)
{
out
=
MKLDNNMatrix
::
create
(
output_
.
value
,
pd
->
dst_primitive_desc
());
// change original output value from cpu matrix to mkldnn matrix
output_
.
value
=
std
::
dynamic_pointer_cast
<
Matrix
>
(
out
);
// create reorder if output value has cpu device and pd do not match
cpuOutVal_
=
nullptr
;
cpuOutVal_
=
nullptr
;
if
(
!
outputIsOnlyMKLDNN
())
{
const
MatrixPtr
&
cpuOut
=
getOutput
(
CPU_DEVICE
).
value
;
memory
::
dims
outDims
=
memory
::
dims
{
bs_
,
oc_
,
oh_
,
ow_
};
cpuOutVal_
=
MKLDNNMatrix
::
create
(
cpuOut
,
outDims
,
format
::
nchw
,
engine_
);
if
(
cpuOutVal_
->
getPrimitiveDesc
()
!=
out
->
getPrimitiveDesc
())
{
cvtOutVal_
=
MKLDNNMatrix
::
createReorder
(
out
,
cpuOutVal_
);
CHECK
(
cvtOutVal_
)
<<
"should not be emptry"
;
}
else
{
// CPU output share the same data of MKLDNN output
cpuOut
->
setData
(
out
->
getData
());
cpuOutVal_
=
out
;
}
}
}
void
MKLDNNConvLayer
::
resetBwdWgtPD
(
std
::
shared_ptr
<
conv_bwdWgt
::
primitive_desc
>&
pd
)
{
memory
::
dims
wgtDims
,
biasDims
,
strides
,
dilations
,
padL
,
padR
;
loadConvSettings
(
wgtDims
,
biasDims
,
strides
,
dilations
,
padL
,
padR
);
// create backward weight using input, output and weight value memory desc
CHECK
(
inVal_
)
<<
"Should have input value"
;
CHECK
(
outVal_
)
<<
"Should have output value"
;
CHECK
(
wgtVal_
)
<<
"Should have weight value"
;
algorithm
algo
=
algorithm
::
convolution_direct
;
padding_kind
padKind
=
padding_kind
::
zero
;
auto
bwdWgtDesc
=
biasVal_
!=
nullptr
?
conv_bwdWgt
::
desc
(
algo
,
inVal_
->
getMemoryDesc
(),
wgtVal_
->
getMemoryDesc
(),
biasVal_
->
getMemoryDesc
(),
outVal_
->
getMemoryDesc
(),
strides
,
padL
,
padR
,
padKind
)
:
conv_bwdWgt
::
desc
(
algo
,
inVal_
->
getMemoryDesc
(),
wgtVal_
->
getMemoryDesc
(),
outVal_
->
getMemoryDesc
(),
strides
,
padL
,
padR
,
padKind
);
pd
.
reset
(
new
conv_bwdWgt
::
primitive_desc
(
bwdWgtDesc
,
engine_
,
*
fwdPD_
));
CHECK
(
pd
->
src_primitive_desc
()
==
inVal_
->
getPrimitiveDesc
())
<<
"primitive desc of in value should equal"
;
CHECK
(
pd
->
diff_dst_primitive_desc
()
==
outVal_
->
getPrimitiveDesc
())
<<
"primitive desc of out grad should equal the out value"
;
CHECK
(
pd
->
diff_weights_primitive_desc
()
==
wgtVal_
->
getPrimitiveDesc
())
<<
"primitive desc of weight grad should equal the weight value"
;
}
void
MKLDNNConvLayer
::
resetBwdDataPD
(
std
::
shared_ptr
<
conv_bwdData
::
primitive_desc
>&
pd
)
{
if
(
inputLayers_
[
0
]
->
getOutput
().
grad
==
nullptr
)
{
return
;
}
memory
::
dims
wgtDims
,
biasDims
,
strides
,
dilations
,
padL
,
padR
;
loadConvSettings
(
wgtDims
,
biasDims
,
strides
,
dilations
,
padL
,
padR
);
CHECK
(
inVal_
)
<<
"Should have input value"
;
CHECK
(
outVal_
)
<<
"Should have output value"
;
// create backward data using input and output value memory desc
// but using weight memory desc with any format
auto
bwdDataDesc
=
conv_bwdData
::
desc
(
algorithm
::
convolution_direct
,
inVal_
->
getMemoryDesc
(),
MKLDNNMatrix
::
createMemoryDesc
(
wgtDims
),
outVal_
->
getMemoryDesc
(),
strides
,
padL
,
padR
,
padding_kind
::
zero
);
pd
.
reset
(
new
conv_bwdData
::
primitive_desc
(
bwdDataDesc
,
engine_
,
*
fwdPD_
));
CHECK
(
pd
->
diff_src_primitive_desc
()
==
inVal_
->
getPrimitiveDesc
())
<<
"primitive desc of in grad should equal the in value"
;
CHECK
(
pd
->
diff_dst_primitive_desc
()
==
outVal_
->
getPrimitiveDesc
())
<<
"primitive desc of out grad should equal"
;
}
void
MKLDNNConvLayer
::
resetBwdBuffers
(
std
::
shared_ptr
<
conv_bwdWgt
::
primitive_desc
>&
wgtPD
,
std
::
shared_ptr
<
conv_bwdData
::
primitive_desc
>&
dataPD
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
)
{
CHECK
(
wgtPD
);
resetOutGrad
(
wgtPD
,
out
);
resetWgtBiasGrad
(
wgtPD
,
wgt
,
bias
);
resetInGrad
(
dataPD
,
in
);
resetWgtValBwdData
(
dataPD
,
wgtValBwdData_
);
}
void
MKLDNNConvLayer
::
resetBwdPipeline
(
std
::
vector
<
primitive
>&
pipeline
,
std
::
shared_ptr
<
conv_bwdWgt
::
primitive_desc
>&
wgtPD
,
std
::
shared_ptr
<
conv_bwdData
::
primitive_desc
>&
dataPD
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
)
{
pipeline
.
clear
();
if
(
cvtOutGrad_
)
{
pipeline
.
push_back
(
*
cvtOutGrad_
);
}
// add bwdWgt handle
if
(
bias
)
{
bwdWgt_
.
reset
(
new
conv_bwdWgt
(
*
wgtPD
,
*
inVal_
,
*
out
,
*
wgt
,
*
bias
));
}
else
{
bwdWgt_
.
reset
(
new
conv_bwdWgt
(
*
wgtPD
,
*
inVal_
,
*
out
,
*
wgt
));
}
pipeline
.
push_back
(
*
bwdWgt_
);
if
(
dataPD
==
nullptr
)
{
return
;
}
if
(
cvtWgtVal_
)
{
pipeline
.
push_back
(
*
cvtWgtVal_
);
}
// add bwdData handle
CHECK
(
wgtValBwdData_
)
<<
"Should have weight memory"
;
bwdData_
.
reset
(
new
conv_bwdData
(
*
dataPD
,
*
out
,
*
wgtValBwdData_
,
*
in
));
pipeline
.
push_back
(
*
bwdData_
);
if
(
cvtInGrad_
)
{
pipeline
.
push_back
(
*
cvtInGrad_
);
}
}
void
MKLDNNConvLayer
::
resetOutGrad
(
std
::
shared_ptr
<
conv_bwdWgt
::
primitive_desc
>&
wgtPD
,
MKLDNNMatrixPtr
&
out
)
{
const
MatrixPtr
&
outMat
=
output_
.
grad
;
out
=
MKLDNNMatrix
::
create
(
outMat
,
wgtPD
->
diff_dst_primitive_desc
());
CHECK
(
outVal_
!=
nullptr
&&
out
->
getPrimitiveDesc
()
==
outVal_
->
getPrimitiveDesc
())
<<
"primitive desc of out grad and value should be equal"
;
// TODO(TJ): merge outgrad
// create reorder if has output grad does not match
cpuOutGrad_
=
nullptr
;
cvtOutGrad_
=
nullptr
;
if
(
!
outputIsOnlyMKLDNN
())
{
const
MatrixPtr
&
cpuOut
=
getOutput
(
CPU_DEVICE
).
grad
;
// same PrimitiveDesc with cpuInVal_
CHECK
(
cpuOutVal_
);
cpuOutGrad_
=
MKLDNNMatrix
::
create
(
cpuOut
,
cpuOutVal_
->
getPrimitiveDesc
());
if
(
cpuOutGrad_
->
getPrimitiveDesc
()
==
out
->
getPrimitiveDesc
())
{
outMat
->
setData
(
cpuOut
->
getData
());
out
=
cpuOutGrad_
;
}
else
{
cvtOutGrad_
=
MKLDNNMatrix
::
createReorder
(
cpuOutGrad_
,
out
);
CHECK
(
cvtOutGrad_
);
}
}
}
void
MKLDNNConvLayer
::
resetWgtBiasGrad
(
std
::
shared_ptr
<
conv_bwdWgt
::
primitive_desc
>&
wgtPD
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
)
{
wgt
=
MKLDNNMatrix
::
create
(
weight_
->
getWGrad
(),
wgtPD
->
diff_weights_primitive_desc
());
CHECK
(
nullptr
!=
wgtVal_
&&
wgt
->
getPrimitiveDesc
()
==
wgtVal_
->
getPrimitiveDesc
())
<<
"primitive desc of weight grad and value should be equal"
;
VLOG
(
MKLDNN_FMTS
)
<<
"weight grad format: "
<<
wgt
->
getFormat
();
if
(
biasVal_
==
nullptr
)
{
return
;
}
bias
=
MKLDNNMatrix
::
create
(
biases_
->
getWGrad
(),
wgtPD
->
diff_bias_primitive_desc
());
CHECK
(
bias
->
getPrimitiveDesc
()
==
biasVal_
->
getPrimitiveDesc
())
<<
"primitive desc of bias grad should equal the bias value"
;
}
void
MKLDNNConvLayer
::
resetInGrad
(
std
::
shared_ptr
<
conv_bwdData
::
primitive_desc
>&
dataPD
,
MKLDNNMatrixPtr
&
in
)
{
if
(
dataPD
==
nullptr
)
{
return
;
}
// TODO(TJ): use outputMaps_ ways to get the inGrad_ when merge outgrad done
in
=
MKLDNNMatrix
::
create
(
inputLayers_
[
0
]
->
getOutput
().
grad
,
dataPD
->
diff_src_primitive_desc
());
CHECK
(
nullptr
!=
inVal_
&&
in
->
getPrimitiveDesc
()
==
inVal_
->
getPrimitiveDesc
())
<<
"primitive desc of input grad and value should be equal"
;
// create reorder if has output grad does not match
cpuInGrad_
=
nullptr
;
cvtInGrad_
=
nullptr
;
if
(
!
inputIsOnlyMKLDNN
())
{
const
MatrixPtr
&
cpuIn
=
getInputGrad
(
0
,
CPU_DEVICE
);
// same PrimitiveDesc with cpuInVal_
CHECK
(
cpuInVal_
);
cpuInGrad_
=
MKLDNNMatrix
::
create
(
cpuIn
,
cpuInVal_
->
getPrimitiveDesc
());
if
(
cpuInGrad_
->
getPrimitiveDesc
()
!=
in
->
getPrimitiveDesc
())
{
const
MatrixPtr
&
dnnIn
=
getInputGrad
(
0
,
MKLDNN_DEVICE
);
in
=
MKLDNNMatrix
::
create
(
dnnIn
,
in
->
getPrimitiveDesc
());
cvtInGrad_
=
MKLDNNMatrix
::
createReorder
(
in
,
cpuInGrad_
);
CHECK
(
cvtInGrad_
);
}
else
{
in
=
cpuInGrad_
;
}
}
}
void
MKLDNNConvLayer
::
resetWgtValBwdData
(
std
::
shared_ptr
<
conv_bwdData
::
primitive_desc
>&
dataPD
,
MKLDNNMatrixPtr
&
wgt
)
{
if
(
dataPD
==
nullptr
)
{
return
;
}
// create new weight value for backward data, and create reorder if necessary
// since the primitive_desc would be different with wgtVal_
CHECK
(
wgtVal_
)
<<
"should have weight value"
;
if
(
dataPD
->
weights_primitive_desc
()
!=
wgtVal_
->
getPrimitiveDesc
())
{
wgtValBwdData_
=
MKLDNNMatrix
::
create
(
nullptr
,
dataPD
->
weights_primitive_desc
());
cvtWgtVal_
=
MKLDNNMatrix
::
createReorder
(
wgtVal_
,
wgtValBwdData_
);
CHECK
(
cvtWgtVal_
);
}
else
{
wgtValBwdData_
=
wgtVal_
;
}
VLOG
(
MKLDNN_FMTS
)
<<
"weight value format for backward data"
<<
wgtValBwdData_
->
getFormat
();
}
}
// namespace paddle
paddle/gserver/layers/MKLDNNConvLayer.h
0 → 100644
浏览文件 @
f2442be9
/* Copyright (c) 2017 PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#pragma once
#include "MKLDNNLayer.h"
#include "mkldnn.hpp"
namespace
paddle
{
typedef
mkldnn
::
convolution_forward
conv_fwd
;
typedef
mkldnn
::
convolution_backward_weights
conv_bwdWgt
;
typedef
mkldnn
::
convolution_backward_data
conv_bwdData
;
/**
* @brief A subclass of MKLDNNLayer conv layer.
*
* The config file api is mkldnn_conv
*/
class
MKLDNNConvLayer
:
public
MKLDNNLayer
{
protected:
// padding height and width
int
ph_
,
pw_
;
// stride height and width
int
sh_
,
sw_
;
// dilation height and width
int
dh_
,
dw_
;
// filter(kenerl) height and width
int
fh_
,
fw_
;
// group number
int
gp_
;
// in resetBwdData, the format of wgtValBwdData_ is different with wgtVal_
MKLDNNMatrixPtr
wgtValBwdData_
;
// convert handle from wgtVal_ to wgtValBwdData_
std
::
shared_ptr
<
mkldnn
::
reorder
>
cvtWgtVal_
;
// save forward primitive_desc, which can be used backward
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>
fwdPD_
;
// MKLDNNMatrixPtr which should be created from CPU Device
MKLDNNMatrixPtr
cpuInVal_
;
MKLDNNMatrixPtr
cpuInGrad_
;
MKLDNNMatrixPtr
cpuOutVal_
;
MKLDNNMatrixPtr
cpuOutGrad_
;
// convert handle between CPU device and MKLDNN device
std
::
shared_ptr
<
mkldnn
::
reorder
>
cvtInVal_
;
std
::
shared_ptr
<
mkldnn
::
reorder
>
cvtInGrad_
;
std
::
shared_ptr
<
mkldnn
::
reorder
>
cvtOutVal_
;
std
::
shared_ptr
<
mkldnn
::
reorder
>
cvtOutGrad_
;
// whether the weight has been init
bool
hasInitedWgt_
;
// true by default, which impact the calculation of output image size.
// details can refer to mathUtil.h
bool
caffeMode_
;
// weight and bias
std
::
unique_ptr
<
Weight
>
weight_
;
std
::
unique_ptr
<
Weight
>
biases_
;
public:
explicit
MKLDNNConvLayer
(
const
LayerConfig
&
config
)
:
MKLDNNLayer
(
config
),
hasInitedWgt_
(
false
),
caffeMode_
(
true
)
{}
~
MKLDNNConvLayer
()
{}
bool
init
(
const
LayerMap
&
layerMap
,
const
ParameterMap
&
parameterMap
)
override
;
void
reshape
(
int
&
bs
,
int
&
ic
,
int
&
ih
,
int
&
iw
,
int
oc
,
int
&
oh
,
int
&
ow
)
override
;
void
resetFwd
(
std
::
vector
<
mkldnn
::
primitive
>&
pipeline
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
)
override
;
void
resetBwd
(
std
::
vector
<
mkldnn
::
primitive
>&
pipeline
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
)
override
;
void
updateInputData
()
override
;
void
updateWeights
(
const
UpdateCallback
&
callback
)
override
;
void
convertWeightsFromPaddle
()
override
;
void
convertWeightsToPaddle
()
override
;
void
printSizeInfo
()
override
{
MKLDNNLayer
::
printSizeInfo
();
VLOG
(
MKLDNN_SIZES
)
<<
getName
()
<<
": fh: "
<<
fh_
<<
", fw: "
<<
fw_
<<
": ph: "
<<
ph_
<<
", pw: "
<<
pw_
<<
", sh: "
<<
sh_
<<
", sw: "
<<
sw_
<<
", dh: "
<<
dh_
<<
", dw: "
<<
dw_
;
}
void
printValueFormatFlow
()
override
{
if
(
cpuInVal_
)
{
VLOG
(
MKLDNN_FMTS
)
<<
cpuInVal_
->
getFormat
()
<<
" >>>"
;
}
MKLDNNLayer
::
printValueFormatFlow
();
if
(
cpuOutVal_
)
{
VLOG
(
MKLDNN_FMTS
)
<<
" >>> "
<<
cpuOutVal_
->
getFormat
();
}
}
void
printGradFormatFlow
()
override
{
if
(
cpuInGrad_
)
{
VLOG
(
MKLDNN_FMTS
)
<<
cpuInGrad_
->
getFormat
()
<<
" <<<"
;
}
MKLDNNLayer
::
printGradFormatFlow
();
if
(
cpuOutGrad_
)
{
VLOG
(
MKLDNN_FMTS
)
<<
" <<< "
<<
cpuOutGrad_
->
getFormat
();
}
}
protected:
/**
* load the dims settings of this conv
*/
void
loadConvSettings
(
mkldnn
::
memory
::
dims
&
wgt
,
mkldnn
::
memory
::
dims
&
bias
,
mkldnn
::
memory
::
dims
&
stride
,
mkldnn
::
memory
::
dims
&
dilation
,
mkldnn
::
memory
::
dims
&
padL
,
mkldnn
::
memory
::
dims
&
padR
);
/**
* reset the forward primitive descriptor.
*/
void
resetFwdPD
(
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
);
/**
* reset the MKLDNNMatrix buffers used in forward.
*/
void
resetFwdBuffers
(
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
);
/**
* reset the forward pipeline.
*/
void
resetFwdPipeline
(
std
::
vector
<
mkldnn
::
primitive
>&
pipeline
,
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
);
/**
* reset MKLDNNMatrix of input value
*/
void
resetInValue
(
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
in
);
/**
* reset MKLDNNMatrix of weight and bias value
*/
void
resetWgtBiasValue
(
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
);
/**
* reset MKLDNNMatrix of output value
*/
void
resetOutValue
(
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
out
);
/**
* reset the backward weight primitive descriptor.
*/
void
resetBwdWgtPD
(
std
::
shared_ptr
<
conv_bwdWgt
::
primitive_desc
>&
pd
);
/**
* reset the backward data primitive descriptor.
*/
void
resetBwdDataPD
(
std
::
shared_ptr
<
conv_bwdData
::
primitive_desc
>&
pd
);
/**
* reset the MKLDNNMatrix buffers used in backward.
*/
void
resetBwdBuffers
(
std
::
shared_ptr
<
conv_bwdWgt
::
primitive_desc
>&
wgtPD
,
std
::
shared_ptr
<
conv_bwdData
::
primitive_desc
>&
dataPD
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
);
/**
* reset the backward pipeline.
*/
void
resetBwdPipeline
(
std
::
vector
<
mkldnn
::
primitive
>&
pipeline
,
std
::
shared_ptr
<
conv_bwdWgt
::
primitive_desc
>&
wgtPD
,
std
::
shared_ptr
<
conv_bwdData
::
primitive_desc
>&
dataPD
,
MKLDNNMatrixPtr
&
in
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
,
MKLDNNMatrixPtr
&
out
);
/**
* reset MKLDNNMatrix of output grad
*/
void
resetOutGrad
(
std
::
shared_ptr
<
conv_bwdWgt
::
primitive_desc
>&
wgtPD
,
MKLDNNMatrixPtr
&
out
);
/**
* reset MKLDNNMatrix of weight and bias grad
*/
void
resetWgtBiasGrad
(
std
::
shared_ptr
<
conv_bwdWgt
::
primitive_desc
>&
wgtPD
,
MKLDNNMatrixPtr
&
wgt
,
MKLDNNMatrixPtr
&
bias
);
/**
* reset MKLDNNMatrix of input grad
*/
void
resetInGrad
(
std
::
shared_ptr
<
conv_bwdData
::
primitive_desc
>&
dataPD
,
MKLDNNMatrixPtr
&
in
);
/**
* reset MKLDNNMatrix of weight value for backward data
* since the primitive_desc would be different with wgtVal_
*/
void
resetWgtValBwdData
(
std
::
shared_ptr
<
conv_bwdData
::
primitive_desc
>&
dataPD
,
MKLDNNMatrixPtr
&
wgt
);
/**
* get padding_r according to
* https://github.com/01org/mkl-dnn/blob/master/tests/gtests/
* test_convolution_forward_common.hpp
* @note: mkldnn dilation start from 0 while paddle start from 1
*/
mkldnn
::
memory
::
dims
getPaddingR
()
const
{
mkldnn
::
memory
::
dims
padR
=
{
ph_
,
pw_
};
for
(
int
i
=
0
;
i
<
2
;
++
i
)
{
if
((
ih_
-
((
fh_
-
1
)
*
dh_
+
1
)
+
ph_
+
padR
[
0
])
/
sh_
+
1
!=
oh_
)
{
++
padR
[
0
];
}
if
((
iw_
-
((
fw_
-
1
)
*
dw_
+
1
)
+
pw_
+
padR
[
1
])
/
sw_
+
1
!=
ow_
)
{
++
padR
[
1
];
}
}
return
padR
;
}
};
}
// namespace paddle
paddle/gserver/tests/test_MKLDNN.cpp
浏览文件 @
f2442be9
...
@@ -17,6 +17,7 @@ limitations under the License. */
...
@@ -17,6 +17,7 @@ limitations under the License. */
#include <vector>
#include <vector>
#include "MKLDNNTester.h"
#include "MKLDNNTester.h"
#include "ModelConfig.pb.h"
#include "ModelConfig.pb.h"
#include "paddle/math/MathUtils.h"
using
namespace
paddle
;
// NOLINT
using
namespace
paddle
;
// NOLINT
...
@@ -63,6 +64,83 @@ TEST(MKLDNNLayer, FcLayer) {
...
@@ -63,6 +64,83 @@ TEST(MKLDNNLayer, FcLayer) {
testFcLayer
({
/*bs*/
15
,
/*ic*/
3
,
/*oc*/
6
,
/*ih*/
16
,
/*iw*/
16
});
testFcLayer
({
/*bs*/
15
,
/*ic*/
3
,
/*oc*/
6
,
/*ih*/
16
,
/*iw*/
16
});
}
}
struct
testConvDesc
{
int
bs
,
gp
;
int
ic
,
ih
,
iw
;
int
oc
,
oh
,
ow
;
int
fh
,
fw
;
int
ph
,
pw
;
int
sh
,
sw
;
int
dh
,
dw
;
};
void
testConvLayer
(
const
testConvDesc
&
pm
)
{
const
std
::
string
compareTypes
[]
=
{
"mkldnn_conv"
,
"exconv"
};
TestConfig
cfg
;
cfg
.
layerConfig
.
set_type
(
compareTypes
[
0
]);
cfg
.
layerConfig
.
set_num_filters
(
pm
.
oc
);
cfg
.
layerConfig
.
set_size
(
pm
.
oc
*
pm
.
oh
*
pm
.
ow
);
// cfg.layerConfig.set_partial_sum(1); // TODO: check it
cfg
.
layerConfig
.
set_shared_biases
(
true
);
cfg
.
inputDefs
.
push_back
(
{
INPUT_DATA
,
"layer_0"
,
/* size of input layer= */
size_t
(
pm
.
ic
*
pm
.
ih
*
pm
.
iw
),
/* size of weight= */
size_t
(
pm
.
oc
*
pm
.
ic
*
pm
.
fh
*
pm
.
fw
/
pm
.
gp
)});
LayerInputConfig
*
input
=
cfg
.
layerConfig
.
add_inputs
();
ConvConfig
*
conv
=
input
->
mutable_conv_conf
();
conv
->
set_groups
(
pm
.
gp
);
conv
->
set_img_size
(
pm
.
iw
);
conv
->
set_img_size_y
(
pm
.
ih
);
conv
->
set_output_x
(
pm
.
ow
);
conv
->
set_output_y
(
pm
.
oh
);
conv
->
set_filter_size
(
pm
.
fw
);
conv
->
set_filter_size_y
(
pm
.
fh
);
conv
->
set_channels
(
pm
.
ic
);
conv
->
set_padding
(
pm
.
pw
);
conv
->
set_padding_y
(
pm
.
ph
);
conv
->
set_stride
(
pm
.
sw
);
conv
->
set_stride_y
(
pm
.
sh
);
conv
->
set_dilation
(
pm
.
dw
);
conv
->
set_dilation_y
(
pm
.
dh
);
conv
->
set_caffe_mode
(
true
);
conv
->
set_filter_channels
(
conv
->
channels
()
/
conv
->
groups
());
CHECK_EQ
(
conv
->
filter_channels
()
*
pm
.
gp
,
conv
->
channels
())
<<
"it is indivisible"
;
int
fh
=
(
pm
.
fh
-
1
)
*
pm
.
dh
+
1
;
int
fw
=
(
pm
.
fw
-
1
)
*
pm
.
dw
+
1
;
int
ow
=
outputSize
(
pm
.
iw
,
fw
,
pm
.
pw
,
pm
.
sw
,
true
);
int
oh
=
outputSize
(
pm
.
ih
,
fh
,
pm
.
ph
,
pm
.
sh
,
true
);
CHECK_EQ
(
ow
,
pm
.
ow
)
<<
"output size check failed"
;
CHECK_EQ
(
oh
,
pm
.
oh
)
<<
"output size check failed"
;
MKLDNNTester
tester
;
for
(
auto
biasSize
:
{
pm
.
oc
,
0
})
{
cfg
.
biasSize
=
biasSize
;
TestConfig
ref
=
cfg
;
ref
.
layerConfig
.
set_type
(
compareTypes
[
1
]);
for
(
auto
bs
:
{
pm
.
bs
,
1
})
{
tester
.
run
(
cfg
,
ref
,
bs
,
pm
.
ih
,
pm
.
iw
);
}
}
}
TEST
(
MKLDNNLayer
,
ConvLayer
)
{
/* bs, gp, ic, ih, iw, oc, oh, ow, fh, fw, ph, pw, sh, sw, dh, dw */
testConvLayer
({
2
,
1
,
3
,
32
,
32
,
16
,
32
,
32
,
3
,
3
,
1
,
1
,
1
,
1
,
1
,
1
});
testConvLayer
({
2
,
1
,
8
,
16
,
16
,
8
,
16
,
16
,
3
,
3
,
1
,
1
,
1
,
1
,
1
,
1
});
testConvLayer
({
3
,
1
,
16
,
32
,
32
,
3
,
32
,
32
,
3
,
3
,
1
,
1
,
1
,
1
,
1
,
1
});
testConvLayer
({
8
,
1
,
16
,
18
,
18
,
32
,
18
,
18
,
3
,
3
,
1
,
1
,
1
,
1
,
1
,
1
});
testConvLayer
({
16
,
1
,
1
,
42
,
31
,
32
,
23
,
11
,
4
,
5
,
3
,
2
,
2
,
3
,
1
,
1
});
testConvLayer
({
2
,
1
,
8
,
16
,
16
,
8
,
8
,
8
,
3
,
3
,
1
,
1
,
2
,
2
,
1
,
1
});
testConvLayer
({
3
,
1
,
8
,
13
,
13
,
8
,
7
,
7
,
3
,
3
,
1
,
1
,
2
,
2
,
1
,
1
});
// with groups
testConvLayer
({
2
,
2
,
4
,
5
,
5
,
8
,
5
,
5
,
3
,
3
,
1
,
1
,
1
,
1
,
1
,
1
});
testConvLayer
({
2
,
3
,
3
,
5
,
5
,
3
,
5
,
5
,
3
,
3
,
1
,
1
,
1
,
1
,
1
,
1
});
testConvLayer
({
4
,
4
,
16
,
3
,
3
,
16
,
3
,
3
,
3
,
3
,
1
,
1
,
1
,
1
,
1
,
1
});
}
// TODO(TJ): add branch test
// TODO(TJ): add branch test
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
{
...
...
paddle/math/MKLDNNMatrix.cpp
浏览文件 @
f2442be9
...
@@ -49,6 +49,27 @@ MKLDNNMatrixPtr MKLDNNMatrix::create(MatrixPtr m,
...
@@ -49,6 +49,27 @@ MKLDNNMatrixPtr MKLDNNMatrix::create(MatrixPtr m,
return
create
(
m
,
memory
::
primitive_desc
(
memory
::
desc
(
dims
,
dtype
,
fmt
),
eg
));
return
create
(
m
,
memory
::
primitive_desc
(
memory
::
desc
(
dims
,
dtype
,
fmt
),
eg
));
}
}
std
::
shared_ptr
<
reorder
>
MKLDNNMatrix
::
createReorder
(
const
MKLDNNMatrixPtr
&
src
,
const
MKLDNNMatrixPtr
&
dst
,
bool
checkData
)
{
if
(
src
==
dst
||
src
->
getPrimitiveDesc
()
==
dst
->
getPrimitiveDesc
())
{
return
nullptr
;
}
if
(
checkData
&&
(
src
->
getData
()
==
dst
->
getData
()))
{
LOG
(
FATAL
)
<<
"can not create reorder with inplace data"
;
return
nullptr
;
}
memory
::
dims
srcDims
=
src
->
getDims
();
memory
::
dims
dstDims
=
dst
->
getDims
();
CHECK_EQ
(
srcDims
.
size
(),
dstDims
.
size
());
for
(
size_t
i
=
0
;
i
<
srcDims
.
size
();
++
i
)
{
CHECK_EQ
(
srcDims
[
i
],
dstDims
[
i
]);
}
return
std
::
make_shared
<
reorder
>
(
*
src
,
*
dst
);
}
void
MKLDNNMatrix
::
reorderDataFrom
(
const
MKLDNNMatrixPtr
&
m
,
void
MKLDNNMatrix
::
reorderDataFrom
(
const
MKLDNNMatrixPtr
&
m
,
memory
::
format
srcFmt
,
memory
::
format
srcFmt
,
memory
::
dims
targetDim
)
{
memory
::
dims
targetDim
)
{
...
...
paddle/math/MKLDNNMatrix.h
浏览文件 @
f2442be9
...
@@ -52,6 +52,31 @@ public:
...
@@ -52,6 +52,31 @@ public:
mkldnn
::
engine
&
eg
,
mkldnn
::
engine
&
eg
,
mkldnn
::
memory
::
data_type
dtype
=
mkldnn
::
memory
::
data_type
::
f32
);
mkldnn
::
memory
::
data_type
dtype
=
mkldnn
::
memory
::
data_type
::
f32
);
/**
* Create Memory descriptor.
* default with any format and f32 dtype
*/
static
mkldnn
::
memory
::
desc
createMemoryDesc
(
const
mkldnn
::
memory
::
dims
&
dims
,
const
mkldnn
::
memory
::
format
&
fmt
=
mkldnn
::
memory
::
format
::
any
,
const
mkldnn
::
memory
::
data_type
&
dtype
=
mkldnn
::
memory
::
data_type
::
f32
)
{
return
mkldnn
::
memory
::
desc
(
dims
,
dtype
,
fmt
);
}
/**
* Create reorder primitive.
* Create a mkldnn::reorder handle for converting src MKLDNNMatrix to dst.
* checkData: for whether to check the data handle of src and dst is the same.
* if true, means check it and do not want support inplace reorder;
* otherwise do not check data which means the created reorder
* maybe inplace buffer and do not guarantee the logical is correct
* since not all format or conversion support inplace.
*/
static
std
::
shared_ptr
<
mkldnn
::
reorder
>
createReorder
(
const
MKLDNNMatrixPtr
&
src
,
const
MKLDNNMatrixPtr
&
dst
,
bool
checkData
=
true
);
public:
public:
/**
/**
* Reorder this MKLDNNMatrix from other format.
* Reorder this MKLDNNMatrix from other format.
...
...
paddle/operators/CMakeLists.txt
浏览文件 @
f2442be9
file
(
GLOB GENERAL_OPS RELATIVE
"
${
CMAKE_CURRENT_SOURCE_DIR
}
"
"*_op.cc"
)
file
(
GLOB GENERAL_OPS RELATIVE
"
${
CMAKE_CURRENT_SOURCE_DIR
}
"
"*_op.cc"
)
string
(
REPLACE
".cc"
""
GENERAL_OPS
"
${
GENERAL_OPS
}
"
)
string
(
REPLACE
".cc"
""
GENERAL_OPS
"
${
GENERAL_OPS
}
"
)
set
(
pybind_file
${
PADDLE_SOURCE_DIR
}
/paddle/pybind/pybind.h
)
file
(
WRITE
${
pybind_file
}
"// Generated by the paddle/operator/CMakeLists.txt. DO NOT EDIT!
\n\n
"
)
function
(
op_library TARGET
)
function
(
op_library TARGET
)
# op_library is a function to create op library. The interface is same as
# op_library is a function to create op library. The interface is same as
# cc_library. But it handle split GPU/CPU code and link some common library
# cc_library. But it handle split GPU/CPU code and link some common library
...
@@ -7,10 +9,11 @@ function(op_library TARGET)
...
@@ -7,10 +9,11 @@ function(op_library TARGET)
set
(
OP_LIBRARY
${
TARGET
}
${
OP_LIBRARY
}
PARENT_SCOPE
)
set
(
OP_LIBRARY
${
TARGET
}
${
OP_LIBRARY
}
PARENT_SCOPE
)
set
(
cc_srcs
)
set
(
cc_srcs
)
set
(
cu_srcs
)
set
(
cu_srcs
)
set
(
op_common_deps operator op_registry
)
set
(
op_common_deps operator op_registry
math_function
)
set
(
options
""
)
set
(
options
""
)
set
(
oneValueArgs
""
)
set
(
oneValueArgs
""
)
set
(
multiValueArgs SRCS DEPS
)
set
(
multiValueArgs SRCS DEPS
)
set
(
pybind_flag 0
)
cmake_parse_arguments
(
op_library
"
${
options
}
"
"
${
oneValueArgs
}
"
cmake_parse_arguments
(
op_library
"
${
options
}
"
"
${
oneValueArgs
}
"
"
${
multiValueArgs
}
"
${
ARGN
}
)
"
${
multiValueArgs
}
"
${
ARGN
}
)
...
@@ -46,22 +49,40 @@ function(op_library TARGET)
...
@@ -46,22 +49,40 @@ function(op_library TARGET)
cc_library
(
${
TARGET
}
SRCS
${
cc_srcs
}
DEPS
${
op_library_DEPS
}
cc_library
(
${
TARGET
}
SRCS
${
cc_srcs
}
DEPS
${
op_library_DEPS
}
${
op_common_deps
}
)
${
op_common_deps
}
)
endif
()
endif
()
# net_op doesn't need pybind
if
(
"
${
TARGET
}
"
STREQUAL
"net_op"
)
set
(
pybind_flag 1
)
endif
()
# pybind USE_NO_KERNEL_OP
file
(
READ
${
TARGET
}
.cc TARGET_CONTENT
)
string
(
REGEX MATCH
"OperatorWithKernel"
regex_result
"
${
TARGET_CONTENT
}
"
)
string
(
REPLACE
"_op"
""
TARGET
"
${
TARGET
}
"
)
if
(
${
pybind_flag
}
EQUAL 0 AND regex_result STREQUAL
""
)
file
(
APPEND
${
pybind_file
}
"USE_NO_KERNEL_OP(
${
TARGET
}
);
\n
"
)
set
(
pybind_flag 1
)
endif
()
# pybind USE_CPU_ONLY_OP
list
(
LENGTH cu_srcs cu_srcs_len
)
if
(
${
pybind_flag
}
EQUAL 0 AND
${
cu_srcs_len
}
EQUAL 0
)
file
(
APPEND
${
pybind_file
}
"USE_CPU_ONLY_OP(
${
TARGET
}
);
\n
"
)
set
(
pybind_flag 1
)
endif
()
# pybind USE_OP
if
(
${
pybind_flag
}
EQUAL 0
)
file
(
APPEND
${
pybind_file
}
"USE_OP(
${
TARGET
}
);
\n
"
)
endif
()
endfunction
()
endfunction
()
add_subdirectory
(
math
)
add_subdirectory
(
math
)
set
(
DEPS_OPS
set
(
DEPS_OPS
identity_op
recurrent_op
)
minus_op
mul_op
recurrent_op
scale_op
)
op_library
(
identity_op DEPS scale_op
)
op_library
(
minus_op DEPS scale_op
)
op_library
(
mul_op DEPS math_function
)
op_library
(
recurrent_op SRCS recurrent_op.cc rnn/recurrent_op_utils.cc
op_library
(
recurrent_op SRCS recurrent_op.cc rnn/recurrent_op_utils.cc
DEPS framework_proto tensor operator net_op
)
DEPS framework_proto tensor net_op
)
op_library
(
scale_op DEPS net_op
)
list
(
REMOVE_ITEM GENERAL_OPS
${
DEPS_OPS
}
)
list
(
REMOVE_ITEM GENERAL_OPS
${
DEPS_OPS
}
)
foreach
(
src
${
GENERAL_OPS
}
)
foreach
(
src
${
GENERAL_OPS
}
)
...
...
paddle/operators/accuracy_op.cc
浏览文件 @
f2442be9
...
@@ -34,7 +34,7 @@ class AccuracyOp : public framework::OperatorWithKernel {
...
@@ -34,7 +34,7 @@ class AccuracyOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_EQ
(
inference
->
dims
()[
0
],
label
->
dims
()[
0
],
PADDLE_ENFORCE_EQ
(
inference
->
dims
()[
0
],
label
->
dims
()[
0
],
"inference size must be the same as label size"
);
"inference size must be the same as label size"
);
ctx
.
Output
<
Tensor
>
(
"Accuracy"
)
->
Resize
({
1
});
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Accuracy"
)
->
Resize
({
1
});
}
}
};
};
...
...
paddle/operators/add_op.cc
浏览文件 @
f2442be9
...
@@ -26,7 +26,8 @@ class AddOp : public framework::OperatorWithKernel {
...
@@ -26,7 +26,8 @@ class AddOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_EQ
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
(),
PADDLE_ENFORCE_EQ
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
(),
ctx
.
Input
<
Tensor
>
(
"Y"
)
->
dims
(),
ctx
.
Input
<
Tensor
>
(
"Y"
)
->
dims
(),
"Two input of Add Op's dimension must be same."
);
"Two input of Add Op's dimension must be same."
);
ctx
.
Output
<
Tensor
>
(
"Out"
)
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
ctx
.
Output
<
framework
::
LoDTensor
>
(
"Out"
)
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
}
}
};
};
...
...
paddle/operators/concat_op.cc
浏览文件 @
f2442be9
...
@@ -26,7 +26,7 @@ class ConcatOp : public framework::OperatorWithKernel {
...
@@ -26,7 +26,7 @@ class ConcatOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
auto
ins
=
ctx
.
MultiInput
<
framework
::
Tensor
>
(
"X"
);
auto
ins
=
ctx
.
MultiInput
<
framework
::
Tensor
>
(
"X"
);
auto
*
out
=
ctx
.
Output
<
framework
::
Tensor
>
(
"Out"
);
auto
*
out
=
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
);
size_t
axis
=
static_cast
<
size_t
>
(
ctx
.
Attr
<
int
>
(
"axis"
));
size_t
axis
=
static_cast
<
size_t
>
(
ctx
.
Attr
<
int
>
(
"axis"
));
size_t
n
=
ins
.
size
();
size_t
n
=
ins
.
size
();
...
...
paddle/operators/concat_op.cu
已删除
100644 → 0
浏览文件 @
36f349e7
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#define EIGEN_USE_GPU
#include "paddle/operators/concat_op.h"
namespace
ops
=
paddle
::
operators
;
// TODO(Yancey1989) Add GPU kernel
paddle/operators/cos_sim_op.cc
浏览文件 @
f2442be9
...
@@ -46,9 +46,9 @@ class CosSimOp : public framework::OperatorWithKernel {
...
@@ -46,9 +46,9 @@ class CosSimOp : public framework::OperatorWithKernel {
" just 1 (which will be broadcasted to match Input(X))."
);
" just 1 (which will be broadcasted to match Input(X))."
);
// resize tensor
// resize tensor
ctx
.
Output
<
Tensor
>
(
"Out"
)
->
Resize
({
x_dims
[
0
],
1
});
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
)
->
Resize
({
x_dims
[
0
],
1
});
ctx
.
Output
<
Tensor
>
(
"XNorm"
)
->
Resize
({
x_dims
[
0
],
1
});
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"XNorm"
)
->
Resize
({
x_dims
[
0
],
1
});
ctx
.
Output
<
Tensor
>
(
"YNorm"
)
->
Resize
({
y_dims
[
0
],
1
});
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"YNorm"
)
->
Resize
({
y_dims
[
0
],
1
});
}
}
};
};
...
@@ -131,8 +131,10 @@ class CosSimOpGrad : public framework::OperatorWithKernel {
...
@@ -131,8 +131,10 @@ class CosSimOpGrad : public framework::OperatorWithKernel {
"Shape of Input(Out@Grad) must be [X.Dim(0), 1]."
);
"Shape of Input(Out@Grad) must be [X.Dim(0), 1]."
);
// resize tensor
// resize tensor
auto
*
x_grad
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
x_grad
=
auto
*
y_grad
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"Y"
));
ctx
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
y_grad
=
ctx
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"Y"
));
if
(
x_grad
)
x_grad
->
Resize
(
x_dims
);
if
(
x_grad
)
x_grad
->
Resize
(
x_dims
);
if
(
y_grad
)
y_grad
->
Resize
(
y_dims
);
if
(
y_grad
)
y_grad
->
Resize
(
y_dims
);
}
}
...
...
paddle/operators/elementwise_mul_op.cc
浏览文件 @
f2442be9
...
@@ -31,7 +31,7 @@ class ElementWiseMulOp : public framework::OperatorWithKernel {
...
@@ -31,7 +31,7 @@ class ElementWiseMulOp : public framework::OperatorWithKernel {
auto
y_dim
=
ctx
.
Input
<
Tensor
>
(
"Y"
)
->
dims
();
auto
y_dim
=
ctx
.
Input
<
Tensor
>
(
"Y"
)
->
dims
();
PADDLE_ENFORCE_GE
(
x_dim
.
size
(),
y_dim
.
size
(),
PADDLE_ENFORCE_GE
(
x_dim
.
size
(),
y_dim
.
size
(),
"Rank of first input must >= rank of second input."
)
"Rank of first input must >= rank of second input."
)
ctx
.
Output
<
Tensor
>
(
"Out"
)
->
Resize
(
x_dim
);
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
)
->
Resize
(
x_dim
);
}
}
};
};
...
@@ -80,8 +80,10 @@ class ElementWiseMulOpGrad : public framework::OperatorWithKernel {
...
@@ -80,8 +80,10 @@ class ElementWiseMulOpGrad : public framework::OperatorWithKernel {
auto
x_dims
=
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
();
auto
x_dims
=
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
();
auto
y_dims
=
ctx
.
Input
<
Tensor
>
(
"Y"
)
->
dims
();
auto
y_dims
=
ctx
.
Input
<
Tensor
>
(
"Y"
)
->
dims
();
auto
out_dims
=
ctx
.
Input
<
Tensor
>
(
framework
::
GradVarName
(
"Out"
))
->
dims
();
auto
out_dims
=
ctx
.
Input
<
Tensor
>
(
framework
::
GradVarName
(
"Out"
))
->
dims
();
auto
*
x_grad
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
x_grad
=
auto
*
y_grad
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"Y"
));
ctx
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
y_grad
=
ctx
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"Y"
));
PADDLE_ENFORCE_GE
(
x_dims
.
size
(),
y_dims
.
size
(),
PADDLE_ENFORCE_GE
(
x_dims
.
size
(),
y_dims
.
size
(),
"Rank of first input must >= rank of second input."
)
"Rank of first input must >= rank of second input."
)
...
...
paddle/operators/fill_zeros_like_op.cc
浏览文件 @
f2442be9
...
@@ -23,7 +23,7 @@ class FillZerosLikeOp : public framework::OperatorWithKernel {
...
@@ -23,7 +23,7 @@ class FillZerosLikeOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
ctx
.
Output
<
framework
::
Tensor
>
(
"Dst"
)
->
Resize
(
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Dst"
)
->
Resize
(
ctx
.
Input
<
framework
::
Tensor
>
(
"Src"
)
->
dims
());
ctx
.
Input
<
framework
::
Tensor
>
(
"Src"
)
->
dims
());
}
}
};
};
...
...
paddle/operators/gather_op.cc
浏览文件 @
f2442be9
...
@@ -28,7 +28,7 @@ class GatherOp : public framework::OperatorWithKernel {
...
@@ -28,7 +28,7 @@ class GatherOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_GE
(
batch_size
,
0
,
"Batch size must be >0"
);
PADDLE_ENFORCE_GE
(
batch_size
,
0
,
"Batch size must be >0"
);
framework
::
DDim
output_dims
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
framework
::
DDim
output_dims
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
output_dims
[
0
]
=
batch_size
;
output_dims
[
0
]
=
batch_size
;
ctx
.
Output
<
Tensor
>
(
"Out"
)
->
Resize
(
output_dims
);
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
)
->
Resize
(
output_dims
);
}
}
};
};
...
@@ -38,7 +38,7 @@ class GatherGradOp : public framework::OperatorWithKernel {
...
@@ -38,7 +38,7 @@ class GatherGradOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
auto
X_grad
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
X_grad
=
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
X
=
ctx
.
Input
<
Tensor
>
(
"X"
);
auto
X
=
ctx
.
Input
<
Tensor
>
(
"X"
);
X_grad
->
Resize
(
X
->
dims
());
X_grad
->
Resize
(
X
->
dims
());
...
...
paddle/operators/gaussian_random_op.cc
浏览文件 @
f2442be9
...
@@ -44,7 +44,7 @@ class GaussianRandomOp : public framework::OperatorWithKernel {
...
@@ -44,7 +44,7 @@ class GaussianRandomOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
context
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
context
)
const
override
{
auto
*
tensor
=
context
.
Output
<
framework
::
Tensor
>
(
"Out"
);
auto
*
tensor
=
context
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
);
auto
dims
=
Attr
<
std
::
vector
<
int
>>
(
"dims"
);
auto
dims
=
Attr
<
std
::
vector
<
int
>>
(
"dims"
);
std
::
vector
<
int64_t
>
temp
;
std
::
vector
<
int64_t
>
temp
;
temp
.
reserve
(
dims
.
size
());
temp
.
reserve
(
dims
.
size
());
...
...
paddle/operators/lookup_table_op.cc
浏览文件 @
f2442be9
...
@@ -25,7 +25,7 @@ class LookupTableOp : public framework::OperatorWithKernel {
...
@@ -25,7 +25,7 @@ class LookupTableOp : public framework::OperatorWithKernel {
void
InferShape
(
const
framework
::
InferShapeContext
&
context
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
context
)
const
override
{
auto
table_t
=
context
.
Input
<
Tensor
>
(
"W"
);
auto
table_t
=
context
.
Input
<
Tensor
>
(
"W"
);
auto
ids_t
=
context
.
Input
<
Tensor
>
(
"Ids"
);
auto
ids_t
=
context
.
Input
<
Tensor
>
(
"Ids"
);
auto
output_t
=
context
.
Output
<
Tensor
>
(
"Out"
);
auto
output_t
=
context
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
);
output_t
->
Resize
({
ids_t
->
dims
()[
0
],
table_t
->
dims
()[
1
]});
output_t
->
Resize
({
ids_t
->
dims
()[
0
],
table_t
->
dims
()[
1
]});
}
}
...
@@ -56,7 +56,8 @@ class LookupTableOpGrad : public framework::OperatorWithKernel {
...
@@ -56,7 +56,8 @@ class LookupTableOpGrad : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
context
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
context
)
const
override
{
auto
table
=
context
.
Input
<
Tensor
>
(
"W"
);
auto
table
=
context
.
Input
<
Tensor
>
(
"W"
);
auto
d_table
=
context
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"W"
));
auto
d_table
=
context
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"W"
));
d_table
->
Resize
(
table
->
dims
());
d_table
->
Resize
(
table
->
dims
());
}
}
};
};
...
...
paddle/operators/mean_op.cc
浏览文件 @
f2442be9
...
@@ -25,7 +25,7 @@ class MeanOp : public framework::OperatorWithKernel {
...
@@ -25,7 +25,7 @@ class MeanOp : public framework::OperatorWithKernel {
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
PADDLE_ENFORCE_NOT_NULL
(
ctx
.
InputVar
(
"X"
),
PADDLE_ENFORCE_NOT_NULL
(
ctx
.
InputVar
(
"X"
),
"Input of MeanOp must be initialized."
);
"Input of MeanOp must be initialized."
);
ctx
.
Output
<
Tensor
>
(
"Out"
)
->
Resize
({
1
});
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
)
->
Resize
({
1
});
}
}
};
};
...
@@ -45,7 +45,7 @@ class MeanGradOp : public framework::OperatorWithKernel {
...
@@ -45,7 +45,7 @@ class MeanGradOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
))
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
framework
::
GradVarName
(
"X"
))
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
}
}
};
};
...
...
paddle/operators/minus_op.cc
浏览文件 @
f2442be9
...
@@ -33,7 +33,7 @@ class MinusOp : public framework::OperatorWithKernel {
...
@@ -33,7 +33,7 @@ class MinusOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_EQ
(
PADDLE_ENFORCE_EQ
(
left_tensor
->
numel
(),
right_tensor
->
numel
(),
left_tensor
->
numel
(),
right_tensor
->
numel
(),
"Minus operator must take two tensor with same num of elements"
);
"Minus operator must take two tensor with same num of elements"
);
ctx
.
Output
<
framework
::
Tensor
>
(
"Out"
)
->
Resize
(
left_tensor
->
dims
());
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
)
->
Resize
(
left_tensor
->
dims
());
}
}
};
};
...
...
paddle/operators/mul_op.cc
浏览文件 @
f2442be9
...
@@ -18,6 +18,7 @@ namespace paddle {
...
@@ -18,6 +18,7 @@ namespace paddle {
namespace
operators
{
namespace
operators
{
using
framework
::
Tensor
;
using
framework
::
Tensor
;
using
framework
::
LoDTensor
;
class
MulOp
:
public
framework
::
OperatorWithKernel
{
class
MulOp
:
public
framework
::
OperatorWithKernel
{
public:
public:
...
@@ -45,7 +46,8 @@ class MulOp : public framework::OperatorWithKernel {
...
@@ -45,7 +46,8 @@ class MulOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_EQ
(
PADDLE_ENFORCE_EQ
(
x_mat_dims
[
1
],
y_mat_dims
[
0
],
x_mat_dims
[
1
],
y_mat_dims
[
0
],
"First matrix's width must be equal with second matrix's height."
);
"First matrix's width must be equal with second matrix's height."
);
ctx
.
Output
<
Tensor
>
(
"Out"
)
->
Resize
({
x_mat_dims
[
0
],
y_mat_dims
[
1
]});
ctx
.
Output
<
framework
::
LoDTensor
>
(
"Out"
)
->
Resize
(
{
x_mat_dims
[
0
],
y_mat_dims
[
1
]});
}
}
};
};
...
@@ -94,8 +96,10 @@ class MulOpGrad : public framework::OperatorWithKernel {
...
@@ -94,8 +96,10 @@ class MulOpGrad : public framework::OperatorWithKernel {
auto
x_dims
=
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
();
auto
x_dims
=
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
();
auto
y_dims
=
ctx
.
Input
<
Tensor
>
(
"Y"
)
->
dims
();
auto
y_dims
=
ctx
.
Input
<
Tensor
>
(
"Y"
)
->
dims
();
auto
out_dims
=
ctx
.
Input
<
Tensor
>
(
framework
::
GradVarName
(
"Out"
))
->
dims
();
auto
out_dims
=
ctx
.
Input
<
Tensor
>
(
framework
::
GradVarName
(
"Out"
))
->
dims
();
auto
*
x_grad
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
x_grad
=
auto
*
y_grad
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"Y"
));
ctx
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
y_grad
=
ctx
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"Y"
));
auto
x_mat_dims
=
auto
x_mat_dims
=
framework
::
flatten_to_2d
(
x_dims
,
Attr
<
int
>
(
"x_num_col_dims"
));
framework
::
flatten_to_2d
(
x_dims
,
Attr
<
int
>
(
"x_num_col_dims"
));
...
...
paddle/operators/cross_entropy_op.cc
→
paddle/operators/
onehot_
cross_entropy_op.cc
浏览文件 @
f2442be9
...
@@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
...
@@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
See the License for the specific language governing permissions and
limitations under the License. */
limitations under the License. */
#include "paddle/operators/cross_entropy_op.h"
#include "paddle/operators/
onehot_
cross_entropy_op.h"
namespace
paddle
{
namespace
paddle
{
namespace
operators
{
namespace
operators
{
...
@@ -29,7 +29,7 @@ class OnehotCrossEntropyOp : public framework::OperatorWithKernel {
...
@@ -29,7 +29,7 @@ class OnehotCrossEntropyOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_EQ
(
X
->
dims
().
size
(),
2
,
"X's dimension must be 2."
);
PADDLE_ENFORCE_EQ
(
X
->
dims
().
size
(),
2
,
"X's dimension must be 2."
);
PADDLE_ENFORCE_EQ
(
label
->
dims
().
size
(),
1
,
"label's dimension must be 1."
);
PADDLE_ENFORCE_EQ
(
label
->
dims
().
size
(),
1
,
"label's dimension must be 1."
);
PADDLE_ENFORCE_EQ
(
X
->
dims
()[
0
],
label
->
dims
()[
0
]);
PADDLE_ENFORCE_EQ
(
X
->
dims
()[
0
],
label
->
dims
()[
0
]);
ctx
.
Output
<
Tensor
>
(
"Y"
)
->
Resize
({
X
->
dims
()[
0
]
});
ctx
.
Output
<
framework
::
LoDTensor
>
(
"Y"
)
->
Resize
({
X
->
dims
()[
0
],
1
});
}
}
};
};
...
@@ -39,7 +39,7 @@ class OnehotCrossEntropyGradientOp : public framework::OperatorWithKernel {
...
@@ -39,7 +39,7 @@ class OnehotCrossEntropyGradientOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
auto
dX
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
dX
=
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
X
=
ctx
.
Input
<
Tensor
>
(
"X"
);
auto
X
=
ctx
.
Input
<
Tensor
>
(
"X"
);
dX
->
Resize
(
X
->
dims
());
dX
->
Resize
(
X
->
dims
());
...
...
paddle/operators/cross_entropy_op.cu
→
paddle/operators/
onehot_
cross_entropy_op.cu
浏览文件 @
f2442be9
文件已移动
paddle/operators/cross_entropy_op.h
→
paddle/operators/
onehot_
cross_entropy_op.h
浏览文件 @
f2442be9
文件已移动
paddle/operators/pad_op.cc
浏览文件 @
f2442be9
...
@@ -34,7 +34,8 @@ class PadOp : public framework::OperatorWithKernel {
...
@@ -34,7 +34,8 @@ class PadOp : public framework::OperatorWithKernel {
for
(
int
i
=
0
;
i
<
x_dim
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
x_dim
.
size
();
++
i
)
{
out_dims
[
i
]
=
x_dim
[
i
]
+
paddings
[
i
*
2
]
+
paddings
[
i
*
2
+
1
];
out_dims
[
i
]
=
x_dim
[
i
]
+
paddings
[
i
*
2
]
+
paddings
[
i
*
2
+
1
];
}
}
ctx
.
Output
<
Tensor
>
(
"Out"
)
->
Resize
(
framework
::
make_ddim
(
out_dims
));
ctx
.
Output
<
framework
::
LoDTensor
>
(
"Out"
)
->
Resize
(
framework
::
make_ddim
(
out_dims
));
}
}
};
};
...
@@ -95,9 +96,9 @@ class PadOpGrad : public framework::OperatorWithKernel {
...
@@ -95,9 +96,9 @@ class PadOpGrad : public framework::OperatorWithKernel {
PADDLE_ENFORCE_NOT_NULL
(
ctx
.
InputVar
(
framework
::
GradVarName
(
"Out"
)),
PADDLE_ENFORCE_NOT_NULL
(
ctx
.
InputVar
(
framework
::
GradVarName
(
"Out"
)),
"Input(Out@GRAD) should not be null"
);
"Input(Out@GRAD) should not be null"
);
auto
x_dims
=
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
();
auto
x_dims
=
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
();
auto
*
x_g
rad
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
x_g
=
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
framework
::
GradVarName
(
"X"
));
if
(
x_g
rad
!=
nullptr
)
{
if
(
x_g
!=
nullptr
)
{
x_g
rad
->
Resize
(
x_dims
);
x_g
->
Resize
(
x_dims
);
}
}
}
}
};
};
...
...
paddle/operators/recurrent_op.cc
浏览文件 @
f2442be9
...
@@ -26,10 +26,11 @@ namespace operators {
...
@@ -26,10 +26,11 @@ namespace operators {
using
Scope
=
framework
::
Scope
;
using
Scope
=
framework
::
Scope
;
using
Variable
=
framework
::
Variable
;
using
Variable
=
framework
::
Variable
;
using
Tensor
=
framework
::
Tensor
;
using
Tensor
=
framework
::
Tensor
;
using
LoDTensor
=
framework
::
LoDTensor
;
void
RecurrentAlgorithm
::
InferShape
(
const
Scope
&
scope
)
const
{
void
RecurrentAlgorithm
::
InferShape
(
const
Scope
&
scope
)
const
{
seq_len_
=
scope
.
FindVar
((
arg_
->
inlinks
[
0
]).
external
)
seq_len_
=
scope
.
FindVar
((
arg_
->
inlinks
[
0
]).
external
)
->
GetMutable
<
Tensor
>
()
->
GetMutable
<
LoD
Tensor
>
()
->
dims
()[
0
];
->
dims
()[
0
];
CreateScopes
(
scope
);
CreateScopes
(
scope
);
auto
step_scopes
=
GetStepScopes
(
scope
);
auto
step_scopes
=
GetStepScopes
(
scope
);
...
@@ -88,7 +89,7 @@ void RecurrentAlgorithm::CreateScopes(const Scope& scope) const {
...
@@ -88,7 +89,7 @@ void RecurrentAlgorithm::CreateScopes(const Scope& scope) const {
// the weight are located in parent scope
// the weight are located in parent scope
for
(
auto
&
var_name
:
input
.
second
)
{
for
(
auto
&
var_name
:
input
.
second
)
{
if
(
!
step_scope
.
FindVar
(
var_name
))
{
if
(
!
step_scope
.
FindVar
(
var_name
))
{
step_scope
.
NewVar
(
var_name
)
->
GetMutable
<
Tensor
>
();
step_scope
.
NewVar
(
var_name
)
->
GetMutable
<
LoD
Tensor
>
();
}
}
}
}
}
}
...
@@ -106,11 +107,12 @@ void RecurrentAlgorithm::CreateScopes(const Scope& scope) const {
...
@@ -106,11 +107,12 @@ void RecurrentAlgorithm::CreateScopes(const Scope& scope) const {
void
RecurrentAlgorithm
::
InitMemories
(
Scope
*
step_scope
,
void
RecurrentAlgorithm
::
InitMemories
(
Scope
*
step_scope
,
bool
infer_shape_mode
)
const
{
bool
infer_shape_mode
)
const
{
for
(
auto
&
attr
:
arg_
->
memories
)
{
for
(
auto
&
attr
:
arg_
->
memories
)
{
Tensor
*
pre_mem
=
step_scope
->
NewVar
(
attr
.
pre_var
)
->
GetMutable
<
Tensor
>
();
auto
*
pre_mem
=
step_scope
->
NewVar
(
attr
.
pre_var
)
->
GetMutable
<
LoD
Tensor
>
();
PADDLE_ENFORCE
(
step_scope
->
FindVar
(
attr
.
boot_var
)
!=
nullptr
,
PADDLE_ENFORCE
(
step_scope
->
FindVar
(
attr
.
boot_var
)
!=
nullptr
,
"memory [%s]'s boot variable [%s] not exists"
,
attr
.
var
,
"memory [%s]'s boot variable [%s] not exists"
,
attr
.
var
,
attr
.
boot_var
);
attr
.
boot_var
);
Tensor
*
boot_mem
=
step_scope
->
FindVar
(
attr
.
boot_var
)
->
GetMutable
<
Tensor
>
();
auto
*
boot_mem
=
step_scope
->
FindVar
(
attr
.
boot_var
)
->
GetMutable
<
LoDTensor
>
();
if
(
infer_shape_mode
)
{
if
(
infer_shape_mode
)
{
pre_mem
->
Resize
(
boot_mem
->
dims
());
pre_mem
->
Resize
(
boot_mem
->
dims
());
PADDLE_ENFORCE_EQ
(
pre_mem
->
dims
().
size
(),
2
);
PADDLE_ENFORCE_EQ
(
pre_mem
->
dims
().
size
(),
2
);
...
@@ -192,9 +194,9 @@ void RecurrentGradientAlgorithm::LinkBootMemoryGradients(
...
@@ -192,9 +194,9 @@ void RecurrentGradientAlgorithm::LinkBootMemoryGradients(
"memory variable [%s] does not exists"
,
attr
.
var
);
"memory variable [%s] does not exists"
,
attr
.
var
);
PADDLE_ENFORCE
(
step_scope
->
FindVar
(
attr
.
boot_var
)
!=
nullptr
,
PADDLE_ENFORCE
(
step_scope
->
FindVar
(
attr
.
boot_var
)
!=
nullptr
,
"boot variable [%s] does not exists"
,
attr
.
boot_var
);
"boot variable [%s] does not exists"
,
attr
.
boot_var
);
Tensor
*
mem_grad
=
step_scope
->
NewVar
(
attr
.
var
)
->
GetMutable
<
Tensor
>
();
auto
*
mem_grad
=
step_scope
->
NewVar
(
attr
.
var
)
->
GetMutable
<
LoD
Tensor
>
();
Tensor
*
boot_mem_grad
=
auto
*
boot_mem_grad
=
step_scope
->
NewVar
(
attr
.
boot_var
)
->
GetMutable
<
Tensor
>
();
step_scope
->
NewVar
(
attr
.
boot_var
)
->
GetMutable
<
LoD
Tensor
>
();
if
(
infer_shape_mode
)
{
if
(
infer_shape_mode
)
{
boot_mem_grad
->
Resize
(
mem_grad
->
dims
());
boot_mem_grad
->
Resize
(
mem_grad
->
dims
());
}
else
{
}
else
{
...
@@ -205,7 +207,7 @@ void RecurrentGradientAlgorithm::LinkBootMemoryGradients(
...
@@ -205,7 +207,7 @@ void RecurrentGradientAlgorithm::LinkBootMemoryGradients(
void
RecurrentGradientAlgorithm
::
InferShape
(
const
Scope
&
scope
)
const
{
void
RecurrentGradientAlgorithm
::
InferShape
(
const
Scope
&
scope
)
const
{
seq_len_
=
scope
.
FindVar
((
arg_
->
inlinks
[
0
]).
external
)
seq_len_
=
scope
.
FindVar
((
arg_
->
inlinks
[
0
]).
external
)
->
GetMutable
<
Tensor
>
()
->
GetMutable
<
LoD
Tensor
>
()
->
dims
()[
0
];
->
dims
()[
0
];
auto
step_scopes
=
GetStepScopes
(
scope
);
auto
step_scopes
=
GetStepScopes
(
scope
);
rnn
::
SegmentInputs
(
step_scopes
,
arg_
->
inlinks
,
seq_len_
,
rnn
::
SegmentInputs
(
step_scopes
,
arg_
->
inlinks
,
seq_len_
,
...
...
paddle/operators/reshape_op.cc
浏览文件 @
f2442be9
...
@@ -46,7 +46,7 @@ class ReshapeOp : public framework::OperatorWithKernel {
...
@@ -46,7 +46,7 @@ class ReshapeOp : public framework::OperatorWithKernel {
std
::
transform
(
shape
.
begin
(),
shape
.
end
(),
shape_int64
.
begin
(),
std
::
transform
(
shape
.
begin
(),
shape
.
end
(),
shape_int64
.
begin
(),
[](
int
a
)
{
return
static_cast
<
int64_t
>
(
a
);
});
[](
int
a
)
{
return
static_cast
<
int64_t
>
(
a
);
});
auto
out_dims
=
framework
::
make_ddim
(
shape_int64
);
auto
out_dims
=
framework
::
make_ddim
(
shape_int64
);
ctx
.
Output
<
framework
::
Tensor
>
(
"Out"
)
->
Resize
(
out_dims
);
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
)
->
Resize
(
out_dims
);
}
}
};
};
...
@@ -90,7 +90,7 @@ class ReshapeGradOp : public framework::OperatorWithKernel {
...
@@ -90,7 +90,7 @@ class ReshapeGradOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_NOT_NULL
(
ctx
.
InputVar
(
framework
::
GradVarName
(
"Out"
)),
PADDLE_ENFORCE_NOT_NULL
(
ctx
.
InputVar
(
framework
::
GradVarName
(
"Out"
)),
"Input(Out@GRAD) shouldn't be null."
);
"Input(Out@GRAD) shouldn't be null."
);
auto
dims
=
ctx
.
Input
<
framework
::
Tensor
>
(
"X"
)
->
dims
();
auto
dims
=
ctx
.
Input
<
framework
::
Tensor
>
(
"X"
)
->
dims
();
auto
*
d_in
=
ctx
.
Output
<
framework
::
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
d_in
=
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
framework
::
GradVarName
(
"X"
));
d_in
->
Resize
(
dims
);
d_in
->
Resize
(
dims
);
}
}
};
};
...
...
paddle/operators/rnn/recurrent_op_utils.cc
浏览文件 @
f2442be9
...
@@ -21,6 +21,7 @@ namespace rnn {
...
@@ -21,6 +21,7 @@ namespace rnn {
namespace
f
=
paddle
::
framework
;
namespace
f
=
paddle
::
framework
;
using
Tensor
=
framework
::
Tensor
;
using
Tensor
=
framework
::
Tensor
;
using
LoDTensor
=
framework
::
LoDTensor
;
void
SegmentInputs
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
void
SegmentInputs
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
const
std
::
vector
<
Link
>&
inlinks
,
const
size_t
seq_len
,
const
std
::
vector
<
Link
>&
inlinks
,
const
size_t
seq_len
,
...
@@ -31,7 +32,7 @@ void SegmentInputs(const std::vector<Scope*>& step_scopes,
...
@@ -31,7 +32,7 @@ void SegmentInputs(const std::vector<Scope*>& step_scopes,
PADDLE_ENFORCE
(
input_var
!=
nullptr
,
"input link [%s] is not in scope."
,
PADDLE_ENFORCE
(
input_var
!=
nullptr
,
"input link [%s] is not in scope."
,
inlinks
[
i
].
external
);
inlinks
[
i
].
external
);
Tensor
*
input
=
input_var
->
GetMutable
<
Tensor
>
();
LoDTensor
*
input
=
input_var
->
GetMutable
<
LoD
Tensor
>
();
f
::
DDim
dims
=
input
->
dims
();
f
::
DDim
dims
=
input
->
dims
();
PADDLE_ENFORCE
(
static_cast
<
size_t
>
(
dims
[
0
])
==
seq_len
,
PADDLE_ENFORCE
(
static_cast
<
size_t
>
(
dims
[
0
])
==
seq_len
,
"all the inlinks must have same length"
);
"all the inlinks must have same length"
);
...
@@ -40,6 +41,8 @@ void SegmentInputs(const std::vector<Scope*>& step_scopes,
...
@@ -40,6 +41,8 @@ void SegmentInputs(const std::vector<Scope*>& step_scopes,
Tensor
*
step_input
=
Tensor
*
step_input
=
step_scopes
[
j
]
->
NewVar
(
inlinks
[
i
].
internal
)
->
GetMutable
<
Tensor
>
();
step_scopes
[
j
]
->
NewVar
(
inlinks
[
i
].
internal
)
->
GetMutable
<
Tensor
>
();
if
(
!
infer_shape_mode
)
{
if
(
!
infer_shape_mode
)
{
// The input of operators of each step is Tensor here.
// Maybe need to modify Slice function.
*
step_input
=
input
->
Slice
<
float
>
(
j
,
j
+
1
);
*
step_input
=
input
->
Slice
<
float
>
(
j
,
j
+
1
);
}
}
step_input
->
Resize
(
step_dims
);
step_input
->
Resize
(
step_dims
);
...
@@ -54,21 +57,23 @@ void ConcatOutputs(const std::vector<Scope*>& step_scopes,
...
@@ -54,21 +57,23 @@ void ConcatOutputs(const std::vector<Scope*>& step_scopes,
auto
output_var
=
step_scopes
[
0
]
->
FindVar
(
outlinks
[
i
].
external
);
auto
output_var
=
step_scopes
[
0
]
->
FindVar
(
outlinks
[
i
].
external
);
PADDLE_ENFORCE
(
output_var
!=
nullptr
,
"output link [%s] is not in scope."
,
PADDLE_ENFORCE
(
output_var
!=
nullptr
,
"output link [%s] is not in scope."
,
outlinks
[
i
].
external
);
outlinks
[
i
].
external
);
Tensor
*
output
=
output_var
->
GetMutable
<
Tensor
>
();
LoDTensor
*
output
=
output_var
->
GetMutable
<
LoD
Tensor
>
();
if
(
infer_shape_mode
)
{
if
(
infer_shape_mode
)
{
auto
step_scope_var
=
step_scopes
[
0
]
->
FindVar
(
outlinks
[
i
].
internal
);
auto
step_scope_var
=
step_scopes
[
0
]
->
FindVar
(
outlinks
[
i
].
internal
);
PADDLE_ENFORCE
(
step_scope_var
!=
nullptr
,
"%s not in scope"
,
PADDLE_ENFORCE
(
step_scope_var
!=
nullptr
,
"%s not in scope"
,
outlinks
[
i
].
internal
);
outlinks
[
i
].
internal
);
f
::
DDim
step_dims
=
step_scope_var
->
template
GetMutable
<
Tensor
>()
->
dims
();
f
::
DDim
step_dims
=
step_scope_var
->
template
GetMutable
<
LoDTensor
>()
->
dims
();
std
::
vector
<
int64_t
>
dims_vec
=
vectorize
(
step_dims
);
std
::
vector
<
int64_t
>
dims_vec
=
vectorize
(
step_dims
);
dims_vec
.
insert
(
dims_vec
.
begin
(),
seq_len
);
dims_vec
.
insert
(
dims_vec
.
begin
(),
seq_len
);
output
->
Resize
(
f
::
make_ddim
(
dims_vec
));
output
->
Resize
(
f
::
make_ddim
(
dims_vec
));
}
else
{
}
else
{
output
->
mutable_data
<
float
>
(
platform
::
CPUPlace
());
output
->
mutable_data
<
float
>
(
platform
::
CPUPlace
());
for
(
size_t
j
=
0
;
j
<
seq_len
;
j
++
)
{
for
(
size_t
j
=
0
;
j
<
seq_len
;
j
++
)
{
Tensor
*
step_output
=
LoDTensor
*
step_output
=
step_scopes
[
j
]
step_scopes
[
j
]
->
FindVar
(
outlinks
[
i
].
internal
)
->
GetMutable
<
Tensor
>
();
->
FindVar
(
outlinks
[
i
].
internal
)
->
GetMutable
<
LoDTensor
>
();
// TODO(luotao02) data type and platform::DeviceContext() should set
// TODO(luotao02) data type and platform::DeviceContext() should set
// correctly
// correctly
(
output
->
Slice
<
float
>
(
j
,
j
+
1
))
(
output
->
Slice
<
float
>
(
j
,
j
+
1
))
...
@@ -94,8 +99,8 @@ void LinkMemories(const std::vector<Scope*>& scopes,
...
@@ -94,8 +99,8 @@ void LinkMemories(const std::vector<Scope*>& scopes,
auto
scope
=
scopes
[
step_id
];
auto
scope
=
scopes
[
step_id
];
auto
linked_scope
=
scopes
[
step_id
+
offset
];
auto
linked_scope
=
scopes
[
step_id
+
offset
];
for
(
auto
&
attr
:
memories
)
{
for
(
auto
&
attr
:
memories
)
{
auto
mem
=
scope
->
FindVar
(
attr
.
pre_var
)
->
GetMutable
<
Tensor
>
();
auto
mem
=
scope
->
FindVar
(
attr
.
pre_var
)
->
GetMutable
<
LoD
Tensor
>
();
auto
linked_mem
=
linked_scope
->
FindVar
(
attr
.
var
)
->
GetMutable
<
Tensor
>
();
auto
linked_mem
=
linked_scope
->
FindVar
(
attr
.
var
)
->
GetMutable
<
LoD
Tensor
>
();
if
(
infer_shape_mode
)
{
if
(
infer_shape_mode
)
{
mem
->
Resize
(
linked_mem
->
dims
());
mem
->
Resize
(
linked_mem
->
dims
());
}
else
{
}
else
{
...
...
paddle/operators/rowwise_add_op.cc
浏览文件 @
f2442be9
...
@@ -37,7 +37,7 @@ class RowwiseAddOp : public framework::OperatorWithKernel {
...
@@ -37,7 +37,7 @@ class RowwiseAddOp : public framework::OperatorWithKernel {
framework
::
slice_ddim
(
x_dims
,
num_col_dims
,
x_dims
.
size
()),
b_dims
,
framework
::
slice_ddim
(
x_dims
,
num_col_dims
,
x_dims
.
size
()),
b_dims
,
"The width of two operands must be same"
);
"The width of two operands must be same"
);
PADDLE_ENFORCE_EQ
(
ctx
.
OutputSize
(
"Out"
),
1
,
"The output size must be 1"
);
PADDLE_ENFORCE_EQ
(
ctx
.
OutputSize
(
"Out"
),
1
,
"The output size must be 1"
);
ctx
.
Output
<
Tensor
>
(
"Out"
)
->
Resize
(
x_dims
);
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
)
->
Resize
(
x_dims
);
}
}
};
};
...
@@ -76,8 +76,8 @@ class RowwiseAddGradOp : public framework::OperatorWithKernel {
...
@@ -76,8 +76,8 @@ class RowwiseAddGradOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_EQ
(
PADDLE_ENFORCE_EQ
(
framework
::
slice_ddim
(
x_dims
,
num_col_dims
,
x_dims
.
size
()),
b_dims
,
framework
::
slice_ddim
(
x_dims
,
num_col_dims
,
x_dims
.
size
()),
b_dims
,
"The width of two operands must be same"
);
"The width of two operands must be same"
);
auto
*
dx
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
dx
=
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
db
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"b"
));
auto
*
db
=
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
framework
::
GradVarName
(
"b"
));
if
(
dx
)
dx
->
Resize
(
x_dims
);
if
(
dx
)
dx
->
Resize
(
x_dims
);
if
(
db
)
db
->
Resize
(
b_dims
);
if
(
db
)
db
->
Resize
(
b_dims
);
}
}
...
...
paddle/operators/scale_op.cc
浏览文件 @
f2442be9
...
@@ -28,7 +28,7 @@ class ScaleOp : public framework::OperatorWithKernel {
...
@@ -28,7 +28,7 @@ class ScaleOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
auto
*
in
=
ctx
.
Input
<
framework
::
Tensor
>
(
"X"
);
auto
*
in
=
ctx
.
Input
<
framework
::
Tensor
>
(
"X"
);
auto
*
out
=
ctx
.
Output
<
framework
::
Tensor
>
(
"Out"
);
auto
*
out
=
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
);
out
->
Resize
(
in
->
dims
());
out
->
Resize
(
in
->
dims
());
}
}
};
};
...
...
paddle/operators/scatter_op.cc
浏览文件 @
f2442be9
...
@@ -35,7 +35,8 @@ class ScatterOp : public framework::OperatorWithKernel {
...
@@ -35,7 +35,8 @@ class ScatterOp : public framework::OperatorWithKernel {
framework
::
DDim
data_dim
(
ctx
.
Input
<
Tensor
>
(
"Updates"
)
->
dims
());
framework
::
DDim
data_dim
(
ctx
.
Input
<
Tensor
>
(
"Updates"
)
->
dims
());
for
(
int
i
=
1
;
i
<
data_dim
.
size
();
++
i
)
for
(
int
i
=
1
;
i
<
data_dim
.
size
();
++
i
)
PADDLE_ENFORCE_EQ
(
data_dim
[
i
],
ctx
.
Input
<
Tensor
>
(
"Updates"
)
->
dims
()[
i
]);
PADDLE_ENFORCE_EQ
(
data_dim
[
i
],
ctx
.
Input
<
Tensor
>
(
"Updates"
)
->
dims
()[
i
]);
ctx
.
Output
<
Tensor
>
(
"Out"
)
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"Ref"
)
->
dims
());
ctx
.
Output
<
framework
::
LoDTensor
>
(
"Out"
)
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"Ref"
)
->
dims
());
}
}
};
};
...
@@ -45,9 +46,11 @@ class ScatterGradOp : public framework::OperatorWithKernel {
...
@@ -45,9 +46,11 @@ class ScatterGradOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
auto
*
dUpdates
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"Updates"
));
auto
*
dUpdates
=
ctx
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"Updates"
));
auto
*
Updates
=
ctx
.
Input
<
Tensor
>
(
"Updates"
);
auto
*
Updates
=
ctx
.
Input
<
Tensor
>
(
"Updates"
);
auto
*
dRef
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"Ref"
));
auto
*
dRef
=
ctx
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"Ref"
));
auto
*
Ref
=
ctx
.
Input
<
Tensor
>
(
"Ref"
);
auto
*
Ref
=
ctx
.
Input
<
Tensor
>
(
"Ref"
);
dRef
->
Resize
(
Ref
->
dims
());
dRef
->
Resize
(
Ref
->
dims
());
...
...
paddle/operators/sequence_avg_pool_op.cc
0 → 100644
浏览文件 @
f2442be9
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/operators/sequence_avg_pool_op.h"
namespace
paddle
{
namespace
operators
{
class
SequenceAvgPoolOp
:
public
framework
::
OperatorWithKernel
{
public:
using
framework
::
OperatorWithKernel
::
OperatorWithKernel
;
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
PADDLE_ENFORCE_NOT_NULL
(
ctx
.
InputVar
(
"X"
),
"Input of SequenceAvgPoolOp"
"must be initialized."
);
auto
*
x
=
ctx
.
Input
<
framework
::
LoDTensor
>
(
"X"
);
auto
dims
=
x
->
dims
();
auto
lod
=
x
->
lod
();
PADDLE_ENFORCE_EQ
(
lod
.
size
(),
1UL
,
"Only support one level sequence now."
);
PADDLE_ENFORCE_GE
(
dims
[
0
],
/*batch size = */
static_cast
<
int64_t
>
(
lod
[
0
].
size
()
-
1
),
"The first dimension of Input(X) must be large than batch size."
);
dims
[
0
]
=
lod
[
0
].
size
()
-
1
;
ctx
.
Output
<
framework
::
LoDTensor
>
(
"Out"
)
->
Resize
({
dims
});
}
};
class
SequenceAvgPoolOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
public:
SequenceAvgPoolOpMaker
(
framework
::
OpProto
*
proto
,
framework
::
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"X"
,
"Input of SequenceAvgPoolOp."
);
AddOutput
(
"Out"
,
"The output of SequenceAvgPoolOp."
);
AddComment
(
R"DOC(
SequenceAvgPoolOp averages features of all time-steps of each instance.
More detailed comments will be added later.
)DOC"
);
}
};
class
SequenceAvgPoolGradOp
:
public
framework
::
OperatorWithKernel
{
public:
using
framework
::
OperatorWithKernel
::
OperatorWithKernel
;
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
PADDLE_ENFORCE_NOT_NULL
(
ctx
.
InputVar
(
framework
::
GradVarName
(
"Out"
)),
"Gradient of Out should not be null"
);
auto
og_dims
=
ctx
.
Input
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"Out"
))
->
dims
();
auto
x_dims
=
ctx
.
Input
<
framework
::
LoDTensor
>
(
"X"
)
->
dims
();
PADDLE_ENFORCE_EQ
(
og_dims
.
size
(),
x_dims
.
size
(),
"The rank of output grad must equal to Input(X)."
);
for
(
int64_t
i
=
1
;
i
<
og_dims
.
size
();
++
i
)
{
PADDLE_ENFORCE_EQ
(
og_dims
[
i
],
x_dims
[
i
],
"The dimension mismatch."
);
}
auto
*
x_grad
=
ctx
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"X"
));
x_grad
->
Resize
(
x_dims
);
}
};
}
// namespace operators
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
sequence_avg_pool
,
ops
::
SequenceAvgPoolOp
,
ops
::
SequenceAvgPoolOpMaker
,
sequence_avg_pool_grad
,
ops
::
SequenceAvgPoolGradOp
);
REGISTER_OP_CPU_KERNEL
(
sequence_avg_pool
,
ops
::
SequenceAvgPoolKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
REGISTER_OP_CPU_KERNEL
(
sequence_avg_pool_grad
,
ops
::
SequenceAvgPoolGradKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
paddle/operators/sequence_avg_pool_op.cu
0 → 100644
浏览文件 @
f2442be9
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#define EIGEN_USE_GPU
#include "paddle/operators/sequence_avg_pool_op.h"
namespace
ops
=
paddle
::
operators
;
REGISTER_OP_GPU_KERNEL
(
sequence_avg_pool
,
ops
::
SequenceAvgPoolKernel
<
paddle
::
platform
::
GPUPlace
,
float
>
);
REGISTER_OP_GPU_KERNEL
(
sequence_avg_pool_grad
,
ops
::
SequenceAvgPoolGradKernel
<
paddle
::
platform
::
GPUPlace
,
float
>
);
paddle/operators/sequence_avg_pool_op.h
0 → 100644
浏览文件 @
f2442be9
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#pragma once
#include "paddle/framework/eigen.h"
#include "paddle/framework/op_registry.h"
namespace
paddle
{
namespace
operators
{
using
Tensor
=
framework
::
Tensor
;
using
LoDTensor
=
framework
::
LoDTensor
;
template
<
typename
T
,
int
MajorType
=
Eigen
::
RowMajor
,
typename
IndexType
=
Eigen
::
DenseIndex
>
using
EigenMatrix
=
framework
::
EigenMatrix
<
T
,
MajorType
,
IndexType
>
;
template
<
typename
Place
,
typename
T
>
class
SequenceAvgPoolKernel
:
public
framework
::
OpKernel
{
public:
void
Compute
(
const
framework
::
ExecutionContext
&
context
)
const
override
{
auto
*
in
=
context
.
Input
<
LoDTensor
>
(
"X"
);
auto
*
out
=
context
.
Output
<
LoDTensor
>
(
"Out"
);
auto
dims
=
in
->
dims
();
auto
lod
=
in
->
lod
();
int64_t
w
=
in
->
numel
()
/
dims
[
0
];
out
->
mutable_data
<
T
>
(
context
.
GetPlace
());
auto
place
=
context
.
GetEigenDevice
<
Place
>
();
for
(
int
i
=
0
;
i
<
static_cast
<
int
>
(
lod
[
0
].
size
())
-
1
;
++
i
)
{
Tensor
in_t
=
in
->
Slice
<
T
>
(
static_cast
<
int
>
(
lod
[
0
][
i
]),
static_cast
<
int
>
(
lod
[
0
][
i
+
1
]));
Tensor
out_t
=
out
->
Slice
<
T
>
(
i
,
i
+
1
);
int64_t
h
=
static_cast
<
int64_t
>
(
lod
[
0
][
i
+
1
]
-
lod
[
0
][
i
]);
auto
in_e
=
EigenMatrix
<
T
>::
From
(
in_t
,
{
h
,
w
});
auto
out_e
=
EigenMatrix
<
T
>::
From
(
out_t
,
{
h
,
w
});
out_e
.
device
(
place
)
=
in_e
.
mean
(
Eigen
::
array
<
int
,
1
>
({{
0
}}));
}
}
};
template
<
typename
Place
,
typename
T
>
class
SequenceAvgPoolGradKernel
:
public
framework
::
OpKernel
{
public:
void
Compute
(
const
framework
::
ExecutionContext
&
context
)
const
override
{
auto
*
in
=
context
.
Output
<
LoDTensor
>
(
"X"
);
auto
*
in_g
=
context
.
Output
<
LoDTensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
out_g
=
context
.
Input
<
LoDTensor
>
(
framework
::
GradVarName
(
"Out"
));
auto
dims
=
in
->
dims
();
auto
lod
=
in
->
lod
();
int64_t
w
=
in
->
numel
()
/
dims
[
0
];
in_g
->
mutable_data
<
T
>
(
context
.
GetPlace
());
auto
place
=
context
.
GetEigenDevice
<
Place
>
();
for
(
int
i
=
0
;
i
<
static_cast
<
int
>
(
lod
[
0
].
size
())
-
1
;
++
i
)
{
auto
in_g_t
=
in_g
->
Slice
<
T
>
(
static_cast
<
int
>
(
lod
[
0
][
i
]),
static_cast
<
int
>
(
lod
[
0
][
i
+
1
]));
auto
out_g_t
=
out_g
->
Slice
<
T
>
(
i
,
i
+
1
);
int64_t
h
=
static_cast
<
int64_t
>
(
lod
[
0
][
i
+
1
]
-
lod
[
0
][
i
]);
auto
in_g_e
=
EigenMatrix
<
T
>::
From
(
in_g_t
,
{
h
,
w
});
auto
out_g_e
=
EigenMatrix
<
T
>::
From
(
out_g_t
,
{
1
,
w
});
Eigen
::
DSizes
<
int
,
2
>
bcast
(
h
,
w
);
in_g_e
.
device
(
place
)
=
(
out_g_e
/
static_cast
<
T
>
(
h
)).
broadcast
(
bcast
);
}
}
};
}
// namespace operators
}
// namespace paddle
paddle/operators/sgd_op.cc
浏览文件 @
f2442be9
...
@@ -23,10 +23,11 @@ class SGDOp : public framework::OperatorWithKernel {
...
@@ -23,10 +23,11 @@ class SGDOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
PADDLE_ENFORCE
(
PADDLE_ENFORCE_EQ
(
ctx
.
Input
<
Tensor
>
(
"param"
)
->
dims
(),
ctx
.
Input
<
Tensor
>
(
"param"
)
->
dims
()
==
ctx
.
Input
<
Tensor
>
(
"grad"
)
->
dims
(),
ctx
.
Input
<
Tensor
>
(
"grad"
)
->
dims
(),
"Two input of SGD Op's dimension must be same."
);
"Two input of SGD Op's dimension must be same."
);
ctx
.
Output
<
Tensor
>
(
"param_out"
)
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"param"
)
->
dims
());
ctx
.
Output
<
framework
::
LoDTensor
>
(
"param_out"
)
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"param"
)
->
dims
());
}
}
};
};
...
...
paddle/operators/sigmoid_op.cc
浏览文件 @
f2442be9
...
@@ -23,7 +23,8 @@ class SigmoidOp : public framework::OperatorWithKernel {
...
@@ -23,7 +23,8 @@ class SigmoidOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
ctx
.
Output
<
Tensor
>
(
"Y"
)
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
ctx
.
Output
<
framework
::
LoDTensor
>
(
"Y"
)
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
}
}
};
};
...
@@ -44,7 +45,7 @@ class SigmoidOpGrad : public framework::OperatorWithKernel {
...
@@ -44,7 +45,7 @@ class SigmoidOpGrad : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
))
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
framework
::
GradVarName
(
"X"
))
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"Y"
)
->
dims
());
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"Y"
)
->
dims
());
}
}
};
};
...
...
paddle/operators/softmax_op.cc
浏览文件 @
f2442be9
...
@@ -25,7 +25,8 @@ class SoftmaxOp : public framework::OperatorWithKernel {
...
@@ -25,7 +25,8 @@ class SoftmaxOp : public framework::OperatorWithKernel {
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
PADDLE_ENFORCE
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
().
size
()
==
2UL
,
PADDLE_ENFORCE
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
().
size
()
==
2UL
,
"The input of softmax op must be a matrix."
);
"The input of softmax op must be a matrix."
);
ctx
.
Output
<
Tensor
>
(
"Y"
)
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
ctx
.
Output
<
framework
::
LoDTensor
>
(
"Y"
)
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
}
}
};
};
...
@@ -71,7 +72,7 @@ class SoftmaxOpGrad : public framework::OperatorWithKernel {
...
@@ -71,7 +72,7 @@ class SoftmaxOpGrad : public framework::OperatorWithKernel {
ctx
.
Input
<
Tensor
>
(
framework
::
GradVarName
(
"Y"
))
->
dims
(),
ctx
.
Input
<
Tensor
>
(
framework
::
GradVarName
(
"Y"
))
->
dims
(),
"Input(Y) and its gradients should have a same shape."
);
"Input(Y) and its gradients should have a same shape."
);
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
))
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
framework
::
GradVarName
(
"X"
))
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
->
Resize
(
ctx
.
Input
<
Tensor
>
(
"X"
)
->
dims
());
}
}
};
};
...
...
paddle/operators/squared_l2_distance_op.cc
浏览文件 @
f2442be9
...
@@ -48,9 +48,9 @@ class SquaredL2DistanceOp : public framework::OperatorWithKernel {
...
@@ -48,9 +48,9 @@ class SquaredL2DistanceOp : public framework::OperatorWithKernel {
"First dimension of target must be equal to input "
"First dimension of target must be equal to input "
"or to 1."
);
"or to 1."
);
ctx
.
Output
<
Tensor
>
(
"sub_result"
)
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"sub_result"
)
->
Resize
({
x_dims
[
0
],
x
->
numel
()
/
x_dims
[
0
]});
->
Resize
({
x_dims
[
0
],
x
->
numel
()
/
x_dims
[
0
]});
ctx
.
Output
<
Tensor
>
(
"Out"
)
->
Resize
({
x_dims
[
0
],
1
});
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
)
->
Resize
({
x_dims
[
0
],
1
});
}
}
};
};
...
@@ -94,8 +94,10 @@ class SquaredL2DistanceGradOp : public framework::OperatorWithKernel {
...
@@ -94,8 +94,10 @@ class SquaredL2DistanceGradOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_EQ
(
out_dims
[
1
],
1
,
PADDLE_ENFORCE_EQ
(
out_dims
[
1
],
1
,
"Second dimension of output gradient "
"Second dimension of output gradient "
"must be 1."
);
"must be 1."
);
auto
*
x_grad
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
x_grad
=
auto
*
y_grad
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"Y"
));
ctx
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
y_grad
=
ctx
.
Output
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"Y"
));
if
(
x_grad
)
x_grad
->
Resize
(
x_dims
);
if
(
x_grad
)
x_grad
->
Resize
(
x_dims
);
if
(
y_grad
)
y_grad
->
Resize
(
y_dims
);
if
(
y_grad
)
y_grad
->
Resize
(
y_dims
);
}
}
...
...
paddle/operators/sum_op.cc
浏览文件 @
f2442be9
...
@@ -23,7 +23,7 @@ class SumOp : public framework::OperatorWithKernel {
...
@@ -23,7 +23,7 @@ class SumOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
auto
ins
=
ctx
.
MultiInput
<
framework
::
Tensor
>
(
"X"
);
auto
ins
=
ctx
.
MultiInput
<
framework
::
Tensor
>
(
"X"
);
auto
*
out
=
ctx
.
Output
<
framework
::
Tensor
>
(
"Out"
);
auto
*
out
=
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
);
int
N
=
ins
.
size
();
int
N
=
ins
.
size
();
auto
in_dim
=
ins
[
0
]
->
dims
();
auto
in_dim
=
ins
[
0
]
->
dims
();
...
@@ -55,7 +55,8 @@ class SumGradOp : public framework::OperatorWithKernel {
...
@@ -55,7 +55,8 @@ class SumGradOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
auto
outputs
=
ctx
.
MultiOutput
<
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
outputs
=
ctx
.
MultiOutput
<
framework
::
LoDTensor
>
(
framework
::
GradVarName
(
"X"
));
auto
dims
=
ctx
.
Input
<
Tensor
>
(
framework
::
GradVarName
(
"Out"
))
->
dims
();
auto
dims
=
ctx
.
Input
<
Tensor
>
(
framework
::
GradVarName
(
"Out"
))
->
dims
();
for
(
auto
output
:
outputs
)
{
for
(
auto
output
:
outputs
)
{
output
->
Resize
(
dims
);
output
->
Resize
(
dims
);
...
...
paddle/operators/top_k_op.cc
浏览文件 @
f2442be9
...
@@ -35,8 +35,8 @@ class TopkOp : public framework::OperatorWithKernel {
...
@@ -35,8 +35,8 @@ class TopkOp : public framework::OperatorWithKernel {
framework
::
DDim
dims
=
input
->
dims
();
framework
::
DDim
dims
=
input
->
dims
();
dims
[
dims
.
size
()
-
1
]
=
k
;
dims
[
dims
.
size
()
-
1
]
=
k
;
ctx
.
Output
<
Tensor
>
(
"Out"
)
->
Resize
(
dims
);
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
)
->
Resize
(
dims
);
ctx
.
Output
<
Tensor
>
(
"Indices"
)
->
Resize
(
dims
);
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Indices"
)
->
Resize
(
dims
);
}
}
};
};
...
...
paddle/operators/uniform_random_op.cc
浏览文件 @
f2442be9
...
@@ -50,7 +50,7 @@ class UniformRandomOp : public framework::OperatorWithKernel {
...
@@ -50,7 +50,7 @@ class UniformRandomOp : public framework::OperatorWithKernel {
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
void
InferShape
(
const
framework
::
InferShapeContext
&
ctx
)
const
override
{
PADDLE_ENFORCE
(
Attr
<
float
>
(
"min"
)
<
Attr
<
float
>
(
"max"
),
PADDLE_ENFORCE
(
Attr
<
float
>
(
"min"
)
<
Attr
<
float
>
(
"max"
),
"uniform_random's min must less then max"
);
"uniform_random's min must less then max"
);
auto
*
tensor
=
ctx
.
Output
<
framework
::
Tensor
>
(
"Out"
);
auto
*
tensor
=
ctx
.
Output
<
framework
::
LoD
Tensor
>
(
"Out"
);
auto
dims
=
Attr
<
std
::
vector
<
int
>>
(
"dims"
);
auto
dims
=
Attr
<
std
::
vector
<
int
>>
(
"dims"
);
std
::
vector
<
int64_t
>
temp
;
std
::
vector
<
int64_t
>
temp
;
temp
.
reserve
(
dims
.
size
());
temp
.
reserve
(
dims
.
size
());
...
...
paddle/pybind/pybind.cc
浏览文件 @
f2442be9
...
@@ -23,6 +23,7 @@ limitations under the License. */
...
@@ -23,6 +23,7 @@ limitations under the License. */
#include "paddle/operators/recurrent_op.h"
#include "paddle/operators/recurrent_op.h"
#include "paddle/platform/enforce.h"
#include "paddle/platform/enforce.h"
#include "paddle/platform/place.h"
#include "paddle/platform/place.h"
#include "paddle/pybind/pybind.h"
#include "paddle/pybind/tensor_py.h"
#include "paddle/pybind/tensor_py.h"
#include "paddle/string/to_string.h"
#include "paddle/string/to_string.h"
#include "pybind11/numpy.h"
#include "pybind11/numpy.h"
...
@@ -31,35 +32,6 @@ limitations under the License. */
...
@@ -31,35 +32,6 @@ limitations under the License. */
namespace
py
=
pybind11
;
namespace
py
=
pybind11
;
USE_OP
(
add
);
USE_OP
(
onehot_cross_entropy
);
USE_OP
(
sgd
);
USE_OP
(
mul
);
USE_OP
(
elementwise_mul
);
USE_OP
(
mean
);
USE_OP
(
sigmoid
);
USE_OP
(
softmax
);
USE_OP
(
rowwise_add
);
USE_OP
(
fill_zeros_like
);
USE_NO_KERNEL_OP
(
recurrent
);
USE_OP
(
gaussian_random
);
USE_OP
(
uniform_random
);
USE_OP
(
lookup_table
);
USE_OP
(
scale
);
USE_NO_KERNEL_OP
(
identity
);
USE_OP
(
minus
);
USE_OP
(
cos_sim
);
USE_CPU_ONLY_OP
(
gather
);
USE_OP
(
pad
);
USE_CPU_ONLY_OP
(
scatter
);
USE_OP
(
accuracy
);
USE_CPU_ONLY_OP
(
concat
);
USE_OP
(
top_k
);
USE_OP
(
squared_l2_distance
);
USE_OP
(
sum
);
USE_OP
(
reshape
);
USE_OP
(
rank_loss
);
namespace
paddle
{
namespace
paddle
{
namespace
framework
{
namespace
framework
{
...
@@ -125,27 +97,21 @@ PYBIND11_PLUGIN(core) {
...
@@ -125,27 +97,21 @@ PYBIND11_PLUGIN(core) {
return
self
.
data
<
float
>
()[
offset
];
return
self
.
data
<
float
>
()[
offset
];
});
});
py
::
class_
<
LoDTensor
>
(
m
,
"LoDTensor"
,
R"DOC(LoD(Leval of Ddetails) Tensor.
py
::
class_
<
LoDTensor
,
Tensor
>
(
m
,
"LoDTensor"
)
.
def_buffer
(
The tensor and LoD info should be created before creating the LoDTensor, then
[](
Tensor
&
self
)
->
py
::
buffer_info
{
return
CastToPyBuffer
(
self
);
})
call the set_tensor and set_lod functions to set them.
.
def
(
"__init__"
,
)DOC"
)
[](
LoDTensor
&
instance
,
const
std
::
vector
<
std
::
vector
<
size_t
>>
&
lod
)
{
.
def
(
"__init__"
,
[](
LoDTensor
&
instance
,
const
std
::
vector
<
std
::
vector
<
size_t
>>
&
lod
,
Tensor
*
t
)
{
#ifdef PADDLE_ONLY_CPU
#ifdef PADDLE_ONLY_CPU
new
(
&
instance
)
LoDTensor
(
lod
,
t
);
new
(
&
instance
)
LoDTensor
(
lod
);
#else
#else
paddle
::
framework
::
LoD
new_lod
;
paddle
::
framework
::
LoD
new_lod
;
new_lod
.
reserve
(
lod
.
size
());
new_lod
.
reserve
(
lod
.
size
());
std
::
copy
(
lod
.
begin
(),
lod
.
end
(),
std
::
back_inserter
(
new_lod
));
std
::
copy
(
lod
.
begin
(),
lod
.
end
(),
std
::
back_inserter
(
new_lod
));
new
(
&
instance
)
LoDTensor
(
new_lod
,
t
);
new
(
&
instance
)
LoDTensor
(
new_lod
);
#endif
#endif
})
})
.
def
(
"set_tensor"
,
[](
LoDTensor
&
self
,
Tensor
*
tensor
)
{
self
.
set_tensor
(
tensor
);
})
.
def
(
"set_lod"
,
.
def
(
"set_lod"
,
[](
LoDTensor
&
self
,
const
std
::
vector
<
std
::
vector
<
size_t
>>
&
lod
)
{
[](
LoDTensor
&
self
,
const
std
::
vector
<
std
::
vector
<
size_t
>>
&
lod
)
{
#ifdef PADDLE_ONLY_CPU
#ifdef PADDLE_ONLY_CPU
...
@@ -157,9 +123,6 @@ call the set_tensor and set_lod functions to set them.
...
@@ -157,9 +123,6 @@ call the set_tensor and set_lod functions to set them.
self
.
set_lod
(
new_lod
);
self
.
set_lod
(
new_lod
);
#endif
#endif
})
})
.
def
(
"tensor"
,
[](
LoDTensor
&
self
)
->
Tensor
&
{
return
self
.
tensor
();
},
py
::
return_value_policy
::
reference
)
.
def
(
"lod"
,
[](
LoDTensor
&
self
)
->
std
::
vector
<
std
::
vector
<
size_t
>>
{
.
def
(
"lod"
,
[](
LoDTensor
&
self
)
->
std
::
vector
<
std
::
vector
<
size_t
>>
{
#ifdef PADDLE_ONLY_CPU
#ifdef PADDLE_ONLY_CPU
return
self
.
lod
();
return
self
.
lod
();
...
@@ -188,9 +151,6 @@ All parameter, weight, gradient are variables in Paddle.
...
@@ -188,9 +151,6 @@ All parameter, weight, gradient are variables in Paddle.
[](
Variable
&
var
,
int
val
)
->
void
{
*
var
.
GetMutable
<
int
>
()
=
val
;
})
[](
Variable
&
var
,
int
val
)
->
void
{
*
var
.
GetMutable
<
int
>
()
=
val
;
})
.
def
(
"get_int"
,
[](
const
Variable
&
var
)
->
int
{
return
var
.
Get
<
int
>
();
})
.
def
(
"get_int"
,
[](
const
Variable
&
var
)
->
int
{
return
var
.
Get
<
int
>
();
})
.
def
(
"get_tensor"
,
.
def
(
"get_tensor"
,
[](
Variable
&
self
)
->
Tensor
*
{
return
self
.
GetMutable
<
Tensor
>
();
},
py
::
return_value_policy
::
reference
)
.
def
(
"get_lod_tensor"
,
[](
Variable
&
self
)
->
LoDTensor
*
{
[](
Variable
&
self
)
->
LoDTensor
*
{
return
self
.
GetMutable
<
LoDTensor
>
();
return
self
.
GetMutable
<
LoDTensor
>
();
},
},
...
...
python/paddle/trainer/config_parser.py
浏览文件 @
f2442be9
...
@@ -2055,20 +2055,26 @@ class ConvLayerBase(LayerBase):
...
@@ -2055,20 +2055,26 @@ class ConvLayerBase(LayerBase):
if
num_filters
is
not
None
:
if
num_filters
is
not
None
:
self
.
config
.
num_filters
=
num_filters
self
.
config
.
num_filters
=
num_filters
use_mkldnn
=
int
(
g_command_config_args
.
get
(
"use_mkldnn"
,
0
))
use_gpu
=
int
(
g_command_config_args
.
get
(
"use_gpu"
,
0
))
use_gpu
=
int
(
g_command_config_args
.
get
(
"use_gpu"
,
0
))
parallel_nn
=
int
(
g_command_config_args
.
get
(
"parallel_nn"
,
0
))
parallel_nn
=
int
(
g_command_config_args
.
get
(
"parallel_nn"
,
0
))
# Automatically select cudnn_type for GPU and exconv for CPU
# Automatically select cudnn_type for GPU, exconv for CPU
# and mkldnn_conv for MKLDNN
# if set type=conv, but still reserve the way user specify
# if set type=conv, but still reserve the way user specify
# exconv or cudnn_conv manually.
# exconv
, mkldnn_conv
or cudnn_conv manually.
if
self
.
layer_type
==
"cudnn_conv"
:
if
self
.
layer_type
==
"cudnn_conv"
:
config_assert
(
use_gpu
,
"cudnn_conv only support GPU"
)
config_assert
(
use_gpu
,
"cudnn_conv only support GPU"
)
if
self
.
layer_type
==
"mkldnn_conv"
:
config_assert
(
use_mkldnn
,
"mkldnn_conv only support MKLDNN"
)
if
(
use_gpu
==
1
and
self
.
layer_type
!=
"exconv"
and
if
(
use_gpu
==
1
and
self
.
layer_type
!=
"exconv"
and
self
.
layer_type
!=
"mkldnn_conv"
and
(
parallel_nn
==
0
or
self
.
config
.
device
>
-
1
)):
(
parallel_nn
==
0
or
self
.
config
.
device
>
-
1
)):
self
.
layer_type
=
"cudnn_conv"
self
.
layer_type
=
"cudnn_conv"
else
:
else
:
self
.
layer_type
=
"exconv"
self
.
layer_type
=
"
mkldnn_conv"
if
use_mkldnn
else
"
exconv"
# need to specify layer in config
# need to specify layer in config
self
.
config
.
type
=
self
.
layer_type
self
.
config
.
type
=
self
.
layer_type
...
@@ -2100,6 +2106,11 @@ class ConvLayer(ConvLayerBase):
...
@@ -2100,6 +2106,11 @@ class ConvLayer(ConvLayerBase):
layer_type
=
'exconv'
layer_type
=
'exconv'
@
config_layer
(
'mkldnn_conv'
)
class
ConvLayer
(
ConvLayerBase
):
layer_type
=
'mkldnn_conv'
@
config_layer
(
'cudnn_conv'
)
@
config_layer
(
'cudnn_conv'
)
class
ConvLayer
(
ConvLayerBase
):
class
ConvLayer
(
ConvLayerBase
):
layer_type
=
'cudnn_conv'
layer_type
=
'cudnn_conv'
...
...
python/paddle/v2/framework/tests/test_cross_entropy_op.py
浏览文件 @
f2442be9
...
@@ -8,20 +8,22 @@ class TestCrossEntropy(OpTest):
...
@@ -8,20 +8,22 @@ class TestCrossEntropy(OpTest):
self
.
op_type
=
"onehot_cross_entropy"
self
.
op_type
=
"onehot_cross_entropy"
batch_size
=
30
batch_size
=
30
class_num
=
10
class_num
=
10
X
=
numpy
.
random
.
uniform
(
0.1
,
1.0
,
X
=
numpy
.
random
.
uniform
(
0.1
,
1.0
,
[
batch_size
,
class_num
]).
astype
(
"float32"
)
[
batch_size
,
class_num
]).
astype
(
"float32"
)
label
=
(
class_num
/
2
)
*
numpy
.
ones
(
batch_size
).
astype
(
"int32"
)
labels
=
numpy
.
random
.
randint
(
0
,
class_num
,
batch_size
,
dtype
=
"int32"
)
self
.
inputs
=
{
'X'
:
X
,
'label'
:
label
}
Y
=
[]
cross_entropy
=
numpy
.
asmatrix
(
for
i
in
range
(
0
,
batch_size
):
[[
-
numpy
.
log
(
X
[
i
][
labels
[
i
]])]
for
i
in
range
(
X
.
shape
[
0
])],
Y
.
append
(
-
numpy
.
log
(
X
[
i
][
label
[
i
]]))
dtype
=
"float32"
)
self
.
outputs
=
{
'Y'
:
numpy
.
array
(
Y
).
astype
(
"float32"
)}
self
.
inputs
=
{
"X"
:
X
,
"label"
:
labels
}
self
.
outputs
=
{
"Y"
:
cross_entropy
}
def
test_check_output
(
self
):
def
test_check_output
(
self
):
self
.
check_output
()
self
.
check_output
()
def
test_check_grad
(
self
):
def
test_check_grad
(
self
):
self
.
check_grad
([
'X'
],
'Y'
)
self
.
check_grad
([
"X"
],
"Y"
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
...
...
python/paddle/v2/framework/tests/test_tensor.py
浏览文件 @
f2442be9
...
@@ -44,79 +44,66 @@ class TestTensor(unittest.TestCase):
...
@@ -44,79 +44,66 @@ class TestTensor(unittest.TestCase):
self
.
assertAlmostEqual
(
2.0
,
tensor_array_2
[
19
,
11
])
self
.
assertAlmostEqual
(
2.0
,
tensor_array_2
[
19
,
11
])
def
test_int_lod_tensor
(
self
):
def
test_int_lod_tensor
(
self
):
places
=
[
core
.
CPUPlace
(),
core
.
GPUPlace
(
0
)]
place
=
core
.
CPUPlace
()
for
place
in
places
:
scope
=
core
.
Scope
()
scope
=
core
.
Scope
()
var_lod
=
scope
.
new_var
(
"test_lod_tensor"
)
var
=
scope
.
new_var
(
"test_tensor"
)
lod_tensor
=
var_lod
.
get_tensor
()
var_lod
=
scope
.
new_var
(
"test_lod_tensor"
)
tensor
=
var
.
get_tensor
()
lod_tensor
=
var_lod
.
get_lod_tensor
()
tensor
.
set_dims
([
4
,
4
,
6
])
tensor
.
alloc_int
(
place
)
array
=
numpy
.
array
(
tensor
)
array
[
0
,
0
,
0
]
=
3
array
[
3
,
3
,
5
]
=
10
tensor
.
set
(
array
,
place
)
lod_tensor
.
set_tensor
(
tensor
)
lod_tensor
.
set_dims
([
4
,
4
,
6
])
lod_tensor
.
set_lod
([[
0
,
2
,
4
]])
lod_tensor
.
alloc_int
(
place
)
array
=
numpy
.
array
(
lod_tensor
)
array
[
0
,
0
,
0
]
=
3
array
[
3
,
3
,
5
]
=
10
lod_tensor
.
set
(
array
,
place
)
lod_tensor
.
set_lod
([[
0
,
2
,
4
]])
lod_v
=
numpy
.
array
(
lod_tensor
.
tensor
()
)
lod_v
=
numpy
.
array
(
lod_tensor
)
self
.
assertTrue
(
numpy
.
alltrue
(
array
==
lod_v
))
self
.
assertTrue
(
numpy
.
alltrue
(
array
==
lod_v
))
lod
=
lod_tensor
.
lod
()
lod
=
lod_tensor
.
lod
()
self
.
assertEqual
(
0
,
lod
[
0
][
0
])
self
.
assertEqual
(
0
,
lod
[
0
][
0
])
self
.
assertEqual
(
2
,
lod
[
0
][
1
])
self
.
assertEqual
(
2
,
lod
[
0
][
1
])
self
.
assertEqual
(
4
,
lod
[
0
][
2
])
self
.
assertEqual
(
4
,
lod
[
0
][
2
])
def
test_float_lod_tensor
(
self
):
def
test_float_lod_tensor
(
self
):
places
=
[
core
.
CPUPlace
(),
core
.
GPUPlace
(
0
)]
place
=
core
.
CPUPlace
()
for
place
in
places
:
scope
=
core
.
Scope
()
scope
=
core
.
Scope
()
var_lod
=
scope
.
new_var
(
"test_lod_tensor"
)
var
=
scope
.
new_var
(
"test_tensor"
)
var_lod
=
scope
.
new_var
(
"test_lod_tensor"
)
tensor
=
var
.
get_tensor
()
lod_tensor
=
var_lod
.
get_lod_tensor
()
tensor
.
set_dims
([
5
,
2
,
3
,
4
])
tensor
.
alloc_float
(
place
)
tensor_array
=
numpy
.
array
(
tensor
)
lod_tensor
=
var_lod
.
get_tensor
()
self
.
assertEqual
((
5
,
2
,
3
,
4
),
tensor_array
.
shape
)
lod_tensor
.
set_dims
([
5
,
2
,
3
,
4
])
tensor_array
[
0
,
0
,
0
,
0
]
=
1.0
lod_tensor
.
alloc_float
(
place
)
tensor_array
[
0
,
0
,
0
,
1
]
=
2.0
tensor
.
set
(
tensor_array
,
place
)
lod_tensor
.
set_tensor
(
tensor
)
tensor_array
=
numpy
.
array
(
lod_tensor
)
self
.
assertEqual
((
5
,
2
,
3
,
4
),
tensor_array
.
shape
)
tensor_array
[
0
,
0
,
0
,
0
]
=
1.0
tensor_array
[
0
,
0
,
0
,
1
]
=
2.0
lod_tensor
.
set
(
tensor_array
,
place
)
lod_v
=
numpy
.
array
(
lod_tensor
.
tensor
()
)
lod_v
=
numpy
.
array
(
lod_tensor
)
self
.
assertAlmostEqual
(
1.0
,
lod_v
[
0
,
0
,
0
,
0
])
self
.
assertAlmostEqual
(
1.0
,
lod_v
[
0
,
0
,
0
,
0
])
self
.
assertAlmostEqual
(
2.0
,
lod_v
[
0
,
0
,
0
,
1
])
self
.
assertAlmostEqual
(
2.0
,
lod_v
[
0
,
0
,
0
,
1
])
self
.
assertEqual
(
len
(
lod_tensor
.
lod
()),
0
)
self
.
assertEqual
(
len
(
lod_tensor
.
lod
()),
0
)
lod_py
=
[[
0
,
2
,
5
],
[
0
,
2
,
4
,
5
]]
lod_py
=
[[
0
,
2
,
5
],
[
0
,
2
,
4
,
5
]]
lod_tensor
.
set_lod
(
lod_py
)
lod_tensor
.
set_lod
(
lod_py
)
lod
=
lod_tensor
.
lod
()
lod
=
lod_tensor
.
lod
()
self
.
assertListEqual
(
lod_py
,
lod
)
self
.
assertListEqual
(
lod_py
,
lod
)
def
test_lod_tensor_init
(
self
):
def
test_lod_tensor_init
(
self
):
scope
=
core
.
Scope
()
scope
=
core
.
Scope
()
var
=
scope
.
new_var
(
"test_tensor"
)
place
=
core
.
CPUPlace
()
place
=
core
.
CPUPlace
()
tensor
=
var
.
get_tensor
()
lod_py
=
[[
0
,
2
,
5
],
[
0
,
2
,
4
,
5
]]
tensor
.
set_dims
([
5
,
2
,
3
,
4
])
lod_tensor
=
core
.
LoDTensor
(
lod_py
)
tensor
.
alloc_float
(
place
)
tensor_array
=
numpy
.
array
(
tensor
)
lod_tensor
.
set_dims
([
5
,
2
,
3
,
4
])
lod_tensor
.
alloc_float
(
place
)
tensor_array
=
numpy
.
array
(
lod_tensor
)
tensor_array
[
0
,
0
,
0
,
0
]
=
1.0
tensor_array
[
0
,
0
,
0
,
0
]
=
1.0
tensor_array
[
0
,
0
,
0
,
1
]
=
2.0
tensor_array
[
0
,
0
,
0
,
1
]
=
2.0
tensor
.
set
(
tensor_array
,
place
)
lod_tensor
.
set
(
tensor_array
,
place
)
lod_py
=
[[
0
,
2
,
5
],
[
0
,
2
,
4
,
5
]]
lod_tensor
=
core
.
LoDTensor
(
lod_py
,
tensor
)
lod_v
=
numpy
.
array
(
lod_tensor
)
lod_v
=
numpy
.
array
(
lod_tensor
.
tensor
())
self
.
assertAlmostEqual
(
1.0
,
lod_v
[
0
,
0
,
0
,
0
])
self
.
assertAlmostEqual
(
1.0
,
lod_v
[
0
,
0
,
0
,
0
])
self
.
assertAlmostEqual
(
2.0
,
lod_v
[
0
,
0
,
0
,
1
])
self
.
assertAlmostEqual
(
2.0
,
lod_v
[
0
,
0
,
0
,
1
])
self
.
assertListEqual
(
lod_py
,
lod_tensor
.
lod
())
self
.
assertListEqual
(
lod_py
,
lod_tensor
.
lod
())
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录