Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
cdd1a8f5
P
Paddle
项目概览
PaddlePaddle
/
Paddle
大约 1 年 前同步成功
通知
2298
Star
20931
Fork
5422
代码
文件
提交
分支
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看板
提交
cdd1a8f5
编写于
8月 14, 2017
作者:
F
fengjiayi
提交者:
GitHub
8月 14, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #3436 from Canpio/refactor_registry_macro
Merge maps in OpRegistry and simplify register macros
上级
f80fea8d
914a2f2b
变更
21
隐藏空白更改
内联
并排
Showing
21 changed file
with
170 addition
and
216 deletion
+170
-216
paddle/framework/backward_test.cc
paddle/framework/backward_test.cc
+10
-13
paddle/framework/grad_op_builder.cc
paddle/framework/grad_op_builder.cc
+21
-19
paddle/framework/grad_op_builder_test.cc
paddle/framework/grad_op_builder_test.cc
+2
-12
paddle/framework/op_registry.h
paddle/framework/op_registry.h
+77
-117
paddle/framework/op_registry_test.cc
paddle/framework/op_registry_test.cc
+4
-5
paddle/framework/operator.cc
paddle/framework/operator.cc
+7
-11
paddle/framework/operator.h
paddle/framework/operator.h
+9
-3
paddle/framework/operator_test.cc
paddle/framework/operator_test.cc
+9
-6
paddle/framework/pybind.cc
paddle/framework/pybind.cc
+10
-7
paddle/operators/add_op.cc
paddle/operators/add_op.cc
+1
-2
paddle/operators/cross_entropy_op.cc
paddle/operators/cross_entropy_op.cc
+2
-3
paddle/operators/fill_zeros_like_op.cc
paddle/operators/fill_zeros_like_op.cc
+2
-1
paddle/operators/gaussian_random_op.cc
paddle/operators/gaussian_random_op.cc
+2
-1
paddle/operators/mean_op.cc
paddle/operators/mean_op.cc
+1
-2
paddle/operators/mul_op.cc
paddle/operators/mul_op.cc
+1
-3
paddle/operators/recurrent_op.cc
paddle/operators/recurrent_op.cc
+3
-2
paddle/operators/rowwise_add_op.cc
paddle/operators/rowwise_add_op.cc
+2
-1
paddle/operators/sgd_op.cc
paddle/operators/sgd_op.cc
+1
-1
paddle/operators/sigmoid_op.cc
paddle/operators/sigmoid_op.cc
+2
-3
paddle/operators/softmax_op.cc
paddle/operators/softmax_op.cc
+2
-2
paddle/operators/uniform_random_op.cc
paddle/operators/uniform_random_op.cc
+2
-2
未找到文件。
paddle/framework/backward_test.cc
浏览文件 @
cdd1a8f5
...
...
@@ -155,19 +155,16 @@ class AddOpMaker : public OpProtoAndCheckerMaker {
namespace
f
=
paddle
::
framework
;
namespace
ops
=
paddle
::
operators
;
using
EnforceNotMet
=
paddle
::
platform
::
EnforceNotMet
;
REGISTER_OP
(
rowwise_add
,
f
::
EmptyOp
,
f
::
RowWiseAddOpMaker
);
REGISTER_GRADIENT_OP
(
rowwise_add
,
rowwise_add_grad
,
f
::
EmptyOp
);
REGISTER_OP
(
mul
,
f
::
EmptyOp
,
f
::
MulOpMaker
);
REGISTER_GRADIENT_OP
(
mul
,
mul_grad
,
f
::
EmptyOp
);
REGISTER_OP
(
sigmoid
,
f
::
EmptyOp
,
f
::
SigmoidOpMaker
);
REGISTER_GRADIENT_OP
(
sigmoid
,
sigmoid_grad
,
f
::
EmptyOp
);
REGISTER_OP
(
nograd
,
f
::
EmptyOp
,
f
::
NoGradOpMaker
);
REGISTER_OP
(
fill_zeros_like
,
f
::
EmptyOp
,
f
::
FillZeroOpMaker
);
REGISTER_OP
(
add
,
f
::
EmptyOp
,
f
::
AddOpMaker
);
REGISTER_GRADIENT_OP
(
add
,
add_grad
,
f
::
EmptyOp
);
REGISTER_OP
(
fc
,
f
::
FcOp
,
f
::
FcOpMaker
);
REGISTER_OP
(
many_output_op
,
f
::
EmptyOp
,
f
::
ManyOutputOpMaker
);
REGISTER_GRADIENT_OP
(
many_output_op
,
many_output_op_grad
,
f
::
EmptyOp
);
REGISTER_OP
(
rowwise_add
,
f
::
EmptyOp
,
f
::
RowWiseAddOpMaker
,
rowwise_add_grad
,
f
::
EmptyOp
);
REGISTER_OP
(
mul
,
f
::
EmptyOp
,
f
::
MulOpMaker
,
mul_grad
,
f
::
EmptyOp
);
REGISTER_OP
(
sigmoid
,
f
::
EmptyOp
,
f
::
SigmoidOpMaker
,
sigmoid_grad
,
f
::
EmptyOp
);
REGISTER_OP_WITHOUT_GRADIENT
(
nograd
,
f
::
EmptyOp
,
f
::
NoGradOpMaker
);
REGISTER_OP_WITHOUT_GRADIENT
(
fill_zeros_like
,
f
::
EmptyOp
,
f
::
FillZeroOpMaker
);
REGISTER_OP
(
add
,
f
::
EmptyOp
,
f
::
AddOpMaker
,
add_grad
,
f
::
EmptyOp
);
REGISTER_OP_WITHOUT_GRADIENT
(
fc
,
f
::
FcOp
,
f
::
FcOpMaker
);
REGISTER_OP
(
many_output_op
,
f
::
EmptyOp
,
f
::
ManyOutputOpMaker
,
many_output_op_grad
,
f
::
EmptyOp
);
TEST
(
Backward
,
simple_op_grad
)
{
auto
fwd
=
f
::
OpRegistry
::
CreateOp
(
...
...
paddle/framework/grad_op_builder.cc
浏览文件 @
cdd1a8f5
...
...
@@ -20,16 +20,14 @@ namespace paddle {
namespace
framework
{
enum
class
OpArgType
{
IN
,
OUT
};
static
void
TransOpArg
(
const
OperatorBase
*
src_op
,
OperatorBase
::
VarNameMap
*
vars
,
const
OpArgType
&
src_type
,
bool
is_grad
)
{
static
void
TransOpArg
(
const
OperatorBase
*
src_op
,
const
OpArgType
&
src_type
,
bool
is_grad
,
OperatorBase
::
VarNameMap
*
vars
)
{
const
auto
&
src_inout
=
src_type
==
OpArgType
::
IN
?
src_op
->
inputs_
:
src_op
->
outputs_
;
auto
&
dst_inout
=
*
vars
;
const
OpProto
&
proto
=
OpProtos
().
at
(
src_op
->
type_
);
const
OpProto
*
proto
=
OpRegistry
::
op_info_map
().
at
(
src_op
->
type_
).
proto_
;
const
auto
&
src_arg_list
=
src_type
==
OpArgType
::
IN
?
proto
.
inputs
()
:
proto
.
outputs
();
src_type
==
OpArgType
::
IN
?
proto
->
inputs
()
:
proto
->
outputs
();
for
(
const
auto
&
arg
:
src_arg_list
)
{
if
(
arg
.
no_gradient
()
&&
!
is_grad
)
continue
;
const
std
::
string
src_name
=
arg
.
name
();
...
...
@@ -43,22 +41,26 @@ static void TransOpArg(const OperatorBase* src_op,
}
OperatorBase
*
BuildGradOp
(
const
OperatorBase
*
op
)
{
auto
gop_type_it
=
OpRegistry
::
grad_ops
().
find
(
op
->
type_
);
PADDLE_ENFORCE
(
gop_type_it
!=
OpRegistry
::
grad_ops
().
end
(),
"Operator %s do not register gradient type"
,
op
->
type_
);
auto
&
grad_op_type
=
gop_type_it
->
second
;
auto
it
=
OpRegistry
::
op_info_map
().
find
(
op
->
type_
);
PADDLE_ENFORCE
(
it
!=
OpRegistry
::
op_info_map
().
end
(),
"'%s' has not been registered."
,
op
->
type_
);
PADDLE_ENFORCE
(
it
->
second
.
proto_
!=
nullptr
,
"'%s' has no OpProto."
,
op
->
type_
);
std
::
string
grad_op_type
=
it
->
second
.
grad_op_type_
;
PADDLE_ENFORCE
(
!
grad_op_type
.
empty
(),
"'%s' has no gradient operator."
,
op
->
type_
);
OperatorBase
::
VarNameMap
inputs
;
OperatorBase
::
VarNameMap
outputs
;
TransOpArg
(
op
,
&
inputs
,
OpArgType
::
IN
,
false
);
// I
TransOpArg
(
op
,
&
inputs
,
OpArgType
::
OUT
,
false
);
// O
TransOpArg
(
op
,
&
inputs
,
OpArgType
::
OUT
,
true
);
// OG
TransOpArg
(
op
,
&
outputs
,
OpArgType
::
IN
,
true
);
// IG
auto
gop_it
=
OpRegistry
::
op_creators
().
find
(
grad_op_type
);
PADDLE_ENFORCE
(
gop_it
!=
OpRegistry
::
op_creators
().
end
(),
"Operator %s 's Gradient %s's creator cannot be found"
,
op
->
type_
,
grad_op_type
);
TransOpArg
(
op
,
OpArgType
::
IN
,
false
,
&
inputs
);
// I
TransOpArg
(
op
,
OpArgType
::
OUT
,
false
,
&
inputs
);
// O
TransOpArg
(
op
,
OpArgType
::
OUT
,
true
,
&
inputs
);
// OG
TransOpArg
(
op
,
OpArgType
::
IN
,
true
,
&
outputs
);
// IG
return
gop_it
->
second
(
grad_op_type
,
inputs
,
outputs
,
op
->
attrs_
);
it
=
OpRegistry
::
op_info_map
().
find
(
grad_op_type
);
PADDLE_ENFORCE
(
it
!=
OpRegistry
::
op_info_map
().
end
(),
"'%s' has not been registered."
,
grad_op_type
);
return
it
->
second
.
creator_
(
grad_op_type
,
inputs
,
outputs
,
op
->
attrs_
);
}
}
// namespace framework
...
...
paddle/framework/grad_op_builder_test.cc
浏览文件 @
cdd1a8f5
...
...
@@ -8,14 +8,6 @@ USE_OP(add_two);
namespace
paddle
{
namespace
framework
{
class
NOP
:
public
OperatorBase
{
public:
using
OperatorBase
::
OperatorBase
;
void
InferShape
(
const
Scope
&
scope
)
const
override
{}
void
Run
(
const
Scope
&
scope
,
const
platform
::
DeviceContext
&
dev_ctx
)
const
override
{}
};
class
MutiInOutOpMaker
:
public
OpProtoAndCheckerMaker
{
public:
MutiInOutOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
...
...
@@ -62,10 +54,8 @@ TEST(GradOpBuilder, AddTwo) {
EXPECT_EQ
(
grad_add_op
->
Output
(
f
::
GradVarName
(
"Y"
)),
f
::
GradVarName
(
"y"
));
}
REGISTER_OP
(
mult_io
,
f
::
NOP
,
f
::
MutiInOutOpMaker
);
REGISTER_GRADIENT_OP
(
mult_io
,
mult_io_grad
,
f
::
NOP
);
REGISTER_OP
(
io_ignored
,
f
::
NOP
,
f
::
IOIgnoredOpMaker
);
REGISTER_GRADIENT_OP
(
io_ignored
,
io_ignored_grad
,
f
::
NOP
);
REGISTER_OP
(
mult_io
,
f
::
NOP
,
f
::
MutiInOutOpMaker
,
mult_io_grad
,
f
::
NOP
);
REGISTER_OP
(
io_ignored
,
f
::
NOP
,
f
::
IOIgnoredOpMaker
,
io_ignored_grad
,
f
::
NOP
);
TEST
(
GradOpBuilder
,
MutiInOut
)
{
std
::
shared_ptr
<
f
::
OperatorBase
>
test_op
(
f
::
OpRegistry
::
CreateOp
(
...
...
paddle/framework/op_registry.h
浏览文件 @
cdd1a8f5
...
...
@@ -17,6 +17,7 @@ limitations under the License. */
#include <algorithm>
#include <atomic>
#include <type_traits>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include "paddle/framework/attribute.h"
...
...
@@ -119,6 +120,12 @@ class OpProtoAndCheckerMaker {
bool
validated_
{
false
};
};
class
NOPMaker
:
public
OpProtoAndCheckerMaker
{
public:
NOPMaker
(
framework
::
OpProto
*
proto
,
framework
::
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{}
};
class
OpRegistry
{
using
VarNameMap
=
OperatorBase
::
VarNameMap
;
using
OpCreator
=
std
::
function
<
OperatorBase
*
(
...
...
@@ -126,46 +133,56 @@ class OpRegistry {
const
VarNameMap
&
/*outputs*/
,
const
AttributeMap
&
/*attrs*/
)
>
;
public:
template
<
typename
OpType
,
typename
ProtoMakerType
>
static
void
RegisterOp
(
const
std
::
string
&
op_type
)
{
op_creators
()[
op_type
]
=
[](
const
std
::
string
&
type
,
const
VarNameMap
&
inputs
,
const
VarNameMap
&
outputs
,
const
AttributeMap
&
attrs
)
{
return
new
OpType
(
type
,
inputs
,
outputs
,
attrs
);
};
OpAttrChecker
&
op_checker
=
op_checkers
()[
op_type
];
OpProto
&
op_proto
=
OpProtos
()[
op_type
];
auto
maker
=
ProtoMakerType
(
&
op_proto
,
&
op_checker
);
maker
.
Validate
();
op_proto
.
set_type
(
op_type
);
PADDLE_ENFORCE
(
op_proto
.
IsInitialized
(),
"Fail to initialize %s's OpProto, because %s is not initialized"
,
op_type
,
op_proto
.
InitializationErrorString
());
}
struct
OpInfo
{
OpCreator
creator_
;
std
::
string
grad_op_type_
;
OpProto
*
proto_
;
OpAttrChecker
*
checker_
;
};
template
<
typename
GradOpType
>
static
void
RegisterGradOp
(
const
std
::
string
&
op_type
,
const
std
::
string
&
grad_op_type
)
{
op_creators
()[
grad_op_type
]
=
[](
const
std
::
string
&
type
,
const
VarNameMap
&
inputs
,
const
VarNameMap
&
outputs
,
const
AttributeMap
&
attrs
)
{
return
new
GradOpType
(
type
,
inputs
,
outputs
,
attrs
);
template
<
typename
OpType
,
typename
ProtoMakerType
,
typename
GradOpType
>
static
void
RegisterOp
(
const
std
::
string
&
op_type
,
const
std
::
string
&
grad_op_type
)
{
PADDLE_ENFORCE
(
op_info_map
().
count
(
op_type
)
==
0
,
"'%s' is registered more than once."
,
op_type
);
OpInfo
op_info
;
op_info
.
creator_
=
[](
const
std
::
string
&
type
,
const
VarNameMap
&
inputs
,
const
VarNameMap
&
outputs
,
const
AttributeMap
&
attrs
)
{
return
new
OpType
(
type
,
inputs
,
outputs
,
attrs
);
};
grad_ops
()[
op_type
]
=
grad_op_type
;
op_info
.
grad_op_type_
=
grad_op_type
;
if
(
std
::
type_index
(
typeid
(
ProtoMakerType
))
!=
std
::
type_index
(
typeid
(
NOPMaker
)))
{
op_info
.
proto_
=
new
OpProto
;
op_info
.
checker_
=
new
OpAttrChecker
;
auto
maker
=
ProtoMakerType
(
op_info
.
proto_
,
op_info
.
checker_
);
maker
.
Validate
();
op_info
.
proto_
->
set_type
(
op_type
);
PADDLE_ENFORCE
(
op_info
.
proto_
->
IsInitialized
(),
"Fail to initialize %s's OpProto, because %s is not initialized"
,
op_type
,
op_info
.
proto_
->
InitializationErrorString
());
}
else
{
op_info
.
proto_
=
nullptr
;
op_info
.
checker_
=
nullptr
;
}
op_info_map
().
insert
(
std
::
make_pair
(
op_type
,
op_info
));
// register gradient op
if
(
!
grad_op_type
.
empty
())
{
RegisterOp
<
GradOpType
,
NOPMaker
,
NOP
>
(
grad_op_type
,
""
);
}
}
static
std
::
shared_ptr
<
OperatorBase
>
CreateOp
(
const
std
::
string
&
type
,
const
VarNameMap
&
inputs
,
const
VarNameMap
&
outputs
,
AttributeMap
attrs
)
{
auto
op_create_it
=
op_creators
().
find
(
type
);
PADDLE_ENFORCE
(
op_create_it
!=
op_creators
().
end
(),
"Operator %s cannot be found."
,
type
);
op_checkers
().
at
(
type
).
Check
(
attrs
);
auto
op
=
op_create_it
->
second
(
type
,
inputs
,
outputs
,
attrs
);
auto
it
=
op_info_map
().
find
(
type
);
PADDLE_ENFORCE
(
it
!=
op_info_map
().
end
(),
"Operator '%s' has not been registered."
,
type
);
it
->
second
.
checker_
->
Check
(
attrs
);
auto
op
=
it
->
second
.
creator_
(
type
,
inputs
,
outputs
,
attrs
);
return
std
::
shared_ptr
<
OperatorBase
>
(
op
);
}
...
...
@@ -200,49 +217,32 @@ class OpRegistry {
return
grad_op
;
}
static
std
::
unordered_map
<
std
::
string
,
std
::
string
>&
grad_ops
()
{
static
std
::
unordered_map
<
std
::
string
,
std
::
string
>
grad_ops_
;
return
grad_ops_
;
}
static
std
::
unordered_map
<
std
::
string
,
OpCreator
>&
op_creators
()
{
static
std
::
unordered_map
<
std
::
string
,
OpCreator
>
op_creators_
;
return
op_creators_
;
}
private:
static
std
::
unordered_map
<
std
::
string
,
OpAttrChecker
>&
op_checkers
()
{
static
std
::
unordered_map
<
std
::
string
,
OpAttrChecker
>
op_checkers_
;
return
op_checkers_
;
static
std
::
unordered_map
<
std
::
string
,
const
OpInfo
>&
op_info_map
()
{
static
std
::
unordered_map
<
std
::
string
,
const
OpInfo
>
op_info_map_
;
return
op_info_map_
;
}
};
class
Registrar
{
public:
// In our design, various kinds of classes, e.g., operators and kernels,
have
//
their corresponding registry and registrar. The action of registration is
//
in the constructor of a global registrar variable, which, however, are not
//
used in the code that calls package framework, and would be removed from
//
the generated binary file by the linker. To avoid such removal, we add
//
Touch to all registrar classes and make USE_OP macros to call this
// method. So, as long as the callee code calls USE_OP, the global
// In our design, various kinds of classes, e.g., operators and kernels,
//
have their corresponding registry and registrar. The action of
//
registration is in the constructor of a global registrar variable, which,
//
however, are not used in the code that calls package framework, and would
//
be removed from the generated binary file by the linker. To avoid such
//
removal, we add Touch to all registrar classes and make USE_OP macros to
//
call this
method. So, as long as the callee code calls USE_OP, the global
// registrar variable won't be removed by the linker.
void
Touch
()
{}
};
template
<
typename
OpType
,
typename
ProtoMakerType
>
template
<
typename
OpType
,
typename
ProtoMakerType
,
typename
GradOpType
>
class
OpRegistrar
:
public
Registrar
{
public:
explicit
OpRegistrar
(
const
char
*
op_type
)
{
OpRegistry
::
RegisterOp
<
OpType
,
ProtoMakerType
>
(
op_type
);
}
};
template
<
typename
GradOpType
>
class
GradOpRegistrar
:
public
Registrar
{
public:
GradOpRegistrar
(
const
char
*
op_type
,
const
char
*
grad_op_type
)
{
OpRegistry
::
RegisterGradOp
<
GradOpType
>
(
op_type
,
grad_op_type
);
explicit
OpRegistrar
(
const
char
*
op_type
)
{
OpRegistrar
(
op_type
,
""
);
}
OpRegistrar
(
const
char
*
op_type
,
const
char
*
grad_op_type
)
{
OpRegistry
::
RegisterOp
<
OpType
,
ProtoMakerType
,
GradOpType
>
(
op_type
,
grad_op_type
);
}
};
...
...
@@ -268,30 +268,20 @@ class OpKernelRegistrar : public Registrar {
/**
* Macro to register Operator.
*/
#define REGISTER_OP(op_type, op_class, op_maker_class) \
#define REGISTER_OP(op_type, op_class, op_maker_class, grad_op_type, \
grad_op_class) \
STATIC_ASSERT_GLOBAL_NAMESPACE( \
__reg_op__##op_type, "REGISTER_OP must be called in global namespace"); \
static ::paddle::framework::OpRegistrar<op_class, op_maker_class> \
__op_registrar_##op_type##__(#op_type); \
static ::paddle::framework::OpRegistrar<op_class, op_maker_class, \
grad_op_class> \
__op_registrar_##op_type##__(#op_type, #grad_op_type); \
int TouchOpRegistrar_##op_type() { \
__op_registrar_##op_type##__.Touch(); \
return 0; \
}
/**
* Macro to register Gradient Operator.
*/
#define REGISTER_GRADIENT_OP(op_type, grad_op_type, grad_op_class) \
STATIC_ASSERT_GLOBAL_NAMESPACE( \
__reg_gradient_op__##op_type##_##grad_op_type, \
"REGISTER_GRADIENT_OP must be called in global namespace"); \
static ::paddle::framework::GradOpRegistrar<grad_op_class> \
__op_gradient_registrar_##op_type##_##grad_op_type##__(#op_type, \
#grad_op_type); \
int TouchOpGradientRegistrar_##op_type() { \
__op_gradient_registrar_##op_type##_##grad_op_type##__.Touch(); \
return 0; \
}
#define REGISTER_OP_WITHOUT_GRADIENT(op_type, op_class, op_maker_class) \
REGISTER_OP(op_type, op_class, op_maker_class, , ::paddle::framework::NOP)
/**
* Macro to register OperatorKernel.
...
...
@@ -307,14 +297,6 @@ class OpKernelRegistrar : public Registrar {
return 0; \
}
/**
* Macro to Forbid user register Gradient Operator.
*/
#define NO_GRADIENT(op_type) \
STATIC_ASSERT_GLOBAL_NAMESPACE( \
__reg_gradient_op__##op_type##_##op_type##_grad, \
"NO_GRADIENT must be called in global namespace")
#define REGISTER_OP_GPU_KERNEL(op_type, ...) \
REGISTER_OP_KERNEL(op_type, GPU, ::paddle::platform::GPUPlace, __VA_ARGS__)
...
...
@@ -333,23 +315,6 @@ class OpKernelRegistrar : public Registrar {
static int use_op_itself_##op_type##_ __attribute__((unused)) = \
TouchOpRegistrar_##op_type()
// TODO(fengjiayi): Most ops' gradient op have not been compeleted. So we use
// `NO_GRAD` to disable micro USE_OP_GRADIENT(op_type). Otherwise the code can't
// be compiled. `NO_GRAD` should be removed after all gradient ops are
// compeleted.
#define NO_GRAD
#ifndef NO_GRAD
#define USE_OP_GRADIENT(op_type) \
STATIC_ASSERT_GLOBAL_NAMESPACE( \
__use_op_gradient_##op_type, \
"USE_OP_GRADIENT must be called in global namespace"); \
extern int TouchOpGradientRegistrar_##op_type(); \
static int use_op_gradient_##op_type##_ __attribute__((unused)) = \
TouchOpGradientRegistrar_##op_type()
#else
#define USE_OP_GRADIENT(op_type)
#endif
#define USE_OP_DEVICE_KERNEL(op_type, DEVICE_TYPE) \
STATIC_ASSERT_GLOBAL_NAMESPACE( \
__use_op_kernel_##op_type##_##DEVICE_TYPE##__, \
...
...
@@ -369,18 +334,13 @@ class OpKernelRegistrar : public Registrar {
USE_OP_DEVICE_KERNEL(op_type, GPU)
#endif
#define USE_NO_GRAD_OP(op_type) \
USE_OP_ITSELF(op_type); \
USE_OP_KERNEL(op_type)
#define USE_CPU_OP(op_type) \
USE_OP_ITSELF(op_type); \
USE_OP_DEVICE_KERNEL(op_type, CPU); \
USE_OP_GRADIENT(op_type)
#define USE_CPU_ONLY_OP(op_type) \
USE_OP_ITSELF(op_type); \
USE_OP_DEVICE_KERNEL(op_type, CPU);
#define USE_OP(op_type)
\
USE_
NO_GRAD_OP
(op_type); \
USE_OP_
GRADIENT
(op_type)
#define USE_OP(op_type) \
USE_
OP_ITSELF
(op_type); \
USE_OP_
KERNEL
(op_type)
}
// namespace framework
}
// namespace paddle
paddle/framework/op_registry_test.cc
浏览文件 @
cdd1a8f5
...
...
@@ -59,11 +59,10 @@ static void BuildVar(const std::string& param_name,
var
->
add_arguments
(
arg_name
);
}
}
REGISTER_OP
(
cos_sim
,
paddle
::
framework
::
CosineOp
,
paddle
::
framework
::
CosineOpProtoAndCheckerMaker
);
REGISTER_OP
(
my_test_op
,
paddle
::
framework
::
MyTestOp
,
paddle
::
framework
::
MyTestOpProtoAndCheckerMaker
);
REGISTER_OP_WITHOUT_GRADIENT
(
cos_sim
,
paddle
::
framework
::
CosineOp
,
paddle
::
framework
::
CosineOpProtoAndCheckerMaker
);
REGISTER_OP_WITHOUT_GRADIENT
(
my_test_op
,
paddle
::
framework
::
MyTestOp
,
paddle
::
framework
::
MyTestOpProtoAndCheckerMaker
);
TEST
(
OpRegistry
,
CreateOp
)
{
paddle
::
framework
::
OpDesc
op_desc
;
...
...
paddle/framework/operator.cc
浏览文件 @
cdd1a8f5
...
...
@@ -33,14 +33,6 @@ ExecutionContext::GetEigenDevice<platform::GPUPlace, Eigen::GpuDevice>() const {
}
#endif
static
std
::
unordered_map
<
std
::
string
,
OpProto
>*
g_op_protos
=
nullptr
;
std
::
unordered_map
<
std
::
string
,
OpProto
>&
OpProtos
()
{
if
(
g_op_protos
==
nullptr
)
{
g_op_protos
=
new
std
::
unordered_map
<
std
::
string
,
OpProto
>
();
}
return
*
g_op_protos
;
}
const
std
::
string
&
OperatorBase
::
Input
(
const
std
::
string
&
name
)
const
{
auto
&
ins
=
Inputs
(
name
);
PADDLE_ENFORCE_EQ
(
ins
.
size
(),
1UL
,
...
...
@@ -149,14 +141,18 @@ std::vector<std::string> OperatorBase::OutputVars(bool has_intermediate) const {
}
return
ret_val
;
}
auto
it
=
Op
Protos
().
find
(
type_
);
auto
it
=
Op
Registry
::
op_info_map
().
find
(
type_
);
PADDLE_ENFORCE
(
it
!=
Op
Protos
().
end
(),
it
!=
Op
Registry
::
op_info_map
().
end
(),
"Operator %s not registered, cannot figure out intermediate outputs"
,
type_
);
PADDLE_ENFORCE
(
it
->
second
.
proto_
!=
nullptr
,
"Operator %s has no OpProto, cannot figure out intermediate outputs"
,
type_
);
// get all OpProto::Var for outputs
for
(
auto
&
o
:
it
->
second
.
outputs
())
{
for
(
auto
&
o
:
it
->
second
.
proto_
->
outputs
())
{
// ignore all intermediate output
if
(
o
.
intermediate
())
continue
;
auto
out
=
outputs_
.
find
(
o
.
name
());
...
...
paddle/framework/operator.h
浏览文件 @
cdd1a8f5
...
...
@@ -50,8 +50,6 @@ inline std::string GradVarName(const std::string& var_name) {
return
var_name
+
kGradVarSuffix
;
}
extern
std
::
unordered_map
<
std
::
string
,
OpProto
>&
OpProtos
();
class
OperatorBase
;
class
InferShapeContext
;
class
ExecutionContext
;
...
...
@@ -129,6 +127,14 @@ class OperatorBase {
AttributeMap
attrs_
;
};
class
NOP
:
public
OperatorBase
{
public:
using
OperatorBase
::
OperatorBase
;
void
InferShape
(
const
Scope
&
scope
)
const
override
{}
void
Run
(
const
Scope
&
scope
,
const
platform
::
DeviceContext
&
dev_ctx
)
const
override
{}
};
class
InferShapeContext
{
public:
InferShapeContext
(
const
OperatorBase
&
op
,
const
Scope
&
scope
)
...
...
@@ -210,7 +216,7 @@ class InferShapeContext {
[
&
](
const
std
::
string
&
sub_name
)
{
auto
var
=
scope_
.
FindVar
(
sub_name
);
PADDLE_ENFORCE_NOT_NULL
(
var
,
"MultiOutput(%s:%s) should not be nullptr"
,
name
,
var
,
"MultiOutput(%s:%s) should not be nullptr
.
"
,
name
,
sub_name
);
return
var
->
GetMutable
<
T
>
();
});
...
...
paddle/framework/operator_test.cc
浏览文件 @
cdd1a8f5
...
...
@@ -65,8 +65,9 @@ static void BuildVar(const std::string& param_name,
}
}
REGISTER_OP
(
test_operator
,
paddle
::
framework
::
OpWithoutKernelTest
,
paddle
::
framework
::
OpeWithoutKernelTestProtoAndCheckerMaker
);
REGISTER_OP_WITHOUT_GRADIENT
(
test_operator
,
paddle
::
framework
::
OpWithoutKernelTest
,
paddle
::
framework
::
OpeWithoutKernelTestProtoAndCheckerMaker
);
TEST
(
OperatorBase
,
all
)
{
paddle
::
framework
::
OpDesc
op_desc
;
...
...
@@ -184,8 +185,9 @@ class CPUKernalMultiInputsTest : public OpKernel {
}
// namespace framework
}
// namespace paddle
REGISTER_OP
(
op_with_kernel
,
paddle
::
framework
::
OpWithKernelTest
,
paddle
::
framework
::
OpKernelTestProtoAndCheckerMaker
);
REGISTER_OP_WITHOUT_GRADIENT
(
op_with_kernel
,
paddle
::
framework
::
OpWithKernelTest
,
paddle
::
framework
::
OpKernelTestProtoAndCheckerMaker
);
REGISTER_OP_CPU_KERNEL
(
op_with_kernel
,
paddle
::
framework
::
CPUKernelTest
<
float
,
float
>
);
...
...
@@ -210,8 +212,9 @@ TEST(OpKernel, all) {
ASSERT_EQ
(
paddle
::
framework
::
cpu_kernel_run_num
,
1
);
}
REGISTER_OP
(
op_multi_inputs_with_kernel
,
paddle
::
framework
::
OpWithKernelTest
,
paddle
::
framework
::
OpKernelTestMultiInputsProtoAndCheckerMaker
);
REGISTER_OP_WITHOUT_GRADIENT
(
op_multi_inputs_with_kernel
,
paddle
::
framework
::
OpWithKernelTest
,
paddle
::
framework
::
OpKernelTestMultiInputsProtoAndCheckerMaker
);
REGISTER_OP_CPU_KERNEL
(
op_multi_inputs_with_kernel
,
paddle
::
framework
::
CPUKernalMultiInputsTest
);
...
...
paddle/framework/pybind.cc
浏览文件 @
cdd1a8f5
...
...
@@ -30,8 +30,8 @@ limitations under the License. */
namespace
py
=
pybind11
;
USE_OP
(
add_two
);
USE_CPU_OP
(
onehot_cross_entropy
);
USE_
NO_GRAD_
OP
(
sgd
);
USE_CPU_O
NLY_O
P
(
onehot_cross_entropy
);
USE_OP
(
sgd
);
USE_OP
(
mul
);
USE_OP
(
mean
);
USE_OP
(
sigmoid
);
...
...
@@ -160,13 +160,16 @@ All parameter, weight, gradient are variables in Paddle.
//! @note: Be careful! PyBind will return std::string as an unicode, not
//! Python str. If you want a str object, you should cast them in Python.
m
.
def
(
"get_all_op_protos"
,
[]()
->
std
::
vector
<
py
::
bytes
>
{
auto
&
protos
=
OpProtos
();
auto
&
op_info_map
=
OpRegistry
::
op_info_map
();
std
::
vector
<
py
::
bytes
>
ret_values
;
for
(
auto
it
=
protos
.
begin
();
it
!=
protos
.
end
();
++
it
)
{
PADDLE_ENFORCE
(
it
->
second
.
IsInitialized
(),
"OpProto must all be initialized"
);
for
(
auto
it
=
op_info_map
.
begin
();
it
!=
op_info_map
.
end
();
++
it
)
{
const
OpProto
*
proto
=
it
->
second
.
proto_
;
if
(
proto
==
nullptr
)
{
continue
;
}
PADDLE_ENFORCE
(
proto
->
IsInitialized
(),
"OpProto must all be initialized"
);
std
::
string
str
;
PADDLE_ENFORCE
(
it
->
second
.
SerializeToString
(
&
str
),
PADDLE_ENFORCE
(
proto
->
SerializeToString
(
&
str
),
"Serialize OpProto Error. This could be a bug of Paddle."
);
ret_values
.
push_back
(
py
::
bytes
(
str
));
}
...
...
paddle/operators/add_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -57,8 +57,7 @@ class AddOpGrad : public framework::OperatorWithKernel {
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
add_two
,
ops
::
AddOp
,
ops
::
AddOpMaker
);
REGISTER_GRADIENT_OP
(
add_two
,
add_two_grad
,
ops
::
AddOpGrad
);
REGISTER_OP
(
add_two
,
ops
::
AddOp
,
ops
::
AddOpMaker
,
add_two_grad
,
ops
::
AddOpGrad
);
REGISTER_OP_CPU_KERNEL
(
add_two
,
ops
::
AddKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
paddle/operators/cross_entropy_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -68,12 +68,11 @@ OnehotCrossEntropy Operator.
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
onehot_cross_entropy
,
ops
::
OnehotCrossEntropyOp
,
ops
::
OnehotCrossEntropyOpMaker
);
ops
::
OnehotCrossEntropyOpMaker
,
onehot_cross_entropy_grad
,
ops
::
OnehotCrossEntropyGradientOp
);
REGISTER_OP_CPU_KERNEL
(
onehot_cross_entropy
,
ops
::
OnehotCrossEntropyOpKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
REGISTER_GRADIENT_OP
(
onehot_cross_entropy
,
onehot_cross_entropy_grad
,
ops
::
OnehotCrossEntropyGradientOp
);
REGISTER_OP_CPU_KERNEL
(
onehot_cross_entropy_grad
,
ops
::
OnehotCrossEntropyGradientOpKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
paddle/operators/fill_zeros_like_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -46,7 +46,8 @@ The output will have the same size with input.
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
fill_zeros_like
,
ops
::
FillZerosLikeOp
,
ops
::
FillZerosLikeOpMaker
);
REGISTER_OP_WITHOUT_GRADIENT
(
fill_zeros_like
,
ops
::
FillZerosLikeOp
,
ops
::
FillZerosLikeOpMaker
);
REGISTER_OP_CPU_KERNEL
(
fill_zeros_like
,
ops
::
FillZerosLikeKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
paddle/operators/gaussian_random_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -81,5 +81,6 @@ Use to initialize tensor with gaussian random generator.
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
gaussian_random
,
ops
::
GaussianRandomOp
,
ops
::
GaussianRandomOpMaker
);
REGISTER_OP_WITHOUT_GRADIENT
(
gaussian_random
,
ops
::
GaussianRandomOp
,
ops
::
GaussianRandomOpMaker
);
REGISTER_OP_CPU_KERNEL
(
gaussian_random
,
ops
::
GaussianRandomKernel
<
float
>
);
paddle/operators/mean_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -54,9 +54,8 @@ class MeanGradOp : public framework::OperatorWithKernel {
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
mean
,
ops
::
MeanOp
,
ops
::
MeanOpMaker
);
REGISTER_OP
(
mean
,
ops
::
MeanOp
,
ops
::
MeanOpMaker
,
mean_grad
,
ops
::
MeanGradOp
);
REGISTER_OP_CPU_KERNEL
(
mean
,
ops
::
MeanKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
REGISTER_GRADIENT_OP
(
mean
,
mean_grad
,
ops
::
MeanGradOp
);
REGISTER_OP_CPU_KERNEL
(
mean_grad
,
ops
::
MeanGradKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
paddle/operators/mul_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -70,7 +70,5 @@ class MulOpGrad : public framework::OperatorWithKernel {
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
mul
,
ops
::
MulOp
,
ops
::
MulOpMaker
);
REGISTER_GRADIENT_OP
(
mul
,
mul_grad
,
ops
::
MulOpGrad
);
REGISTER_OP
(
mul
,
ops
::
MulOp
,
ops
::
MulOpMaker
,
mul_grad
,
ops
::
MulOpGrad
);
REGISTER_OP_CPU_KERNEL
(
mul
,
ops
::
MulKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
paddle/operators/recurrent_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -246,5 +246,6 @@ RecurrentGradientOp::RecurrentGradientOp(
}
// namespace operators
}
// namespace paddle
REGISTER_OP
(
recurrent_op
,
paddle
::
operators
::
RecurrentOp
,
paddle
::
operators
::
RecurrentAlgorithmProtoAndCheckerMaker
);
REGISTER_OP_WITHOUT_GRADIENT
(
recurrent_op
,
paddle
::
operators
::
RecurrentOp
,
paddle
::
operators
::
RecurrentAlgorithmProtoAndCheckerMaker
);
paddle/operators/rowwise_add_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -54,6 +54,7 @@ for i in xrange(X.shape[0]):
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
rowwise_add
,
ops
::
RowWiseAddOp
,
ops
::
RowWiseAddOpMaker
);
REGISTER_OP_WITHOUT_GRADIENT
(
rowwise_add
,
ops
::
RowWiseAddOp
,
ops
::
RowWiseAddOpMaker
);
REGISTER_OP_CPU_KERNEL
(
rowwise_add
,
ops
::
RowWiseAddKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
paddle/operators/sgd_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -51,6 +51,6 @@ param_out = param - learning_rate * grad;
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
sgd
,
ops
::
SGDOp
,
ops
::
SGDOpMaker
);
REGISTER_OP
_WITHOUT_GRADIENT
(
sgd
,
ops
::
SGDOp
,
ops
::
SGDOpMaker
);
REGISTER_OP_CPU_KERNEL
(
sgd
,
ops
::
SGDOpKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
paddle/operators/sigmoid_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -52,9 +52,8 @@ class SigmoidOpGrad : public framework::OperatorWithKernel {
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
sigmoid
,
ops
::
SigmoidOp
,
ops
::
SigmoidOpMaker
);
REGISTER_GRADIENT_OP
(
sigmoid
,
sigmoid_grad
,
ops
::
SigmoidOpGrad
);
REGISTER_OP
(
sigmoid
,
ops
::
SigmoidOp
,
ops
::
SigmoidOpMaker
,
sigmoid_grad
,
ops
::
SigmoidOpGrad
);
REGISTER_OP_CPU_KERNEL
(
sigmoid
,
ops
::
SigmoidKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
REGISTER_OP_CPU_KERNEL
(
...
...
paddle/operators/softmax_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -62,9 +62,9 @@ class SoftmaxOpGrad : public framework::OperatorWithKernel {
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
softmax
,
ops
::
SoftmaxOp
,
ops
::
SoftmaxOpMaker
);
REGISTER_OP
(
softmax
,
ops
::
SoftmaxOp
,
ops
::
SoftmaxOpMaker
,
softmax_grad
,
ops
::
SoftmaxOpGrad
);
REGISTER_OP_CPU_KERNEL
(
softmax
,
ops
::
SoftmaxKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
REGISTER_GRADIENT_OP
(
softmax
,
softmax_grad
,
ops
::
SoftmaxOpGrad
);
REGISTER_OP_CPU_KERNEL
(
softmax_grad
,
ops
::
SoftmaxGradKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
paddle/operators/uniform_random_op.cc
浏览文件 @
cdd1a8f5
...
...
@@ -81,7 +81,7 @@ Used to initialize tensor with uniform random generator.
}
// namespace operators
}
// namespace paddle
REGISTER_OP
(
uniform_random
,
paddle
::
operators
::
UniformRandomOp
,
paddle
::
operators
::
UniformRandomOpMaker
);
REGISTER_OP
_WITHOUT_GRADIENT
(
uniform_random
,
paddle
::
operators
::
UniformRandomOp
,
paddle
::
operators
::
UniformRandomOpMaker
);
REGISTER_OP_CPU_KERNEL
(
uniform_random
,
paddle
::
operators
::
CPUUniformRandomKernel
<
float
>
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录