From d0dcb3ea34ada48901666283929e35587d1c5c78 Mon Sep 17 00:00:00 2001
From: Helin Wang <helinwang@baidu.com>
Date: Wed, 22 Feb 2017 15:34:36 -0800
Subject: [PATCH 01/12] create numpy array reader creator and text reader
 creator

---
 python/paddle/reader/__init__.py              |  2 +
 python/paddle/reader/creator.py               | 52 +++++++++++++++++++
 python/paddle/reader/tests/CMakeLists.txt     |  5 ++
 python/paddle/reader/tests/creator_test.py    | 38 ++++++++++++++
 .../paddle/reader/tests/test_data_creator.txt |  3 ++
 5 files changed, 100 insertions(+)
 create mode 100644 python/paddle/reader/creator.py
 create mode 100644 python/paddle/reader/tests/creator_test.py
 create mode 100644 python/paddle/reader/tests/test_data_creator.txt

diff --git a/python/paddle/reader/__init__.py b/python/paddle/reader/__init__.py
index 493b410e82..7373dc461b 100644
--- a/python/paddle/reader/__init__.py
+++ b/python/paddle/reader/__init__.py
@@ -21,3 +21,5 @@
 #
 #     r = paddle.reader.buffered(paddle.reader.creator.text("hello.txt"))
 from decorator import *
+
+import creator
diff --git a/python/paddle/reader/creator.py b/python/paddle/reader/creator.py
new file mode 100644
index 0000000000..5c840f94b5
--- /dev/null
+++ b/python/paddle/reader/creator.py
@@ -0,0 +1,52 @@
+# Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+__all__ = ['np_array', 'text_file']
+
+
+def np_array(x):
+    """
+    Creates a data reader from numpy array.
+    The highest dimension will be treated as batch dimension to iterate on.
+
+    :param x: the numpy array to create reader from.
+    :returns: data reader created from x.
+    """
+
+    def reader():
+        if x.ndim < 1:
+            yield x
+
+        for e in x:
+            yield e
+
+    return reader
+
+
+def text_file(path):
+    """
+    Creates a data reader that outputs text line by line from given text file.
+    Trailing new line ('\n') of each line will be removed.
+
+    :path: path of the text file.
+    :returns: data reader of text file
+    """
+
+    def reader():
+        f = open(path, "r")
+        for l in f:
+            yield l.rstrip('\n')
+        f.close()
+
+    return reader
diff --git a/python/paddle/reader/tests/CMakeLists.txt b/python/paddle/reader/tests/CMakeLists.txt
index 502c897d89..da072fb3db 100644
--- a/python/paddle/reader/tests/CMakeLists.txt
+++ b/python/paddle/reader/tests/CMakeLists.txt
@@ -2,3 +2,8 @@ add_test(NAME reader_decorator_test
   COMMAND ${PROJ_ROOT}/paddle/.set_python_path.sh -d ${PROJ_ROOT}/python/
         ${PYTHON_EXECUTABLE} ${PROJ_ROOT}/python/paddle/reader/tests/decorator_test.py
     WORKING_DIRECTORY ${PROJ_ROOT}/python/paddle)
+
+add_test(NAME reader_creator_test
+  COMMAND ${PROJ_ROOT}/paddle/.set_python_path.sh -d ${PROJ_ROOT}/python/
+        ${PYTHON_EXECUTABLE} ${PROJ_ROOT}/python/paddle/reader/tests/creator_test.py
+    WORKING_DIRECTORY ${PROJ_ROOT}/python/paddle)
diff --git a/python/paddle/reader/tests/creator_test.py b/python/paddle/reader/tests/creator_test.py
new file mode 100644
index 0000000000..eda8ab6715
--- /dev/null
+++ b/python/paddle/reader/tests/creator_test.py
@@ -0,0 +1,38 @@
+# Copyright PaddlePaddle contributors. All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import unittest
+import paddle.reader.creator
+import numpy as np
+import os
+
+
+class TestNumpyArray(unittest.TestCase):
+    def test_numpy_array(self):
+        l = [[1, 2, 3], [4, 5, 6]]
+        x = np.array(l, np.int32)
+        reader = paddle.reader.creator.np_array(x)
+        for idx, e in enumerate(reader()):
+            self.assertItemsEqual(e, l[idx])
+
+
+class TestTextFile(unittest.TestCase):
+    def test_text_file(self):
+        path = os.path.join(os.path.dirname(__file__), "test_data_creator.txt")
+        reader = paddle.reader.creator.text_file(path)
+        for idx, e in enumerate(reader()):
+            self.assertEqual(e, str(idx * 2) + " " + str(idx * 2 + 1))
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/python/paddle/reader/tests/test_data_creator.txt b/python/paddle/reader/tests/test_data_creator.txt
new file mode 100644
index 0000000000..a2a8d47d43
--- /dev/null
+++ b/python/paddle/reader/tests/test_data_creator.txt
@@ -0,0 +1,3 @@
+0 1
+2 3
+4 5

