From 0380bfb3cf693cf233a3ad5fa4382fc65a2c7a02 Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Wed, 19 Jul 2017 17:47:06 +0800
Subject: [PATCH 01/11] Expose Net to Python

* Expose PlainNet to Python, make python can add_op, complete_add_op
* Provide a low level api to manipulate Net
* Unittest for Net::DebugString
---
 paddle/framework/net.cc                      |  5 +-
 paddle/pybind/pybind.cc                      | 71 ++++++++++++++------
 python/paddle/v2/framework/tests/test_net.py | 28 ++++++++
 3 files changed, 81 insertions(+), 23 deletions(-)
 create mode 100644 python/paddle/v2/framework/tests/test_net.py

diff --git a/paddle/framework/net.cc b/paddle/framework/net.cc
index 501536657d..407a69fda6 100644
--- a/paddle/framework/net.cc
+++ b/paddle/framework/net.cc
@@ -61,7 +61,10 @@ std::string PlainNet::DebugString() const {
   std::ostringstream os;
   os << this->type_ << ":" << std::endl;
   for (auto& op : ops_) {
-    os << "\t" << op->DebugString() << std::endl;
+    std::istringstream is(op->DebugString());
+    for (std::string line; std::getline(is, line);) {
+      os << "    " << line << std::endl;
+    }
   }
   return os.str();
 }
diff --git a/paddle/pybind/pybind.cc b/paddle/pybind/pybind.cc
index 7e84550f77..bd126f0e97 100644
--- a/paddle/pybind/pybind.cc
+++ b/paddle/pybind/pybind.cc
@@ -13,15 +13,16 @@ See the License for the specific language governing permissions and
 limitations under the License. */
 
 #include <Python.h>
-#include <paddle/framework/op_registry.h>
-#include <paddle/framework/operator.h>
-#include <paddle/framework/scope.h>
-#include <paddle/pybind/tensor_bind.h>
-#include <pybind11/numpy.h>
-#include <pybind11/pybind11.h>
-#include <pybind11/stl.h>
 #include <fstream>
 #include <vector>
+#include "paddle/framework/net.h"
+#include "paddle/framework/op_registry.h"
+#include "paddle/framework/operator.h"
+#include "paddle/framework/scope.h"
+#include "paddle/pybind/tensor_bind.h"
+#include "pybind11/numpy.h"
+#include "pybind11/pybind11.h"
+#include "pybind11/stl.h"
 
 namespace py = pybind11;
 namespace pd = paddle::framework;
@@ -29,6 +30,17 @@ namespace pd = paddle::framework;
 USE_OP(add_two);
 USE_OP_WITHOUT_KERNEL(fc);
 
+template <typename ClassType>
+void ExposeOperator(ClassType& m) {
+  m.def("infer_shape", &ClassType::type::InferShape)
+      .def("run", &ClassType::type::Run)
+      .def("outputs",
+           [](const typename ClassType::type& op) -> std::vector<std::string> {
+             return op.outputs_;
+           })
+      .def("__str__", &ClassType::type::DebugString);
+}
+
 PYBIND11_PLUGIN(core) {
   py::module m("core", "C++ core of Paddle Paddle");
 
@@ -107,21 +119,36 @@ All parameter, weight, gradient are variables in Paddle.
         return new paddle::platform::CPUDeviceContext();
       });
 
-  py::class_<pd::OperatorBase, pd::OperatorPtr>(m, "Operator")
-      .def("__str__", &pd::OperatorBase::DebugString)
-      .def_static("create",
-                  [](py::bytes protobin) {
-                    pd::OpDesc desc;
-                    PADDLE_ENFORCE(desc.ParsePartialFromString(protobin),
-                                   "Cannot parse user input to OpDesc");
-                    PADDLE_ENFORCE(desc.IsInitialized(),
-                                   "User OpDesc is not initialized, reason %s",
-                                   desc.InitializationErrorString());
-                    return pd::OpRegistry::CreateOp(desc);
-                  })
-      .def("infer_shape", &pd::OperatorBase::InferShape)
-      .def("run", &pd::OperatorBase::Run)
-      .def("outputs", [](const pd::OperatorPtr& op) { return op->outputs_; });
+  py::class_<pd::OperatorBase, pd::OperatorPtr> operator_base(m, "Operator");
+
+  operator_base.def_static("create", [](py::bytes protobin) -> pd::OperatorPtr {
+    pd::OpDesc desc;
+    PADDLE_ENFORCE(desc.ParsePartialFromString(protobin),
+                   "Cannot parse user input to OpDesc");
+    PADDLE_ENFORCE(desc.IsInitialized(),
+                   "User OpDesc is not initialized, reason %s",
+                   desc.InitializationErrorString());
+    return pd::OpRegistry::CreateOp(desc);
+  });
+  ExposeOperator(operator_base);
+
+  using PlainNetPtr = std::shared_ptr<pd::PlainNet>;
+  py::class_<pd::PlainNet, PlainNetPtr> net(m, "Net");
+
+  net.def_static("create",
+                 []() -> std::shared_ptr<pd::PlainNet> {
+                   auto retv = std::make_shared<pd::PlainNet>();
+                   retv->type_ = "naive_net";
+                   return retv;
+                 })
+      .def("add_op", &pd::PlainNet::AddOp)
+      .def("add_op",
+           [](PlainNetPtr& self, const PlainNetPtr& net) -> void {
+             self->AddOp(std::static_pointer_cast<pd::OperatorBase>(net));
+           })
+      .def("complete_add_op", &pd::PlainNet::CompleteAddOp)
+      .def("complete_add_op", [](PlainNetPtr& self) { self->CompleteAddOp(); });
+  ExposeOperator(net);
 
   return m.ptr();
 }
