Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
Paddle
提交
c92348c3
P
Paddle
项目概览
BaiXuePrincess
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
c92348c3
编写于
9月 28, 2019
作者:
L
lvmengsi
提交者:
GitHub
9月 28, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix conv_grad_grad (#20054)
上级
4e99c2af
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
63 addition
and
53 deletion
+63
-53
paddle/fluid/operators/conv_cudnn_op.cu.cc
paddle/fluid/operators/conv_cudnn_op.cu.cc
+27
-22
paddle/fluid/operators/conv_op.cc
paddle/fluid/operators/conv_op.cc
+10
-7
paddle/fluid/operators/conv_op.h
paddle/fluid/operators/conv_op.h
+26
-24
未找到文件。
paddle/fluid/operators/conv_cudnn_op.cu.cc
浏览文件 @
c92348c3
...
...
@@ -355,15 +355,17 @@ class CUDNNConvDoubleGradOpKernel : public framework::OpKernel<T> {
size_t
workspace_size
=
0
;
if
(
ddO
)
{
ddy
=
ddO
->
mutable_data
<
T
>
(
ctx
.
GetPlace
());
args1
.
handle
=
handle
;
args1
.
idesc
.
set
(
*
ddX
,
iwo_group
);
args1
.
wdesc
.
set
(
*
W
,
layout
,
iwo_group
);
args1
.
odesc
.
set
(
*
ddO
,
iwo_group
);
args1
.
cdesc
.
set
(
dtype
,
paddings
,
strides
,
dilations
,
c_group
);
using
search1
=
SearchAlgorithm
<
cudnnConvolutionFwdAlgoPerf_t
>
;
fwd_algo1
=
search1
::
Find
<
T
>
(
args1
,
exhaustive_search
,
false
,
0
,
ctx
);
workspace_size
=
search1
::
GetWorkspaceSize
(
args1
,
fwd_algo1
);
if
(
ddX
)
{
args1
.
handle
=
handle
;
args1
.
idesc
.
set
(
*
ddX
,
iwo_group
);
args1
.
wdesc
.
set
(
*
W
,
layout
,
iwo_group
);
args1
.
odesc
.
set
(
*
ddO
,
iwo_group
);
args1
.
cdesc
.
set
(
dtype
,
paddings
,
strides
,
dilations
,
c_group
);
using
search1
=
SearchAlgorithm
<
cudnnConvolutionFwdAlgoPerf_t
>
;
fwd_algo1
=
search1
::
Find
<
T
>
(
args1
,
exhaustive_search
,
false
,
0
,
ctx
);
workspace_size
=
search1
::
GetWorkspaceSize
(
args1
,
fwd_algo1
);
}
if
(
ddW
)
{
ddw
=
ddW
->
data
<
T
>
();
...
...
@@ -380,7 +382,7 @@ class CUDNNConvDoubleGradOpKernel : public framework::OpKernel<T> {
}
}
if
(
dW
)
{
if
(
dW
&&
ddX
)
{
dw
=
dW
->
mutable_data
<
T
>
(
ctx
.
GetPlace
());
args3
.
handle
=
handle
;
args3
.
idesc
.
set
(
*
ddX
,
iwo_group
);
...
...
@@ -423,17 +425,20 @@ class CUDNNConvDoubleGradOpKernel : public framework::OpKernel<T> {
auto
wkspace_handle
=
dev_ctx
.
cudnn_workspace_handle
();
if
(
ddO
)
{
ddx
=
ddX
->
data
<
T
>
();
for
(
int
i
=
0
;
i
<
groups
;
i
++
)
{
wkspace_handle
.
RunFunc
(
[
&
](
void
*
workspace_ptr
)
{
CUDNN_ENFORCE
(
platform
::
dynload
::
cudnnConvolutionForward
(
handle
,
&
alpha
,
args1
.
idesc
.
desc
(),
ddx
+
i
*
group_offset_in
,
args1
.
wdesc
.
desc
(),
w
+
i
*
group_offset_filter
,
args1
.
cdesc
.
desc
(),
fwd_algo1
,
workspace_ptr
,
workspace_size
,
&
beta
,
args1
.
odesc
.
desc
(),
ddy
+
i
*
group_offset_out
));
},
workspace_size
);
if
(
ddX
)
{
ddx
=
ddX
->
data
<
T
>
();
for
(
int
i
=
0
;
i
<
groups
;
i
++
)
{
wkspace_handle
.
RunFunc
(
[
&
](
void
*
workspace_ptr
)
{
CUDNN_ENFORCE
(
platform
::
dynload
::
cudnnConvolutionForward
(
handle
,
&
alpha
,
args1
.
idesc
.
desc
(),
ddx
+
i
*
group_offset_in
,
args1
.
wdesc
.
desc
(),
w
+
i
*
group_offset_filter
,
args1
.
cdesc
.
desc
(),
fwd_algo1
,
workspace_ptr
,
workspace_size
,
&
beta
,
args1
.
odesc
.
desc
(),
ddy
+
i
*
group_offset_out
));
},
workspace_size
);
}
}
if
(
ddW
)
{
for
(
int
i
=
0
;
i
<
groups
;
i
++
)
{
...
...
@@ -451,7 +456,7 @@ class CUDNNConvDoubleGradOpKernel : public framework::OpKernel<T> {
}
}
if
(
dW
)
{
if
(
dW
&&
ddX
)
{
ddx
=
ddX
->
data
<
T
>
();
for
(
int
i
=
0
;
i
<
groups
;
i
++
)
{
wkspace_handle
.
RunFunc
(
...
...
paddle/fluid/operators/conv_op.cc
浏览文件 @
c92348c3
...
...
@@ -553,9 +553,10 @@ class Conv2DDoubleGradMaker : public framework::SingleGradOpDescMaker {
auto
ddw
=
OutputGrad
(
framework
::
GradVarName
(
"Filter"
));
std
::
vector
<
std
::
string
>
empty_str
=
{};
op
->
SetOutput
(
"DDOutput"
,
ddx
.
empty
()
?
empty_str
:
InputGrad
(
framework
::
GradVarName
(
"Output"
)));
op
->
SetOutput
(
"DDOutput"
,
(
ddx
.
empty
()
&&
ddw
.
empty
())
?
empty_str
:
InputGrad
(
framework
::
GradVarName
(
"Output"
)));
op
->
SetOutput
(
"DFilter"
,
ddx
.
empty
()
?
empty_str
:
InputGrad
(
"Filter"
));
op
->
SetOutput
(
"DInput"
,
ddw
.
empty
()
?
empty_str
:
InputGrad
(
"Input"
));
...
...
@@ -587,9 +588,10 @@ class Conv3DDoubleGradMaker : public framework::SingleGradOpDescMaker {
auto
ddw
=
OutputGrad
(
framework
::
GradVarName
(
"Filter"
));
std
::
vector
<
std
::
string
>
empty_str
=
{};
op
->
SetOutput
(
"DDOutput"
,
ddx
.
empty
()
?
empty_str
:
InputGrad
(
framework
::
GradVarName
(
"Output"
)));
op
->
SetOutput
(
"DDOutput"
,
(
ddx
.
empty
()
&&
ddw
.
empty
())
?
empty_str
:
InputGrad
(
framework
::
GradVarName
(
"Output"
)));
op
->
SetOutput
(
"DFilter"
,
ddx
.
empty
()
?
empty_str
:
InputGrad
(
"Filter"
));
op
->
SetOutput
(
"DInput"
,
ddw
.
empty
()
?
empty_str
:
InputGrad
(
"Input"
));
...
...
@@ -604,7 +606,8 @@ void ConvOpDoubleGrad::InferShape(framework::InferShapeContext* ctx) const {
auto
w_dims
=
ctx
->
GetInputDim
(
"Filter"
);
auto
do_dims
=
ctx
->
GetInputDim
(
"DOutput"
);
if
(
ctx
->
HasOutput
(
"DDOutput"
)
&&
ctx
->
HasInput
(
"DDInput"
))
{
if
(
ctx
->
HasOutput
(
"DDOutput"
)
&&
(
ctx
->
HasInput
(
"DDInput"
)
||
(
ctx
->
HasInput
(
"DDFilter"
))))
{
ctx
->
SetOutputDim
(
"DDOutput"
,
do_dims
);
}
if
(
ctx
->
HasOutput
(
"DFilter"
)
&&
ctx
->
HasInput
(
"DDInput"
))
{
...
...
paddle/fluid/operators/conv_op.h
浏览文件 @
c92348c3
...
...
@@ -506,7 +506,7 @@ class GemmConvDoubleGradKernel : public framework::OpKernel<T> {
// dw = ddx * dy ==> dw(Cout, Cin, kh, kw), ddx(N, Cin, H, W), dy(N, Cout,
// oH, oW)
// dw convolution double grad: im2col(vol2col) + gemm
if
(
dW
)
{
if
(
dW
&&
ddX
)
{
dW
->
mutable_data
<
T
>
(
ctx
.
GetPlace
());
set_zero
(
dev_ctx
,
dW
,
static_cast
<
T
>
(
0
));
Tensor
dW_arr
=
*
dW
;
...
...
@@ -549,36 +549,38 @@ class GemmConvDoubleGradKernel : public framework::OpKernel<T> {
math
::
Im2ColFunctor
<
math
::
ColFormat
::
kCFO
,
DeviceContext
,
T
>
im2col
;
math
::
Vol2ColFunctor
<
DeviceContext
,
T
>
vol2col
;
for
(
int
i
=
0
;
i
<
batch_size
;
++
i
)
{
Tensor
ddx_batch
=
ddX
->
Slice
(
i
,
i
+
1
).
Resize
(
input_shape
);
Tensor
x_batch
=
X
->
Slice
(
i
,
i
+
1
).
Resize
(
input_shape
);
Tensor
ddy_batch
=
ddY
->
Slice
(
i
,
i
+
1
).
Resize
(
output_matrix_shape
);
for
(
int
g
=
0
;
g
<
groups
;
++
g
)
{
Tensor
x_slice
=
x_batch
.
Slice
(
g
*
in_step
,
(
g
+
1
)
*
in_step
);
Tensor
ddx_slice
=
ddx_batch
.
Slice
(
g
*
in_step
,
(
g
+
1
)
*
in_step
);
if
(
!
is_expand
)
{
col
.
ShareDataWith
(
ddx_slice
);
col_matrix
.
ShareDataWith
(
col
);
col_matrix
.
Resize
(
col_matrix_shape
);
}
else
if
(
data_dim
==
2U
)
{
// im2col
im2col
(
dev_ctx
,
ddx_slice
,
dilations
,
strides
,
std
::
vector
<
int
>
{
paddings
[
0
],
paddings
[
1
],
paddings
[
0
],
paddings
[
1
]},
&
col
);
}
else
if
(
data_dim
==
3U
)
{
// vol2col
vol2col
(
dev_ctx
,
ddx_slice
,
dilations
,
strides
,
paddings
,
&
col
);
}
// gemm
Tensor
ddy_slice
=
ddy_batch
.
Slice
(
g
*
out_step
,
(
g
+
1
)
*
out_step
);
Tensor
w_slice
=
W
.
Slice
(
g
*
out_step
,
(
g
+
1
)
*
out_step
);
blas
.
MatMul
(
w_slice
,
false
,
col_matrix
,
false
,
T
(
1.0
),
&
ddy_slice
,
T
(
0.0
));
if
(
ddX
)
{
Tensor
ddx_batch
=
ddX
->
Slice
(
i
,
i
+
1
).
Resize
(
input_shape
);
Tensor
ddx_slice
=
ddx_batch
.
Slice
(
g
*
in_step
,
(
g
+
1
)
*
in_step
);
if
(
!
is_expand
)
{
col
.
ShareDataWith
(
ddx_slice
);
col_matrix
.
ShareDataWith
(
col
);
col_matrix
.
Resize
(
col_matrix_shape
);
}
else
if
(
data_dim
==
2U
)
{
// im2col
im2col
(
dev_ctx
,
ddx_slice
,
dilations
,
strides
,
std
::
vector
<
int
>
{
paddings
[
0
],
paddings
[
1
],
paddings
[
0
],
paddings
[
1
]},
&
col
);
}
else
if
(
data_dim
==
3U
)
{
// vol2col
vol2col
(
dev_ctx
,
ddx_slice
,
dilations
,
strides
,
paddings
,
&
col
);
}
// gemm
Tensor
w_slice
=
W
.
Slice
(
g
*
out_step
,
(
g
+
1
)
*
out_step
);
blas
.
MatMul
(
w_slice
,
false
,
col_matrix
,
false
,
T
(
1.0
),
&
ddy_slice
,
T
(
0.0
));
}
if
(
ddW_in
)
{
Tensor
ddW
;
ddW
.
ShareDataWith
(
*
ddW_in
).
Resize
(
filter_matrix_shape
);
Tensor
x_batch
=
X
->
Slice
(
i
,
i
+
1
).
Resize
(
input_shape
);
Tensor
x_slice
=
x_batch
.
Slice
(
g
*
in_step
,
(
g
+
1
)
*
in_step
);
if
(
!
is_expand
)
{
col
.
ShareDataWith
(
x_slice
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录