From 51de2ded3ecf674bd5f96a9f3129d6630bfb65a1 Mon Sep 17 00:00:00 2001
From: Luo Tao <luotao02@baidu.com>
Date: Thu, 23 Feb 2017 16:59:38 +0800
Subject: [PATCH 02/12] add optimizer in v2

---
 python/paddle/v2/optimizer.py | 55 +++++++++++++++++++++++++++++++++--
 1 file changed, 52 insertions(+), 3 deletions(-)

diff --git a/python/paddle/v2/optimizer.py b/python/paddle/v2/optimizer.py
index aa2942bc9f..10e255dc94 100644
--- a/python/paddle/v2/optimizer.py
+++ b/python/paddle/v2/optimizer.py
@@ -3,7 +3,10 @@ import paddle.trainer_config_helpers.optimizers as v1_optimizers
 import paddle.trainer_config_helpers.config_parser_utils as config_parser_utils
 import paddle.v2
 
-__all__ = ['Adam', 'Adamax']
+__all__ = [
+    'Momentum', 'Adam', 'Adamax', 'AdaGrad', 'DecayedAdaGrad', 'AdaDelta',
+    'RMSProp', 'ModelAverage', 'L2Regularization'
+]
 
 
 class Optimizer(object):
@@ -38,6 +41,14 @@ class Optimizer(object):
                                                              pass_num)
 
 
