-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Python Generate OpCreation Methods by OpProto #2893
Python Generate OpCreation Methods by OpProto #2893
Conversation
All OpCreation method are generated by `create_op_creation_methods::__bootstrap__` method, and stores in `op_creations` object and its methods. There are three parts to implement this feature. 1. Get all registered `OpProto` from C++ side. It is implemented in `get_all_op_protos` method. 1. Create a function to convert `kwargs` to `OpDesc` base on each op's `OpProto`. The `OpDescCreationMethod` class. 1. Convert `OpProto` to `docstring` by `get_docstring_from_op_proto` method. All three methods are unit tested. The `__bootstrap__` just combines them together and create a method in runtime. For details, please reference the doc string in `create_op_creation_methods.py` and the unit test `test_op_creation_methods.py`.
13ec575
to
9e0c680
Compare
paddle/framework/op_registry.h
Outdated
@@ -222,6 +235,17 @@ class OpRegistry { | |||
}; | |||
|
|||
private: | |||
static void AssignTempVariable(OperatorBase* op) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assign is not a good name, maybe GenNameForTempVar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool!
for (auto& attr : op_desc.attrs()) { | ||
op->attrs_[attr.name()] = AttrTypeHelper::GetAttrValue(attr); | ||
} | ||
op_checkers().at(op_type).Check(op->attrs_); | ||
|
||
//! Convert Temporary variable name to an unique variable name. | ||
GenerateTempVariableName(op.get()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
因为temp var name是c++这边自动生成的,所以python那边就管不了这些Var了是么,这些Var应该如何创建,被谁创建?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Python这边会在运行Op之前扫描这个Op的输入和输出,进而创建对应的variable
@@ -39,6 +39,13 @@ using OperatorPtr = std::shared_ptr<OperatorBase>; | |||
*/ | |||
class OperatorBase { | |||
public: | |||
/// If a variable is a empty variable, that name will be used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should add some more comment about what is empty variable
and temp variable
protostrs = core.get_all_op_protos() | ||
ret_values = [] | ||
for pbstr in protostrs: | ||
op_proto = op_proto_pb2.OpProto.FromString(str(pbstr)) | ||
ret_values.append(op_proto) | ||
return ret_values | ||
|
||
|
||
class OpDescCreationMethod(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class OpDescCreator(object):
def create(self, *args, **kwargs):
...
return op_desc
I think above is better for reading and understanding code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A Function object
(https://en.wikipedia.org/wiki/Function_object) or functor is a very common way for many programming languages.
Using Function object
can hold internal states and make function implementation into small pieces and more readable.
@@ -17,6 +16,7 @@ | |||
|
|||
class Optimizer(object): | |||
def __init__(self, **kwargs): | |||
import py_paddle.swig_paddle as swig_api |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the purpose of this change? to speed up the importing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same reason in #2864
|
||
class TestOpCreations(unittest.TestCase): | ||
def test_all(self): | ||
add_op = creation.op_creations.add_two(X="a", Y="b", Out="z") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
creation.op_creations 感觉应该做一个alias
比如 ops 或者 operators,不过这个可以后边再搞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! except for some naming style~
All OpCreation method are generated by
create_op_creation_methods::__bootstrap__
method, and stores inop_creations
object and its methods.There are three parts to implement this feature.
OpProto
from C++ side. It is implemented inget_all_op_protos
method.kwargs
toOpDesc
base on each op'sOpProto
. TheOpDescCreationMethod
class.OpProto
todocstring
byget_docstring_from_op_proto
method.
All three methods are unit tested. The
__bootstrap__
just combinesthem together and create a method in runtime.
For details, please reference the doc string in
create_op_creation_methods.py
and the unit testtest_op_creation_methods.py
.