diff --git a/python/paddle/v2/framework/tests/test_net.py b/python/paddle/v2/framework/tests/test_net.py
new file mode 100644
index 0000000000..6a97c24990
--- /dev/null
+++ b/python/paddle/v2/framework/tests/test_net.py
@@ -0,0 +1,28 @@
+import paddle.v2.framework.core as core
+from paddle.v2.framework.create_op_creation_methods import op_creations
+import unittest
+
+
+class TestNet(unittest.TestCase):
+    def test_net_all(self):
+        net = core.Net.create()
+        op1 = op_creations.add_two(X="X", Y="Y", Out="Out")
+        net.add_op(op1)
+
+        net2 = core.Net.create()
+        net2.add_op(op_creations.fc(X="X", W="w", Y="fc.out"))
+        net2.complete_add_op(True)
+        net.add_op(net2)
+        net.complete_add_op(True)
+        expected = '''naive_net:
+    Op(add_two), inputs:(X, Y), outputs:(Out).
+    naive_net:
+        fc:
+            Op(mul), inputs:(X, w), outputs:(@TEMP@fc@0).
+            Op(sigmoid), inputs:(@TEMP@fc@0), outputs:(fc.out).
+'''
+        self.assertEqual(expected, str(net))
+
+
+if __name__ == '__main__':
+    unittest.main()

From 684563660bab79408b3bf180cf0d49786bc3dd8b Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Mon, 24 Jul 2017 11:33:20 +0800
Subject: [PATCH 02/11] Init commit

---
 .../framework/create_op_creation_methods.py   |  3 +
 python/paddle/v2/framework/network.py         | 86 +++++++++++++++++++
 2 files changed, 89 insertions(+)
 create mode 100644 python/paddle/v2/framework/network.py

diff --git a/python/paddle/v2/framework/create_op_creation_methods.py b/python/paddle/v2/framework/create_op_creation_methods.py
index 7248c3f52a..b034efffb6 100644
--- a/python/paddle/v2/framework/create_op_creation_methods.py
+++ b/python/paddle/v2/framework/create_op_creation_methods.py
@@ -220,6 +220,9 @@ def create_op_creation_method(op_proto):
     __impl__.all_input_args = [var.name for var in op_proto.inputs]
     __impl__.all_output_args = [var.name for var in op_proto.outputs]
     __impl__.all_attr_args = [attr.name for attr in op_proto.attrs]
+    __impl__.all_not_temp_output_args = [
+        var.name for var in op_proto.outputs if not var.temporary
+    ]
 
     return __impl__
 
diff --git a/python/paddle/v2/framework/network.py b/python/paddle/v2/framework/network.py
new file mode 100644
index 0000000000..347e7bb5ae
--- /dev/null
+++ b/python/paddle/v2/framework/network.py
@@ -0,0 +1,86 @@
+import paddle.v2.framework.core as core
+from paddle.v2.framework.create_op_creation_methods import op_creations
+from default_scope_funcs import create_var, get_var, get_cur_scope
+
+
+class NetworkFunctor(object):
+    def __init__(self, func, net):
+        self.func = func
+        self.net = net
+
+    def __call__(self, **kwargs):
+        inputs = self.func.all_input_args
+        for ipt in inputs:
+            if ipt in kwargs:
+                var = kwargs[ipt]
+                if isinstance(var, basestring):
+                    var_name = var
+                    var = create_var(var)
+                    self.net.var_name_map[var] = var_name
+                if not isinstance(var, core.Variable):
+                    raise TypeError(
+                        "Input of op creation must be string or variable")
+
+                kwargs[ipt] = self.net.var_name_map[var]
+
+        notemp_outputs = self.func.all_not_temp_output_args
+
+        for name in notemp_outputs:
+            if name not in kwargs:
+                kwargs[
+                    name] = self.func.__name__ + "@OUT@%d" % self.net.generate_idx
+                self.net.generate_idx += 1
+
+        outputs = self.func.all_output_args
+        for opt in outputs:
+            if opt in kwargs:
+                var = kwargs[opt]
+                if isinstance(var, basestring):
+                    var_name = var
+                    var = create_var(var)
+                    self.net.var_name_map[var] = var_name
+                if not isinstance(var, core.Variable):
+                    raise TypeError(
+                        "Output of op creation must be string or variable")
+                kwargs[opt] = self.net.var_name_map[var]
+
+        op = self.func(**kwargs)
+
+        self.net.net.add_op(op)
+
+        lst = [get_var(kwargs[opt]) for opt in notemp_outputs]
+        if len(lst) == 1:
+            return lst[0]
+        elif len(lst) == 0:
+            return None
+        else:
+            return lst
+
+
+class Network(object):
+    def __init__(self):
+        self.net = core.Net.create()
+        funcs = (func_name for func_name in dir(op_creations)
+                 if not func_name.startswith("__"))
+        self.generate_idx = 0
+        self.var_name_map = dict()
+
+        for func_name in funcs:
+            func = getattr(op_creations, func_name)
+            impl = NetworkFunctor(func, self)
+            setattr(self, func_name, impl.__call__)
+        self.__complete_add_op__ = False
+
+    def infer_shape(self):
+        self.net.infer_shape(get_cur_scope())
+
+    def __str__(self):
+        return str(self.net)
+
+
+if __name__ == '__main__':
+    net = Network()
+    out = net.add_two(X="a", Y="b")
+    fc_out = net.fc(X=out, W="fc.w", b="fc.b", activation="softmax")
+
+    print str(net)

From 9e4fac1ef42c572728e2645d506849ca1c166769 Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Mon, 24 Jul 2017 16:12:28 +0800
Subject: [PATCH 03/11] Complete Add Op

---
 python/paddle/v2/framework/network.py | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/python/paddle/v2/framework/network.py b/python/paddle/v2/framework/network.py
index 347e7bb5ae..bde48851a0 100644
--- a/python/paddle/v2/framework/network.py
+++ b/python/paddle/v2/framework/network.py
@@ -72,11 +72,21 @@ class Network(object):
         self.__complete_add_op__ = False
 
     def infer_shape(self):
+        self.complete_add_op()
         self.net.infer_shape(get_cur_scope())
 
+    def run(self, device_context):
+        self.complete_add_op()
+        self.net.run(get_cur_scope(), device_context)
+
     def __str__(self):
         return str(self.net)
 
+    def complete_add_op(self):
+        if not self.__complete_add_op__:
+            self.net.complete_add_op()
+            self.__complete_add_op__ = True
+
 
 if __name__ == '__main__':
     net = Network()

From 0ab678e9e275a079d938333d1c536fe2766f37b1 Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Mon, 24 Jul 2017 17:38:50 +0800
Subject: [PATCH 04/11] Add unittest for network

