Skip to content
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

Merged
merged 5 commits into from
Jul 17, 2017

Conversation

reyoung
Copy link
Collaborator

@reyoung reyoung commented Jul 15, 2017

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.
  2. Create a function to convert kwargs to OpDesc base on each op's
    OpProto. The OpDescCreationMethod class.
  3. 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.

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`.
@@ -222,6 +235,17 @@ class OpRegistry {
};

private:
static void AssignTempVariable(OperatorBase* op) {
Copy link
Member

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?

Copy link
Collaborator Author

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());
Copy link
Member

@jacquesqiao jacquesqiao Jul 17, 2017

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应该如何创建,被谁创建?

Copy link
Collaborator Author

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.
Copy link
Member

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):
Copy link
Member

@jacquesqiao jacquesqiao Jul 17, 2017

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.

Copy link
Collaborator Author

@reyoung reyoung Jul 17, 2017

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
Copy link
Member

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?

Copy link
Collaborator Author

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")
Copy link
Member

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,不过这个可以后边再搞

Copy link
Member

@jacquesqiao jacquesqiao left a 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~

@reyoung reyoung merged commit df707d0 into PaddlePaddle:develop Jul 17, 2017
@reyoung reyoung deleted the feature/op_creation_methods branch July 17, 2017 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants