Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
69827f30
P
Paddle
项目概览
Crayon鑫
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
69827f30
编写于
6月 19, 2018
作者:
Q
Qiao Longfei
提交者:
GitHub
6月 19, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #11527 from jacquesqiao/concat-grad-support-data-input
concat support data as input
上级
210790d8
ad1ad738
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
68 addition
and
42 deletion
+68
-42
paddle/fluid/operators/concat_op.h
paddle/fluid/operators/concat_op.h
+26
-15
paddle/fluid/operators/math/concat.cc
paddle/fluid/operators/math/concat.cc
+15
-10
paddle/fluid/operators/math/concat.cu
paddle/fluid/operators/math/concat.cu
+25
-16
paddle/fluid/operators/math/concat.h
paddle/fluid/operators/math/concat.h
+2
-1
未找到文件。
paddle/fluid/operators/concat_op.h
浏览文件 @
69827f30
...
...
@@ -60,34 +60,45 @@ template <typename DeviceContext, typename T>
class
ConcatGradKernel
:
public
framework
::
OpKernel
<
T
>
{
public:
void
Compute
(
const
framework
::
ExecutionContext
&
ctx
)
const
{
auto
*
in
=
ctx
.
Input
<
framework
::
Tensor
>
(
framework
::
GradVarName
(
"Out"
));
auto
*
out_grad
=
ctx
.
Input
<
framework
::
Tensor
>
(
framework
::
GradVarName
(
"Out"
));
auto
ins
=
ctx
.
MultiInput
<
framework
::
Tensor
>
(
"X"
);
auto
out_var_names
=
ctx
.
Outputs
(
framework
::
GradVarName
(
"X"
));
auto
outs
=
ctx
.
MultiOutput
<
framework
::
Tensor
>
(
framework
::
GradVarName
(
"X"
));
int64_t
axis
=
static_cast
<
int64_t
>
(
ctx
.
Attr
<
int
>
(
"axis"
));
// get output tensor that the name is not kEmptyVarName
std
::
vector
<
framework
::
Tensor
*>
outputs
;
for
(
size_t
j
=
0
;
j
<
outs
.
size
();
++
j
)
{
if
(
out_var_names
[
j
]
!=
framework
::
kEmptyVarName
)
{
outs
[
j
]
->
mutable_data
<
T
>
(
ctx
.
GetPlace
());
outputs
.
push_back
(
outs
[
j
]);
}
else
{
outputs
.
push_back
(
nullptr
);
}
}
// Sometimes direct copies will be faster, this maybe need deeply analysis.
if
(
axis
==
0
&&
outs
.
size
()
<
10
)
{
size_t
input_offset
=
0
;
auto
in_stride
=
framework
::
stride_numel
(
in
->
dims
());
const
auto
in_stride
=
framework
::
stride_numel
(
out_grad
->
dims
());
for
(
auto
&
out
:
outs
)
{
out
->
mutable_data
<
T
>
(
ctx
.
GetPlace
());
auto
out_stride
=
framework
::
stride_numel
(
out
->
dims
());
StridedNumelCopyWithAxis
<
T
>
(
ctx
.
device_context
(),
axis
,
out
->
data
<
T
>
(),
out_stride
,
in
->
data
<
T
>
()
+
input_offset
,
in_stride
,
out_stride
[
axis
]);
for
(
size_t
i
=
0
;
i
<
outs
.
size
();
++
i
)
{
auto
out_stride
=
framework
::
stride_numel
(
ins
[
i
]
->
dims
());
auto
*
out
=
outputs
[
i
];
if
(
out
!=
nullptr
)
{
StridedNumelCopyWithAxis
<
T
>
(
ctx
.
device_context
(),
axis
,
out
->
data
<
T
>
(),
out_stride
,
out_grad
->
data
<
T
>
()
+
input_offset
,
in_stride
,
out_stride
[
axis
]);
}
input_offset
+=
out_stride
[
axis
];
}
}
else
{
std
::
vector
<
framework
::
Tensor
>
outputs
(
outs
.
size
());
for
(
size_t
j
=
0
;
j
<
outs
.
size
();
++
j
)
{
outs
[
j
]
->
mutable_data
<
T
>
(
ctx
.
GetPlace
());
outputs
[
j
]
=
*
outs
[
j
];
}
auto
&
dev_ctx
=
ctx
.
template
device_context
<
DeviceContext
>();
paddle
::
operators
::
math
::
ConcatGradFunctor
<
DeviceContext
,
T
>
concat_grad_functor
;
concat_grad_functor
(
dev_ctx
,
*
in
,
static_cast
<
int
>
(
axis
),
&
outputs
);
concat_grad_functor
(
dev_ctx
,
*
out_grad
,
ins
,
static_cast
<
int
>
(
axis
),
&
outputs
);
}
}
};
...
...
paddle/fluid/operators/math/concat.cc
浏览文件 @
69827f30
...
...
@@ -70,35 +70,40 @@ template <typename T>
class
ConcatGradFunctor
<
platform
::
CPUDeviceContext
,
T
>
{
public:
void
operator
()(
const
platform
::
CPUDeviceContext
&
context
,
const
framework
::
Tensor
&
input
,
const
int
axis
,
std
::
vector
<
framework
::
Tensor
>*
outputs
)
{
const
framework
::
Tensor
&
input
,
const
std
::
vector
<
const
framework
::
Tensor
*>&
ref_inputs
,
const
int
axis
,
std
::
vector
<
framework
::
Tensor
*>*
outputs
)
{
// TODO(zcd): Add input data validity checking
in
t
num
=
outputs
->
size
();
size_
t
num
=
outputs
->
size
();
int
input_rows
=
1
;
auto
dim_0
=
outputs
->
at
(
0
).
dims
();
auto
dim_0
=
ref_inputs
[
0
]
->
dims
();
for
(
int
i
=
0
;
i
<
axis
;
++
i
)
{
input_rows
*=
dim_0
[
i
];
}
int
input_cols
=
0
;
std
::
vector
<
int64_t
>
output_cols
(
outputs
->
size
());
for
(
in
t
i
=
0
;
i
<
num
;
++
i
)
{
int
t_cols
=
outputs
->
at
(
i
).
numel
()
/
input_rows
;
for
(
size_
t
i
=
0
;
i
<
num
;
++
i
)
{
int
t_cols
=
ref_inputs
[
i
]
->
numel
()
/
input_rows
;
input_cols
+=
t_cols
;
output_cols
[
i
]
=
t_cols
;
}
auto
cpu_place
=
boost
::
get
<
platform
::
CPUPlace
>
(
context
.
GetPlace
());
// computation
for
(
in
t
k
=
0
;
k
<
input_rows
;
++
k
)
{
for
(
size_
t
k
=
0
;
k
<
input_rows
;
++
k
)
{
const
T
*
src_ptr
=
input
.
data
<
T
>
()
+
k
*
input_cols
;
int
col_idx
=
0
;
for
(
int
j
=
0
;
j
<
num
;
++
j
)
{
int
col_len
=
output_cols
[
j
];
T
*
dst_ptr
=
outputs
->
at
(
j
).
data
<
T
>
()
+
k
*
col_len
;
memory
::
Copy
(
cpu_place
,
dst_ptr
,
cpu_place
,
src_ptr
+
col_idx
,
sizeof
(
T
)
*
col_len
);
auto
*
out_tensor
=
outputs
->
at
(
j
);
if
(
out_tensor
!=
nullptr
)
{
T
*
dst_ptr
=
out_tensor
->
data
<
T
>
()
+
k
*
col_len
;
memory
::
Copy
(
cpu_place
,
dst_ptr
,
cpu_place
,
src_ptr
+
col_idx
,
sizeof
(
T
)
*
col_len
);
}
col_idx
+=
col_len
;
}
}
...
...
paddle/fluid/operators/math/concat.cu
浏览文件 @
69827f30
...
...
@@ -102,10 +102,12 @@ __global__ void KernelConcatGrad(const T* input_data, const int in_row,
int
local_col
=
tid_x
-
curr_offset
;
int
segment_width
=
curr_col_offset
-
curr_offset
;
T
*
output_ptr
=
outputs_data
[
curr_segment
];
int
tid_y
=
blockIdx
.
y
*
blockDim
.
y
+
threadIdx
.
y
;
for
(;
tid_y
<
in_row
;
tid_y
+=
blockDim
.
y
*
gridDim
.
y
)
output_ptr
[
tid_y
*
segment_width
+
local_col
]
=
input_data
[
tid_y
*
in_col
+
tid_x
];
if
(
output_ptr
!=
nullptr
)
{
int
tid_y
=
blockIdx
.
y
*
blockDim
.
y
+
threadIdx
.
y
;
for
(;
tid_y
<
in_row
;
tid_y
+=
blockDim
.
y
*
gridDim
.
y
)
output_ptr
[
tid_y
*
segment_width
+
local_col
]
=
input_data
[
tid_y
*
in_col
+
tid_x
];
}
}
}
...
...
@@ -118,10 +120,12 @@ __global__ void KernelConcatGrad(const T* input_data, const int in_row,
int
split
=
tid_x
/
fixed_out_col
;
int
in_offset
=
tid_x
-
split
*
fixed_out_col
;
T
*
output_ptr
=
outputs_data
[
split
];
int
tid_y
=
blockIdx
.
y
*
blockDim
.
y
+
threadIdx
.
y
;
for
(;
tid_y
<
in_row
;
tid_y
+=
blockDim
.
y
*
gridDim
.
y
)
output_ptr
[
tid_y
*
fixed_out_col
+
in_offset
]
=
input_data
[
tid_y
*
in_col
+
tid_x
];
if
(
output_ptr
!=
nullptr
)
{
int
tid_y
=
blockIdx
.
y
*
blockDim
.
y
+
threadIdx
.
y
;
for
(;
tid_y
<
in_row
;
tid_y
+=
blockDim
.
y
*
gridDim
.
y
)
output_ptr
[
tid_y
*
fixed_out_col
+
in_offset
]
=
input_data
[
tid_y
*
in_col
+
tid_x
];
}
}
}
...
...
@@ -203,17 +207,18 @@ template <typename T>
class
ConcatGradFunctor
<
platform
::
CUDADeviceContext
,
T
>
{
public:
void
operator
()(
const
platform
::
CUDADeviceContext
&
context
,
const
framework
::
Tensor
&
input
,
const
int
axis
,
std
::
vector
<
framework
::
Tensor
>*
outputs
)
{
const
framework
::
Tensor
&
input
,
const
std
::
vector
<
const
framework
::
Tensor
*>&
ref_inputs
,
const
int
axis
,
std
::
vector
<
framework
::
Tensor
*>*
outputs
)
{
// TODO(zcd): Add input data validity checking
int
o_num
=
outputs
->
size
();
int
out_row
=
1
;
auto
dim_0
=
outputs
->
at
(
0
).
dims
();
auto
dim_0
=
ref_inputs
[
0
]
->
dims
();
for
(
int
i
=
0
;
i
<
axis
;
++
i
)
{
out_row
*=
dim_0
[
i
];
}
int
out
_col
=
outputs
->
at
(
0
).
numel
()
/
out_row
;
int
out
0_col
=
ref_inputs
[
0
]
->
numel
()
/
out_row
;
int
in_col
=
0
,
in_row
=
out_row
;
bool
sameShape
=
true
;
...
...
@@ -223,13 +228,17 @@ class ConcatGradFunctor<platform::CUDADeviceContext, T> {
outputs_cols
[
0
]
=
0
;
for
(
int
i
=
0
;
i
<
o_num
;
++
i
)
{
int
t_col
=
outputs
->
at
(
i
)
.
numel
()
/
out_row
;
int
t_col
=
outputs
->
at
(
i
)
->
numel
()
/
out_row
;
if
(
sameShape
)
{
if
(
t_col
!=
out_col
)
sameShape
=
false
;
if
(
t_col
!=
out
0
_col
)
sameShape
=
false
;
}
in_col
+=
t_col
;
outputs_cols
[
i
+
1
]
=
in_col
;
outputs_ptr
[
i
]
=
outputs
->
at
(
i
).
data
<
T
>
();
if
(
outputs
->
at
(
i
)
!=
nullptr
)
{
outputs_ptr
[
i
]
=
outputs
->
at
(
i
)
->
data
<
T
>
();
}
else
{
outputs_ptr
[
i
]
=
nullptr
;
}
}
T
**
dev_out_gpu_data
=
...
...
@@ -255,7 +264,7 @@ class ConcatGradFunctor<platform::CUDADeviceContext, T> {
if
(
sameShape
)
{
KernelConcatGrad
<<<
grid_size
,
block_size
,
0
,
context
.
stream
()
>>>
(
input
.
data
<
T
>
(),
in_row
,
in_col
,
out_col
,
dev_out_gpu_data
);
input
.
data
<
T
>
(),
in_row
,
in_col
,
out
0
_col
,
dev_out_gpu_data
);
}
else
{
const
int
*
dev_outs_col_data
=
outputs_cols
.
CUDAData
(
context
.
GetPlace
());
KernelConcatGrad
<<<
grid_size
,
block_size
,
0
,
context
.
stream
()
>>>
(
...
...
paddle/fluid/operators/math/concat.h
浏览文件 @
69827f30
...
...
@@ -57,7 +57,8 @@ template <typename DeviceContext, typename T>
class
ConcatGradFunctor
{
public:
void
operator
()(
const
DeviceContext
&
context
,
const
framework
::
Tensor
&
input
,
const
int
axis
,
std
::
vector
<
framework
::
Tensor
>*
outputs
);
const
std
::
vector
<
const
framework
::
Tensor
*>&
ref_inputs
,
const
int
axis
,
std
::
vector
<
framework
::
Tensor
*>*
outputs
);
};
}
// namespace math
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录