---
 paddle/pybind/pybind.cc                       | 11 -----
 python/paddle/v2/framework/network.py         | 40 +++++++++++++++++--
 .../paddle/v2/framework/tests/CMakeLists.txt  |  3 +-
 .../paddle/v2/framework/tests/test_network.py | 23 +++++++++++
 4 files changed, 62 insertions(+), 15 deletions(-)
 create mode 100644 python/paddle/v2/framework/tests/test_network.py

diff --git a/paddle/pybind/pybind.cc b/paddle/pybind/pybind.cc
index 62539c1076..43c52957a1 100644
--- a/paddle/pybind/pybind.cc
+++ b/paddle/pybind/pybind.cc
@@ -56,17 +56,6 @@ void ExposeOperator(ClassType& m) {
       .def("__str__", &ClassType::type::DebugString);
 }
 
-template <typename ClassType>
-void ExposeOperator(ClassType& m) {
-  m.def("infer_shape", &ClassType::type::InferShape)
-      .def("run", &ClassType::type::Run)
-      .def("outputs",
-           [](const typename ClassType::type& op) -> std::vector<std::string> {
-             return op.outputs_;
-           })
-      .def("__str__", &ClassType::type::DebugString);
-}
-
 PYBIND11_PLUGIN(core) {
   py::module m("core", "C++ core of PaddlePaddle");
 
diff --git a/python/paddle/v2/framework/network.py b/python/paddle/v2/framework/network.py
index bde48851a0..ade7e4b85e 100644
--- a/python/paddle/v2/framework/network.py
+++ b/python/paddle/v2/framework/network.py
@@ -2,13 +2,28 @@ import paddle.v2.framework.core as core
 from paddle.v2.framework.create_op_creation_methods import op_creations
 from default_scope_funcs import create_var, get_var, get_cur_scope
 
+__all__ = ['Network']  # Only expose Network
+
 
 class NetworkFunctor(object):
+    """
+    Network Op Creation Function. Used internally in this module.
+    It convert string input to Variable. If it is not created before, just 
+    create in scope.
+    
+    It is a functor object. means the instances are callable.
+    
+    :param func: The op creation function which generated in Python.
+    :param net: The Network instance.
+    """
+
     def __init__(self, func, net):
         self.func = func
         self.net = net
 
-    def __call__(self, **kwargs):
+    def __call__(self, *args, **kwargs):
+        if len(args) != 0:
+            raise ValueError("Paddle must use keyword argument")
         inputs = self.func.all_input_args
         for ipt in inputs:
             if ipt in kwargs:
@@ -58,6 +73,22 @@ class NetworkFunctor(object):
 
 
 class Network(object):
+    """
+    The network concept. It avoid user to manually create operator, create 
+    variable, and combine them into a Net. Just use Network.xxx can create the
+    operator, create variables in default scope, and add them into `self.net`.
+    
+    For example:
+    
+    ..  code-block: python
+    
+        net = Network()
+        out = net.add_two(X="a", Y="b")
+        fc_out = net.fc(X="out", W="fc.w")
+        
+        net.run(...)
+    """
+
     def __init__(self):
         self.net = core.Net.create()
         funcs = (func_name for func_name in dir(op_creations)
@@ -65,6 +96,9 @@ class Network(object):
         self.generate_idx = 0
         self.var_name_map = dict()
 
+        # TODO(yuyang18): This code can work, but do not generate a good
+        # docstring, try to give a better way generate function in runtime
+        # later.
         for func_name in funcs:
             func = getattr(op_creations, func_name)
             impl = NetworkFunctor(func, self)
@@ -92,5 +126,5 @@ if __name__ == '__main__':
     net = Network()
     out = net.add_two(X="a", Y="b")
     fc_out = net.fc(X=out, W="fc.w", b="fc.b", activation="softmax")
-
-    print str(net)
+    net.complete_add_op()
+    print net
diff --git a/python/paddle/v2/framework/tests/CMakeLists.txt b/python/paddle/v2/framework/tests/CMakeLists.txt
index b3eb2ef8a8..7d1229a34c 100644
--- a/python/paddle/v2/framework/tests/CMakeLists.txt
+++ b/python/paddle/v2/framework/tests/CMakeLists.txt
@@ -12,4 +12,5 @@ add_python_test(test_framework
     test_mul_op.py
     test_sigmoid_op.py
     test_softmax_op.py
-    test_rowwise_add_op.py)
+    test_rowwise_add_op.py
+    test_network.py)
diff --git a/python/paddle/v2/framework/tests/test_network.py b/python/paddle/v2/framework/tests/test_network.py
new file mode 100644
index 0000000000..310290e34b
--- /dev/null
+++ b/python/paddle/v2/framework/tests/test_network.py
@@ -0,0 +1,23 @@
+from paddle.v2.framework.network import Network
+import paddle.v2.framework.core as core
+import unittest
+
+
+class TestNet(unittest.TestCase):
+    def test_net_all(self):
+        net = Network()
+        out = net.add_two(X="X", Y="Y")
+        fc_out = net.fc(X=out, W="w")
+        net.complete_add_op()
+        self.assertTrue(isinstance(fc_out, core.Variable))
+        self.assertEqual(
+            '''Op(naive_net), inputs:(@EMPTY@, X, Y, w), outputs:(@TEMP@fc@0, add_two@OUT@0, fc@OUT@1).
+    Op(add_two), inputs:(X, Y), outputs:(add_two@OUT@0).
+    Op(fc), inputs:(add_two@OUT@0, w, @EMPTY@), outputs:(fc@OUT@1, @TEMP@fc@0).
+        Op(mul), inputs:(add_two@OUT@0, w), outputs:(@TEMP@fc@0).
+        Op(sigmoid), inputs:(@TEMP@fc@0), outputs:(fc@OUT@1).
+''', str(net))
+
+
+if __name__ == '__main__':
+    unittest.main()

From 0ceeacbe455c3e74431dfd92c4d837a52869d424 Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Mon, 24 Jul 2017 18:12:50 +0800
Subject: [PATCH 05/11] Make Scope can lookup variable name by variable

* Refine unittest also
---
 paddle/framework/scope.h                         | 13 ++++++++++++-
 paddle/framework/scope_test.cc                   |  2 ++
 paddle/pybind/pybind.cc                          | 10 +++++++++-
 python/paddle/v2/framework/network.py            | 14 ++++----------
 python/paddle/v2/framework/tests/test_network.py |  9 +++++++++
 5 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/paddle/framework/scope.h b/paddle/framework/scope.h
index 79c9ffd1a6..cbbccf465d 100644
--- a/paddle/framework/scope.h
+++ b/paddle/framework/scope.h
@@ -56,7 +56,9 @@ class Scope {
     if (var) {
       return var;
     } else {
-      vars_[name] = std::unique_ptr<Variable>(new Variable());
+      auto ptr = new Variable();
+      vars_[name] = std::unique_ptr<Variable>(ptr);
+      var_names_[ptr] = name;
       return GetVariable(name);
     }
   }
@@ -88,7 +90,16 @@ class Scope {
             (parent_ && parent_->HasVariable(name)));
   }
 