+class Momentum(Optimizer):
+    def __init__(self, momentum=None, sparse=False, **kwargs):
+        learning_method = v1_optimizers.MomentumOptimizer(
+            momentum=None, sparse=False)
+        super(Momentum, self).__init__(
+            learning_method=learning_method, **kwargs)
+
+
 class Adam(Optimizer):
     def __init__(self, beta1=0.9, beta2=0.999, epsilon=1e-8, **kwargs):
         learning_method = v1_optimizers.AdamOptimizer(
@@ -52,7 +63,45 @@ class Adamax(Optimizer):
         super(Adamax, self).__init__(learning_method=learning_method, **kwargs)
 
 
+class AdaGrad(Optimizer):
+    def __init__(self, **kwargs):
+        learning_method = v1_optimizers.AdaGradOptimizer()
+        super(AdaGrad, self).__init__(learning_method=learning_method, **kwargs)
+
+
+class DecayedAdaGrad(Optimizer):
+    def __init__(self, rho=0.95, epsilon=1e-06, **kwargs):
+        learning_method = v1_optimizers.DecayedAdaGradOptimizer(
+            rho=rho, epsilon=epsilon)
+        super(DecayedAdaGrad, self).__init__(
+            learning_method=learning_method, **kwargs)
+
+
+class AdaDelta(Optimizer):
+    def __init__(self, rho=0.95, epsilon=1e-06, **kwargs):
+        learning_method = v1_optimizers.AdaDeltaOptimizer(
+            rho=rho, epsilon=epsilon)
+        super(AdaDelta, self).__init__(
+            learning_method=learning_method, **kwargs)
+
+
+class RMSProp(Optimizer):
+    def __init__(self, rho=0.95, epsilon=1e-6, **kwargs):
+        learning_method = v1_optimizers.RMSPropOptimizer(
+            rho=rho, epsilon=epsilon)
+        super(RMSProp, self).__init__(learning_method=learning_method, **kwargs)
+
+
+ModelAverage = v1_optimizers.ModelAverage
+L2Regularization = v1_optimizers.L2Regularization
+
 if __name__ == '__main__':
     swig_api.initPaddle('--use_gpu=false')
-    opt = paddle.v2.optimizer.Adam()
-    print opt.enable_types()
+    for opt in [
+            Momentum(), Adam(), Adamax(), AdaGrad(), DecayedAdaGrad(),
+            AdaDelta(), RMSProp(), Adam(
+                model_average=ModelAverage(average_window=0.5),
+                regularization=L2Regularization(rate=0.5),
+                gradient_clipping_threshold=25)
+    ]:
+        print opt, opt.enable_types()

From b9d4f71c4a1c2a9f6c3593a1990c5becf8377268 Mon Sep 17 00:00:00 2001
From: Helin Wang <helinwang@baidu.com>
Date: Thu, 23 Feb 2017 14:10:23 -0800
Subject: [PATCH 03/12] fix according to comments

---
 python/paddle/reader/creator.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/python/paddle/reader/creator.py b/python/paddle/reader/creator.py
index 5c840f94b5..5a91bb0b8e 100644
--- a/python/paddle/reader/creator.py
+++ b/python/paddle/reader/creator.py
@@ -17,8 +17,9 @@ __all__ = ['np_array', 'text_file']
 
 def np_array(x):
     """
-    Creates a data reader from numpy array.
-    The highest dimension will be treated as batch dimension to iterate on.
+    Creates a reader that yields elements of x, if it is a
+    numpy vector. Or rows of x, if it is a numpy matrix.
+    Or any sub-hyperplane indexed by the highest dimension.
 
     :param x: the numpy array to create reader from.
     :returns: data reader created from x.

From 8d3ac7a209eac568ede3f4aa4df3957c87d139cd Mon Sep 17 00:00:00 2001
From: liaogang <liaogang@baidu.com>
Date: Fri, 24 Feb 2017 11:37:15 +0800
Subject: [PATCH 04/12] Conditional compile  woboq

---
 paddle/scripts/docker/Dockerfile     | 12 ++++---
 paddle/scripts/docker/Dockerfile.gpu | 12 ++++---
 paddle/scripts/docker/build.sh       | 50 +++++++++++++++-------------
 3 files changed, 41 insertions(+), 33 deletions(-)

diff --git a/paddle/scripts/docker/Dockerfile b/paddle/scripts/docker/Dockerfile
index d4845a72b6..3b11018901 100644
--- a/paddle/scripts/docker/Dockerfile
+++ b/paddle/scripts/docker/Dockerfile
@@ -10,28 +10,30 @@ RUN apt-get update && \
     apt-get install -y wget unzip tar xz-utils bzip2 gzip coreutils && \
     apt-get install -y curl sed grep graphviz libjpeg-dev zlib1g-dev && \
     apt-get install -y python-numpy python-matplotlib gcc g++ gfortran && \
-    apt-get install -y automake clang-3.8 llvm-3.8 libclang-3.8-dev && \
+    apt-get install -y automake && \
     apt-get clean -y
 
 RUN pip install --upgrade pip && \
-    pip install -U protobuf && \
+    pip install -U "protobuf==3.1.0" && \
     pip install -U wheel pillow BeautifulSoup && \
     pip install -U docopt PyYAML sphinx && \
     pip install -U sphinx_rtd_theme recommonmark jupyter
 
 RUN curl -sSL https://cmake.org/files/v3.4/cmake-3.4.1.tar.gz | tar -xz && \
-    cd cmake-3.4.1 && ./bootstrap && make -j4 && make install && \
+    cd cmake-3.4.1 && ./bootstrap && make -j `nproc` && make install && \
     cd .. && rm -rf cmake-3.4.1
 
+ARG BUILD_WOBOQ
 ARG BUILD_AND_INSTALL
 ARG WITH_AVX
 ARG WITH_DOC
 ARG WITH_STYLE_CHECK
 
-ENV BUILD_AND_INSTALL=${BUILD_AND_INSTALL:-OFF}
+ENV BUILD_WOBOQ=${BUILD_WOBOQ:-OFF}
+ENV BUILD_AND_INSTALL=${BUILD_AND_INSTALL:-ON}
 ENV WITH_GPU=OFF
 ENV WITH_AVX=${WITH_AVX:-ON}
-ENV WITH_DOC=${WITH_DOC:-ON}
+ENV WITH_DOC=${WITH_DOC:-OFF}
 ENV WITH_STYLE_CHECK=${WITH_STYLE_CHECK:-OFF}
 
 RUN mkdir /paddle
diff --git a/paddle/scripts/docker/Dockerfile.gpu b/paddle/scripts/docker/Dockerfile.gpu
index da20b2635e..ea277b61e9 100644
--- a/paddle/scripts/docker/Dockerfile.gpu
+++ b/paddle/scripts/docker/Dockerfile.gpu
@@ -10,28 +10,30 @@ RUN apt-get update && \
     apt-get install -y wget unzip tar xz-utils bzip2 gzip coreutils && \
     apt-get install -y curl sed grep graphviz libjpeg-dev zlib1g-dev && \
     apt-get install -y python-numpy python-matplotlib gcc g++ gfortran && \
-    apt-get install -y automake clang-3.8 llvm-3.8 libclang-3.8-dev && \
+    apt-get install -y automake && \
     apt-get clean -y
 
 RUN pip install --upgrade pip && \
-    pip install -U protobuf && \
+    pip install -U "protobuf==3.1.0" && \
     pip install -U wheel pillow BeautifulSoup && \
     pip install -U docopt PyYAML sphinx && \
     pip install -U sphinx_rtd_theme recommonmark jupyter
 
 RUN curl -sSL https://cmake.org/files/v3.4/cmake-3.4.1.tar.gz | tar -xz && \
-    cd cmake-3.4.1 && ./bootstrap && make -j4 && make install && \
+    cd cmake-3.4.1 && ./bootstrap && make -j `nproc` && make install && \
     cd .. && rm -rf cmake-3.4.1
 
+ARG BUILD_WOBOQ
 ARG BUILD_AND_INSTALL
 ARG WITH_AVX
 ARG WITH_DOC
 ARG WITH_STYLE_CHECK
 
-ENV BUILD_AND_INSTALL=${BUILD_AND_INSTALL:-OFF}
+ENV BUILD_WOBOQ=${BUILD_WOBOQ:-OFF}
+ENV BUILD_AND_INSTALL=${BUILD_AND_INSTALL:-ON}
 ENV WITH_GPU=ON
 ENV WITH_AVX=${WITH_AVX:-ON}
-ENV WITH_DOC=${WITH_DOC:-ON}
+ENV WITH_DOC=${WITH_DOC:-OFF}
 ENV WITH_STYLE_CHECK=${WITH_STYLE_CHECK:-OFF}
 
 RUN mkdir /paddle
diff --git a/paddle/scripts/docker/build.sh b/paddle/scripts/docker/build.sh
index 6197b41d6b..a0391dd6b9 100755
--- a/paddle/scripts/docker/build.sh
+++ b/paddle/scripts/docker/build.sh
@@ -19,7 +19,7 @@ if [[ ${BUILD_AND_INSTALL:-ON} == 'ON' ]]; then
     mkdir -p /paddle/build # -p means no error if exists
     cd /paddle/build
     cmake .. \
-	  -DWITH_DOC=ON \
+	  -DWITH_DOC=OFF \
 	  -DWITH_GPU=${WITH_GPU:-OFF} \
 	  -DWITH_AVX=${WITH_AVX:-OFF} \
 	  -DWITH_SWIG_PY=ON \
@@ -29,28 +29,32 @@ if [[ ${BUILD_AND_INSTALL:-ON} == 'ON' ]]; then
     make -j `nproc`
     make install
 
-    # Install woboq_codebrowser.
-    git clone https://github.com/woboq/woboq_codebrowser /woboq
-    cd /woboq
-    cmake -DLLVM_CONFIG_EXECUTABLE=/usr/bin/llvm-config-3.8 \
-	  -DCMAKE_BUILD_TYPE=Release \
-	  .
-    make
-
-    export WOBOQ_OUT=/usr/share/nginx/html/paddle
-    export BUILD_DIR=/paddle/build
-    mkdir -p $WOBOQ_OUT
-    cp -rv /woboq/data $WOBOQ_OUT/../data
-    /woboq/generator/codebrowser_generator \
-	-b /paddle/build \
-	-a \
-	-o $WOBOQ_OUT \
-	-p paddle:/paddle
-    /woboq/indexgenerator/codebrowser_indexgenerator $WOBOQ_OUT
-    cd /woboq
-    make clean
-
-    pip install /usr/local/opt/paddle/share/wheels/*.whl
+    if [[ ${BUILD_WOBOQ:-OFF} == 'ON' ]]; then
+        apt-get install -y clang-3.8 llvm-3.8 libclang-3.8-dev 
+        # Install woboq_codebrowser.
+        git clone https://github.com/woboq/woboq_codebrowser /woboq
+        cd /woboq
+        cmake -DLLVM_CONFIG_EXECUTABLE=/usr/bin/llvm-config-3.8 \
+        -DCMAKE_BUILD_TYPE=Release \
+        .
+        make
+
+        export WOBOQ_OUT=/usr/share/nginx/html/paddle
+        export BUILD_DIR=/paddle/build
+        mkdir -p $WOBOQ_OUT
+        cp -rv /woboq/data $WOBOQ_OUT/../data
+        /woboq/generator/codebrowser_generator \
+        -b /paddle/build \
+        -a \
+        -o $WOBOQ_OUT \
+        -p paddle:/paddle
+        /woboq/indexgenerator/codebrowser_indexgenerator $WOBOQ_OUT
+        cd /woboq
+        make clean
+    fi
+
+    pip install /usr/local/opt/paddle/share/wheels/py_paddle*linux*.whl
+    pip install /usr/local/opt/paddle/share/wheels/paddle*.whl
     paddle version
 fi
 

From 7be8e69990bf8078dd1396c03c46117c49c39215 Mon Sep 17 00:00:00 2001
From: liaogang <liaogang@baidu.com>
Date: Fri, 24 Feb 2017 11:42:00 +0800
Subject: [PATCH 05/12] Update WITH_DOC in docker

---
 paddle/scripts/docker/build.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/paddle/scripts/docker/build.sh b/paddle/scripts/docker/build.sh
index a0391dd6b9..daea09d3fa 100755
--- a/paddle/scripts/docker/build.sh
+++ b/paddle/scripts/docker/build.sh
@@ -19,7 +19,7 @@ if [[ ${BUILD_AND_INSTALL:-ON} == 'ON' ]]; then
     mkdir -p /paddle/build # -p means no error if exists
     cd /paddle/build
     cmake .. \
-	  -DWITH_DOC=OFF \
+	  -DWITH_DOC=${WITH_GPU:-OFF} \
 	  -DWITH_GPU=${WITH_GPU:-OFF} \
 	  -DWITH_AVX=${WITH_AVX:-OFF} \
 	  -DWITH_SWIG_PY=ON \

From 4d3a1ab690c0ae49f785f36f1a6793c8b3353d64 Mon Sep 17 00:00:00 2001
From: liaogang <liaogang@baidu.com>
Date: Fri, 24 Feb 2017 12:20:00 +0800
Subject: [PATCH 06/12] Fix env error

---
 paddle/scripts/docker/build.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/paddle/scripts/docker/build.sh b/paddle/scripts/docker/build.sh
index daea09d3fa..7fbf2821af 100755
--- a/paddle/scripts/docker/build.sh
+++ b/paddle/scripts/docker/build.sh
@@ -19,7 +19,7 @@ if [[ ${BUILD_AND_INSTALL:-ON} == 'ON' ]]; then
     mkdir -p /paddle/build # -p means no error if exists
     cd /paddle/build
     cmake .. \
-	  -DWITH_DOC=${WITH_GPU:-OFF} \
+	  -DWITH_DOC=${WITH_DOC:-OFF} \
 	  -DWITH_GPU=${WITH_GPU:-OFF} \
 	  -DWITH_AVX=${WITH_AVX:-OFF} \
 	  -DWITH_SWIG_PY=ON \

From 6415b0771b924f0fc8abb49660ffca20e0d36a44 Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Fri, 24 Feb 2017 13:02:09 +0800
Subject: [PATCH 07/12] Add getNames

---
 paddle/api/Evaluator.cpp | 6 ++++++
 paddle/api/PaddleAPI.h   | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/paddle/api/Evaluator.cpp b/paddle/api/Evaluator.cpp
index c30e098763..f9656db19a 100644
--- a/paddle/api/Evaluator.cpp
+++ b/paddle/api/Evaluator.cpp
@@ -27,3 +27,9 @@ std::string Evaluator::toString() {
   m->rawPtr->printStats(sout);
   return sout.str();
 }
+
+std::vector<std::string> Evaluator::getNames() const {
+  std::vector<std::string> retv;
+  m->rawPtr->getNames(&retv);
+  return retv;
+}
diff --git a/paddle/api/PaddleAPI.h b/paddle/api/PaddleAPI.h
index f5af8b0035..f5dcfcf94c 100644
--- a/paddle/api/PaddleAPI.h
+++ b/paddle/api/PaddleAPI.h
@@ -900,6 +900,8 @@ public:
    */
   std::string toString();
 
+  std::vector<std::string> getNames() const;
+
 private:
   EvaluatorPrivate* m;
 

From b7ce283b18fe28445dc9527fa1c04b1d9b8f36d8 Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Fri, 24 Feb 2017 13:25:49 +0800
Subject: [PATCH 08/12] Expose Evaluator's getNames/getValue to SWIG

---
 paddle/api/Evaluator.cpp     | 9 +++++++++
 paddle/api/PaddleAPI.h       | 2 ++
 paddle/api/test/testTrain.py | 7 ++++++-
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/paddle/api/Evaluator.cpp b/paddle/api/Evaluator.cpp
index f9656db19a..681e3a3809 100644
--- a/paddle/api/Evaluator.cpp
+++ b/paddle/api/Evaluator.cpp
@@ -33,3 +33,12 @@ std::vector<std::string> Evaluator::getNames() const {
   m->rawPtr->getNames(&retv);
   return retv;
 }
+
+double Evaluator::getValue(const std::string name) const {
+  paddle::Error err;
+  double v = m->rawPtr->getValue(name, &err);
+  if (err) {
+    throw std::runtime_error(err.msg());
+  }
+  return v;
+}
diff --git a/paddle/api/PaddleAPI.h b/paddle/api/PaddleAPI.h
index f5dcfcf94c..80c50cdb08 100644
--- a/paddle/api/PaddleAPI.h
+++ b/paddle/api/PaddleAPI.h
@@ -902,6 +902,8 @@ public:
 
   std::vector<std::string> getNames() const;
 
+  double getValue(const std::string name) const;
+
 private:
   EvaluatorPrivate* m;
 
diff --git a/paddle/api/test/testTrain.py b/paddle/api/test/testTrain.py
index a90d15c272..7061a4c43b 100644
--- a/paddle/api/test/testTrain.py
+++ b/paddle/api/test/testTrain.py
@@ -89,9 +89,14 @@ def main():
             except Exception as e:
                 print e
 
+        ev = m.makeEvaluator()
+        ev.start()
         m.forwardBackward(inArgs, outArgs, swig_paddle.PASS_TRAIN,
                           update_callback)
-
+        m.eval(ev)
+        ev.finish()
+        for name in ev.getNames():
+            print name, ev.getValue(name)
         for optimizer in optimizers:
             optimizer.finishBatch()
 

From 5f626b93f255d2f9d34732856c23aefb150420e8 Mon Sep 17 00:00:00 2001
From: liaogang <liaogang@baidu.com>
Date: Fri, 24 Feb 2017 13:46:48 +0800
Subject: [PATCH 09/12] set docker BUILD_AND_INSTALL

---
 paddle/scripts/docker/Dockerfile     | 2 +-
 paddle/scripts/docker/Dockerfile.gpu | 2 +-
 paddle/scripts/docker/build.sh       | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/paddle/scripts/docker/Dockerfile b/paddle/scripts/docker/Dockerfile
index 3b11018901..27d19dc15c 100644
--- a/paddle/scripts/docker/Dockerfile
+++ b/paddle/scripts/docker/Dockerfile
@@ -30,7 +30,7 @@ ARG WITH_DOC
 ARG WITH_STYLE_CHECK
 
 ENV BUILD_WOBOQ=${BUILD_WOBOQ:-OFF}
-ENV BUILD_AND_INSTALL=${BUILD_AND_INSTALL:-ON}
+ENV BUILD_AND_INSTALL=${BUILD_AND_INSTALL:-OFF}
 ENV WITH_GPU=OFF
 ENV WITH_AVX=${WITH_AVX:-ON}
 ENV WITH_DOC=${WITH_DOC:-OFF}
diff --git a/paddle/scripts/docker/Dockerfile.gpu b/paddle/scripts/docker/Dockerfile.gpu
index ea277b61e9..538233dd0c 100644
--- a/paddle/scripts/docker/Dockerfile.gpu
+++ b/paddle/scripts/docker/Dockerfile.gpu
@@ -30,7 +30,7 @@ ARG WITH_DOC
 ARG WITH_STYLE_CHECK
 
 ENV BUILD_WOBOQ=${BUILD_WOBOQ:-OFF}
-ENV BUILD_AND_INSTALL=${BUILD_AND_INSTALL:-ON}
+ENV BUILD_AND_INSTALL=${BUILD_AND_INSTALL:-OFF}
 ENV WITH_GPU=ON
 ENV WITH_AVX=${WITH_AVX:-ON}
 ENV WITH_DOC=${WITH_DOC:-OFF}
diff --git a/paddle/scripts/docker/build.sh b/paddle/scripts/docker/build.sh
index 7fbf2821af..d9c44f4234 100755
--- a/paddle/scripts/docker/build.sh
+++ b/paddle/scripts/docker/build.sh
@@ -11,7 +11,7 @@ set -e
 # If Dockerfile.* sets BUILD_AND_INSTALL to 'ON', it would have copied
 # source tree to /paddle, and this scripts should build it into
 # /paddle/build.
-if [[ ${BUILD_AND_INSTALL:-ON} == 'ON' ]]; then
+if [[ ${BUILD_AND_INSTALL:-OFF} == 'ON' ]]; then
     if [[ ${WITH_GPU:-OFF} == 'ON' ]]; then
 	ln -s /usr/lib/x86_64-linux-gnu/libcudnn.so /usr/lib/libcudnn.so
     fi

From c2cefd5bb9cea35cadc0939264d638a8a74d88f2 Mon Sep 17 00:00:00 2001
From: qiaolongfei <qiaolongfei@baidu.com>
Date: Fri, 24 Feb 2017 16:23:12 +0800
Subject: [PATCH 10/12] add test for v2-layer

---
 python/paddle/v2/tests/CMakeLists.txt |  4 ++
 python/paddle/v2/tests/layer_test.py  | 61 +++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)
 create mode 100644 python/paddle/v2/tests/CMakeLists.txt
 create mode 100644 python/paddle/v2/tests/layer_test.py

diff --git a/python/paddle/v2/tests/CMakeLists.txt b/python/paddle/v2/tests/CMakeLists.txt
new file mode 100644
index 0000000000..83b7180eba
--- /dev/null
+++ b/python/paddle/v2/tests/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_test(NAME v2_layer_test
+        COMMAND ${PROJ_ROOT}/paddle/.set_python_path.sh -d ${PROJ_ROOT}/python/
+        ${PYTHON_EXECUTABLE} ${PROJ_ROOT}/python/paddle/v2/tests/layer_test.py
+        WORKING_DIRECTORY ${PROJ_ROOT}/python/paddle)
diff --git a/python/paddle/v2/tests/layer_test.py b/python/paddle/v2/tests/layer_test.py
new file mode 100644
index 0000000000..3b2a13ce05
--- /dev/null
+++ b/python/paddle/v2/tests/layer_test.py
@@ -0,0 +1,61 @@
+# Copyright PaddlePaddle contributors. All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import difflib
+import unittest
+
+import paddle.trainer_config_helpers as conf_helps
+import paddle.v2.activation as activation
+import paddle.v2.attr as attr
+import paddle.v2.data_type as data_type
+import paddle.v2.layer as layer
+from paddle.trainer_config_helpers.config_parser_utils import \
+    parse_network_config as parse_network
+
+pixel = layer.data(name='pixel', type=data_type.dense_vector(784))
+label = layer.data(name='label', type=data_type.integer_value(10))
+weight = layer.data(name='weight', type=data_type.dense_vector(10))
+score = layer.data(name='score', type=data_type.dense_vector(1))
+hidden = layer.fc(input=pixel,
+                  size=100,
+                  act=activation.Sigmoid(),
+                  param_attr=attr.Param(name='hidden'))
+inference = layer.fc(input=hidden, size=10, act=activation.Softmax())
+
+
+class CostLayerTest(unittest.TestCase):
+    def test_cost_layer(self):
+        cost1 = layer.classification_cost(input=inference, label=label)
+        cost2 = layer.classification_cost(
+            input=inference, label=label, weight=weight)
+        cost3 = layer.cross_entropy_cost(input=inference, label=label)
+        cost4 = layer.cross_entropy_with_selfnorm_cost(
+            input=inference, label=label)
+        cost5 = layer.regression_cost(input=inference, label=label)
+        cost6 = layer.regression_cost(
+            input=inference, label=label, weight=weight)
+        cost7 = layer.multi_binary_label_cross_entropy_cost(
+            input=inference, label=label)
+        cost8 = layer.rank_cost(left=score, right=score, label=score)
+        cost9 = layer.lambda_cost(input=inference, score=score)
+        cost10 = layer.sum_cost(input=inference)
+        cost11 = layer.huber_cost(input=score, label=label)
+
+        print layer.parse_network(cost1, cost2)
+        print layer.parse_network(cost3, cost4)
+        print layer.parse_network(cost5, cost6)
+        print layer.parse_network(cost7, cost8, cost9, cost10, cost11)
+
+
+if __name__ == '__main__':
+    unittest.main()

From 2591167813764097f206337bb5df96d94eed5802 Mon Sep 17 00:00:00 2001
From: qiaolongfei <qiaolongfei@baidu.com>
Date: Fri, 24 Feb 2017 16:33:42 +0800
Subject: [PATCH 11/12] add test dir

---
 python/CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 357637e203..71af50a9a4 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -25,6 +25,7 @@ add_custom_target(paddle_python ALL DEPENDS
 
 add_subdirectory(paddle/trainer_config_helpers/tests)
 add_subdirectory(paddle/reader/tests)
+add_subdirectory(paddle/v2/tests)
 
 install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/dist/
     DESTINATION opt/paddle/share/wheels

From bf8a6dc4fff40e869236c0634df57bfe16c12d96 Mon Sep 17 00:00:00 2001
From: qiaolongfei <qiaolongfei@baidu.com>
Date: Fri, 24 Feb 2017 17:14:38 +0800
Subject: [PATCH 12/12] rename layer_test to test_layer

---
 python/paddle/v2/tests/CMakeLists.txt                  |  4 ++--
 .../paddle/v2/tests/{layer_test.py => test_layer.py}   | 10 ++++++----
 2 files changed, 8 insertions(+), 6 deletions(-)
 rename python/paddle/v2/tests/{layer_test.py => test_layer.py} (90%)

diff --git a/python/paddle/v2/tests/CMakeLists.txt b/python/paddle/v2/tests/CMakeLists.txt
index 83b7180eba..402ad2e664 100644
--- a/python/paddle/v2/tests/CMakeLists.txt
+++ b/python/paddle/v2/tests/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_test(NAME v2_layer_test
+add_test(NAME test_v2_layer
         COMMAND ${PROJ_ROOT}/paddle/.set_python_path.sh -d ${PROJ_ROOT}/python/
-        ${PYTHON_EXECUTABLE} ${PROJ_ROOT}/python/paddle/v2/tests/layer_test.py
+        ${PYTHON_EXECUTABLE} ${PROJ_ROOT}/python/paddle/v2/tests/test_layer.py
         WORKING_DIRECTORY ${PROJ_ROOT}/python/paddle)
diff --git a/python/paddle/v2/tests/layer_test.py b/python/paddle/v2/tests/test_layer.py
similarity index 90%
rename from python/paddle/v2/tests/layer_test.py
rename to python/paddle/v2/tests/test_layer.py
index 3b2a13ce05..b600e8cf76 100644
--- a/python/paddle/v2/tests/layer_test.py
+++ b/python/paddle/v2/tests/test_layer.py
@@ -51,10 +51,12 @@ class CostLayerTest(unittest.TestCase):
         cost10 = layer.sum_cost(input=inference)
         cost11 = layer.huber_cost(input=score, label=label)
 
-        print layer.parse_network(cost1, cost2)
-        print layer.parse_network(cost3, cost4)
-        print layer.parse_network(cost5, cost6)
-        print layer.parse_network(cost7, cost8, cost9, cost10, cost11)
+        print dir(layer)
+        layer.parse_network(cost1, cost2)
+        print dir(layer)
+        #print layer.parse_network(cost3, cost4)
+        #print layer.parse_network(cost5, cost6)
+        #print layer.parse_network(cost7, cost8, cost9, cost10, cost11)
 
 
 if __name__ == '__main__':