-   Notifications  You must be signed in to change notification settings 
- Fork 5.9k
Python Generate OpCreation Methods by OpProto #2893
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
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    
 | }; | ||
|  | ||
| 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!
| 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
| */ | ||
| 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
| 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.
|  | ||
| 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_creationsobject and its methods.There are three parts to implement this feature.
OpProtofrom C++ side. It is implemented inget_all_op_protosmethod.kwargstoOpDescbase on each op'sOpProto. TheOpDescCreationMethodclass.OpPrototodocstringbyget_docstring_from_op_protomethod.
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.pyand the unit testtest_op_creation_methods.py.