+  std::string GetVariableName(Variable* const var) const {
+    try {
+      return var_names_.at(var);
+    } catch (...) {
+      return "";
+    }
+  }
+
  private:
+  std::unordered_map<Variable*, std::string> var_names_;
   std::unordered_map<std::string, std::unique_ptr<Variable>> vars_;
   std::shared_ptr<Scope> parent_{nullptr};
 };
diff --git a/paddle/framework/scope_test.cc b/paddle/framework/scope_test.cc
index df1afb200c..51de74ddfe 100644
--- a/paddle/framework/scope_test.cc
+++ b/paddle/framework/scope_test.cc
@@ -40,6 +40,8 @@ TEST(Scope, Create) {
   /// already exist.
   Variable* var4 = scope->CreateVariable("a");
   EXPECT_EQ(var4, var2);
+
+  EXPECT_EQ("a", scope->GetVariableName(var4));
 }
 
 TEST(Scope, Parent) {
diff --git a/paddle/pybind/pybind.cc b/paddle/pybind/pybind.cc
index 43c52957a1..3588004122 100644
--- a/paddle/pybind/pybind.cc
+++ b/paddle/pybind/pybind.cc
@@ -56,6 +56,11 @@ void ExposeOperator(ClassType& m) {
       .def("__str__", &ClassType::type::DebugString);
 }
 
+static size_t UniqueIntegerGenerator() {
+  static std::atomic<size_t> generator;
+  return generator.fetch_add(1);
+}
+
 PYBIND11_PLUGIN(core) {
   py::module m("core", "C++ core of PaddlePaddle");
 
@@ -106,7 +111,8 @@ All parameter, weight, gradient are variables in Paddle.
            py::return_value_policy::reference)
       .def("create_var",
            &pd::Scope::CreateVariable,
-           py::return_value_policy::reference);
+           py::return_value_policy::reference)
+      .def("get_var_name", &pd::Scope::GetVariableName);
 
   //! @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.
@@ -166,5 +172,7 @@ All parameter, weight, gradient are variables in Paddle.
       .def("complete_add_op", [](PlainNetPtr& self) { self->CompleteAddOp(); });
   ExposeOperator(net);
 
+  m.def("unique_integer", UniqueIntegerGenerator);
+
   return m.ptr();
 }
diff --git a/python/paddle/v2/framework/network.py b/python/paddle/v2/framework/network.py
index ade7e4b85e..c85e87413e 100644
--- a/python/paddle/v2/framework/network.py
+++ b/python/paddle/v2/framework/network.py
@@ -29,35 +29,31 @@ class NetworkFunctor(object):
             if ipt in kwargs:
                 var = kwargs[ipt]
                 if isinstance(var, basestring):
-                    var_name = var
                     var = create_var(var)
-                    self.net.var_name_map[var] = var_name
                 if not isinstance(var, core.Variable):
                     raise TypeError(
                         "Input of op creation must be string or variable")
 
-                kwargs[ipt] = self.net.var_name_map[var]
+                kwargs[ipt] = get_cur_scope().get_var_name(var)
 
         notemp_outputs = self.func.all_not_temp_output_args
 
         for name in notemp_outputs:
             if name not in kwargs:
                 kwargs[
-                    name] = self.func.__name__ + "@OUT@%d" % self.net.generate_idx
-                self.net.generate_idx += 1
+                    name] = self.func.__name__ + "@OUT@%d" % core.unique_integer(
+                    )
 
         outputs = self.func.all_output_args
         for opt in outputs:
             if opt in kwargs:
                 var = kwargs[opt]
                 if isinstance(var, basestring):
-                    var_name = var
                     var = create_var(var)
-                    self.net.var_name_map[var] = var_name
                 if not isinstance(var, core.Variable):
                     raise TypeError(
                         "Output of op creation must be string or variable")
-                kwargs[opt] = self.net.var_name_map[var]
+                kwargs[opt] = get_cur_scope().get_var_name(var)
 
         op = self.func(**kwargs)
 
@@ -93,8 +89,6 @@ class Network(object):
         self.net = core.Net.create()
         funcs = (func_name for func_name in dir(op_creations)
                  if not func_name.startswith("__"))
-        self.generate_idx = 0
-        self.var_name_map = dict()
 
         # TODO(yuyang18): This code can work, but do not generate a good
         # docstring, try to give a better way generate function in runtime
