提交 61f4706b 编写于 作者: W wanghaoshuang

Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into fix_avg

repos:
- repo: https://github.com/Lucas-C/pre-commit-hooks.git - repo: https://github.com/Lucas-C/pre-commit-hooks.git
sha: v1.0.1 sha: v1.0.1
hooks: hooks:
...@@ -25,6 +26,14 @@ ...@@ -25,6 +26,14 @@
entry: bash ./.clang_format.hook -i entry: bash ./.clang_format.hook -i
language: system language: system
files: \.(c|cc|cxx|cpp|cu|h|hpp|hxx|proto)$ files: \.(c|cc|cxx|cpp|cu|h|hpp|hxx|proto)$
- repo: local
hooks:
- id: cpplint-cpp-source
name: cpplint
description: Check C++ code style using cpplint.py.
entry: bash ./tools/codestyle/cpplint_pre_commit.hook
language: system
files: \.(c|cc|cxx|cpp|cu|h|hpp|hxx)$
- repo: https://github.com/PaddlePaddle/pre-commit-golang - repo: https://github.com/PaddlePaddle/pre-commit-golang
sha: 8337620115c25ff8333f1b1a493bd031049bd7c0 sha: 8337620115c25ff8333f1b1a493bd031049bd7c0
hooks: hooks:
......
...@@ -34,7 +34,7 @@ addons: ...@@ -34,7 +34,7 @@ addons:
- automake - automake
- libtool - libtool
- ccache - ccache
ssh_known_hosts: 52.76.173.135 ssh_known_hosts: 13.229.163.131
before_install: before_install:
- if [[ "$JOB" == "check_style" ]]; then sudo ln -s /usr/bin/clang-format-3.8 /usr/bin/clang-format; fi - if [[ "$JOB" == "check_style" ]]; then sudo ln -s /usr/bin/clang-format-3.8 /usr/bin/clang-format; fi
# Paddle is using protobuf 3.1 currently. Protobuf 3.2 breaks the compatibility. So we specify the python # Paddle is using protobuf 3.1 currently. Protobuf 3.2 breaks the compatibility. So we specify the python
......
add_custom_target(paddle_apis ALL
DEPENDS paddle_v2_apis paddle_fluid_apis)
add_custom_target(paddle_docs ALL
DEPENDS paddle_v2_docs paddle_v2_docs_cn
paddle_fluid_docs paddle_fluid_docs_cn)
add_subdirectory(v2) add_subdirectory(v2)
add_subdirectory(fluid) add_subdirectory(fluid)
...@@ -27,6 +27,8 @@ sphinx_add_target(paddle_fluid_docs ...@@ -27,6 +27,8 @@ sphinx_add_target(paddle_fluid_docs
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_HTML_DIR_EN}) ${SPHINX_HTML_DIR_EN})
add_dependencies(paddle_fluid_docs gen_proto_py)
# configured documentation tools and intermediate build results # configured documentation tools and intermediate build results
set(BINARY_BUILD_DIR_CN "${CMAKE_CURRENT_BINARY_DIR}/cn/_build") set(BINARY_BUILD_DIR_CN "${CMAKE_CURRENT_BINARY_DIR}/cn/_build")
...@@ -47,3 +49,7 @@ sphinx_add_target(paddle_fluid_docs_cn ...@@ -47,3 +49,7 @@ sphinx_add_target(paddle_fluid_docs_cn
${SPHINX_CACHE_DIR_CN} ${SPHINX_CACHE_DIR_CN}
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_HTML_DIR_CN}) ${SPHINX_HTML_DIR_CN})
add_dependencies(paddle_fluid_docs_cn gen_proto_py)
add_subdirectory(api)
# configured documentation tools and intermediate build results
set(BINARY_BUILD_DIR_EN "${CMAKE_CURRENT_BINARY_DIR}/en/_build")
# Sphinx cache with pickled ReST documents
set(SPHINX_CACHE_DIR_EN "${CMAKE_CURRENT_BINARY_DIR}/en/_doctrees")
# HTML output director
set(SPHINX_HTML_DIR_EN "${CMAKE_CURRENT_BINARY_DIR}/en/html")
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/../../templates/conf.py.en.in"
"${BINARY_BUILD_DIR_EN}/conf.py"
@ONLY)
sphinx_add_target(paddle_fluid_apis
html
${BINARY_BUILD_DIR_EN}
${SPHINX_CACHE_DIR_EN}
${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_HTML_DIR_EN})
add_dependencies(paddle_fluid_apis gen_proto_py framework_py_proto copy_paddle_pybind)
# API Doc Standard
- [API Doc Structure](#API Doc Structure)
- [Format and Examples](#Format and Examples)
- [Complete Example](#Complete Example)
## API Doc Structure
API Doc should contain the following parts(please write them in order):
- Python API Definition
The definition of API
- Function Description
Description of API's function.
The description includes: meaning, purpose and operation on input of API, reference and corresponding link(if any), formula(if necessary) and explanations of key variables in the formula.
- Args Description
Description of API parameters.
Introduce parameters one by one according to the order in API definition.
The introduction includes: data type, default value(if any), meaning, etc.
- Returns
Introduction of API returned value.
Introduce meaning of returned value, provide correspoding format if necessary.
If returned value is a tuple containing multiple parameters, then introduce parameters one by one in order.
- Raises(if any)
Abnormality, error that may occur, and possible reasons. If there are more than one possible abnormity or error, they should be listed in order.
- Note(if any)
Matters needing attention. If there are more than one matters, they should be listed in order.
- Examples
Examples of how to use API.
## Format and Examples
API documentation must obey reStructuredText format, please refer to [here](http://sphinx-doc-zh.readthedocs.io/en/latest/rest.html).
Format and examples of each part of API documantation are as follows: (take fc for example)
- Python API Definition
- Format
[Python API Definition]
- Example
```
fc(input,
size,
num_flatten_dims=1,
param_attr=None,
bias_attr=None,
act=None,
name=None,
main_program=None,
startup_program=None)
```
- Function Description
- Format
This part contains (please write them in order):
[Function Description]
[Formula]
[Symbols' Descriptions if necessary]
[References if necessary]
- Example
[Function Description]
```
**Fully Connected Layer**
The fully connected layer can take multiple tensors as its inputs. It
creates a variable called weights for each input tensor, which represents
a fully connected weight matrix from each input unit to each output unit.
The fully connected layer multiplies each input tensor with its coresponding
weight to produce an output Tensor. If multiple input tensors are given,
the results of multiple multiplications will be sumed up. If bias_attr is
not None, a bias variable will be created and added to the output. Finally,
if activation is not None, it will be applied to the output as well.
```
[Formula]
```
This process can be formulated as follows:
.. math::
Out = Act({\sum_{i=0}^{N-1}X_iW_i + b})
```
[Symbols' Descriptions if necessary]
```
In the above equation:
* :math:`N`: Number of the input.
* :math:`X_i`: The input tensor.
* :math:`W`: The weights created by this layer.
* :math:`b`: The bias parameter created by this layer (if needed).
* :math:`Act`: The activation function.
* :math:`Out`: The output tensor.
```
[References if necessary]
Since there is no need for reference of fc, we omit them here. Under other circumstances, please provide explicit reference and link, take layer_norm for example:
```
Refer to `Layer Normalization <https://arxiv.org/pdf/1607.06450v1.pdf>`_ for more details.
```
- Args Description
- Format
\[Arg's Name\][(Data Type, Default Value)][Description]
- Example
part of fc parameters are as follows:
```
Args:
input (Variable|list of Variable): The input tensor(s) of this layer, and the dimension of
the input tensor(s) is at least 2.
param_attr (ParamAttr|list of ParamAttr, default None): The parameter attribute for learnable
parameters/weights of this layer.
name (str, default None): The name of this layer.
```
- Returns
- Format
[Name][Shape]
- Example
```
Returns:
A tensor variable storing the transformation result.
```
when returned value contain more than one tuple, please introduce every parameter in order, take dynamic_lstm for example:
```
Returns:
A tuple containing:
The hidden state of LSTM whose shape is (T X D).
The cell state of LSTM whose shape is (T X D).
```
- Raises
- Format
[Exception Type][Condition]
- Example
```
Raises:
ValueError: If the rank of the input is less than 2.
```
- Note
- Format
[Note]
- Example
there is no Note in fc, so we omit this part. If there is any note, please write clearly. If there are more than one notes, please list them in order. Take scaled\_dot\_product\_attention for example:
```
Note:
1. When num_heads > 1, three linear projections are learned respectively
to map input queries, keys and values into queries', keys' and values'.
queries', keys' and values' have the same shapes with queries, keys
and values.
2. When num_heads == 1, scaled_dot_product_attention has no learnable
parameters.
```
- Examples
- Format
\[Python Code Snipper]
- Example
```
Examples:
.. code-block:: python
data = fluid.layers.data(name="data", shape=[32, 32], dtype="float32")
fc = fluid.layers.fc(input=data, size=1000, act="tanh")
```
## Complete Example
Complete Example of fc please see [here](src/fc.py)
...@@ -20,13 +20,15 @@ configure_file( ...@@ -20,13 +20,15 @@ configure_file(
"${BINARY_BUILD_DIR_EN}/conf.py" "${BINARY_BUILD_DIR_EN}/conf.py"
@ONLY) @ONLY)
sphinx_add_target(paddle_docs sphinx_add_target(paddle_v2_docs
html html
${BINARY_BUILD_DIR_EN} ${BINARY_BUILD_DIR_EN}
${SPHINX_CACHE_DIR_EN} ${SPHINX_CACHE_DIR_EN}
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_HTML_DIR_EN}) ${SPHINX_HTML_DIR_EN})
add_dependencies(paddle_v2_docs gen_proto_py)
# configured documentation tools and intermediate build results # configured documentation tools and intermediate build results
set(BINARY_BUILD_DIR_CN "${CMAKE_CURRENT_BINARY_DIR}/cn/_build") set(BINARY_BUILD_DIR_CN "${CMAKE_CURRENT_BINARY_DIR}/cn/_build")
...@@ -41,11 +43,13 @@ configure_file( ...@@ -41,11 +43,13 @@ configure_file(
"${BINARY_BUILD_DIR_CN}/conf.py" "${BINARY_BUILD_DIR_CN}/conf.py"
@ONLY) @ONLY)
sphinx_add_target(paddle_docs_cn sphinx_add_target(paddle_v2_docs_cn
html html
${BINARY_BUILD_DIR_CN} ${BINARY_BUILD_DIR_CN}
${SPHINX_CACHE_DIR_CN} ${SPHINX_CACHE_DIR_CN}
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_HTML_DIR_CN}) ${SPHINX_HTML_DIR_CN})
add_dependencies(paddle_v2_docs_cn gen_proto_py)
add_subdirectory(api) add_subdirectory(api)
...@@ -12,9 +12,11 @@ configure_file( ...@@ -12,9 +12,11 @@ configure_file(
"${BINARY_BUILD_DIR_EN}/conf.py" "${BINARY_BUILD_DIR_EN}/conf.py"
@ONLY) @ONLY)
sphinx_add_target(paddle_api_docs sphinx_add_target(paddle_v2_apis
html html
${BINARY_BUILD_DIR_EN} ${BINARY_BUILD_DIR_EN}
${SPHINX_CACHE_DIR_EN} ${SPHINX_CACHE_DIR_EN}
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${SPHINX_HTML_DIR_EN}) ${SPHINX_HTML_DIR_EN})
add_dependencies(paddle_v2_apis gen_proto_py framework_py_proto copy_paddle_pybind)
...@@ -139,3 +139,77 @@ PaddlePaddle使用avx SIMD指令提高cpu执行效率,因此错误的使用二 ...@@ -139,3 +139,77 @@ PaddlePaddle使用avx SIMD指令提高cpu执行效率,因此错误的使用二
touch ../extern_mklml-stamp/extern_mklml-download touch ../extern_mklml-stamp/extern_mklml-download
// 4. 接着编译即可 // 4. 接着编译即可
9. 在Mac上无法安装numpy等Python包,权限错误
------------------
Mac上对自带的Python和包有严格的权限保护,最好不要在自带的Python上安装。建议用virtualenv建立一个新的Python环境来操作。
virtualenv的基本原理是将机器上的Python运行所需的运行环境完整地拷贝一份。我们可以在一台机器上制造多份拷贝,并在这多个拷贝之间自由切换,这样就相当于在一台机器上拥有了多个相互隔离、互不干扰的Python环境。
下面简单介绍下如何用virtualenv为Paddle生成一个专用的Python环境:
安装virtualenv:
::::::::::::::::
virtualenv本身也是Python的一个包,可以用pip进行安装:
.. code-block:: bash
sudo -H pip install virtualenv
由于virtualenv需要安装给系统自带的Python,因此需要使用sudo权限。
创建一个新的Python运行环境:
:::::::::::::::::::
.. code-block:: bash
virtualenv --no-site-packages paddle
--no-site-packages 参数表示不拷贝已有的任何第三方包,创造一个完全干净的新Python环境。后面的paddle是我们为这个新创建的环境取的名字。
执行完这一步后,当前目录下应该会出现一个名为paddle(或者你取的其他名字)的目录。这个目录里保存了运行一个Python环境所需要的各种文件。
启动运行环境:
::::::::::::::::
.. code-block:: bash
source paddle/bin/activate
执行后会发现命令提示符前面增加了(paddle)字样,说明已经成功启动了名为‘paddle’的Python环境。执行which python,可以发现使用的已经是刚刚创建的paddle目录下的Python。
在这个环境中,我们可以自由地进行Paddle的安装、使用和开发工作,无需担心对系统自带Python的影响。
退出运行环境:
:::::::::::::::
直接执行:
.. code-block:: bash
deactivate
可以看到命令提示符前面的(paddle)字样消失。
自动启动某一Python环境:
::::::::::::::::
如果我们经常使用Paddle,我们每次打开终端后都需要执行一下source paddle/bin/activate来启动环境,比较繁琐。为了简便,可以修改终端的配置文件,来让终端每次启动后自动启动特定的Python环境。
执行:
.. code-block:: bash
vi ~/.bash_profile
打开终端配置文件,并在文件的最后添加一行:
.. code-block:: bash
source paddle/bin/activate
保存并关闭文件。
这样,每次打开终端时就会自动启动名为‘paddle’的Python环境了。
...@@ -2,4 +2,80 @@ ...@@ -2,4 +2,80 @@
Model Configuration Model Configuration
################### ###################
TBD .. contents::
1. How to deal with error :code:`Duplicated layer name`
----------------------------------------------------------
The general reason for this error is that users may have set the same value for the attribute :code:`name` in different layers. Try to find out the :code:`name` attribute with the same value in diffrent layers and set them differently.
2. How to use :code:`paddle.layer.memory`'s attribute :code:`name`
----------------------------------------------------------------------
* :code:`paddle.layer.memory` is used to get the output of a layer's last timestep and the layer is specified by the attribute :code:`name` . Thus, :code:`paddle.layer.memory` will associate with the layer that has the same value of attribute :code:`name` , and uses the output of the layer's last timestep as the input of its current timestep.
* All the PaddlePaddle's layers have a unique name, which is set by the attribute :code:`name` . PaddlePaddle will automatically set it for the user when it is not explicitly set. :code:`paddle.layer.memory` is not a real layer, its name is set by the attribute :code:`memory_name` and PaddlePaddle will also automatically set it when the user does not explicitly set. The :code:`paddle.layer.memory` attribute :code:`name` is used to specify the layer it is associated with, and needs to be explicitly set by the user.
3. What is the difference between the two ways of using dropout
-----------------------------------------------------------------
* There are two ways to use dropout in PaddlePaddle
* Set the :code:`drop_rate` parameter in the layer's :code:`layer_atter` attribute. Take :code:`paddle.layer.fc` as an example:
.. code-block:: python
fc = paddle.layer.fc(input=input, layer_attr=paddle.attr.ExtraLayerAttribute(drop_rate=0.5))
* Use :code:`paddle.layer.dropout` layer. Take :code:`paddle.layer.fc` as an example:
.. code-block:: python
fc = paddle.layer.fc(input=input)
drop_fc = paddle.layer.dropout(input=fc, dropout_rate=0.5)
* :code:`paddle.layer.dropout` actually uses the :code:`paddle.layer.add_to` layer and sets :code:`drop_rate` as the previous method. This method is very memory intensive.
* PaddlePaddle implements dropout in the activation function rather than in the layer.
* :code:`paddle.layer.lstmemory`, :code:`paddle.layer.grumemory`, :code:`paddle.layer.recurrent` implement activation of output in an unusual way, so we cannot use dropout by setting :code:`drop_rate` . To use dropout for these layers, we could use the second method, which is to use :code:`paddle.layer.dropout`.
4. The differences between different recurrent layers
--------------------------------------------------------
Take LSTM as an example. There are several kinds of recurrent layers in PaddlePaddle:
* :code:`paddle.layer.lstmemory`
* :code:`paddle.networks.simple_lstm`
* :code:`paddle.networks.lstmemory_group`
* :code:`paddle.networks.bidirectional_lstm`
According to implementations, recurrent layer can be classified into 2 types:
1. Recurrent layer implemented by recurrent_group:
* Using this type of recurrent layers, users can access the intermediate value calculated by the recurrent unit within a timestep (eg: hidden states, memory cells, etc.)
* :code:`paddle.networks.lstmemory_group` belongs to this type of recurrent layers.
2. Recurrent layer implemented as a complete operation:
* Users can only access output values when using this type of recurrent layers.
* :code:`paddle.networks.lstmemory_group` , :code:`paddle.networks.simple_lstm` and :code:`paddle.networks.bidirectional_lstm` belong to this type of recurrent layer;
By implementing recurrent layer as a complete operation, CPU and GPU calculations can be optimized. Therefore, the second type of recurrent layer is more efficient than the first one. In practical applications, we propose to use the second type of recurrent layers if there is no need to access the intermediate variable of LSTM.
In addition, PaddlePaddle also contains a kind of LSTM calculation unit: :code:`paddle.networks.lstmemory_unit`:
* Unlike the recurrent layer described above, :code:`paddle.networks.lstmemory_unit` defines the computational process of an LSTM unit in a timestep. It is not a complete recurrent layer, nor can it receive sequence data as input.
* :code:`paddle.networks.lstmemory_unit` can only be used as a step function in recurrent_group.
5. Can Softmax's calculation dimension be specified?
--------------------------------------------------------------------
We can't specify calculation dimension for PaddlePaddle's softmax. It can only be calculated by rows.
In image tasks, for NCHW, if you need to calculate softmax in C dimension, you could use :code:`paddle.layer.switch_order` to change the dimension order, that is, convert NCHW to NHWC, then do the reshape operation and calculate softmax.
6. Does PaddlePaddle support variable-dimensional data inputs
----------------------------------------------------------------
PaddlePaddle provides :code:`paddle.data_type.dense_array` to support variable-dimensional data input. Simply set the dimension of the data layer to a value larger than the dimension of the input data for occupancy.
...@@ -2,10 +2,25 @@ ...@@ -2,10 +2,25 @@
Set Command-line Parameters Set Command-line Parameters
=========================== ===========================
The implementation of deep learning algorithms has a variety of characteristics, such as running environment, running stage, structure of the model and the traning strategy. PaddlePaddle supports the user to set various command-line parameters flexibly, which helps to achieve control of the model training or prediction process.
In this part, we take several actual scenarios as an example, and the use of some command-line parameters is displayed:
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
use_case_en.md use_case_en.md
Then, we summarize and classify the use of all command-line parameters:
.. toctree::
:maxdepth: 1
arguments_en.md arguments_en.md
Finally, the detailed descriptions are given, and we try to explain the propeties and significance of these command-line parameters in detail:
.. toctree::
:maxdepth: 1
detail_introduction_en.md detail_introduction_en.md
...@@ -104,7 +104,7 @@ cc_test(init_test SRCS init_test.cc DEPS init) ...@@ -104,7 +104,7 @@ cc_test(init_test SRCS init_test.cc DEPS init)
cc_test(op_kernel_type_test SRCS op_kernel_type_test.cc DEPS place device_context framework_proto) cc_test(op_kernel_type_test SRCS op_kernel_type_test.cc DEPS place device_context framework_proto)
cc_test(cow_ptr_tests SRCS details/cow_ptr_test.cc) cc_test(cow_ptr_tests SRCS details/cow_ptr_test.cc)
# cc_test(channel_test SRCS channel_test.cc) cc_test(channel_test SRCS channel_test.cc)
cc_test(tuple_test SRCS tuple_test.cc ) cc_test(tuple_test SRCS tuple_test.cc )
cc_test(concurrency_test SRCS concurrency_test.cc DEPS go_op channel_close_op channel_create_op cc_test(concurrency_test SRCS concurrency_test.cc DEPS go_op channel_close_op channel_create_op
channel_send_op channel_recv_op sum_op select_op elementwise_add_op compare_op channel_send_op channel_recv_op sum_op select_op elementwise_add_op compare_op
......
...@@ -138,8 +138,8 @@ void ChannelImpl<T>::Send(T *item) { ...@@ -138,8 +138,8 @@ void ChannelImpl<T>::Send(T *item) {
// If channel is closed, throw exception // If channel is closed, throw exception
if (closed_) { if (closed_) {
lock.unlock();
send_return(); send_return();
lock.unlock();
PADDLE_THROW("Cannot send on closed channel"); PADDLE_THROW("Cannot send on closed channel");
} }
...@@ -152,11 +152,9 @@ void ChannelImpl<T>::Send(T *item) { ...@@ -152,11 +152,9 @@ void ChannelImpl<T>::Send(T *item) {
if (m != nullptr) { if (m != nullptr) {
*(m->data) = std::move(*item); *(m->data) = std::move(*item);
m->Notify(); m->Notify();
lock.unlock();
send_return(); send_return();
return; return;
} else { } else {
lock.unlock();
Send(item); Send(item);
send_return(); send_return();
return; return;
...@@ -169,8 +167,6 @@ void ChannelImpl<T>::Send(T *item) { ...@@ -169,8 +167,6 @@ void ChannelImpl<T>::Send(T *item) {
if (buf_.size() < cap_) { if (buf_.size() < cap_) {
// Copy to buffer // Copy to buffer
buf_.push_back(std::move(*item)); buf_.push_back(std::move(*item));
// Release lock and return true
lock.unlock();
send_return(); send_return();
return; return;
} }
...@@ -181,8 +177,8 @@ void ChannelImpl<T>::Send(T *item) { ...@@ -181,8 +177,8 @@ void ChannelImpl<T>::Send(T *item) {
sendq.push_back(m); sendq.push_back(m);
m->Wait(lock); m->Wait(lock);
if (m->chan_closed) { if (m->chan_closed) {
lock.unlock();
send_return(); send_return();
lock.unlock();
PADDLE_THROW("Cannot send on closed channel"); PADDLE_THROW("Cannot send on closed channel");
} }
send_return(); send_return();
...@@ -195,10 +191,7 @@ bool ChannelImpl<T>::Receive(T *item) { ...@@ -195,10 +191,7 @@ bool ChannelImpl<T>::Receive(T *item) {
// If channel is closed and buffer is empty or // If channel is closed and buffer is empty or
// channel is unbuffered // channel is unbuffered
if (closed_ && buf_.empty()) { if (closed_ && buf_.empty()) return recv_return(false);
lock.unlock();
return recv_return(false);
}
// If there is a sender, directly receive the value we want // If there is a sender, directly receive the value we want
// from the sender. In case of a buffered channel, read from // from the sender. In case of a buffered channel, read from
...@@ -229,7 +222,6 @@ bool ChannelImpl<T>::Receive(T *item) { ...@@ -229,7 +222,6 @@ bool ChannelImpl<T>::Receive(T *item) {
} else } else
return recv_return(Receive(item)); return recv_return(Receive(item));
} }
lock.unlock();
return recv_return(true); return recv_return(true);
} }
...@@ -238,8 +230,7 @@ bool ChannelImpl<T>::Receive(T *item) { ...@@ -238,8 +230,7 @@ bool ChannelImpl<T>::Receive(T *item) {
// Directly read from buffer // Directly read from buffer
*item = std::move(buf_.front()); *item = std::move(buf_.front());
buf_.pop_front(); buf_.pop_front();
// Release lock and return true // return true
lock.unlock();
return recv_return(true); return recv_return(true);
} }
......
...@@ -517,6 +517,7 @@ void OperatorWithKernel::RunImpl(const Scope& scope, ...@@ -517,6 +517,7 @@ void OperatorWithKernel::RunImpl(const Scope& scope,
// do data transform // do data transform
Scope& new_scope = scope.NewScope(); Scope& new_scope = scope.NewScope();
std::vector<std::string> inplace_vars;
for (auto& var_name_item : this->Inputs()) { for (auto& var_name_item : this->Inputs()) {
for (auto& var_name : var_name_item.second) { for (auto& var_name : var_name_item.second) {
auto* var = scope.FindVar(var_name); auto* var = scope.FindVar(var_name);
...@@ -529,10 +530,7 @@ void OperatorWithKernel::RunImpl(const Scope& scope, ...@@ -529,10 +530,7 @@ void OperatorWithKernel::RunImpl(const Scope& scope,
auto out_var_names = OutputVars(true); auto out_var_names = OutputVars(true);
if (std::find(out_var_names.begin(), out_var_names.end(), if (std::find(out_var_names.begin(), out_var_names.end(),
var_name) != out_var_names.end()) { var_name) != out_var_names.end()) {
PADDLE_THROW( inplace_vars.push_back(var_name);
"var %s is both input and output, "
"does not support transform",
var_name);
} }
VLOG(3) << "Transform Variable " << var_name << " from " VLOG(3) << "Transform Variable " << var_name << " from "
<< kernel_type_for_var << " to " << expected_kernel_key; << kernel_type_for_var << " to " << expected_kernel_key;
...@@ -551,6 +549,13 @@ void OperatorWithKernel::RunImpl(const Scope& scope, ...@@ -551,6 +549,13 @@ void OperatorWithKernel::RunImpl(const Scope& scope,
kernel_iter->second->Compute( kernel_iter->second->Compute(
ExecutionContext(*this, new_scope, *new_dev_ctx)); ExecutionContext(*this, new_scope, *new_dev_ctx));
for (auto& var_name : inplace_vars) {
VLOG(3) << "share inplace var " + var_name + " back to it's original scope";
auto* original_tensor = GetMutableTensorFromVar(scope.FindVar(var_name));
auto* transformed_tensor = GetTensorFromVar(new_scope.FindVar(var_name));
original_tensor->ShareDataWith(*transformed_tensor);
}
/*For profiling/benchmark only*/ /*For profiling/benchmark only*/
if (FLAGS_benchmark) { if (FLAGS_benchmark) {
new_dev_ctx->Wait(); new_dev_ctx->Wait();
......
...@@ -13,6 +13,7 @@ See the License for the specific language governing permissions and ...@@ -13,6 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. */ limitations under the License. */
#include "paddle/fluid/framework/parallel_executor.h" #include "paddle/fluid/framework/parallel_executor.h"
#include <string>
#include "ThreadPool.h" #include "ThreadPool.h"
...@@ -102,30 +103,43 @@ void ParallelExecutor::BCastParamsToGPUs( ...@@ -102,30 +103,43 @@ void ParallelExecutor::BCastParamsToGPUs(
auto *main_scope = member_->local_scopes_[0]; auto *main_scope = member_->local_scopes_[0];
for (auto *var_desc : startup_program.Block(0).AllVars()) { for (auto *var_desc : startup_program.Block(0).AllVars()) {
size_t idx = var_desc->Name().find("@GRAD");
if (idx != std::string::npos) continue;
if (var_desc->GetType() == proto::VarType::LOD_TENSOR) { if (var_desc->GetType() == proto::VarType::LOD_TENSOR) {
auto &main_tensor = auto &main_tensor =
main_scope->FindVar(var_desc->Name())->Get<LoDTensor>(); main_scope->FindVar(var_desc->Name())->Get<LoDTensor>();
ncclDataType_t data_type = platform::ToNCCLDataType(main_tensor.type());
auto &dims = main_tensor.dims();
size_t numel = main_tensor.numel();
platform::NCCLGroupGuard guard; auto &dims = main_tensor.dims();
for (size_t i = 0; i < member_->places_.size(); ++i) { if (paddle::platform::is_gpu_place(main_tensor.place())) {
auto place = member_->places_[i]; size_t numel = main_tensor.numel();
void *buffer; ncclDataType_t data_type = platform::ToNCCLDataType(main_tensor.type());
if (i == 0) { platform::NCCLGroupGuard guard;
buffer = const_cast<void *>(main_tensor.data<void>()); for (size_t i = 0; i < member_->places_.size(); ++i) {
} else { auto place = member_->places_[i];
void *buffer;
if (i == 0) {
buffer = const_cast<void *>(main_tensor.data<void>());
} else {
auto local_scope = member_->local_scopes_[i];
auto *t =
local_scope->Var(var_desc->Name())->GetMutable<LoDTensor>();
t->Resize(dims);
buffer = t->mutable_data(place, main_tensor.type());
}
auto &nccl_ctx = member_->nccl_ctxs_->at(place);
platform::dynload::ncclBcast(buffer, numel, data_type, 0,
nccl_ctx.comm_, nccl_ctx.stream());
}
} else {
platform::CPUPlace cpu;
for (size_t i = 1; i < member_->places_.size(); ++i) {
auto local_scope = member_->local_scopes_[i]; auto local_scope = member_->local_scopes_[i];
auto *t = local_scope->Var(var_desc->Name())->GetMutable<LoDTensor>(); auto *t = local_scope->Var(var_desc->Name())->GetMutable<LoDTensor>();
t->Resize(dims); t->Resize(dims);
buffer = t->mutable_data(place, main_tensor.type()); t->mutable_data(cpu, main_tensor.type());
paddle::framework::TensorCopy(main_tensor, cpu, t);
} }
auto &nccl_ctx = member_->nccl_ctxs_->at(place);
platform::dynload::ncclBcast(buffer, numel, data_type, 0,
nccl_ctx.comm_, nccl_ctx.stream());
} }
} }
member_->nccl_ctxs_->WaitAll(); member_->nccl_ctxs_->WaitAll();
......
...@@ -29,6 +29,11 @@ class CompareOpProtoMaker : public framework::OpProtoAndCheckerMaker { ...@@ -29,6 +29,11 @@ class CompareOpProtoMaker : public framework::OpProtoAndCheckerMaker {
AddInput("Y", string::Sprintf( AddInput("Y", string::Sprintf(
"(LoDTensor) the right hand operand of %s operator", "(LoDTensor) the right hand operand of %s operator",
comment.type)); comment.type));
AddAttr<bool>("force_cpu",
"(bool, default false) Force fill output variable to cpu "
"memory. Otherwise, fill output variable to the running "
"device")
.SetDefault(false);
AddOutput("Out", string::Sprintf( AddOutput("Out", string::Sprintf(
"(LoDTensor) n-dim bool tensor. Each element is %s", "(LoDTensor) n-dim bool tensor. Each element is %s",
comment.equation)); comment.equation));
...@@ -75,7 +80,9 @@ class CompareOp : public framework::OperatorWithKernel { ...@@ -75,7 +80,9 @@ class CompareOp : public framework::OperatorWithKernel {
const framework::ExecutionContext &ctx) const override { const framework::ExecutionContext &ctx) const override {
framework::OpKernelType kt = OperatorWithKernel::GetExpectedKernelType(ctx); framework::OpKernelType kt = OperatorWithKernel::GetExpectedKernelType(ctx);
// CompareOp kernel's device type is decided by input tensor place // CompareOp kernel's device type is decided by input tensor place
kt.place_ = ctx.Input<framework::LoDTensor>("X")->place(); bool force_cpu = ctx.Attr<bool>("force_cpu");
kt.place_ = force_cpu ? platform::CPUPlace()
: ctx.Input<framework::LoDTensor>("X")->place();
return kt; return kt;
} }
}; };
......
...@@ -54,7 +54,18 @@ class ConditionalOp : public framework::OperatorBase { ...@@ -54,7 +54,18 @@ class ConditionalOp : public framework::OperatorBase {
"numel should be 1, actual numel is %d", "numel should be 1, actual numel is %d",
ips[0]->numel()); ips[0]->numel());
} }
return ips[0]->data<bool>()[0]; bool res = false;
if (platform::is_gpu_place(ips[0]->place())) {
#ifdef PADDLE_WITH_CUDA
framework::LoDTensor cpu_tensor;
framework::TensorCopy(*ips[0], platform::CPUPlace(), &cpu_tensor);
platform::DeviceContextPool::Instance().Get(ips[0]->place())->Wait();
res = cpu_tensor.data<bool>()[0];
#endif
} else {
res = ips[0]->data<bool>()[0];
}
return res;
} }
}; };
......
...@@ -2,7 +2,8 @@ if(WITH_DISTRIBUTE) ...@@ -2,7 +2,8 @@ if(WITH_DISTRIBUTE)
grpc_library(sendrecvop_grpc SRCS bytebuffer_stream.cc sendrecvop_utils.cc grpc_client.cc grpc_library(sendrecvop_grpc SRCS bytebuffer_stream.cc sendrecvop_utils.cc grpc_client.cc
grpc_server.cc variable_response.cc PROTO send_recv.proto DEPS lod_tensor selected_rows) grpc_server.cc variable_response.cc PROTO send_recv.proto DEPS lod_tensor selected_rows)
set(DISTRIBUTE_COMPILE_FLAGS "-Wno-non-virtual-dtor -Wno-error=non-virtual-dtor -Wno-error=delete-non-virtual-dtor") set(DISTRIBUTE_COMPILE_FLAGS "-Wno-non-virtual-dtor -Wno-error=non-virtual-dtor -Wno-error=delete-non-virtual-dtor")
set_source_files_properties(test_serde.cc PROPERTIES COMPILE_FLAGS ${DISTRIBUTE_COMPILE_FLAGS}) set_source_files_properties(serde_test.cc grpc_server_test PROPERTIES COMPILE_FLAGS ${DISTRIBUTE_COMPILE_FLAGS})
cc_test(serde_test SRCS test_serde.cc variable_response.cc DEPS grpc++_unsecure grpc_unsecure gpr cc_test(serde_test SRCS serde_test.cc variable_response.cc DEPS grpc++_unsecure grpc_unsecure gpr
cares zlib protobuf sendrecvop_grpc) cares zlib protobuf sendrecvop_grpc)
cc_test(grpc_server_test SRCS grpc_server_test.cc DEPS sendrecvop_grpc grpc++_unsecure grpc_unsecure gpr cares zlib protobuf)
endif() endif()
...@@ -150,7 +150,8 @@ bool RPCClient::AsyncPrefetchVariable(const std::string& ep, ...@@ -150,7 +150,8 @@ bool RPCClient::AsyncPrefetchVariable(const std::string& ep,
s->response_call_back_ = ProcGetResponse; s->response_call_back_ = ProcGetResponse;
auto call = s->stub_g_.PrepareUnaryCall( auto call = s->stub_g_.PrepareUnaryCall(
s->context_.get(), "/sendrecv.SendRecvService/GetVariable", req, &cq_); s->context_.get(), "/sendrecv.SendRecvService/PrefetchVariable", req,
&cq_);
call->StartCall(); call->StartCall();
call->Finish(&s->reply_, &s->status_, (void*)s); call->Finish(&s->reply_, &s->status_, (void*)s);
}); });
......
...@@ -128,6 +128,47 @@ class RequestGet final : public RequestBase { ...@@ -128,6 +128,47 @@ class RequestGet final : public RequestBase {
SimpleBlockQueue<MessageWithName>* queue_; SimpleBlockQueue<MessageWithName>* queue_;
}; };
class RequestPrefetch final : public RequestBase {
public:
explicit RequestPrefetch(GrpcService::AsyncService* service,
::grpc::ServerCompletionQueue* cq,
framework::Scope* scope,
const platform::DeviceContext* dev_ctx,
framework::Executor* executor,
framework::ProgramDesc* program, int blkid)
: RequestBase(service, cq, dev_ctx),
responder_(&ctx_),
scope_(scope),
executor_(executor),
program_(program),
blkid_(blkid) {
int method_id = static_cast<int>(detail::GrpcMethod::kPrefetchVariable);
service_->RequestAsyncUnary(method_id, &ctx_, &request_, &responder_, cq_,
cq_, this);
}
virtual ~RequestPrefetch() {}
virtual std::string GetReqName() { return request_.varname(); }
virtual void Process() {
// prefetch process...
::grpc::ByteBuffer reply;
// TODO(Yancey1989): execute the Block which containers prefetch ops
responder_.Finish(reply, ::grpc::Status::OK, this);
status_ = FINISH;
}
protected:
sendrecv::VariableMessage request_;
ServerAsyncResponseWriter<::grpc::ByteBuffer> responder_;
framework::Scope* scope_;
framework::Executor* executor_;
framework::ProgramDesc* program_;
int blkid_;
};
void AsyncGRPCServer::WaitClientGet(int count) { void AsyncGRPCServer::WaitClientGet(int count) {
int fetch_barriers = 0; int fetch_barriers = 0;
while (fetch_barriers < count) { while (fetch_barriers < count) {
...@@ -147,6 +188,7 @@ void AsyncGRPCServer::RunSyncUpdate() { ...@@ -147,6 +188,7 @@ void AsyncGRPCServer::RunSyncUpdate() {
cq_send_ = builder.AddCompletionQueue(); cq_send_ = builder.AddCompletionQueue();
cq_get_ = builder.AddCompletionQueue(); cq_get_ = builder.AddCompletionQueue();
cq_prefetch_ = builder.AddCompletionQueue();
server_ = builder.BuildAndStart(); server_ = builder.BuildAndStart();
LOG(INFO) << "Server listening on " << address_ << std::endl; LOG(INFO) << "Server listening on " << address_ << std::endl;
...@@ -155,6 +197,8 @@ void AsyncGRPCServer::RunSyncUpdate() { ...@@ -155,6 +197,8 @@ void AsyncGRPCServer::RunSyncUpdate() {
std::bind(&AsyncGRPCServer::TryToRegisterNewSendOne, this); std::bind(&AsyncGRPCServer::TryToRegisterNewSendOne, this);
std::function<void()> get_register = std::function<void()> get_register =
std::bind(&AsyncGRPCServer::TryToRegisterNewGetOne, this); std::bind(&AsyncGRPCServer::TryToRegisterNewGetOne, this);
std::function<void()> prefetch_register =
std::bind(&AsyncGRPCServer::TryToRegisterNewPrefetchOne, this);
t_send_.reset( t_send_.reset(
new std::thread(std::bind(&AsyncGRPCServer::HandleRequest, this, new std::thread(std::bind(&AsyncGRPCServer::HandleRequest, this,
...@@ -163,24 +207,27 @@ void AsyncGRPCServer::RunSyncUpdate() { ...@@ -163,24 +207,27 @@ void AsyncGRPCServer::RunSyncUpdate() {
t_get_.reset( t_get_.reset(
new std::thread(std::bind(&AsyncGRPCServer::HandleRequest, this, new std::thread(std::bind(&AsyncGRPCServer::HandleRequest, this,
cq_get_.get(), "cq_get", get_register))); cq_get_.get(), "cq_get", get_register)));
t_prefetch_.reset(new std::thread(
std::bind(&AsyncGRPCServer::HandleRequest, this, cq_prefetch_.get(),
"cq_prefetch", prefetch_register)));
// wait server // wait server
server_->Wait(); server_->Wait();
t_send_->join(); t_send_->join();
t_get_->join(); t_get_->join();
t_prefetch_->join();
} }
void AsyncGRPCServer::ShutdownQueue() { void AsyncGRPCServer::ShutdownQueue() {
std::unique_lock<std::mutex> lock(cq_mutex_); std::unique_lock<std::mutex> lock(cq_mutex_);
cq_send_->Shutdown(); cq_send_->Shutdown();
cq_get_->Shutdown(); cq_get_->Shutdown();
is_shut_down_ = true;
} }
// This URL explains why shutdown is complicate: // This URL explains why shutdown is complicate:
void AsyncGRPCServer::ShutDown() { void AsyncGRPCServer::ShutDown() {
server_->Shutdown(); is_shut_down_ = true;
ShutdownQueue(); ShutdownQueue();
server_->Shutdown();
} }
void AsyncGRPCServer::TryToRegisterNewSendOne() { void AsyncGRPCServer::TryToRegisterNewSendOne() {
...@@ -203,6 +250,18 @@ void AsyncGRPCServer::TryToRegisterNewGetOne() { ...@@ -203,6 +250,18 @@ void AsyncGRPCServer::TryToRegisterNewGetOne() {
VLOG(4) << "Create RequestGet status:" << get->Status(); VLOG(4) << "Create RequestGet status:" << get->Status();
} }
void AsyncGRPCServer::TryToRegisterNewPrefetchOne() {
std::unique_lock<std::mutex> lock(cq_mutex_);
if (is_shut_down_) {
return;
}
RequestPrefetch* prefetch =
new RequestPrefetch(&service_, cq_prefetch_.get(), scope_, dev_ctx_,
executor_, program_, prefetch_blk_id_);
VLOG(4) << "Create RequestPrefetch status:" << prefetch->Status();
}
// FIXME(typhoonzero): change cq_name to enum. // FIXME(typhoonzero): change cq_name to enum.
void AsyncGRPCServer::HandleRequest(::grpc::ServerCompletionQueue* cq, void AsyncGRPCServer::HandleRequest(::grpc::ServerCompletionQueue* cq,
std::string cq_name, std::string cq_name,
...@@ -213,14 +272,14 @@ void AsyncGRPCServer::HandleRequest(::grpc::ServerCompletionQueue* cq, ...@@ -213,14 +272,14 @@ void AsyncGRPCServer::HandleRequest(::grpc::ServerCompletionQueue* cq,
bool ok = false; bool ok = false;
while (true) { while (true) {
if (!cq->Next(&tag, &ok)) { if (!cq->Next(&tag, &ok)) {
LOG(INFO) << cq_name << " get CompletionQueue shutdown!"; LOG(INFO) << cq_name << " CompletionQueue shutdown!";
break; break;
} }
PADDLE_ENFORCE(tag); PADDLE_ENFORCE(tag);
// FIXME(typhoonzero): de-couple the barriers with recv_op // FIXME(typhoonzero): de-couple the barriers with recv_op
if (cq_name == "cq_get") WaitCond(1); if (!is_shut_down_ && cq_name == "cq_get") WaitCond(1);
if (cq_name == "cq_send") WaitCond(0); if (!is_shut_down_ && cq_name == "cq_send") WaitCond(0);
RequestBase* base = (RequestBase*)tag; RequestBase* base = (RequestBase*)tag;
// reference: // reference:
......
...@@ -17,7 +17,9 @@ limitations under the License. */ ...@@ -17,7 +17,9 @@ limitations under the License. */
#include <grpc++/grpc++.h> #include <grpc++/grpc++.h>
#include <thread> #include <thread>
#include "paddle/fluid/framework/executor.h"
#include "paddle/fluid/framework/lod_tensor.h" #include "paddle/fluid/framework/lod_tensor.h"
#include "paddle/fluid/framework/program_desc.h"
#include "paddle/fluid/framework/scope.h" #include "paddle/fluid/framework/scope.h"
#include "paddle/fluid/framework/selected_rows.h" #include "paddle/fluid/framework/selected_rows.h"
#include "paddle/fluid/framework/var_type.h" #include "paddle/fluid/framework/var_type.h"
...@@ -53,6 +55,12 @@ class AsyncGRPCServer final { ...@@ -53,6 +55,12 @@ class AsyncGRPCServer final {
void SetDevCtx(const platform::DeviceContext *dev_ctx) { dev_ctx_ = dev_ctx; } void SetDevCtx(const platform::DeviceContext *dev_ctx) { dev_ctx_ = dev_ctx; }
void SetProgram(framework::ProgramDesc *program) { program_ = program; }
void SetPrefetchBlkdId(int blkid) { prefetch_blk_id_ = blkid; }
void SetExecutor(framework::Executor *executor) { executor_ = executor; }
const ReceivedMessage Get() { return this->var_recv_queue_.Pop(); } const ReceivedMessage Get() { return this->var_recv_queue_.Pop(); }
void Push(const std::string &msg_name) { void Push(const std::string &msg_name) {
...@@ -66,6 +74,7 @@ class AsyncGRPCServer final { ...@@ -66,6 +74,7 @@ class AsyncGRPCServer final {
std::function<void()> TryToRegisterNewOne); std::function<void()> TryToRegisterNewOne);
void TryToRegisterNewSendOne(); void TryToRegisterNewSendOne();
void TryToRegisterNewGetOne(); void TryToRegisterNewGetOne();
void TryToRegisterNewPrefetchOne();
void ShutdownQueue(); void ShutdownQueue();
private: private:
...@@ -73,6 +82,7 @@ class AsyncGRPCServer final { ...@@ -73,6 +82,7 @@ class AsyncGRPCServer final {
volatile bool is_shut_down_ = false; volatile bool is_shut_down_ = false;
std::unique_ptr<::grpc::ServerCompletionQueue> cq_send_; std::unique_ptr<::grpc::ServerCompletionQueue> cq_send_;
std::unique_ptr<::grpc::ServerCompletionQueue> cq_get_; std::unique_ptr<::grpc::ServerCompletionQueue> cq_get_;
std::unique_ptr<::grpc::ServerCompletionQueue> cq_prefetch_;
GrpcService::AsyncService service_; GrpcService::AsyncService service_;
std::unique_ptr<::grpc::Server> server_; std::unique_ptr<::grpc::Server> server_;
...@@ -92,6 +102,11 @@ class AsyncGRPCServer final { ...@@ -92,6 +102,11 @@ class AsyncGRPCServer final {
std::unique_ptr<std::thread> t_send_; std::unique_ptr<std::thread> t_send_;
std::unique_ptr<std::thread> t_get_; std::unique_ptr<std::thread> t_get_;
std::unique_ptr<std::thread> t_prefetch_;
int prefetch_blk_id_;
framework::ProgramDesc *program_;
framework::Executor *executor_;
}; };
}; // namespace detail }; // namespace detail
......
/* 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. */
#include <unistd.h>
#include <string>
#include <thread>
#include "gtest/gtest.h"
#include "paddle/fluid/operators/detail/grpc_client.h"
#include "paddle/fluid/operators/detail/grpc_server.h"
namespace framework = paddle::framework;
namespace platform = paddle::platform;
namespace detail = paddle::operators::detail;
std::unique_ptr<detail::AsyncGRPCServer> rpc_service_;
void StartServer(const std::string& endpoint) {
rpc_service_.reset(new detail::AsyncGRPCServer(endpoint));
}
TEST(PREFETCH, CPU) {
// start up a server instance backend
// TODO(Yancey1989): Need to start a server with optimize blocks and
// prefetch blocks.
std::thread server_thread(StartServer, "127.0.0.1:8889");
framework::Scope scope;
platform::CPUPlace place;
platform::CPUDeviceContext ctx(place);
// create var on local scope
std::string var_name("tmp_0");
auto var = scope.Var(var_name);
auto tensor = var->GetMutable<framework::LoDTensor>();
tensor->Resize({10, 10});
detail::RPCClient client;
client.AsyncPrefetchVariable("127.0.0.1:8889", ctx, scope, var_name, "");
server_thread.join();
rpc_service_.reset(nullptr);
}
...@@ -76,6 +76,7 @@ namespace detail { ...@@ -76,6 +76,7 @@ namespace detail {
enum class GrpcMethod { enum class GrpcMethod {
kSendVariable, kSendVariable,
kGetVariable, kGetVariable,
kPrefetchVariable,
}; };
static const int kGrpcNumMethods = static const int kGrpcNumMethods =
...@@ -87,6 +88,8 @@ inline const char* GrpcMethodName(GrpcMethod id) { ...@@ -87,6 +88,8 @@ inline const char* GrpcMethodName(GrpcMethod id) {
return "/sendrecv.SendRecvService/SendVariable"; return "/sendrecv.SendRecvService/SendVariable";
case GrpcMethod::kGetVariable: case GrpcMethod::kGetVariable:
return "/sendrecv.SendRecvService/GetVariable"; return "/sendrecv.SendRecvService/GetVariable";
case GrpcMethod::kPrefetchVariable:
return "/sendrecv.SendREcvService/PrefetchVariable";
} }
// Shouldn't be reached. // Shouldn't be reached.
......
...@@ -21,6 +21,8 @@ service SendRecvService { ...@@ -21,6 +21,8 @@ service SendRecvService {
rpc SendVariable(VariableMessage) returns (VoidMessage) {} rpc SendVariable(VariableMessage) returns (VoidMessage) {}
// Argument VariableMessage for GetVariable should only contain varname. // Argument VariableMessage for GetVariable should only contain varname.
rpc GetVariable(VariableMessage) returns (VariableMessage) {} rpc GetVariable(VariableMessage) returns (VariableMessage) {}
// Prefetch variable by Ids
rpc PrefetchVariable(VariableMessage) returns (VariableMessage) {}
} }
// VariableMessage is serialized paddle variable message. // VariableMessage is serialized paddle variable message.
......
...@@ -11,9 +11,10 @@ distributed under the License is distributed on an "AS IS" BASIS, ...@@ -11,9 +11,10 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. */ limitations under the License. */
#pragma once #pragma once
#include <random> #include <random>
#include "paddle/fluid/framework/eigen.h" #include "paddle/fluid/framework/eigen.h"
#include "paddle/fluid/framework/op_registry.h" #include "paddle/fluid/framework/op_registry.h"
......
...@@ -13,8 +13,10 @@ See the License for the specific language governing permissions and ...@@ -13,8 +13,10 @@ See the License for the specific language governing permissions and
limitations under the License. */ limitations under the License. */
#include <unistd.h> #include <unistd.h>
#include <string> #include <string>
#include <thread> #include <thread> // NOLINT
#include <vector>
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "paddle/fluid/framework/op_registry.h" #include "paddle/fluid/framework/op_registry.h"
...@@ -30,9 +32,9 @@ namespace m = paddle::operators::math; ...@@ -30,9 +32,9 @@ namespace m = paddle::operators::math;
USE_OP(dropout); USE_OP(dropout);
void Compare(f::Scope& scope, p::DeviceContext& ctx) { void Compare(f::Scope* scope, const p::DeviceContext& ctx) {
// init // init
auto var = scope.Var("X"); auto var = scope->Var("X");
auto tensor = var->GetMutable<f::LoDTensor>(); auto tensor = var->GetMutable<f::LoDTensor>();
tensor->Resize({10, 10}); tensor->Resize({10, 10});
...@@ -44,12 +46,12 @@ void Compare(f::Scope& scope, p::DeviceContext& ctx) { ...@@ -44,12 +46,12 @@ void Compare(f::Scope& scope, p::DeviceContext& ctx) {
TensorFromVector(init, ctx, tensor); TensorFromVector(init, ctx, tensor);
auto place = ctx.GetPlace(); auto place = ctx.GetPlace();
auto out_var = scope.Var("Out"); auto out_var = scope->Var("Out");
auto out_tensor = out_var->GetMutable<f::LoDTensor>(); auto out_tensor = out_var->GetMutable<f::LoDTensor>();
out_tensor->Resize({10, 10}); out_tensor->Resize({10, 10});
out_tensor->mutable_data<float>(place); // allocate out_tensor->mutable_data<float>(place); // allocate
auto mask_var = scope.Var("Mask"); auto mask_var = scope->Var("Mask");
auto mask_tensor = mask_var->GetMutable<f::LoDTensor>(); auto mask_tensor = mask_var->GetMutable<f::LoDTensor>();
mask_tensor->Resize({10, 10}); mask_tensor->Resize({10, 10});
mask_tensor->mutable_data<float>(place); // allocate mask_tensor->mutable_data<float>(place); // allocate
...@@ -63,7 +65,7 @@ void Compare(f::Scope& scope, p::DeviceContext& ctx) { ...@@ -63,7 +65,7 @@ void Compare(f::Scope& scope, p::DeviceContext& ctx) {
auto dropout_op = f::OpRegistry::CreateOp( auto dropout_op = f::OpRegistry::CreateOp(
"dropout", {{"X", {"X"}}}, {{"Out", {"Out"}}, {"Mask", {"Mask"}}}, attrs); "dropout", {{"X", {"X"}}}, {{"Out", {"Out"}}, {"Mask", {"Mask"}}}, attrs);
dropout_op->Run(scope, place); dropout_op->Run(*scope, place);
std::vector<float> out_vec; std::vector<float> out_vec;
TensorToVector(*out_tensor, ctx, &out_vec); TensorToVector(*out_tensor, ctx, &out_vec);
...@@ -81,6 +83,11 @@ void Compare(f::Scope& scope, p::DeviceContext& ctx) { ...@@ -81,6 +83,11 @@ void Compare(f::Scope& scope, p::DeviceContext& ctx) {
} }
} }
// TODO(wyi): Due to
// https://github.com/PaddlePaddle/Paddle/issues/9507, I temporarily
// disable this test to remove the prevention of the merge of
// unrelated PRs.
/*
TEST(Dropout, CPUDense) { TEST(Dropout, CPUDense) {
f::Scope scope; f::Scope scope;
p::CPUPlace place; p::CPUPlace place;
...@@ -94,3 +101,4 @@ TEST(Dropout, GPUDense) { ...@@ -94,3 +101,4 @@ TEST(Dropout, GPUDense) {
p::CUDADeviceContext ctx(place); p::CUDADeviceContext ctx(place);
Compare(scope, ctx); Compare(scope, ctx);
} }
*/
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved. // Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
//
Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
You may obtain a copy of the License at // You may obtain a copy of the License at
//
http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
//
Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
limitations under the License. */ // limitations under the License.
#include "paddle/fluid/framework/op_registry.h" #include "paddle/fluid/operators/increment_op.h"
namespace paddle { namespace paddle {
namespace operators { namespace operators {
class IncrementInferShape : public framework::InferShapeBase { class IncrementOp : public framework::OperatorWithKernel {
public: public:
void operator()(framework::InferShapeContext *ctx) const override { IncrementOp(const std::string &type, const framework::VariableNameMap &inputs,
const framework::VariableNameMap &outputs,
const framework::AttributeMap &attrs)
: OperatorWithKernel(type, inputs, outputs, attrs) {}
void InferShape(framework::InferShapeContext *ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), PADDLE_ENFORCE(ctx->HasInput("X"),
"Input(X) of IncrementOp should not be null."); "Input(X) of IncrementOp should not be null.");
PADDLE_ENFORCE(ctx->HasOutput("Out"), PADDLE_ENFORCE(ctx->HasOutput("Out"),
"Output(Out) of IncrementOp should not be null."); "Output(Out) of IncrementOp should not be null.");
PADDLE_ENFORCE_EQ(1, framework::product(ctx->GetInputDim("X"))); PADDLE_ENFORCE_EQ(1, framework::product(ctx->GetInputDim("X")));
ctx->SetOutputDim("Out", ctx->GetInputDim("X")); ctx->SetOutputDim("Out", ctx->GetInputDim("X"));
ctx->ShareLoD("X", "Out");
} }
};
struct IncrementFunctor {
IncrementFunctor(const framework::LoDTensor &x, framework::LoDTensor *out,
float value)
: x_(x), out_(out), value_(value) {}
template <typename T>
void operator()() const {
*out_->data<T>() = *x_.data<T>() + static_cast<T>(value_);
}
const framework::LoDTensor &x_;
framework::LoDTensor *out_;
float value_;
};
class IncrementOp : public framework::OperatorBase {
public:
IncrementOp(const std::string &type, const framework::VariableNameMap &inputs,
const framework::VariableNameMap &outputs,
const framework::AttributeMap &attrs)
: OperatorBase(type, inputs, outputs, attrs) {}
private:
void RunImpl(const framework::Scope &scope,
const platform::Place &place) const override {
auto &x = scope.FindVar(Input("X"))->Get<framework::LoDTensor>();
auto &out =
*scope.FindVar(Output("Out"))->GetMutable<framework::LoDTensor>();
PADDLE_ENFORCE(platform::is_cpu_place(x.place())); protected:
out.Resize(x.dims()); framework::OpKernelType GetExpectedKernelType(
out.mutable_data(x.place(), x.type()); const framework::ExecutionContext &ctx) const override {
float value = Attr<float>("step"); framework::OpKernelType kt = OperatorWithKernel::GetExpectedKernelType(ctx);
VLOG(10) << Output("Out") << " increase " << Input("X") << " with " // IncrementOp kernel's device type is decided by input tensor place
<< value; kt.place_ = ctx.Input<framework::LoDTensor>("X")->place();
framework::VisitDataType(framework::ToDataType(out.type()), return kt;
IncrementFunctor(x, &out, value));
} }
}; };
...@@ -108,5 +83,10 @@ class IncrementGradOpMaker : public framework::SingleGradOpDescMaker { ...@@ -108,5 +83,10 @@ class IncrementGradOpMaker : public framework::SingleGradOpDescMaker {
} // namespace paddle } // namespace paddle
namespace ops = paddle::operators; namespace ops = paddle::operators;
REGISTER_OPERATOR(increment, ops::IncrementOp, ops::IncrementInferShape, REGISTER_OPERATOR(increment, ops::IncrementOp, ops::IncrementOpMaker,
ops::IncrementOpMaker, ops::IncrementGradOpMaker); ops::IncrementGradOpMaker);
REGISTER_OP_CPU_KERNEL(
increment, ops::IncrementKernel<paddle::platform::CPUDeviceContext, float>,
ops::IncrementKernel<paddle::platform::CPUDeviceContext, double>,
ops::IncrementKernel<paddle::platform::CPUDeviceContext, int>,
ops::IncrementKernel<paddle::platform::CPUDeviceContext, int64_t>)
// Copyright (c) 2018 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.
#include "paddle/fluid/operators/increment_op.h"
namespace ops = paddle::operators;
REGISTER_OP_CUDA_KERNEL(
increment, ops::IncrementKernel<paddle::platform::CUDADeviceContext, float>,
ops::IncrementKernel<paddle::platform::CUDADeviceContext, double>,
ops::IncrementKernel<paddle::platform::CUDADeviceContext, int>,
ops::IncrementKernel<paddle::platform::CUDADeviceContext, int64_t>)
// Copyright (c) 2018 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.
#pragma once
#include "paddle/fluid/framework/eigen.h"
#include "paddle/fluid/framework/op_registry.h"
namespace paddle {
namespace operators {
template <typename DeviceContext, typename T>
class IncrementKernel : public framework::OpKernel<T> {
public:
void Compute(const framework::ExecutionContext& context) const override {
auto* x_tensor = context.Input<framework::Tensor>("X");
auto* out_tensor = context.Output<framework::Tensor>("Out");
float step = context.Attr<float>("step");
out_tensor->mutable_data<T>(context.GetPlace());
auto& dev =
*context.template device_context<DeviceContext>().eigen_device();
framework::EigenScalar<T>::From(*out_tensor).device(dev) =
framework::EigenScalar<T>::From(*x_tensor) + static_cast<T>(step);
}
};
} // namespace operators
} // namespace paddle
...@@ -54,6 +54,24 @@ static void CreateTensorFromMessageType(framework::Variable *var, ...@@ -54,6 +54,24 @@ static void CreateTensorFromMessageType(framework::Variable *var,
} }
} }
static void ParallelExecuteBlocks(const std::vector<size_t> &parallel_blkids,
framework::Executor *executor,
framework::ProgramDesc *program,
framework::Scope *scope) {
std::vector<std::future<void>> fs;
for (size_t idx : parallel_blkids) {
fs.push_back(framework::Async([&executor, &program, &scope, idx]() {
int run_block = idx; // thread local
try {
executor->Run(*program, scope, run_block, false, false);
} catch (std::exception &e) {
LOG(ERROR) << "run sub program error " << e.what();
}
}));
}
for (size_t i = 0; i < fs.size(); ++i) fs[i].wait();
}
class ListenAndServOp : public framework::OperatorBase { class ListenAndServOp : public framework::OperatorBase {
public: public:
ListenAndServOp(const std::string &type, ListenAndServOp(const std::string &type,
...@@ -70,7 +88,6 @@ class ListenAndServOp : public framework::OperatorBase { ...@@ -70,7 +88,6 @@ class ListenAndServOp : public framework::OperatorBase {
void Stop() override { void Stop() override {
rpc_service_->Push(LISTEN_TERMINATE_MESSAGE); rpc_service_->Push(LISTEN_TERMINATE_MESSAGE);
rpc_service_->ShutDown();
server_thread_->join(); server_thread_->join();
} }
...@@ -135,34 +152,27 @@ class ListenAndServOp : public framework::OperatorBase { ...@@ -135,34 +152,27 @@ class ListenAndServOp : public framework::OperatorBase {
break; break;
} }
// put optimize blocks in the thread pool to start run, the last block
// should be global ops.
// NOTE: if is_gpu_place, CUDA kernels are laugched by multiple threads // NOTE: if is_gpu_place, CUDA kernels are laugched by multiple threads
// and this will still work. // and this will still work.
std::vector<std::future<void>> fs; // The optimize blocks which have the same parent ID would run parallel
// TODO(Yancey1989): need to use ParallelExecutor for future
size_t last_parent_blkid = program->Block(1).Parent();
std::vector<size_t> parallel_blkids;
parallel_blkids.push_back(1);
double ts = detail::GetTimestamp(); double ts = detail::GetTimestamp();
// block0 contains only listen_and_serv op, start run from block1. for (size_t blkid = 2; blkid < num_blocks; ++blkid) {
for (int blkid = 1; blkid < num_blocks - 1; ++blkid) { if (program->Block(blkid).Parent() != last_parent_blkid) {
fs.push_back( for (size_t idx : parallel_blkids) VLOG(3) << idx;
framework::Async([&executor, &program, &recv_scope, blkid]() { ParallelExecuteBlocks(parallel_blkids, &executor, program,
int run_block = blkid; // thread local &recv_scope);
try { parallel_blkids.clear();
executor.Run(*program, &recv_scope, run_block, false, false); last_parent_blkid = program->Block(blkid).Parent();
} catch (std::exception &e) {
LOG(ERROR) << "run sub program error " << e.what();
}
}));
}
for (int i = 0; i < num_blocks - 2; ++i) fs[i].wait();
// Run global block at final step, or block1 if there are only 2 blocks
if (num_blocks >= 2) {
try {
executor.Run(*program, &recv_scope, num_blocks - 1, false, false);
} catch (std::exception &e) {
LOG(ERROR) << "run sub program error " << e.what();
} }
parallel_blkids.push_back(blkid);
} }
ParallelExecuteBlocks(parallel_blkids, &executor, program, &recv_scope);
VLOG(2) << "run all blocks spent (ms) " << detail::GetTimestamp() - ts; VLOG(2) << "run all blocks spent (ms) " << detail::GetTimestamp() - ts;
// Reset the received sparse variables, the sum operator would not // Reset the received sparse variables, the sum operator would not
...@@ -178,10 +188,6 @@ class ListenAndServOp : public framework::OperatorBase { ...@@ -178,10 +188,6 @@ class ListenAndServOp : public framework::OperatorBase {
rpc_service_->WaitClientGet(fan_in); rpc_service_->WaitClientGet(fan_in);
sparse_vars.clear(); sparse_vars.clear();
} // while(true) } // while(true)
// for (int i = 0; i < num_blocks; ++i) {
// delete blk_ctx_list[i];
// }
} }
protected: protected:
......
...@@ -214,7 +214,10 @@ class LRNOpMaker : public framework::OpProtoAndCheckerMaker { ...@@ -214,7 +214,10 @@ class LRNOpMaker : public framework::OpProtoAndCheckerMaker {
"Defaults to \"NHWC\". Specify the data format of the output data, " "Defaults to \"NHWC\". Specify the data format of the output data, "
"the input will be transformed automatically. ") "the input will be transformed automatically. ")
.SetDefault("AnyLayout"); .SetDefault("AnyLayout");
AddAttr<bool>("is_test", "").SetDefault(false); AddAttr<bool>("is_test",
"Turns on memory optimization that optimizes away "
"unnecessary memory allocations. Used by MKLDNN.")
.SetDefault(false);
AddComment(R"DOC( AddComment(R"DOC(
Local Response Normalization Operator. Local Response Normalization Operator.
......
...@@ -121,6 +121,10 @@ class LRNGradKernel : public framework::OpKernel<T> { ...@@ -121,6 +121,10 @@ class LRNGradKernel : public framework::OpKernel<T> {
T alpha = ctx.Attr<T>("alpha"); T alpha = ctx.Attr<T>("alpha");
T beta = ctx.Attr<T>("beta"); T beta = ctx.Attr<T>("beta");
PADDLE_ENFORCE(
!ctx.Attr<bool>("is_test"),
"is_test attribute should be set to False in training phase.");
LRNGradFunctor<DeviceContext, T> f; LRNGradFunctor<DeviceContext, T> f;
f(ctx, x, out, mid, x_g, out_g, N, C, H, W, n, alpha, beta); f(ctx, x, out, mid, x_g, out_g, N, C, H, W, n, alpha, beta);
} }
......
...@@ -122,7 +122,8 @@ void StartServerNet(bool is_sparse) { ...@@ -122,7 +122,8 @@ void StartServerNet(bool is_sparse) {
// sub program run in listen_and_serv_op, for simple test we use sum // sub program run in listen_and_serv_op, for simple test we use sum
f::ProgramDesc program; f::ProgramDesc program;
f::BlockDesc *optimize_block = program.MutableBlock(0); const auto &root_block = program.Block(0);
auto *optimize_block = program.AppendBlock(root_block);
// X for server side tensors, RX for received tensers, must be of same shape. // X for server side tensors, RX for received tensers, must be of same shape.
AddOp("sum", {{"X", {"x0", "x1"}}}, {{"Out", {"Out"}}}, {}, optimize_block); AddOp("sum", {{"X", {"x0", "x1"}}}, {{"Out", {"Out"}}}, {}, optimize_block);
......
...@@ -13,7 +13,9 @@ See the License for the specific language governing permissions and ...@@ -13,7 +13,9 @@ See the License for the specific language governing permissions and
limitations under the License. */ limitations under the License. */
#include "paddle/fluid/platform/profiler.h" #include "paddle/fluid/platform/profiler.h"
#ifdef PADDLE_WITH_CUDA
#include "cuda_runtime.h" #include "cuda_runtime.h"
#endif
#include "gtest/gtest.h" #include "gtest/gtest.h"
TEST(Event, CpuElapsedTime) { TEST(Event, CpuElapsedTime) {
...@@ -159,6 +161,7 @@ TEST(RecordEvent, RecordEvent) { ...@@ -159,6 +161,7 @@ TEST(RecordEvent, RecordEvent) {
DisableProfiler(EventSortingKey::kTotal, "/tmp/profiler"); DisableProfiler(EventSortingKey::kTotal, "/tmp/profiler");
} }
#ifdef PADDLE_WITH_CUDA
TEST(TMP, stream_wait) { TEST(TMP, stream_wait) {
cudaStream_t stream; cudaStream_t stream;
cudaStreamCreate(&stream); cudaStreamCreate(&stream);
...@@ -166,3 +169,4 @@ TEST(TMP, stream_wait) { ...@@ -166,3 +169,4 @@ TEST(TMP, stream_wait) {
cudaStreamSynchronize(stream); cudaStreamSynchronize(stream);
cudaStreamSynchronize(stream); cudaStreamSynchronize(stream);
} }
#endif
...@@ -125,9 +125,8 @@ EOF ...@@ -125,9 +125,8 @@ EOF
-DWITH_AVX=${WITH_AVX:-ON} \ -DWITH_AVX=${WITH_AVX:-ON} \
-DWITH_SWIG_PY=ON \ -DWITH_SWIG_PY=ON \
-DWITH_STYLE_CHECK=OFF -DWITH_STYLE_CHECK=OFF
make -j `nproc` gen_proto_py framework_py_proto
make -j `nproc` copy_paddle_pybind make -j `nproc` paddle_docs paddle_apis
make -j `nproc` paddle_docs paddle_docs_cn paddle_api_docs
popd popd
fi fi
......
...@@ -7,9 +7,8 @@ cd $TRAVIS_BUILD_DIR/build ...@@ -7,9 +7,8 @@ cd $TRAVIS_BUILD_DIR/build
# Compile Documentation only. # Compile Documentation only.
cmake .. -DCMAKE_BUILD_TYPE=Release -DWITH_GPU=OFF -DWITH_MKL=OFF -DWITH_DOC=ON -DWITH_STYLE_CHECK=OFF cmake .. -DCMAKE_BUILD_TYPE=Release -DWITH_GPU=OFF -DWITH_MKL=OFF -DWITH_DOC=ON -DWITH_STYLE_CHECK=OFF
make -j `nproc` gen_proto_py framework_py_proto
make -j `nproc` copy_paddle_pybind make -j `nproc` paddle_docs paddle_apis
make -j `nproc` paddle_docs paddle_docs_cn paddle_api_docs
# check websites for broken links # check websites for broken links
linkchecker doc/v2/en/html/index.html linkchecker doc/v2/en/html/index.html
......
...@@ -73,12 +73,13 @@ add_custom_target(paddle_python ALL DEPENDS ${paddle_python_deps}) ...@@ -73,12 +73,13 @@ add_custom_target(paddle_python ALL DEPENDS ${paddle_python_deps})
set(PADDLE_PYTHON_PACKAGE_DIR ${CMAKE_CURRENT_BINARY_DIR}/dist/) set(PADDLE_PYTHON_PACKAGE_DIR ${CMAKE_CURRENT_BINARY_DIR}/dist/)
if (WITH_TESTING) if (WITH_TESTING)
add_subdirectory(paddle/reader/tests)
add_subdirectory(paddle/dataset/tests)
if(NOT WITH_FLUID_ONLY) if(NOT WITH_FLUID_ONLY)
add_subdirectory(paddle/trainer_config_helpers/tests) add_subdirectory(paddle/trainer_config_helpers/tests)
if (WITH_SWIG_PY) if (WITH_SWIG_PY)
# enable v2 API unittest only when paddle swig api is compiled # enable v2 API unittest only when paddle swig api is compiled
add_subdirectory(paddle/v2/tests) add_subdirectory(paddle/v2/tests)
add_subdirectory(paddle/v2/reader/tests)
add_subdirectory(paddle/v2/plot/tests) add_subdirectory(paddle/v2/plot/tests)
endif() endif()
endif() endif()
......
...@@ -14,8 +14,14 @@ ...@@ -14,8 +14,14 @@
try: try:
from version import full_version as __version__ from version import full_version as __version__
from version import commit as __git_commit__ from version import commit as __git_commit__
except ImportError: except ImportError:
import sys import sys
sys.stderr.write('''Warning with import paddle: you should not sys.stderr.write('''Warning with import paddle: you should not
import paddle from the source directory; please install paddlepaddle*.whl firstly.''' import paddle from the source directory; please install paddlepaddle*.whl firstly.'''
) )
import reader
import dataset
import batch
batch = batch.batch
...@@ -28,6 +28,7 @@ import wmt16 ...@@ -28,6 +28,7 @@ import wmt16
import mq2007 import mq2007
import flowers import flowers
import voc2012 import voc2012
import image
__all__ = [ __all__ = [
'mnist', 'mnist',
...@@ -43,4 +44,5 @@ __all__ = [ ...@@ -43,4 +44,5 @@ __all__ = [
'mq2007', 'mq2007',
'flowers', 'flowers',
'voc2012', 'voc2012',
'image',
] ]
...@@ -31,7 +31,7 @@ images per class. ...@@ -31,7 +31,7 @@ images per class.
import cPickle import cPickle
import itertools import itertools
import numpy import numpy
import paddle.v2.dataset.common import paddle.dataset.common
import tarfile import tarfile
__all__ = ['train100', 'test100', 'train10', 'test10', 'convert'] __all__ = ['train100', 'test100', 'train10', 'test10', 'convert']
...@@ -75,7 +75,7 @@ def train100(): ...@@ -75,7 +75,7 @@ def train100():
:rtype: callable :rtype: callable
""" """
return reader_creator( return reader_creator(
paddle.v2.dataset.common.download(CIFAR100_URL, 'cifar', CIFAR100_MD5), paddle.dataset.common.download(CIFAR100_URL, 'cifar', CIFAR100_MD5),
'train') 'train')
...@@ -90,7 +90,7 @@ def test100(): ...@@ -90,7 +90,7 @@ def test100():
:rtype: callable :rtype: callable
""" """
return reader_creator( return reader_creator(
paddle.v2.dataset.common.download(CIFAR100_URL, 'cifar', CIFAR100_MD5), paddle.dataset.common.download(CIFAR100_URL, 'cifar', CIFAR100_MD5),
'test') 'test')
...@@ -105,7 +105,7 @@ def train10(): ...@@ -105,7 +105,7 @@ def train10():
:rtype: callable :rtype: callable
""" """
return reader_creator( return reader_creator(
paddle.v2.dataset.common.download(CIFAR10_URL, 'cifar', CIFAR10_MD5), paddle.dataset.common.download(CIFAR10_URL, 'cifar', CIFAR10_MD5),
'data_batch') 'data_batch')
...@@ -120,20 +120,20 @@ def test10(): ...@@ -120,20 +120,20 @@ def test10():
:rtype: callable :rtype: callable
""" """
return reader_creator( return reader_creator(
paddle.v2.dataset.common.download(CIFAR10_URL, 'cifar', CIFAR10_MD5), paddle.dataset.common.download(CIFAR10_URL, 'cifar', CIFAR10_MD5),
'test_batch') 'test_batch')
def fetch(): def fetch():
paddle.v2.dataset.common.download(CIFAR10_URL, 'cifar', CIFAR10_MD5) paddle.dataset.common.download(CIFAR10_URL, 'cifar', CIFAR10_MD5)
paddle.v2.dataset.common.download(CIFAR100_URL, 'cifar', CIFAR100_MD5) paddle.dataset.common.download(CIFAR100_URL, 'cifar', CIFAR100_MD5)
def convert(path): def convert(path):
""" """
Converts dataset to recordio format Converts dataset to recordio format
""" """
paddle.v2.dataset.common.convert(path, train100(), 1000, "cifar_train100") paddle.dataset.common.convert(path, train100(), 1000, "cifar_train100")
paddle.v2.dataset.common.convert(path, test100(), 1000, "cifar_test100") paddle.dataset.common.convert(path, test100(), 1000, "cifar_test100")
paddle.v2.dataset.common.convert(path, train10(), 1000, "cifar_train10") paddle.dataset.common.convert(path, train10(), 1000, "cifar_train10")
paddle.v2.dataset.common.convert(path, test10(), 1000, "cifar_test10") paddle.dataset.common.convert(path, test10(), 1000, "cifar_test10")
...@@ -19,7 +19,7 @@ import errno ...@@ -19,7 +19,7 @@ import errno
import shutil import shutil
import sys import sys
import importlib import importlib
import paddle.v2.dataset import paddle.dataset
import cPickle import cPickle
import glob import glob
import cPickle as pickle import cPickle as pickle
...@@ -105,24 +105,24 @@ def download(url, module_name, md5sum, save_name=None): ...@@ -105,24 +105,24 @@ def download(url, module_name, md5sum, save_name=None):
def fetch_all(): def fetch_all():
for module_name in filter(lambda x: not x.startswith("__"), for module_name in filter(lambda x: not x.startswith("__"),
dir(paddle.v2.dataset)): dir(paddle.dataset)):
if "fetch" in dir( if "fetch" in dir(
importlib.import_module("paddle.v2.dataset.%s" % module_name)): importlib.import_module("paddle.dataset.%s" % module_name)):
getattr( getattr(
importlib.import_module("paddle.v2.dataset.%s" % module_name), importlib.import_module("paddle.dataset.%s" % module_name),
"fetch")() "fetch")()
def fetch_all_recordio(path): def fetch_all_recordio(path):
for module_name in filter(lambda x: not x.startswith("__"), for module_name in filter(lambda x: not x.startswith("__"),
dir(paddle.v2.dataset)): dir(paddle.dataset)):
if "convert" in dir( if "convert" in dir(
importlib.import_module("paddle.v2.dataset.%s" % module_name)) and \ importlib.import_module("paddle.dataset.%s" % module_name)) and \
not module_name == "common": not module_name == "common":
ds_path = os.path.join(path, module_name) ds_path = os.path.join(path, module_name)
must_mkdirs(ds_path) must_mkdirs(ds_path)
getattr( getattr(
importlib.import_module("paddle.v2.dataset.%s" % module_name), importlib.import_module("paddle.dataset.%s" % module_name),
"convert")(ds_path) "convert")(ds_path)
...@@ -130,7 +130,7 @@ def split(reader, line_count, suffix="%05d.pickle", dumper=cPickle.dump): ...@@ -130,7 +130,7 @@ def split(reader, line_count, suffix="%05d.pickle", dumper=cPickle.dump):
""" """
you can call the function as: you can call the function as:
split(paddle.v2.dataset.cifar.train10(), line_count=1000, split(paddle.dataset.cifar.train10(), line_count=1000,
suffix="imikolov-train-%05d.pickle") suffix="imikolov-train-%05d.pickle")
the output files as: the output files as:
......
...@@ -23,7 +23,7 @@ to initialize SRL model. ...@@ -23,7 +23,7 @@ to initialize SRL model.
import tarfile import tarfile
import gzip import gzip
import itertools import itertools
import paddle.v2.dataset.common import paddle.dataset.common
__all__ = ['test, get_dict', 'get_embedding', 'convert'] __all__ = ['test, get_dict', 'get_embedding', 'convert']
...@@ -203,14 +203,11 @@ def get_dict(): ...@@ -203,14 +203,11 @@ def get_dict():
Get the word, verb and label dictionary of Wikipedia corpus. Get the word, verb and label dictionary of Wikipedia corpus.
""" """
word_dict = load_dict( word_dict = load_dict(
paddle.v2.dataset.common.download(WORDDICT_URL, 'conll05st', paddle.dataset.common.download(WORDDICT_URL, 'conll05st', WORDDICT_MD5))
WORDDICT_MD5))
verb_dict = load_dict( verb_dict = load_dict(
paddle.v2.dataset.common.download(VERBDICT_URL, 'conll05st', paddle.dataset.common.download(VERBDICT_URL, 'conll05st', VERBDICT_MD5))
VERBDICT_MD5))
label_dict = load_label_dict( label_dict = load_label_dict(
paddle.v2.dataset.common.download(TRGDICT_URL, 'conll05st', paddle.dataset.common.download(TRGDICT_URL, 'conll05st', TRGDICT_MD5))
TRGDICT_MD5))
return word_dict, verb_dict, label_dict return word_dict, verb_dict, label_dict
...@@ -218,7 +215,7 @@ def get_embedding(): ...@@ -218,7 +215,7 @@ def get_embedding():
""" """
Get the trained word vector based on Wikipedia corpus. Get the trained word vector based on Wikipedia corpus.
""" """
return paddle.v2.dataset.common.download(EMB_URL, 'conll05st', EMB_MD5) return paddle.dataset.common.download(EMB_URL, 'conll05st', EMB_MD5)
def test(): def test():
...@@ -235,23 +232,23 @@ def test(): ...@@ -235,23 +232,23 @@ def test():
""" """
word_dict, verb_dict, label_dict = get_dict() word_dict, verb_dict, label_dict = get_dict()
reader = corpus_reader( reader = corpus_reader(
paddle.v2.dataset.common.download(DATA_URL, 'conll05st', DATA_MD5), paddle.dataset.common.download(DATA_URL, 'conll05st', DATA_MD5),
words_name='conll05st-release/test.wsj/words/test.wsj.words.gz', words_name='conll05st-release/test.wsj/words/test.wsj.words.gz',
props_name='conll05st-release/test.wsj/props/test.wsj.props.gz') props_name='conll05st-release/test.wsj/props/test.wsj.props.gz')
return reader_creator(reader, word_dict, verb_dict, label_dict) return reader_creator(reader, word_dict, verb_dict, label_dict)
def fetch(): def fetch():
paddle.v2.dataset.common.download(WORDDICT_URL, 'conll05st', WORDDICT_MD5) paddle.dataset.common.download(WORDDICT_URL, 'conll05st', WORDDICT_MD5)
paddle.v2.dataset.common.download(VERBDICT_URL, 'conll05st', VERBDICT_MD5) paddle.dataset.common.download(VERBDICT_URL, 'conll05st', VERBDICT_MD5)
paddle.v2.dataset.common.download(TRGDICT_URL, 'conll05st', TRGDICT_MD5) paddle.dataset.common.download(TRGDICT_URL, 'conll05st', TRGDICT_MD5)
paddle.v2.dataset.common.download(EMB_URL, 'conll05st', EMB_MD5) paddle.dataset.common.download(EMB_URL, 'conll05st', EMB_MD5)
paddle.v2.dataset.common.download(DATA_URL, 'conll05st', DATA_MD5) paddle.dataset.common.download(DATA_URL, 'conll05st', DATA_MD5)
def convert(path): def convert(path):
""" """
Converts dataset to recordio format Converts dataset to recordio format
""" """
paddle.v2.dataset.common.convert(path, test(), 1000, "conl105_train") paddle.dataset.common.convert(path, test(), 1000, "conl105_train")
paddle.v2.dataset.common.convert(path, test(), 1000, "conl105_test") paddle.dataset.common.convert(path, test(), 1000, "conl105_test")
...@@ -34,8 +34,8 @@ import functools ...@@ -34,8 +34,8 @@ import functools
from common import download from common import download
import tarfile import tarfile
import scipy.io as scio import scipy.io as scio
from paddle.v2.image import * from paddle.dataset.image import *
from paddle.v2.reader import * from paddle.reader import *
import os import os
import numpy as np import numpy as np
from multiprocessing import cpu_count from multiprocessing import cpu_count
......
...@@ -20,7 +20,7 @@ of 25,000 highly polar movie reviews for training, and 25,000 for testing. ...@@ -20,7 +20,7 @@ of 25,000 highly polar movie reviews for training, and 25,000 for testing.
Besides, this module also provides API for building dictionary. Besides, this module also provides API for building dictionary.
""" """
import paddle.v2.dataset.common import paddle.dataset.common
import collections import collections
import tarfile import tarfile
import re import re
...@@ -37,8 +37,7 @@ def tokenize(pattern): ...@@ -37,8 +37,7 @@ def tokenize(pattern):
Read files that match the given pattern. Tokenize and yield each file. Read files that match the given pattern. Tokenize and yield each file.
""" """
with tarfile.open(paddle.v2.dataset.common.download(URL, 'imdb', with tarfile.open(paddle.dataset.common.download(URL, 'imdb', MD5)) as tarf:
MD5)) as tarf:
# Note that we should use tarfile.next(), which does # Note that we should use tarfile.next(), which does
# sequential access of member files, other than # sequential access of member files, other than
# tarfile.extractfile, which does random access and might # tarfile.extractfile, which does random access and might
...@@ -136,7 +135,7 @@ def word_dict(): ...@@ -136,7 +135,7 @@ def word_dict():
def fetch(): def fetch():
paddle.v2.dataset.common.download(URL, 'imdb', MD5) paddle.dataset.common.download(URL, 'imdb', MD5)
def convert(path): def convert(path):
...@@ -144,5 +143,5 @@ def convert(path): ...@@ -144,5 +143,5 @@ def convert(path):
Converts dataset to recordio format Converts dataset to recordio format
""" """
w = word_dict() w = word_dict()
paddle.v2.dataset.common.convert(path, lambda: train(w), 1000, "imdb_train") paddle.dataset.common.convert(path, lambda: train(w), 1000, "imdb_train")
paddle.v2.dataset.common.convert(path, lambda: test(w), 1000, "imdb_test") paddle.dataset.common.convert(path, lambda: test(w), 1000, "imdb_test")
...@@ -18,7 +18,7 @@ This module will download dataset from ...@@ -18,7 +18,7 @@ This module will download dataset from
http://www.fit.vutbr.cz/~imikolov/rnnlm/ and parse training set and test set http://www.fit.vutbr.cz/~imikolov/rnnlm/ and parse training set and test set
into paddle reader creators. into paddle reader creators.
""" """
import paddle.v2.dataset.common import paddle.dataset.common
import collections import collections
import tarfile import tarfile
...@@ -54,9 +54,9 @@ def build_dict(min_word_freq=50): ...@@ -54,9 +54,9 @@ def build_dict(min_word_freq=50):
train_filename = './simple-examples/data/ptb.train.txt' train_filename = './simple-examples/data/ptb.train.txt'
test_filename = './simple-examples/data/ptb.valid.txt' test_filename = './simple-examples/data/ptb.valid.txt'
with tarfile.open( with tarfile.open(
paddle.v2.dataset.common.download( paddle.dataset.common.download(paddle.dataset.imikolov.URL,
paddle.v2.dataset.imikolov.URL, 'imikolov', 'imikolov',
paddle.v2.dataset.imikolov.MD5)) as tf: paddle.dataset.imikolov.MD5)) as tf:
trainf = tf.extractfile(train_filename) trainf = tf.extractfile(train_filename)
testf = tf.extractfile(test_filename) testf = tf.extractfile(test_filename)
word_freq = word_count(testf, word_count(trainf)) word_freq = word_count(testf, word_count(trainf))
...@@ -77,9 +77,9 @@ def build_dict(min_word_freq=50): ...@@ -77,9 +77,9 @@ def build_dict(min_word_freq=50):
def reader_creator(filename, word_idx, n, data_type): def reader_creator(filename, word_idx, n, data_type):
def reader(): def reader():
with tarfile.open( with tarfile.open(
paddle.v2.dataset.common.download( paddle.dataset.common.download(
paddle.v2.dataset.imikolov.URL, 'imikolov', paddle.dataset.imikolov.URL, 'imikolov',
paddle.v2.dataset.imikolov.MD5)) as tf: paddle.dataset.imikolov.MD5)) as tf:
f = tf.extractfile(filename) f = tf.extractfile(filename)
UNK = word_idx['<unk>'] UNK = word_idx['<unk>']
...@@ -145,7 +145,7 @@ def test(word_idx, n, data_type=DataType.NGRAM): ...@@ -145,7 +145,7 @@ def test(word_idx, n, data_type=DataType.NGRAM):
def fetch(): def fetch():
paddle.v2.dataset.common.download(URL, "imikolov", MD5) paddle.dataset.common.download(URL, "imikolov", MD5)
def convert(path): def convert(path):
...@@ -154,8 +154,7 @@ def convert(path): ...@@ -154,8 +154,7 @@ def convert(path):
""" """
N = 5 N = 5
word_dict = build_dict() word_dict = build_dict()
paddle.v2.dataset.common.convert(path, paddle.dataset.common.convert(path,
train(word_dict, N), 1000, train(word_dict, N), 1000, "imikolov_train")
"imikolov_train") paddle.dataset.common.convert(path,
paddle.v2.dataset.common.convert(path, test(word_dict, N), 1000, "imikolov_test")
test(word_dict, N), 1000, "imikolov_test")
...@@ -17,7 +17,7 @@ MNIST dataset. ...@@ -17,7 +17,7 @@ MNIST dataset.
This module will download dataset from http://yann.lecun.com/exdb/mnist/ and This module will download dataset from http://yann.lecun.com/exdb/mnist/ and
parse training set and test set into paddle reader creators. parse training set and test set into paddle reader creators.
""" """
import paddle.v2.dataset.common import paddle.dataset.common
import subprocess import subprocess
import numpy import numpy
import platform import platform
...@@ -85,10 +85,10 @@ def train(): ...@@ -85,10 +85,10 @@ def train():
:rtype: callable :rtype: callable
""" """
return reader_creator( return reader_creator(
paddle.v2.dataset.common.download(TRAIN_IMAGE_URL, 'mnist', paddle.dataset.common.download(TRAIN_IMAGE_URL, 'mnist',
TRAIN_IMAGE_MD5), TRAIN_IMAGE_MD5),
paddle.v2.dataset.common.download(TRAIN_LABEL_URL, 'mnist', paddle.dataset.common.download(TRAIN_LABEL_URL, 'mnist',
TRAIN_LABEL_MD5), 100) TRAIN_LABEL_MD5), 100)
def test(): def test():
...@@ -102,22 +102,21 @@ def test(): ...@@ -102,22 +102,21 @@ def test():
:rtype: callable :rtype: callable
""" """
return reader_creator( return reader_creator(
paddle.v2.dataset.common.download(TEST_IMAGE_URL, 'mnist', paddle.dataset.common.download(TEST_IMAGE_URL, 'mnist', TEST_IMAGE_MD5),
TEST_IMAGE_MD5), paddle.dataset.common.download(TEST_LABEL_URL, 'mnist', TEST_LABEL_MD5),
paddle.v2.dataset.common.download(TEST_LABEL_URL, 'mnist', 100)
TEST_LABEL_MD5), 100)
def fetch(): def fetch():
paddle.v2.dataset.common.download(TRAIN_IMAGE_URL, 'mnist', TRAIN_IMAGE_MD5) paddle.dataset.common.download(TRAIN_IMAGE_URL, 'mnist', TRAIN_IMAGE_MD5)
paddle.v2.dataset.common.download(TRAIN_LABEL_URL, 'mnist', TRAIN_LABEL_MD5) paddle.dataset.common.download(TRAIN_LABEL_URL, 'mnist', TRAIN_LABEL_MD5)
paddle.v2.dataset.common.download(TEST_IMAGE_URL, 'mnist', TEST_IMAGE_MD5) paddle.dataset.common.download(TEST_IMAGE_URL, 'mnist', TEST_IMAGE_MD5)
paddle.v2.dataset.common.download(TEST_LABEL_URL, 'mnist', TRAIN_LABEL_MD5) paddle.dataset.common.download(TEST_LABEL_URL, 'mnist', TRAIN_LABEL_MD5)
def convert(path): def convert(path):
""" """
Converts dataset to recordio format Converts dataset to recordio format
""" """
paddle.v2.dataset.common.convert(path, train(), 1000, "minist_train") paddle.dataset.common.convert(path, train(), 1000, "minist_train")
paddle.v2.dataset.common.convert(path, test(), 1000, "minist_test") paddle.dataset.common.convert(path, test(), 1000, "minist_test")
...@@ -23,7 +23,7 @@ set and test set into paddle reader creators. ...@@ -23,7 +23,7 @@ set and test set into paddle reader creators.
""" """
import zipfile import zipfile
import paddle.v2.dataset.common import paddle.dataset.common
import re import re
import random import random
import functools import functools
...@@ -100,7 +100,7 @@ USER_INFO = None ...@@ -100,7 +100,7 @@ USER_INFO = None
def __initialize_meta_info__(): def __initialize_meta_info__():
fn = paddle.v2.dataset.common.download(URL, "movielens", MD5) fn = paddle.dataset.common.download(URL, "movielens", MD5)
global MOVIE_INFO global MOVIE_INFO
if MOVIE_INFO is None: if MOVIE_INFO is None:
pattern = re.compile(r'^(.*)\((\d+)\)$') pattern = re.compile(r'^(.*)\((\d+)\)$')
...@@ -247,15 +247,15 @@ def unittest(): ...@@ -247,15 +247,15 @@ def unittest():
def fetch(): def fetch():
paddle.v2.dataset.common.download(URL, "movielens", MD5) paddle.dataset.common.download(URL, "movielens", MD5)
def convert(path): def convert(path):
""" """
Converts dataset to recordio format Converts dataset to recordio format
""" """
paddle.v2.dataset.common.convert(path, train(), 1000, "movielens_train") paddle.dataset.common.convert(path, train(), 1000, "movielens_train")
paddle.v2.dataset.common.convert(path, test(), 1000, "movielens_test") paddle.dataset.common.convert(path, test(), 1000, "movielens_test")
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -26,7 +26,7 @@ from itertools import chain ...@@ -26,7 +26,7 @@ from itertools import chain
import nltk import nltk
from nltk.corpus import movie_reviews from nltk.corpus import movie_reviews
import paddle.v2.dataset.common import paddle.dataset.common
__all__ = ['train', 'test', 'get_word_dict', 'convert'] __all__ = ['train', 'test', 'get_word_dict', 'convert']
NUM_TRAINING_INSTANCES = 1600 NUM_TRAINING_INSTANCES = 1600
...@@ -39,13 +39,13 @@ def download_data_if_not_yet(): ...@@ -39,13 +39,13 @@ def download_data_if_not_yet():
""" """
try: try:
# make sure that nltk can find the data # make sure that nltk can find the data
if paddle.v2.dataset.common.DATA_HOME not in nltk.data.path: if paddle.dataset.common.DATA_HOME not in nltk.data.path:
nltk.data.path.append(paddle.v2.dataset.common.DATA_HOME) nltk.data.path.append(paddle.dataset.common.DATA_HOME)
movie_reviews.categories() movie_reviews.categories()
except LookupError: except LookupError:
print "Downloading movie_reviews data set, please wait....." print "Downloading movie_reviews data set, please wait....."
nltk.download( nltk.download(
'movie_reviews', download_dir=paddle.v2.dataset.common.DATA_HOME) 'movie_reviews', download_dir=paddle.dataset.common.DATA_HOME)
print "Download data set success....." print "Download data set success....."
print "Path is " + nltk.data.find('corpora/movie_reviews').path print "Path is " + nltk.data.find('corpora/movie_reviews').path
...@@ -129,13 +129,12 @@ def test(): ...@@ -129,13 +129,12 @@ def test():
def fetch(): def fetch():
nltk.download( nltk.download('movie_reviews', download_dir=paddle.dataset.common.DATA_HOME)
'movie_reviews', download_dir=paddle.v2.dataset.common.DATA_HOME)
def convert(path): def convert(path):
""" """
Converts dataset to recordio format Converts dataset to recordio format
""" """
paddle.v2.dataset.common.convert(path, train, 1000, "sentiment_train") paddle.dataset.common.convert(path, train, 1000, "sentiment_train")
paddle.v2.dataset.common.convert(path, test, 1000, "sentiment_test") paddle.dataset.common.convert(path, test, 1000, "sentiment_test")
py_test(test_image SRCS test_image.py)
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2.dataset.cifar import paddle.dataset.cifar
import unittest import unittest
...@@ -29,25 +29,25 @@ class TestCIFAR(unittest.TestCase): ...@@ -29,25 +29,25 @@ class TestCIFAR(unittest.TestCase):
def test_test10(self): def test_test10(self):
instances, max_label_value = self.check_reader( instances, max_label_value = self.check_reader(
paddle.v2.dataset.cifar.test10()) paddle.dataset.cifar.test10())
self.assertEqual(instances, 10000) self.assertEqual(instances, 10000)
self.assertEqual(max_label_value, 9) self.assertEqual(max_label_value, 9)
def test_train10(self): def test_train10(self):
instances, max_label_value = self.check_reader( instances, max_label_value = self.check_reader(
paddle.v2.dataset.cifar.train10()) paddle.dataset.cifar.train10())
self.assertEqual(instances, 50000) self.assertEqual(instances, 50000)
self.assertEqual(max_label_value, 9) self.assertEqual(max_label_value, 9)
def test_test100(self): def test_test100(self):
instances, max_label_value = self.check_reader( instances, max_label_value = self.check_reader(
paddle.v2.dataset.cifar.test100()) paddle.dataset.cifar.test100())
self.assertEqual(instances, 10000) self.assertEqual(instances, 10000)
self.assertEqual(max_label_value, 99) self.assertEqual(max_label_value, 99)
def test_train100(self): def test_train100(self):
instances, max_label_value = self.check_reader( instances, max_label_value = self.check_reader(
paddle.v2.dataset.cifar.train100()) paddle.dataset.cifar.train100())
self.assertEqual(instances, 50000) self.assertEqual(instances, 50000)
self.assertEqual(max_label_value, 99) self.assertEqual(max_label_value, 99)
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2.dataset.common import paddle.dataset.common
import unittest import unittest
import tempfile import tempfile
import glob import glob
...@@ -24,14 +24,14 @@ class TestCommon(unittest.TestCase): ...@@ -24,14 +24,14 @@ class TestCommon(unittest.TestCase):
with open(temp_path, 'w') as f: with open(temp_path, 'w') as f:
f.write("Hello\n") f.write("Hello\n")
self.assertEqual('09f7e02f1290be211da707a266f153b3', self.assertEqual('09f7e02f1290be211da707a266f153b3',
paddle.v2.dataset.common.md5file(temp_path)) paddle.dataset.common.md5file(temp_path))
def test_download(self): def test_download(self):
yi_avatar = 'https://avatars0.githubusercontent.com/u/1548775?v=3&s=460' yi_avatar = 'https://avatars0.githubusercontent.com/u/1548775?v=3&s=460'
self.assertEqual( self.assertEqual(
paddle.v2.dataset.common.DATA_HOME + '/test/1548775?v=3&s=460', paddle.dataset.common.DATA_HOME + '/test/1548775?v=3&s=460',
paddle.v2.dataset.common.download( paddle.dataset.common.download(yi_avatar, 'test',
yi_avatar, 'test', 'f75287202d6622414c706c36c16f8e0d')) 'f75287202d6622414c706c36c16f8e0d'))
def test_split(self): def test_split(self):
def test_reader(): def test_reader():
...@@ -42,7 +42,7 @@ class TestCommon(unittest.TestCase): ...@@ -42,7 +42,7 @@ class TestCommon(unittest.TestCase):
return reader return reader
_, temp_path = tempfile.mkstemp() _, temp_path = tempfile.mkstemp()
paddle.v2.dataset.common.split( paddle.dataset.common.split(
test_reader(), 4, suffix=temp_path + '/test-%05d.pickle') test_reader(), 4, suffix=temp_path + '/test-%05d.pickle')
files = glob.glob(temp_path + '/test-%05d.pickle') files = glob.glob(temp_path + '/test-%05d.pickle')
self.assertEqual(len(files), 3) self.assertEqual(len(files), 3)
...@@ -52,7 +52,7 @@ class TestCommon(unittest.TestCase): ...@@ -52,7 +52,7 @@ class TestCommon(unittest.TestCase):
for x in xrange(5): for x in xrange(5):
with open(temp_path + '/%05d.test' % x) as f: with open(temp_path + '/%05d.test' % x) as f:
f.write('%d\n' % x) f.write('%d\n' % x)
reader = paddle.v2.dataset.common.cluster_files_reader( reader = paddle.dataset.common.cluster_files_reader(
temp_path + '/*.test', 5, 0) temp_path + '/*.test', 5, 0)
for idx, e in enumerate(reader()): for idx, e in enumerate(reader()):
self.assertEqual(e, str("0")) self.assertEqual(e, str("0"))
...@@ -69,9 +69,9 @@ class TestCommon(unittest.TestCase): ...@@ -69,9 +69,9 @@ class TestCommon(unittest.TestCase):
return reader return reader
path = tempfile.mkdtemp() path = tempfile.mkdtemp()
paddle.v2.dataset.common.convert(path, paddle.dataset.common.convert(path,
test_reader(), num_shards, test_reader(), num_shards,
'random_images') 'random_images')
files = glob.glob(path + '/random_images-*') files = glob.glob(path + '/random_images-*')
self.assertEqual(len(files), num_shards) self.assertEqual(len(files), num_shards)
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2.dataset.flowers import paddle.dataset.flowers
import unittest import unittest
...@@ -30,19 +30,19 @@ class TestFlowers(unittest.TestCase): ...@@ -30,19 +30,19 @@ class TestFlowers(unittest.TestCase):
def test_train(self): def test_train(self):
instances, max_label_value = self.check_reader( instances, max_label_value = self.check_reader(
paddle.v2.dataset.flowers.train()) paddle.dataset.flowers.train())
self.assertEqual(instances, 6149) self.assertEqual(instances, 6149)
self.assertEqual(max_label_value, 102) self.assertEqual(max_label_value, 102)
def test_test(self): def test_test(self):
instances, max_label_value = self.check_reader( instances, max_label_value = self.check_reader(
paddle.v2.dataset.flowers.test()) paddle.dataset.flowers.test())
self.assertEqual(instances, 1020) self.assertEqual(instances, 1020)
self.assertEqual(max_label_value, 102) self.assertEqual(max_label_value, 102)
def test_valid(self): def test_valid(self):
instances, max_label_value = self.check_reader( instances, max_label_value = self.check_reader(
paddle.v2.dataset.flowers.valid()) paddle.dataset.flowers.valid())
self.assertEqual(instances, 1020) self.assertEqual(instances, 1020)
self.assertEqual(max_label_value, 102) self.assertEqual(max_label_value, 102)
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2.dataset.imdb import paddle.dataset.imdb
import unittest import unittest
import re import re
...@@ -30,15 +30,13 @@ class TestIMDB(unittest.TestCase): ...@@ -30,15 +30,13 @@ class TestIMDB(unittest.TestCase):
def test_build_dict(self): def test_build_dict(self):
if self.word_idx == None: if self.word_idx == None:
self.word_idx = paddle.v2.dataset.imdb.build_dict(TRAIN_PATTERN, self.word_idx = paddle.dataset.imdb.build_dict(TRAIN_PATTERN, 150)
150)
self.assertEqual(len(self.word_idx), 7036) self.assertEqual(len(self.word_idx), 7036)
def check_dataset(self, dataset, expected_size): def check_dataset(self, dataset, expected_size):
if self.word_idx == None: if self.word_idx == None:
self.word_idx = paddle.v2.dataset.imdb.build_dict(TRAIN_PATTERN, self.word_idx = paddle.dataset.imdb.build_dict(TRAIN_PATTERN, 150)
150)
sum = 0 sum = 0
for l in dataset(self.word_idx): for l in dataset(self.word_idx):
...@@ -47,10 +45,10 @@ class TestIMDB(unittest.TestCase): ...@@ -47,10 +45,10 @@ class TestIMDB(unittest.TestCase):
self.assertEqual(sum, expected_size) self.assertEqual(sum, expected_size)
def test_train(self): def test_train(self):
self.check_dataset(paddle.v2.dataset.imdb.train, 25000) self.check_dataset(paddle.dataset.imdb.train, 25000)
def test_test(self): def test_test(self):
self.check_dataset(paddle.v2.dataset.imdb.test, 25000) self.check_dataset(paddle.dataset.imdb.test, 25000)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -12,10 +12,10 @@ ...@@ -12,10 +12,10 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2.dataset.imikolov import paddle.dataset.imikolov
import unittest import unittest
WORD_DICT = paddle.v2.dataset.imikolov.build_dict() WORD_DICT = paddle.dataset.imikolov.build_dict()
class TestMikolov(unittest.TestCase): class TestMikolov(unittest.TestCase):
...@@ -25,7 +25,7 @@ class TestMikolov(unittest.TestCase): ...@@ -25,7 +25,7 @@ class TestMikolov(unittest.TestCase):
def test_train(self): def test_train(self):
n = 5 n = 5
self.check_reader(paddle.v2.dataset.imikolov.train(WORD_DICT, n), n) self.check_reader(paddle.dataset.imikolov.train(WORD_DICT, n), n)
first_line = 'aer banknote berlitz calloway centrust cluett fromstein '\ first_line = 'aer banknote berlitz calloway centrust cluett fromstein '\
'gitano guterman hydro-quebec ipo kia memotec mlx nahb punts '\ 'gitano guterman hydro-quebec ipo kia memotec mlx nahb punts '\
...@@ -34,16 +34,16 @@ class TestMikolov(unittest.TestCase): ...@@ -34,16 +34,16 @@ class TestMikolov(unittest.TestCase):
WORD_DICT.get(ch, WORD_DICT['<unk>']) WORD_DICT.get(ch, WORD_DICT['<unk>'])
for ch in first_line.split(' ') for ch in first_line.split(' ')
] ]
for l in paddle.v2.dataset.imikolov.train( for l in paddle.dataset.imikolov.train(
WORD_DICT, n=-1, WORD_DICT, n=-1,
data_type=paddle.v2.dataset.imikolov.DataType.SEQ)(): data_type=paddle.dataset.imikolov.DataType.SEQ)():
read_line = l[0][1:] read_line = l[0][1:]
break break
self.assertEqual(first_line, read_line) self.assertEqual(first_line, read_line)
def test_test(self): def test_test(self):
n = 5 n = 5
self.check_reader(paddle.v2.dataset.imikolov.test(WORD_DICT, n), n) self.check_reader(paddle.dataset.imikolov.test(WORD_DICT, n), n)
first_line = 'consumers may want to move their telephones a little '\ first_line = 'consumers may want to move their telephones a little '\
'closer to the tv set' 'closer to the tv set'
...@@ -51,9 +51,9 @@ class TestMikolov(unittest.TestCase): ...@@ -51,9 +51,9 @@ class TestMikolov(unittest.TestCase):
WORD_DICT.get(ch, WORD_DICT['<unk>']) WORD_DICT.get(ch, WORD_DICT['<unk>'])
for ch in first_line.split(' ') for ch in first_line.split(' ')
] ]
for l in paddle.v2.dataset.imikolov.test( for l in paddle.dataset.imikolov.test(
WORD_DICT, n=-1, WORD_DICT, n=-1,
data_type=paddle.v2.dataset.imikolov.DataType.SEQ)(): data_type=paddle.dataset.imikolov.DataType.SEQ)():
read_line = l[0][1:] read_line = l[0][1:]
break break
self.assertEqual(first_line, read_line) self.assertEqual(first_line, read_line)
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2.dataset.mnist import paddle.dataset.mnist
import unittest import unittest
...@@ -29,13 +29,13 @@ class TestMNIST(unittest.TestCase): ...@@ -29,13 +29,13 @@ class TestMNIST(unittest.TestCase):
def test_train(self): def test_train(self):
instances, max_label_value = self.check_reader( instances, max_label_value = self.check_reader(
paddle.v2.dataset.mnist.train()) paddle.dataset.mnist.train())
self.assertEqual(instances, 60000) self.assertEqual(instances, 60000)
self.assertEqual(max_label_value, 9) self.assertEqual(max_label_value, 9)
def test_test(self): def test_test(self):
instances, max_label_value = self.check_reader( instances, max_label_value = self.check_reader(
paddle.v2.dataset.mnist.test()) paddle.dataset.mnist.test())
self.assertEqual(instances, 10000) self.assertEqual(instances, 10000)
self.assertEqual(max_label_value, 9) self.assertEqual(max_label_value, 9)
......
...@@ -12,19 +12,19 @@ ...@@ -12,19 +12,19 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2.dataset.mq2007 import paddle.dataset.mq2007
import unittest import unittest
class TestMQ2007(unittest.TestCase): class TestMQ2007(unittest.TestCase):
def test_pairwise(self): def test_pairwise(self):
for label, query_left, query_right in paddle.v2.dataset.mq2007.test( for label, query_left, query_right in paddle.dataset.mq2007.test(
format="pairwise"): format="pairwise"):
self.assertEqual(query_left.shape(), (46, )) self.assertEqual(query_left.shape(), (46, ))
self.assertEqual(query_right.shape(), (46, )) self.assertEqual(query_right.shape(), (46, ))
def test_listwise(self): def test_listwise(self):
for label_array, query_array in paddle.v2.dataset.mq2007.test( for label_array, query_array in paddle.dataset.mq2007.test(
format="listwise"): format="listwise"):
self.assertEqual(len(label_array), len(query_array)) self.assertEqual(len(label_array), len(query_array))
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
import unittest import unittest
import numpy as np import numpy as np
import paddle.v2.image as image import paddle.dataset.image as image
class Image(unittest.TestCase): class Image(unittest.TestCase):
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
import unittest import unittest
import nltk import nltk
import paddle.v2.dataset.sentiment as st import paddle.dataset.sentiment as st
from nltk.corpus import movie_reviews from nltk.corpus import movie_reviews
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2.dataset.voc2012 import paddle.dataset.voc2012
import unittest import unittest
...@@ -26,15 +26,15 @@ class TestVOC(unittest.TestCase): ...@@ -26,15 +26,15 @@ class TestVOC(unittest.TestCase):
return sum return sum
def test_train(self): def test_train(self):
count = self.check_reader(paddle.v2.dataset.voc_seg.train()) count = self.check_reader(paddle.dataset.voc_seg.train())
self.assertEqual(count, 2913) self.assertEqual(count, 2913)
def test_test(self): def test_test(self):
count = self.check_reader(paddle.v2.dataset.voc_seg.test()) count = self.check_reader(paddle.dataset.voc_seg.test())
self.assertEqual(count, 1464) self.assertEqual(count, 1464)
def test_val(self): def test_val(self):
count = self.check_reader(paddle.v2.dataset.voc_seg.val()) count = self.check_reader(paddle.dataset.voc_seg.val())
self.assertEqual(count, 1449) self.assertEqual(count, 1449)
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2.dataset.wmt16 import paddle.dataset.wmt16
import unittest import unittest
...@@ -34,28 +34,28 @@ class TestWMT16(unittest.TestCase): ...@@ -34,28 +34,28 @@ class TestWMT16(unittest.TestCase):
def test_train(self): def test_train(self):
for idx, sample in enumerate( for idx, sample in enumerate(
paddle.v2.dataset.wmt16.train( paddle.dataset.wmt16.train(
src_dict_size=100000, trg_dict_size=100000)()): src_dict_size=100000, trg_dict_size=100000)()):
if idx >= 10: break if idx >= 10: break
self.checkout_one_sample(sample) self.checkout_one_sample(sample)
def test_test(self): def test_test(self):
for idx, sample in enumerate( for idx, sample in enumerate(
paddle.v2.dataset.wmt16.test( paddle.dataset.wmt16.test(
src_dict_size=1000, trg_dict_size=1000)()): src_dict_size=1000, trg_dict_size=1000)()):
if idx >= 10: break if idx >= 10: break
self.checkout_one_sample(sample) self.checkout_one_sample(sample)
def test_val(self): def test_val(self):
for idx, sample in enumerate( for idx, sample in enumerate(
paddle.v2.dataset.wmt16.validation( paddle.dataset.wmt16.validation(
src_dict_size=1000, trg_dict_size=1000)()): src_dict_size=1000, trg_dict_size=1000)()):
if idx >= 10: break if idx >= 10: break
self.checkout_one_sample(sample) self.checkout_one_sample(sample)
def test_get_dict(self): def test_get_dict(self):
dict_size = 1000 dict_size = 1000
word_dict = paddle.v2.dataset.wmt16.get_dict("en", dict_size, True) word_dict = paddle.dataset.wmt16.get_dict("en", dict_size, True)
self.assertEqual(len(word_dict), dict_size) self.assertEqual(len(word_dict), dict_size)
self.assertEqual(word_dict[0], "<s>") self.assertEqual(word_dict[0], "<s>")
self.assertEqual(word_dict[1], "<e>") self.assertEqual(word_dict[1], "<e>")
......
...@@ -21,8 +21,7 @@ parse training set and test set into paddle reader creators. ...@@ -21,8 +21,7 @@ parse training set and test set into paddle reader creators.
import numpy as np import numpy as np
import os import os
import paddle.v2.dataset.common import paddle.dataset.common
from paddle.v2.parameters import Parameters
__all__ = ['train', 'test'] __all__ = ['train', 'test']
...@@ -85,7 +84,7 @@ def train(): ...@@ -85,7 +84,7 @@ def train():
:rtype: callable :rtype: callable
""" """
global UCI_TRAIN_DATA global UCI_TRAIN_DATA
load_data(paddle.v2.dataset.common.download(URL, 'uci_housing', MD5)) load_data(paddle.dataset.common.download(URL, 'uci_housing', MD5))
def reader(): def reader():
for d in UCI_TRAIN_DATA: for d in UCI_TRAIN_DATA:
...@@ -105,7 +104,7 @@ def test(): ...@@ -105,7 +104,7 @@ def test():
:rtype: callable :rtype: callable
""" """
global UCI_TEST_DATA global UCI_TEST_DATA
load_data(paddle.v2.dataset.common.download(URL, 'uci_housing', MD5)) load_data(paddle.dataset.common.download(URL, 'uci_housing', MD5))
def reader(): def reader():
for d in UCI_TEST_DATA: for d in UCI_TEST_DATA:
...@@ -114,21 +113,13 @@ def test(): ...@@ -114,21 +113,13 @@ def test():
return reader return reader
def model():
tar_file = paddle.v2.dataset.common.download(URL_MODEL, 'fit_a_line.tar',
MD5_MODEL)
with open(tar_file, 'r') as f:
parameters = Parameters.from_tar(f)
return parameters
def fetch(): def fetch():
paddle.v2.dataset.common.download(URL, 'uci_housing', MD5) paddle.dataset.common.download(URL, 'uci_housing', MD5)
def convert(path): def convert(path):
""" """
Converts dataset to recordio format Converts dataset to recordio format
""" """
paddle.v2.dataset.common.convert(path, train(), 1000, "uci_housing_train") paddle.dataset.common.convert(path, train(), 1000, "uci_housing_train")
paddle.v2.dataset.common.convert(path, test(), 1000, "uci_houseing_test") paddle.dataset.common.convert(path, test(), 1000, "uci_houseing_test")
...@@ -22,8 +22,8 @@ with segmentation has been increased from 7,062 to 9,993. ...@@ -22,8 +22,8 @@ with segmentation has been increased from 7,062 to 9,993.
import tarfile import tarfile
import io import io
import numpy as np import numpy as np
from paddle.v2.dataset.common import download from paddle.dataset.common import download
from paddle.v2.image import * from paddle.dataset.image import *
from PIL import Image from PIL import Image
__all__ = ['train', 'test', 'val'] __all__ = ['train', 'test', 'val']
......
...@@ -22,8 +22,7 @@ parse training set and test set into paddle reader creators. ...@@ -22,8 +22,7 @@ parse training set and test set into paddle reader creators.
import tarfile import tarfile
import gzip import gzip
import paddle.v2.dataset.common import paddle.dataset.common
from paddle.v2.parameters import Parameters
__all__ = [ __all__ = [
'train', 'train',
...@@ -123,7 +122,7 @@ def train(dict_size): ...@@ -123,7 +122,7 @@ def train(dict_size):
:rtype: callable :rtype: callable
""" """
return reader_creator( return reader_creator(
paddle.v2.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN), paddle.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN),
'train/train', dict_size) 'train/train', dict_size)
...@@ -139,27 +138,20 @@ def test(dict_size): ...@@ -139,27 +138,20 @@ def test(dict_size):
:rtype: callable :rtype: callable
""" """
return reader_creator( return reader_creator(
paddle.v2.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN), paddle.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN),
'test/test', dict_size) 'test/test', dict_size)
def gen(dict_size): def gen(dict_size):
return reader_creator( return reader_creator(
paddle.v2.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN), paddle.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN),
'gen/gen', dict_size) 'gen/gen', dict_size)
def model():
tar_file = paddle.v2.dataset.common.download(URL_MODEL, 'wmt14', MD5_MODEL)
with gzip.open(tar_file, 'r') as f:
parameters = Parameters.from_tar(f)
return parameters
def get_dict(dict_size, reverse=True): def get_dict(dict_size, reverse=True):
# if reverse = False, return dict = {'a':'001', 'b':'002', ...} # if reverse = False, return dict = {'a':'001', 'b':'002', ...}
# else reverse = true, return dict = {'001':'a', '002':'b', ...} # else reverse = true, return dict = {'001':'a', '002':'b', ...}
tar_file = paddle.v2.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN) tar_file = paddle.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN)
src_dict, trg_dict = __read_to_dict(tar_file, dict_size) src_dict, trg_dict = __read_to_dict(tar_file, dict_size)
if reverse: if reverse:
src_dict = {v: k for k, v in src_dict.items()} src_dict = {v: k for k, v in src_dict.items()}
...@@ -168,8 +160,8 @@ def get_dict(dict_size, reverse=True): ...@@ -168,8 +160,8 @@ def get_dict(dict_size, reverse=True):
def fetch(): def fetch():
paddle.v2.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN) paddle.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN)
paddle.v2.dataset.common.download(URL_MODEL, 'wmt14', MD5_MODEL) paddle.dataset.common.download(URL_MODEL, 'wmt14', MD5_MODEL)
def convert(path): def convert(path):
...@@ -177,6 +169,5 @@ def convert(path): ...@@ -177,6 +169,5 @@ def convert(path):
Converts dataset to recordio format Converts dataset to recordio format
""" """
dict_size = 30000 dict_size = 30000
paddle.v2.dataset.common.convert(path, paddle.dataset.common.convert(path, train(dict_size), 1000, "wmt14_train")
train(dict_size), 1000, "wmt14_train") paddle.dataset.common.convert(path, test(dict_size), 1000, "wmt14_test")
paddle.v2.dataset.common.convert(path, test(dict_size), 1000, "wmt14_test")
...@@ -33,7 +33,7 @@ import tarfile ...@@ -33,7 +33,7 @@ import tarfile
import gzip import gzip
from collections import defaultdict from collections import defaultdict
import paddle.v2.dataset.common import paddle.dataset.common
__all__ = [ __all__ = [
"train", "train",
...@@ -76,7 +76,7 @@ def __build_dict(tar_file, dict_size, save_path, lang): ...@@ -76,7 +76,7 @@ def __build_dict(tar_file, dict_size, save_path, lang):
def __load_dict(tar_file, dict_size, lang, reverse=False): def __load_dict(tar_file, dict_size, lang, reverse=False):
dict_path = os.path.join(paddle.v2.dataset.common.DATA_HOME, dict_path = os.path.join(paddle.dataset.common.DATA_HOME,
"wmt16/%s_%d.dict" % (lang, dict_size)) "wmt16/%s_%d.dict" % (lang, dict_size))
if not os.path.exists(dict_path) or ( if not os.path.exists(dict_path) or (
len(open(dict_path, "r").readlines()) != dict_size): len(open(dict_path, "r").readlines()) != dict_size):
...@@ -178,8 +178,8 @@ def train(src_dict_size, trg_dict_size, src_lang="en"): ...@@ -178,8 +178,8 @@ def train(src_dict_size, trg_dict_size, src_lang="en"):
src_lang) src_lang)
return reader_creator( return reader_creator(
tar_file=paddle.v2.dataset.common.download(DATA_URL, "wmt16", DATA_MD5, tar_file=paddle.dataset.common.download(DATA_URL, "wmt16", DATA_MD5,
"wmt16.tar.gz"), "wmt16.tar.gz"),
file_name="wmt16/train", file_name="wmt16/train",
src_dict_size=src_dict_size, src_dict_size=src_dict_size,
trg_dict_size=trg_dict_size, trg_dict_size=trg_dict_size,
...@@ -227,8 +227,8 @@ def test(src_dict_size, trg_dict_size, src_lang="en"): ...@@ -227,8 +227,8 @@ def test(src_dict_size, trg_dict_size, src_lang="en"):
src_lang) src_lang)
return reader_creator( return reader_creator(
tar_file=paddle.v2.dataset.common.download(DATA_URL, "wmt16", DATA_MD5, tar_file=paddle.dataset.common.download(DATA_URL, "wmt16", DATA_MD5,
"wmt16.tar.gz"), "wmt16.tar.gz"),
file_name="wmt16/test", file_name="wmt16/test",
src_dict_size=src_dict_size, src_dict_size=src_dict_size,
trg_dict_size=trg_dict_size, trg_dict_size=trg_dict_size,
...@@ -274,8 +274,8 @@ def validation(src_dict_size, trg_dict_size, src_lang="en"): ...@@ -274,8 +274,8 @@ def validation(src_dict_size, trg_dict_size, src_lang="en"):
src_lang) src_lang)
return reader_creator( return reader_creator(
tar_file=paddle.v2.dataset.common.download(DATA_URL, "wmt16", DATA_MD5, tar_file=paddle.dataset.common.download(DATA_URL, "wmt16", DATA_MD5,
"wmt16.tar.gz"), "wmt16.tar.gz"),
file_name="wmt16/val", file_name="wmt16/val",
src_dict_size=src_dict_size, src_dict_size=src_dict_size,
trg_dict_size=trg_dict_size, trg_dict_size=trg_dict_size,
...@@ -303,12 +303,12 @@ def get_dict(lang, dict_size, reverse=False): ...@@ -303,12 +303,12 @@ def get_dict(lang, dict_size, reverse=False):
if lang == "en": dict_size = min(dict_size, TOTAL_EN_WORDS) if lang == "en": dict_size = min(dict_size, TOTAL_EN_WORDS)
else: dict_size = min(dict_size, TOTAL_DE_WORDS) else: dict_size = min(dict_size, TOTAL_DE_WORDS)
dict_path = os.path.join(paddle.v2.dataset.common.DATA_HOME, dict_path = os.path.join(paddle.dataset.common.DATA_HOME,
"wmt16/%s_%d.dict" % (lang, dict_size)) "wmt16/%s_%d.dict" % (lang, dict_size))
assert os.path.exists(dict_path), "Word dictionary does not exist. " assert os.path.exists(dict_path), "Word dictionary does not exist. "
"Please invoke paddle.dataset.wmt16.train/test/validation first " "Please invoke paddle.dataset.wmt16.train/test/validation first "
"to build the dictionary." "to build the dictionary."
tar_file = os.path.join(paddle.v2.dataset.common.DATA_HOME, "wmt16.tar.gz") tar_file = os.path.join(paddle.dataset.common.DATA_HOME, "wmt16.tar.gz")
return __load_dict(tar_file, dict_size, lang, reverse) return __load_dict(tar_file, dict_size, lang, reverse)
...@@ -323,7 +323,7 @@ def convert(path, src_dict_size, trg_dict_size, src_lang): ...@@ -323,7 +323,7 @@ def convert(path, src_dict_size, trg_dict_size, src_lang):
"""Converts dataset to recordio format. """Converts dataset to recordio format.
""" """
paddle.v2.dataset.common.convert( paddle.dataset.common.convert(
path, path,
train( train(
src_dict_size=src_dict_size, src_dict_size=src_dict_size,
...@@ -331,7 +331,7 @@ def convert(path, src_dict_size, trg_dict_size, src_lang): ...@@ -331,7 +331,7 @@ def convert(path, src_dict_size, trg_dict_size, src_lang):
src_lang=src_lang), src_lang=src_lang),
1000, 1000,
"wmt16_train") "wmt16_train")
paddle.v2.dataset.common.convert( paddle.dataset.common.convert(
path, path,
test( test(
src_dict_size=src_dict_size, src_dict_size=src_dict_size,
...@@ -339,7 +339,7 @@ def convert(path, src_dict_size, trg_dict_size, src_lang): ...@@ -339,7 +339,7 @@ def convert(path, src_dict_size, trg_dict_size, src_lang):
src_lang=src_lang), src_lang=src_lang),
1000, 1000,
"wmt16_test") "wmt16_test")
paddle.v2.dataset.common.convert( paddle.dataset.common.convert(
path, path,
validation( validation(
src_dict_size=src_dict_size, src_dict_size=src_dict_size,
......
...@@ -338,15 +338,24 @@ class DistributeTranspiler: ...@@ -338,15 +338,24 @@ class DistributeTranspiler:
else: else:
self._append_pserver_non_opt_ops(block, op) self._append_pserver_non_opt_ops(block, op)
append_block = optimize_block
# append lr decay ops to the child block if exits
lr_ops = self._get_lr_ops()
if len(lr_ops) > 0:
for _, op in enumerate(lr_ops):
self._append_pserver_non_opt_ops(append_block, op)
append_block = pserver_program.create_block(append_block.idx)
# append op to the current block # append op to the current block
per_opt_block = optimize_block per_opt_block = append_block
for _, opt_op in enumerate(opt_op_on_pserver): for _, opt_op in enumerate(opt_op_on_pserver):
for _, op in enumerate(self.optimize_ops): for _, op in enumerate(self.optimize_ops):
# optimizer is connected to itself # optimizer is connected to itself
if ufind.is_connected(op, opt_op) and \ if ufind.is_connected(op, opt_op) and \
op not in global_ops: op not in global_ops:
__append_optimize_op__(op, per_opt_block) __append_optimize_op__(op, per_opt_block)
per_opt_block = pserver_program.create_block(0) per_opt_block = pserver_program.create_block(append_block.idx)
# append global ops # append global ops
for glb_op in global_ops: for glb_op in global_ops:
...@@ -786,3 +795,33 @@ class DistributeTranspiler: ...@@ -786,3 +795,33 @@ class DistributeTranspiler:
else: else:
iomap[key] = vars iomap[key] = vars
return iomap return iomap
def _get_lr_ops(self):
lr_ops = []
# find learning rate variables by optimize op
lr_vars = set()
for op in self.optimize_ops:
if self._is_opt_op(op):
lr_vars.add(op.input("LearningRate")[0])
find_ops = []
# find ops which output is lr var
block = self.program.global_block()
for op in block.ops:
if set(op.output_arg_names) & lr_vars:
find_ops.append(op)
# make a union find struct by the ops in default_main_program
ufind = UnionFind(block.ops)
for op1 in block.ops:
for op2 in block.ops:
# NOTE: we need to skip all optimize ops, since it is connected
# with forward/backward ops and lr ops, we only need the lr ops.
if op1 != op2 and self._is_op_connected(op1, op2) and \
not self._is_opt_op(op1) and not self._is_opt_op(op2):
ufind.union(op1, op2)
# find all ops which is related with lr var
for op1 in block.ops:
for op2 in find_ops:
if ufind.is_connected(op1, op2):
lr_ops.append(op1)
return lr_ops
...@@ -18,6 +18,7 @@ from tensor import assign, fill_constant ...@@ -18,6 +18,7 @@ from tensor import assign, fill_constant
from .. import core from .. import core
from ..framework import Program, Variable, Operator from ..framework import Program, Variable, Operator
from ..layer_helper import LayerHelper, unique_name from ..layer_helper import LayerHelper, unique_name
from ..initializer import force_init_on_cpu
from ops import logical_and, logical_not, logical_or from ops import logical_and, logical_not, logical_or
__all__ = [ __all__ = [
...@@ -949,7 +950,7 @@ def create_array(dtype): ...@@ -949,7 +950,7 @@ def create_array(dtype):
dtype=dtype) dtype=dtype)
def less_than(x, y, cond=None, **ignored): def less_than(x, y, force_cpu=True, cond=None, **ignored):
""" """
**Less than** **Less than**
...@@ -958,6 +959,7 @@ def less_than(x, y, cond=None, **ignored): ...@@ -958,6 +959,7 @@ def less_than(x, y, cond=None, **ignored):
Args: Args:
x(Variable): First operand of *less_than* x(Variable): First operand of *less_than*
y(Variable): Second operand of *less_than* y(Variable): Second operand of *less_than*
force_cpu(Bool|True): The output data will be on CPU if set true.
cond(Variable|None): Optional output variable to store the result of *less_than* cond(Variable|None): Optional output variable to store the result of *less_than*
Returns: Returns:
...@@ -974,8 +976,11 @@ def less_than(x, y, cond=None, **ignored): ...@@ -974,8 +976,11 @@ def less_than(x, y, cond=None, **ignored):
cond.stop_gradient = True cond.stop_gradient = True
helper.append_op( helper.append_op(
type='less_than', inputs={'X': [x], type='less_than',
'Y': [y]}, outputs={'Out': [cond]}) inputs={'X': [x],
'Y': [y]},
outputs={'Out': [cond]},
attrs={'force_cpu': force_cpu or force_init_on_cpu()})
return cond return cond
...@@ -1396,7 +1401,8 @@ class DynamicRNN(object): ...@@ -1396,7 +1401,8 @@ class DynamicRNN(object):
type='less_than', type='less_than',
inputs={'X': self.step_idx, inputs={'X': self.step_idx,
'Y': self.max_seq_len}, 'Y': self.max_seq_len},
outputs={'Out': self.cond}) outputs={'Out': self.cond},
attrs={'force_cpu': True})
input_array = parent_block.create_var( input_array = parent_block.create_var(
name=unique_name.generate('dynamic_rnn_input_array'), name=unique_name.generate('dynamic_rnn_input_array'),
...@@ -1445,7 +1451,11 @@ class DynamicRNN(object): ...@@ -1445,7 +1451,11 @@ class DynamicRNN(object):
for new_mem, mem_array in self.mem_link: for new_mem, mem_array in self.mem_link:
array_write(x=new_mem, i=self.step_idx, array=mem_array) array_write(x=new_mem, i=self.step_idx, array=mem_array)
less_than(x=self.step_idx, y=self.max_seq_len, cond=self.cond) less_than(
x=self.step_idx,
y=self.max_seq_len,
force_cpu=True,
cond=self.cond)
self.status = DynamicRNN.AFTER_RNN self.status = DynamicRNN.AFTER_RNN
for each_array in self.output_array: for each_array in self.output_array:
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
# limitations under the License. # limitations under the License.
import numpy as np import numpy as np
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import paddle.fluid.core as core import paddle.fluid.core as core
import paddle.fluid.framework as framework import paddle.fluid.framework as framework
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import contextlib import contextlib
import numpy import numpy
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
from __future__ import print_function from __future__ import print_function
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import contextlib import contextlib
import math import math
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
import math import math
import numpy as np import numpy as np
import paddle.v2 as paddle import paddle
import paddle.v2.dataset.conll05 as conll05 import paddle.dataset.conll05 as conll05
import paddle.fluid as fluid import paddle.fluid as fluid
from paddle.fluid.initializer import init_on_cpu from paddle.fluid.initializer import init_on_cpu
import contextlib import contextlib
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
import contextlib import contextlib
import numpy as np import numpy as np
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import paddle.fluid.framework as framework import paddle.fluid.framework as framework
import paddle.fluid.layers as pd import paddle.fluid.layers as pd
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
from __future__ import print_function from __future__ import print_function
import argparse import argparse
import paddle.fluid as fluid import paddle.fluid as fluid
import paddle.v2 as paddle import paddle
import sys import sys
import numpy import numpy
import unittest import unittest
......
...@@ -16,7 +16,7 @@ import math ...@@ -16,7 +16,7 @@ import math
import sys import sys
import os import os
import numpy as np import numpy as np
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import paddle.fluid.framework as framework import paddle.fluid.framework as framework
import paddle.fluid.layers as layers import paddle.fluid.layers as layers
......
...@@ -15,7 +15,7 @@ from __future__ import print_function ...@@ -15,7 +15,7 @@ from __future__ import print_function
import unittest import unittest
import paddle.fluid as fluid import paddle.fluid as fluid
import paddle.v2 as paddle import paddle
import contextlib import contextlib
import math import math
import numpy as np import numpy as np
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import unittest import unittest
import os import os
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
# limitations under the License. # limitations under the License.
import numpy as np import numpy as np
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import math import math
import sys import sys
......
...@@ -16,7 +16,7 @@ from __future__ import print_function ...@@ -16,7 +16,7 @@ from __future__ import print_function
import sys import sys
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import math import math
import sys import sys
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
# limitations under the License. # limitations under the License.
import numpy as np import numpy as np
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import paddle.fluid.core as core import paddle.fluid.core as core
import paddle.fluid.framework as framework import paddle.fluid.framework as framework
......
...@@ -19,7 +19,7 @@ import os ...@@ -19,7 +19,7 @@ import os
import matplotlib import matplotlib
import numpy import numpy
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
matplotlib.use('Agg') matplotlib.use('Agg')
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import numpy as np import numpy as np
import sys import sys
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
from __future__ import print_function from __future__ import print_function
import numpy as np import numpy as np
import paddle.v2 as paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
BATCH_SIZE = 128 BATCH_SIZE = 128
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册