Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
8987946f
P
Paddle
项目概览
机器未来
/
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看板
未验证
提交
8987946f
编写于
4月 09, 2020
作者:
L
liym27
提交者:
GitHub
4月 09, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Api/Op (select_input/select_ouput) error message enhancement. (#23445)
上级
fab9464f
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
92 addition
and
44 deletion
+92
-44
paddle/fluid/operators/select_input_op.cc
paddle/fluid/operators/select_input_op.cc
+7
-3
paddle/fluid/operators/select_op_helper.h
paddle/fluid/operators/select_op_helper.h
+9
-4
paddle/fluid/operators/select_output_op.cc
paddle/fluid/operators/select_output_op.cc
+7
-3
python/paddle/fluid/layers/control_flow.py
python/paddle/fluid/layers/control_flow.py
+10
-8
python/paddle/fluid/tests/unittests/test_select_input_output_op.py
...ddle/fluid/tests/unittests/test_select_input_output_op.py
+59
-26
未找到文件。
paddle/fluid/operators/select_input_op.cc
浏览文件 @
8987946f
...
...
@@ -40,9 +40,13 @@ class SelectInputOp : public framework::OperatorBase {
size_t
output_branch
=
static_cast
<
size_t
>
(
GetBranchNumber
(
mask
));
const
std
::
vector
<
std
::
string
>
&
x_names
=
Inputs
(
"X"
);
PADDLE_ENFORCE_LT
(
output_branch
,
x_names
.
size
(),
"Selected branch number is greater than actual branch "
"num in SelectInputOp"
);
PADDLE_ENFORCE_LT
(
output_branch
,
x_names
.
size
(),
platform
::
errors
::
InvalidArgument
(
"Input 'Mask' in SelectInputOp is invalid. "
"'Mask' must be less than the size of input vector 'X'. "
"But received Mask = %d, X's size = %d."
,
output_branch
,
x_names
.
size
()));
const
framework
::
Variable
*
selected_x
=
scope
.
FindVar
(
x_names
[
output_branch
]);
...
...
paddle/fluid/operators/select_op_helper.h
浏览文件 @
8987946f
...
...
@@ -27,7 +27,11 @@ namespace operators {
// selected branch number.
inline
int
GetBranchNumber
(
const
framework
::
LoDTensor
&
mask
)
{
PADDLE_ENFORCE_EQ
(
mask
.
numel
(),
1
,
"Mask in SelectOutputOp must have numel 1."
);
platform
::
errors
::
InvalidArgument
(
"The numel of Input(Mask) in SelectInputOp or "
"SelectOutputOp must be 1. "
"But received %d, and it's shape is [%s]."
,
mask
.
numel
(),
mask
.
dims
()));
if
(
platform
::
is_cpu_place
(
mask
.
place
()))
{
return
mask
.
data
<
int
>
()[
0
];
}
...
...
@@ -36,9 +40,10 @@ inline int GetBranchNumber(const framework::LoDTensor &mask) {
#ifdef PADDLE_WITH_CUDA
framework
::
TensorCopySync
(
mask
,
platform
::
CPUPlace
(),
cpu_mask
.
get
());
#else
PADDLE_THROW
(
"This version of PaddlePaddle doen NOT support GPU but got GPU tensor "
"Mask in SelectOutputOp. Please compile WITH_GPU option"
);
PADDLE_THROW
(
platform
::
errors
::
PreconditionNotMet
(
"This version of PaddlePaddle does NOT support GPU, "
"but got GPU tensor 'Mask' in SelectInputOp or SelectOutputOp. "
"Please compile PaddlePaddle WITH_GPU first."
));
#endif
return
cpu_mask
->
data
<
int
>
()[
0
];
}
...
...
paddle/fluid/operators/select_output_op.cc
浏览文件 @
8987946f
...
...
@@ -41,9 +41,13 @@ class SelectOutputOp : public framework::OperatorBase {
size_t
output_branch
=
static_cast
<
size_t
>
(
GetBranchNumber
(
mask
));
const
std
::
vector
<
std
::
string
>
&
out_names
=
Outputs
(
"Out"
);
PADDLE_ENFORCE_LT
(
output_branch
,
out_names
.
size
(),
"Selected branch number is greater than actual branch "
"num in SelectOutputOp"
);
PADDLE_ENFORCE_LT
(
output_branch
,
out_names
.
size
(),
platform
::
errors
::
InvalidArgument
(
"Input 'Mask' in SelectOutputOp is invalid. "
"'Mask' must be less than the size of output vector 'Out'. "
"But received Mask = %d, Out's size = %d."
,
output_branch
,
out_names
.
size
()));
const
framework
::
Variable
*
x
=
scope
.
FindVar
(
Input
(
"X"
));
framework
::
Variable
*
selected_out
=
scope
.
FindVar
(
out_names
[
output_branch
]);
...
...
python/paddle/fluid/layers/control_flow.py
浏览文件 @
8987946f
...
...
@@ -56,6 +56,10 @@ def select_output(input, outputs, mask):
Variable: The outputs variables
"""
helper
=
LayerHelper
(
'select_output'
,
**
locals
())
check_type
(
input
,
'input'
,
(
Variable
),
'select_output'
)
check_variable_and_dtype
(
mask
,
'mask'
,
[
'int32'
],
'select_output'
)
check_type
(
outputs
,
'outputs'
,
(
list
,
tuple
),
'select_output'
)
helper
.
append_op
(
type
=
'select_output'
,
inputs
=
{
'X'
:
input
,
...
...
@@ -80,14 +84,12 @@ def select_input(inputs, mask):
Variable: The selected input variable
"""
helper
=
LayerHelper
(
'select_input'
,
**
locals
())
if
isinstance
(
inputs
,
list
)
or
isinstance
(
inputs
,
tuple
):
input_dtype
=
inputs
[
0
].
dtype
input_shape
=
inputs
[
0
].
shape
input_type
=
inputs
[
0
].
type
else
:
input_dtype
=
inputs
.
dtype
input_shape
=
inputs
.
shape
input_type
=
inputs
.
type
check_type
(
inputs
,
'inputs'
,
(
list
,
tuple
),
'select_input'
)
check_variable_and_dtype
(
mask
,
'mask'
,
[
'int32'
],
'select_input'
)
input_dtype
=
inputs
[
0
].
dtype
input_shape
=
inputs
[
0
].
shape
input_type
=
inputs
[
0
].
type
out
=
helper
.
create_variable
(
dtype
=
input_dtype
,
shape
=
input_shape
,
type
=
input_type
)
...
...
python/paddle/fluid/tests/unittests/test_select_input_output_op.py
浏览文件 @
8987946f
...
...
@@ -60,34 +60,67 @@ class TestSplitMergeSelectedVarOps(unittest.TestCase):
self
.
assertTrue
(
np
.
allclose
(
np
.
asarray
(
ret
[
0
]),
feed_x
))
self
.
assertTrue
(
np
.
allclose
(
np
.
asarray
(
ret
[
1
]),
x_grad
))
def
test_forward_backward_single_tensor_output
(
self
):
program
=
Program
()
with
program_guard
(
program
):
x
=
layers
.
data
(
name
=
'x'
,
shape
=
[
2
],
dtype
=
'float32'
)
x
.
stop_gradient
=
False
# For test gradient
class
TestSelectInputOpError
(
unittest
.
TestCase
):
def
test_errors
(
self
):
with
program_guard
(
Program
(),
Program
()):
mask
=
layers
.
data
(
name
=
'mask'
,
shape
=
[
1
],
dtype
=
'int32'
)
in1
=
layers
.
data
(
name
=
'in1'
,
shape
=
[
1
],
dtype
=
'int32'
)
# 1. The type of inputs in select_input must be list or tuple.
def
test_inputs_type
():
select_input
(
1
,
mask
)
self
.
assertRaises
(
TypeError
,
test_inputs_type
)
# 2. The type of mask in select_input must be Variable.
def
test_mask_type
():
select_input
([
in1
],
mask
=
1
)
self
.
assertRaises
(
TypeError
,
test_mask_type
)
# 3. The dtype of mask in select_input must be int32 or int64.
def
test_mask_dtype
():
mask
=
layers
.
data
(
name
=
'mask2'
,
shape
=
[
1
],
dtype
=
'float32'
)
select_input
([
in1
],
mask
)
self
.
assertRaises
(
TypeError
,
test_mask_dtype
)
class
TestSelectOutput_Error
(
unittest
.
TestCase
):
def
test_errors
(
self
):
with
program_guard
(
Program
(),
Program
()):
in1
=
layers
.
data
(
name
=
'in1'
,
shape
=
[
1
],
dtype
=
'int32'
)
mask_int32
=
layers
.
data
(
name
=
'mask_int32'
,
shape
=
[
1
],
dtype
=
'int32'
)
mask_float32
=
layers
.
data
(
name
=
'mask_float32'
,
shape
=
[
1
],
dtype
=
'float32'
)
out1
=
layers
.
data
(
name
=
'out1'
,
shape
=
[
1
],
dtype
=
'int32'
)
# 1. The type of input in select_output must Variable.
def
test_input_type
():
select_output
(
1
,
[
out1
],
mask_int32
)
self
.
assertRaises
(
TypeError
,
test_input_type
)
# 2. The type of mask in select_output must be Variable.
def
test_mask_type
():
select_output
(
in1
,
[
out1
],
mask
=
1
)
self
.
assertRaises
(
TypeError
,
test_mask_type
)
# 3. The dtype of mask in select_output must be int32 or int64.
def
test_mask_dtype
():
select_output
(
in1
,
[
out1
],
mask
=
mask_float32
)
self
.
assertRaises
(
TypeError
,
test_mask_dtype
)
# 4. The type of mask in select_output must be list or tuple.
def
test_outputs_type
():
select_output
(
in1
,
out1
,
mask
=
mask_int32
)
out
=
program
.
current_block
().
create_var
(
dtype
=
'float32'
,
type
=
core
.
VarDesc
.
VarType
.
LOD_TENSOR
)
select_output
(
x
,
out
,
mask
)
y
=
select_input
(
out
,
mask
)
mean
=
layers
.
mean
(
y
)
append_backward
(
mean
)
place
=
fluid
.
CUDAPlace
(
0
)
if
core
.
is_compiled_with_cuda
(
)
else
fluid
.
CPUPlace
()
exe
=
Executor
(
place
)
feed_x
=
np
.
asarray
([
1.3
,
-
1.4
]).
astype
(
np
.
float32
)
feed_mask
=
np
.
asarray
([
0
]).
astype
(
np
.
int32
)
ret
=
exe
.
run
(
program
,
feed
=
{
'x'
:
feed_x
,
'mask'
:
feed_mask
},
fetch_list
=
[
y
.
name
,
x
.
grad_name
])
x_grad
=
np
.
asarray
([
0.5
,
0.5
]).
astype
(
np
.
float32
)
self
.
assertTrue
(
np
.
allclose
(
np
.
asarray
(
ret
[
0
]),
feed_x
))
self
.
assertTrue
(
np
.
allclose
(
np
.
asarray
(
ret
[
1
]),
x_grad
))
self
.
assertRaises
(
TypeError
,
test_outputs_type
)
if
__name__
==
'__main__'
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录