diff --git a/python/paddle/v2/framework/tests/test_network.py b/python/paddle/v2/framework/tests/test_network.py
index 310290e34b..457f8f13a6 100644
--- a/python/paddle/v2/framework/tests/test_network.py
+++ b/python/paddle/v2/framework/tests/test_network.py
@@ -18,6 +18,15 @@ class TestNet(unittest.TestCase):
         Op(sigmoid), inputs:(@TEMP@fc@0), outputs:(fc@OUT@1).
 ''', str(net))
 
+        net2 = Network()
+        tmp = net2.add_two(X="X", Y="Y")
+        self.assertTrue(isinstance(tmp, core.Variable))
+        net2.complete_add_op()
+        self.assertEqual(
+            '''Op(naive_net), inputs:(X, Y), outputs:(add_two@OUT@2).
+    Op(add_two), inputs:(X, Y), outputs:(add_two@OUT@2).
+''', str(net2))
+
 
 if __name__ == '__main__':
     unittest.main()

From b80590d70b9d5d963cbf077671b4458f46cc9713 Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Tue, 25 Jul 2017 13:33:42 +0800
Subject: [PATCH 06/11] Remove test_plain_net

---
 .../paddle/v2/framework/tests/CMakeLists.txt  |  2 +-
 python/paddle/v2/framework/tests/test_net.py  | 10 ++++---
 .../v2/framework/tests/test_plain_net.py      | 30 -------------------
 3 files changed, 7 insertions(+), 35 deletions(-)
 delete mode 100644 python/paddle/v2/framework/tests/test_plain_net.py

diff --git a/python/paddle/v2/framework/tests/CMakeLists.txt b/python/paddle/v2/framework/tests/CMakeLists.txt
index 7d1229a34c..cdaaa60674 100644
--- a/python/paddle/v2/framework/tests/CMakeLists.txt
+++ b/python/paddle/v2/framework/tests/CMakeLists.txt
@@ -3,7 +3,7 @@ add_python_test(test_framework
     test_scope.py
     test_default_scope_funcs.py
     test_op_creation_methods.py
-    test_plain_net.py
+    test_net.py
     test_tensor.py
     test_fc_op.py
     test_add_two_op.py
diff --git a/python/paddle/v2/framework/tests/test_net.py b/python/paddle/v2/framework/tests/test_net.py
index 6a97c24990..db776d6b64 100644
--- a/python/paddle/v2/framework/tests/test_net.py
+++ b/python/paddle/v2/framework/tests/test_net.py
@@ -14,14 +14,16 @@ class TestNet(unittest.TestCase):
         net2.complete_add_op(True)
         net.add_op(net2)
         net.complete_add_op(True)
-        expected = '''naive_net:
+
+        expected = '''
+Op(plain_net), inputs:(@EMPTY@, X, Y, w), outputs:(@TEMP@fc@0, Out, fc.out).
     Op(add_two), inputs:(X, Y), outputs:(Out).
-    naive_net:
-        fc:
+    Op(plain_net), inputs:(@EMPTY@, X, w), outputs:(@TEMP@fc@0, fc.out).
+        Op(fc), inputs:(X, w, @EMPTY@), outputs:(fc.out, @TEMP@fc@0).
             Op(mul), inputs:(X, w), outputs:(@TEMP@fc@0).
             Op(sigmoid), inputs:(@TEMP@fc@0), outputs:(fc.out).
 '''
-        self.assertEqual(expected, str(net))
+        self.assertEqual(expected, "\n" + str(net))
 
 
 if __name__ == '__main__':
diff --git a/python/paddle/v2/framework/tests/test_plain_net.py b/python/paddle/v2/framework/tests/test_plain_net.py
deleted file mode 100644
index 2b919aca28..0000000000
--- a/python/paddle/v2/framework/tests/test_plain_net.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import paddle.v2.framework.core as core
-from paddle.v2.framework.create_op_creation_methods import op_creations
-import unittest
-
-
-class TestNet(unittest.TestCase):
-    def test_net_all(self):
-        net = core.PlainNet.create()
-        op1 = op_creations.add_two(X="X", Y="Y", Out="Out")
-        net.add_op(op1)
-
-        net2 = core.PlainNet.create()
-        net2.add_op(op_creations.fc(X="X", W="w", Y="fc.out"))
-        net2.complete_add_op(True)
-        net.add_op(net2)
-        net.complete_add_op(True)
-
-        expected = '''
-Op(plain_net), inputs:(@EMPTY@, X, Y, w), outputs:(@TEMP@fc@0, Out, fc.out).
-    Op(add_two), inputs:(X, Y), outputs:(Out).
-    Op(plain_net), inputs:(@EMPTY@, X, w), outputs:(@TEMP@fc@0, fc.out).
-        Op(fc), inputs:(X, w, @EMPTY@), outputs:(fc.out, @TEMP@fc@0).
-            Op(mul), inputs:(X, w), outputs:(@TEMP@fc@0).
-            Op(sigmoid), inputs:(@TEMP@fc@0), outputs:(fc.out).
-'''
-        self.assertEqual(expected, "\n" + str(net))
-
-
-if __name__ == '__main__':
-    unittest.main()

From 754f0c68da61ae4b7a5a67cdc9d841159bd73fbe Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Tue, 25 Jul 2017 15:26:01 +0800
Subject: [PATCH 07/11] Fix unittest

---
 paddle/framework/scope.h                         | 16 ++++++++--------
 paddle/framework/scope_test.cc                   |  3 +++
 paddle/pybind/pybind.cc                          | 10 +---------
 python/paddle/v2/framework/tests/test_network.py |  4 ++--
 4 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/paddle/framework/scope.h b/paddle/framework/scope.h
index cbbccf465d..4faaf84144 100644
--- a/paddle/framework/scope.h
+++ b/paddle/framework/scope.h
@@ -57,8 +57,8 @@ class Scope {
       return var;
     } else {
       auto ptr = new Variable();
-      vars_[name] = std::unique_ptr<Variable>(ptr);
-      var_names_[ptr] = name;
+      name_to_var_[name] = std::unique_ptr<Variable>(ptr);
+      var_to_name_[ptr] = name;
       return GetVariable(name);
     }
   }
@@ -70,8 +70,8 @@ class Scope {
    * from it's parent scope. Return nullptr if not found.
    */
   Variable* GetVariable(const std::string& name) const {
-    auto it = vars_.find(name);
-    if (it != vars_.end()) {
+    auto it = name_to_var_.find(name);
+    if (it != name_to_var_.end()) {
       return it->second.get();
     } else if (parent_ != nullptr) {
       return parent_->GetVariable(name);
@@ -86,21 +86,21 @@ class Scope {
    * Find if there is a Variable in this scope and it's parent scope
    */
   bool HasVariable(const std::string& name) const {
-    return (vars_.find(name) != vars_.end() ||
+    return (name_to_var_.find(name) != name_to_var_.end() ||
             (parent_ && parent_->HasVariable(name)));
   }
 
   std::string GetVariableName(Variable* const var) const {
     try {
-      return var_names_.at(var);
+      return var_to_name_.at(var);
     } catch (...) {
       return "";
     }
   }
 
  private:
-  std::unordered_map<Variable*, std::string> var_names_;
-  std::unordered_map<std::string, std::unique_ptr<Variable>> vars_;
+  std::unordered_map<Variable*, std::string> var_to_name_;
+  std::unordered_map<std::string, std::unique_ptr<Variable>> name_to_var_;
   std::shared_ptr<Scope> parent_{nullptr};
 };
 
diff --git a/paddle/framework/scope_test.cc b/paddle/framework/scope_test.cc
index 51de74ddfe..ff069c7be0 100644
--- a/paddle/framework/scope_test.cc
+++ b/paddle/framework/scope_test.cc
@@ -42,6 +42,9 @@ TEST(Scope, Create) {
   EXPECT_EQ(var4, var2);
 
   EXPECT_EQ("a", scope->GetVariableName(var4));
+  Scope scope2;
+  auto var = scope2.CreateVariable("tmp");
+  EXPECT_EQ("", scope->GetVariableName(var));
 }
 
 TEST(Scope, Parent) {
diff --git a/paddle/pybind/pybind.cc b/paddle/pybind/pybind.cc
index 3588004122..0b152d03c0 100644
--- a/paddle/pybind/pybind.cc
+++ b/paddle/pybind/pybind.cc
@@ -15,14 +15,6 @@ limitations under the License. */
 #include <Python.h>
 #include <fstream>
 #include <vector>
-#include "paddle/framework/net.h"
-#include "paddle/framework/op_registry.h"
-#include "paddle/framework/operator.h"
-#include "paddle/framework/scope.h"
-#include "paddle/pybind/tensor_bind.h"
-#include "pybind11/numpy.h"
-#include "pybind11/pybind11.h"
-#include "pybind11/stl.h"
 
 #include "paddle/framework/net.h"
 #include "paddle/framework/op_registry.h"
@@ -160,7 +152,7 @@ All parameter, weight, gradient are variables in Paddle.
   net.def_static("create",
                  []() -> std::shared_ptr<pd::PlainNet> {
                    auto retv = std::make_shared<pd::PlainNet>();
-                   retv->type_ = "naive_net";
+                   retv->type_ = "plain_net";
                    return retv;
                  })
       .def("add_op", &pd::PlainNet::AddOp)
diff --git a/python/paddle/v2/framework/tests/test_network.py b/python/paddle/v2/framework/tests/test_network.py
index 457f8f13a6..6d53e233e9 100644
--- a/python/paddle/v2/framework/tests/test_network.py
+++ b/python/paddle/v2/framework/tests/test_network.py
@@ -11,7 +11,7 @@ class TestNet(unittest.TestCase):
         net.complete_add_op()
         self.assertTrue(isinstance(fc_out, core.Variable))
         self.assertEqual(
-            '''Op(naive_net), inputs:(@EMPTY@, X, Y, w), outputs:(@TEMP@fc@0, add_two@OUT@0, fc@OUT@1).
+            '''Op(plain_net), inputs:(@EMPTY@, X, Y, w), outputs:(@TEMP@fc@0, add_two@OUT@0, fc@OUT@1).
     Op(add_two), inputs:(X, Y), outputs:(add_two@OUT@0).
     Op(fc), inputs:(add_two@OUT@0, w, @EMPTY@), outputs:(fc@OUT@1, @TEMP@fc@0).
         Op(mul), inputs:(add_two@OUT@0, w), outputs:(@TEMP@fc@0).
@@ -23,7 +23,7 @@ class TestNet(unittest.TestCase):
         self.assertTrue(isinstance(tmp, core.Variable))
         net2.complete_add_op()
         self.assertEqual(
-            '''Op(naive_net), inputs:(X, Y), outputs:(add_two@OUT@2).
+            '''Op(plain_net), inputs:(X, Y), outputs:(add_two@OUT@2).
     Op(add_two), inputs:(X, Y), outputs:(add_two@OUT@2).
 ''', str(net2))
 

From e3f5fdcc7a242ec8d65e20554bbc2ceb79c0c900 Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Tue, 25 Jul 2017 17:04:45 +0800
Subject: [PATCH 08/11] Make PADDLE_ENFORCE and PADDLE_THROW catchable

* Use EnforceNotMet to unify all exception types.
---
 paddle/platform/enforce.h       | 68 ++++++++++++++++++---------------
 paddle/platform/enforce_test.cc |  2 +-
 2 files changed, 38 insertions(+), 32 deletions(-)

diff --git a/paddle/platform/enforce.h b/paddle/platform/enforce.h
index b06ab8a2f1..a3a10fc07f 100644
--- a/paddle/platform/enforce.h
+++ b/paddle/platform/enforce.h
@@ -36,6 +36,21 @@ limitations under the License. */
 namespace paddle {
 namespace platform {
 
+struct EnforceNotMet : public std::exception {
+  std::exception_ptr exp_;
+  std::string err_str_;
+
+  EnforceNotMet(std::exception_ptr e, const char* f, int l) : exp_(e) {
+    try {
+      std::rethrow_exception(exp_);
+    } catch (const std::exception& exp) {
+      err_str_ = string::Sprintf("%s at [%s:%d]", exp.what(), f, l);
+    }
+  }
+
+  const char* what() const noexcept { return err_str_.c_str(); }
+};
+
 // Because most enforce conditions would evaluate to true, we can use
 // __builtin_expect to instruct the C++ compiler to generate code that
 // always forces branch prediction of true.
@@ -52,9 +67,7 @@ template <typename... Args>
 inline typename std::enable_if<sizeof...(Args) != 0, void>::type throw_on_error(
     int stat, const Args&... args) {
   if (UNLIKELY(!(stat))) {
-    throw std::runtime_error(
-        string::Sprintf(args...) +
-        string::Sprintf(" at [%s:%s];", __FILE__, __LINE__));
+    throw std::runtime_error(string::Sprintf(args...));
   }
 }
 
@@ -64,12 +77,8 @@ template <typename... Args>
 inline typename std::enable_if<sizeof...(Args) != 0, void>::type throw_on_error(
     cudaError_t e, const Args&... args) {
   if (UNLIKELY(e)) {
-    // clang-format off
-    throw thrust::system_error(
-        e, thrust::cuda_category(),
-        string::Sprintf(args...) +
-        string::Sprintf(" at [%s:%s];", __FILE__, __LINE__));
-    // clang-format on
+    throw thrust::system_error(e, thrust::cuda_category(),
+                               string::Sprintf(args...));
   }
 }
 
@@ -77,12 +86,8 @@ template <typename... Args>
 inline typename std::enable_if<sizeof...(Args) != 0, void>::type throw_on_error(
     curandStatus_t stat, const Args&... args) {
   if (stat != CURAND_STATUS_SUCCESS) {
-    // clang-format off
-    throw thrust::system_error(
-        cudaErrorLaunchFailure, thrust::cuda_category(),
-        string::Sprintf(args...) +
-        string::Sprintf(" at [%s:%s];", __FILE__, __LINE__));
-    // clang-format on
+    throw thrust::system_error(cudaErrorLaunchFailure, thrust::cuda_category(),
+                               string::Sprintf(args...));
   }
 }
 
@@ -92,12 +97,8 @@ inline typename std::enable_if<sizeof...(Args) != 0, void>::type throw_on_error(
   if (stat == CUDNN_STATUS_SUCCESS) {
     return;
   } else {
-    // clang-format off
-    throw std::runtime_error(
-        platform::dynload::cudnnGetErrorString(stat) +
-        string::Sprintf(args...) +
-        string::Sprintf(" at [%s:%s];", __FILE__, __LINE__));
-    // clang-format on
+    throw std::runtime_error(platform::dynload::cudnnGetErrorString(stat) +
+                             string::Sprintf(args...));
   }
 }
 
@@ -126,22 +127,27 @@ inline typename std::enable_if<sizeof...(Args) != 0, void>::type throw_on_error(
   } else if (stat == CUBLAS_STATUS_LICENSE_ERROR) {
     err = "CUBLAS: license error, ";
   }
-  throw std::runtime_error(err + string::Sprintf(args...) +
-                           string::Sprintf(" at [%s:%s];", __FILE__, __LINE__));
+  throw std::runtime_error(err + string::Sprintf(args...));
 }
 
 #endif  // PADDLE_ONLY_CPU
 
-#define PADDLE_THROW(...)                                     \
-  do {                                                        \
-    throw std::runtime_error(                                 \
-        string::Sprintf(__VA_ARGS__) +                        \
-        string::Sprintf(" at [%s:%s];", __FILE__, __LINE__)); \
+#define PADDLE_THROW(...)                                      \
+  do {                                                         \
+    throw ::paddle::platform::EnforceNotMet(                   \
+        std::make_exception_ptr(                               \
+            std::runtime_error(string::Sprintf(__VA_ARGS__))), \
+        __FILE__, __LINE__);                                   \
   } while (0)
 
-#define PADDLE_ENFORCE(...)                          \
-  do {                                               \
-    ::paddle::platform::throw_on_error(__VA_ARGS__); \
+#define PADDLE_ENFORCE(...)                                             \
+  do {                                                                  \
+    try {                                                               \
+      ::paddle::platform::throw_on_error(__VA_ARGS__);                  \
+    } catch (...) {                                                     \
+      throw ::paddle::platform::EnforceNotMet(std::current_exception(), \
+                                              __FILE__, __LINE__);      \
+    }                                                                   \
   } while (0)
 
 }  // namespace platform
diff --git a/paddle/platform/enforce_test.cc b/paddle/platform/enforce_test.cc
index d7152f8150..2ac31812a8 100644
--- a/paddle/platform/enforce_test.cc
+++ b/paddle/platform/enforce_test.cc
@@ -23,7 +23,7 @@ TEST(ENFORCE, FAILED) {
   bool in_catch = false;
   try {
     PADDLE_ENFORCE(false, "Enforce is not ok %d at all", 123);
-  } catch (const std::runtime_error& error) {
+  } catch (paddle::platform::EnforceNotMet error) {
     // your error handling code here
     in_catch = true;
     std::string msg = "Enforce is not ok 123 at all";

From bc09551e8cd9ec23c538d1782bc4fdacf2dbf6a3 Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Tue, 25 Jul 2017 17:36:12 +0800
Subject: [PATCH 09/11] Fix unittest

---
 paddle/framework/net_op_test.cc      |  2 +-
 paddle/framework/op_registry_test.cc | 10 +++++-----
 paddle/framework/tensor_test.cc      |  4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/paddle/framework/net_op_test.cc b/paddle/framework/net_op_test.cc
index 20b42cbb49..d924058624 100644
--- a/paddle/framework/net_op_test.cc
+++ b/paddle/framework/net_op_test.cc
@@ -69,7 +69,7 @@ TEST(OpKernel, all) {
   net->Run(scope, dev_ctx);
   ASSERT_EQ(2, infer_shape_cnt);
   ASSERT_EQ(2, run_cnt);
-  ASSERT_THROW(net->AddOp(op2), std::runtime_error);
+  ASSERT_THROW(net->AddOp(op2), paddle::platform::EnforceNotMet);
 }
 TEST(AddBackwardOp, TestGradOp) {
   auto net = std::make_shared<PlainNet>();
diff --git a/paddle/framework/op_registry_test.cc b/paddle/framework/op_registry_test.cc
index 05095372d8..2ef781bf86 100644
--- a/paddle/framework/op_registry_test.cc
+++ b/paddle/framework/op_registry_test.cc
@@ -90,7 +90,7 @@ TEST(OpRegistry, IllegalAttr) {
   bool caught = false;
   try {
     paddle::framework::OpRegistry::CreateOp(op_desc);
-  } catch (std::runtime_error& err) {
+  } catch (paddle::platform::EnforceNotMet err) {
     caught = true;
     std::string msg = "larger_than check fail";
     const char* err_msg = err.what();
@@ -136,7 +136,7 @@ TEST(OpRegistry, CustomChecker) {
   bool caught = false;
   try {
     paddle::framework::OpRegistry::CreateOp(op_desc);
-  } catch (std::runtime_error& err) {
+  } catch (paddle::platform::EnforceNotMet err) {
     caught = true;
     std::string msg = "Attribute 'test_attr' is required!";
     const char* err_msg = err.what();
@@ -154,7 +154,7 @@ TEST(OpRegistry, CustomChecker) {
   caught = false;
   try {
     paddle::framework::OpRegistry::CreateOp(op_desc);
-  } catch (std::runtime_error& err) {
+  } catch (paddle::platform::EnforceNotMet err) {
     caught = true;
     std::string msg = "'test_attr' must be even!";
     const char* err_msg = err.what();
@@ -192,7 +192,7 @@ TEST(ProtoMaker, DuplicatedAttr) {
   pd::OpProto op_proto;
   pd::OpAttrChecker op_checker;
   auto proto_maker = TestAttrProtoMaker(&op_proto, &op_checker);
-  ASSERT_THROW(proto_maker.Validate(), std::runtime_error);
+  ASSERT_THROW(proto_maker.Validate(), paddle::platform::EnforceNotMet);
 }
 
 class TestInOutProtoMaker : public pd::OpProtoAndCheckerMaker {
@@ -208,5 +208,5 @@ TEST(ProtoMaker, DuplicatedInOut) {
   pd::OpProto op_proto;
   pd::OpAttrChecker op_checker;
   auto proto_maker = TestInOutProtoMaker(&op_proto, &op_checker);
-  ASSERT_THROW(proto_maker.Validate(), std::runtime_error);
+  ASSERT_THROW(proto_maker.Validate(), paddle::platform::EnforceNotMet);
 }
diff --git a/paddle/framework/tensor_test.cc b/paddle/framework/tensor_test.cc
index 089844dc01..530a8fb05e 100644
--- a/paddle/framework/tensor_test.cc
+++ b/paddle/framework/tensor_test.cc
@@ -33,7 +33,7 @@ TEST(Tensor, DataAssert) {
   bool caught = false;
   try {
     src_tensor.data<double>();
-  } catch (std::runtime_error& err) {
+  } catch (paddle::platform::EnforceNotMet err) {
     caught = true;
     std::string msg =
         "Tenosr holds no memory. Call Tensor::mutable_data first.";
@@ -107,7 +107,7 @@ TEST(Tensor, ShareDataWith) {
     bool caught = false;
     try {
       dst_tensor.ShareDataWith<float>(src_tensor);
-    } catch (std::runtime_error& err) {
+    } catch (paddle::platform::EnforceNotMet err) {
       caught = true;
       std::string msg =
           "Tenosr holds no memory. Call Tensor::mutable_data first.";

From e5cb9b77b6026912a34be7bb8044ddad76450842 Mon Sep 17 00:00:00 2001
From: dongzhihong <dzhwinter@gmail.com>
Date: Wed, 26 Jul 2017 09:37:36 +0800
Subject: [PATCH 10/11] "fix gen list"

---
 python/paddle/v2/dataset/mq2007.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/python/paddle/v2/dataset/mq2007.py b/python/paddle/v2/dataset/mq2007.py
index cffb319ad8..b705c9109b 100644
--- a/python/paddle/v2/dataset/mq2007.py
+++ b/python/paddle/v2/dataset/mq2007.py
@@ -242,9 +242,9 @@ def gen_list(querylist):
     if not isinstance(querylist, QueryList):
         querylist = QueryList(querylist)
     querylist._correct_ranking_()
-    relevance_score_list = [query.relevance_score for query in querylist]
+    relevance_score_list = [[query.relevance_score] for query in querylist]
     feature_vector_list = [query.feature_vector for query in querylist]
-    yield np.array(relevance_score_list).T, np.array(feature_vector_list)
+    yield np.array(relevance_score_list), np.array(feature_vector_list)
 
 
 def query_filter(querylists):

From ccdc26284897f39d57e6f93ba1e264e6e0473c1d Mon Sep 17 00:00:00 2001
From: caoying03 <caoying03@baidu.com>
Date: Tue, 25 Jul 2017 15:29:02 +0800
Subject: [PATCH 11/11] enable v2 use cudnn batch norm automatically.

---
 python/paddle/trainer/config_parser.py | 3 +--
 python/paddle/v2/__init__.py           | 8 ++++++++
 python/paddle/v2/layer.py              | 3 ---
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/python/paddle/trainer/config_parser.py b/python/paddle/trainer/config_parser.py
index fc112f1327..5477158ecb 100644
--- a/python/paddle/trainer/config_parser.py
+++ b/python/paddle/trainer/config_parser.py
@@ -2055,8 +2055,7 @@ class BatchNormLayer(LayerBase):
         # Automatically select cudnn_batch_norm for GPU and batch_norm for CPU.
         # Also based on cudnn version.
         use_cudnn = use_gpu and batch_norm_type != "batch_norm" and \
-            ((not parallel_nn) or self.config.device > -1) and \
-            cudnn_version >= 4007
+                ((not parallel_nn) or self.config.device > -1)
         self.layer_type = "cudnn_batch_norm" if use_cudnn else "batch_norm"
         super(BatchNormLayer, self).__init__(
             name, self.layer_type, 0, inputs=inputs, **xargs)
diff --git a/python/paddle/v2/__init__.py b/python/paddle/v2/__init__.py
index 07ab2c9b18..5bea980611 100644
--- a/python/paddle/v2/__init__.py
+++ b/python/paddle/v2/__init__.py
@@ -34,6 +34,7 @@ import minibatch
 import plot
 import image
 import model
+import paddle.trainer.config_parser as cp
 
 __all__ = [
     'optimizer',
@@ -58,6 +59,8 @@ __all__ = [
     'model',
 ]
 
+cp.begin_parse()
+
 
 def init(**kwargs):
     import py_paddle.swig_paddle as api
@@ -73,6 +76,11 @@ def init(**kwargs):
     for key in args_dict.keys():
         args.append('--%s=%s' % (key, str(args_dict[key])))
 
+    if 'use_gpu' in kwargs:
+        cp.g_command_config_args['use_gpu'] = kwargs['use_gpu']
+    assert 'parallel_nn' not in kwargs, ("currently 'parallel_nn' is not "
+                                         "supported in v2 APIs.")
+
     api.initPaddle(*args)
 
 
diff --git a/python/paddle/v2/layer.py b/python/paddle/v2/layer.py
index 4ade1c6f32..6a2bb8d337 100644
--- a/python/paddle/v2/layer.py
+++ b/python/paddle/v2/layer.py
@@ -324,6 +324,3 @@ def parse_network(output_layers, extra_layers=None):
 
 def get_layer(name):
     return config_base.__layer_map__.get(name)
-
-
-cp.begin_parse()