Skip to content

Commit 4854a42

Browse files
committed
Merge branch 'develop' of https://github.com/baidu/Paddle into inference
2 parents 9360835 + 4adc8a7 commit 4854a42

File tree

250 files changed

+5419
-630
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

250 files changed

+5419
-630
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ third_party/
2121
cmake-build-*
2222

2323
# generated while compiling
24-
python/paddle/v2/framework/core.so
24+
python/paddle/v2/fluid/core.so
2525
paddle/pybind/pybind.h
2626
CMakeFiles
2727
cmake_install.cmake

cmake/external/openblas.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ INCLUDE_DIRECTORIES(${CBLAS_INC_DIR})
115115
# linear algebra libraries for cc_library(xxx SRCS xxx.c DEPS cblas)
116116
SET(dummyfile ${CMAKE_CURRENT_BINARY_DIR}/cblas_dummy.c)
117117
FILE(WRITE ${dummyfile} "const char * dummy = \"${dummyfile}\";")
118-
IF(${CBLAS_PROVIDER} EQUAL MKLML)
118+
IF("${CBLAS_PROVIDER}" STREQUAL "MKLML")
119119
ADD_LIBRARY(cblas SHARED ${dummyfile})
120120
ELSE()
121121
ADD_LIBRARY(cblas STATIC ${dummyfile})

cmake/generic.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
9393
if(NOT APPLE AND NOT ANDROID)
9494
find_package(Threads REQUIRED)
9595
link_libraries(${CMAKE_THREAD_LIBS_INIT})
96-
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -ldl -lrt")
96+
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -pthread -ldl -lrt")
9797
endif(NOT APPLE AND NOT ANDROID)
9898

9999
function(merge_static_libs TARGET_NAME)

doc/api/v2/config/layer.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ maxout
8282
.. autoclass:: paddle.v2.layer.maxout
8383
:noindex:
8484

85+
roi_pool
86+
--------
87+
.. autoclass:: paddle.v2.layer.roi_pool
88+
:noindex:
89+
8590
Norm Layer
8691
==========
8792

doc/design/mkldnn/README.MD

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- [CMake](#cmake)
1616
- [Layers](#layers)
1717
- [Activations](#activations)
18+
- [Weights](#weights)
1819
- [Unit Tests](#unit-tests)
1920
- [Protobuf Messages](#protobuf-messages)
2021
- [Python API](#python-api)
@@ -45,17 +46,23 @@ Figure 1. PaddlePaddle on IA.
4546

4647
### Layers
4748
所有MKL-DNN相关的C++ layers,都会按照PaddlePaddle的目录结构存放在
48-
`paddle/gserver/layers`中,并且文件名都会一以*Mkldnn*开头。
49+
`paddle/gserver/layers`中,并且文件名都会一以*MKLDNN*开头。
4950

50-
所有MKL-DNN的layers都会继承于一个叫做`MkldnnLayer`的父类,该父类继承于PaddlePaddle的基类`Layer`
51+
所有MKL-DNN的layers都会继承于一个叫做`MKLDNNLayer`的父类,该父类继承于PaddlePaddle的基类`Layer`
52+
53+
`MKLDNNLayer`中会提供一些必要的接口和函数,并且会写好`forward``backward`的基本逻辑。部分函数定义为纯虚函数,子类只需要实现这些函数即可。
5154

5255
### Activations
53-
由于在PaddlePaddle中,激活函数是独立于layer概念的,所以会在`paddle/gserver/activations`目录下添加一个`MkldnnActivation.h`文件定义一些用于MKL-DNN的接口,实现方法还是会在`ActivationFunction.cpp`文件
56+
由于在PaddlePaddle中,激活函数是独立于layer概念的,所以会在`paddle/gserver/activations`目录下添加`MKLDNNActivation.h``MKLDNNActivation.cpp`文件用于定义和使用MKL-DNN的接口
5457

55-
### Unit Tests
56-
会在`paddle/gserver/test`目录下添加`test_Mkldnn.cpp``MkldnnTester.*`用于MKL-DNN的测试。
58+
### Weights
59+
由于有些layer是含有参数的,我们会尽量让MKL-DNN的参数与PaddlePaddle中`parameter`共享一块内存。
60+
同时,由于MKL-DNN在训练时使用的参数layout可能与PaddlePaddle默认的`nchw`不一致,我们会在网络训练的开始和结束时分别转换这个layout,使得最终保存的参数格式与PaddlePaddle一致。
5761

58-
Activation的测试,计划在PaddlePaddle原有的测试文件上直接添加新的测试type。
62+
### Unit Tests
63+
会在`paddle/gserver/test`目录下添加`test_MKLDNN.cpp``MKLDNNTester.*`用于MKL-DNN的测试。
64+
测试分为每个layer(或activation)的单元测试和简单网络的整体测试。
65+
每个测试会对比PaddlePaddle中CPU算出的结果与MKL-DNN的结果,小于某个比较小的阈值认为通过。
5966

6067
### Protobuf Messages
6168
根据具体layer的需求可能会在`proto/ModelConfig.proto`里面添加必要的选项。
@@ -82,7 +89,7 @@ if use_mkldnn
8289
会在`v1_api_demo`目录下添加一个`mkldnn`的文件夹,里面放入一些用于MKL-DNN测试的demo脚本。
8390

8491
### Benchmarking
85-
会考虑添加部分逻辑在`benchmark/paddle/image/run.sh`添加使用MKL-DNN的测试
92+
会添加`benchmark/paddle/image/run_mkldnn.sh`用于测试使用MKL-DNN之后的性能
8693

8794
### Others
8895
1. 如果在使用MKL-DNN的情况下,会把CPU的Buffer对齐为64。
@@ -94,14 +101,16 @@ if use_mkldnn
94101

95102
我们总结出一些特别需要注意的点:
96103

97-
1. 使用**deviceId_**。为了尽可能少的在父类Layer中添加变量或者函数,我们决定使用已有的`deviceId_`变量来区分layer的属性,定义`-2``MkldnnLayer`特有的设备ID。
104+
1. 使用**deviceId_**。为了尽可能少的在父类Layer中添加变量或者函数,我们决定使用已有的`deviceId_`变量来区分layer的属性,定义`-2``MKLDNNLayer`特有的设备ID。
98105
2. 重写父类Layer的**init**函数,修改`deviceId_``-2`,代表这个layer是用于跑在MKL-DNN的环境下。
99-
3. 创建`MkldnnMatrix`,用于管理MKL-DNN会用到的相关memory函数、接口以及会用的到格式信息。
100-
4. 创建`MkldnnBase`,定义一些除了layer和memory相关的类和函数。包括MKL-DNN会用到`MkldnnStream``CpuEngine`,和未来可能还会用到`FPGAEngine`等。
101-
5.**Argument**里添加两个`MkldnnMatrixPtr`,取名为`mkldnnValue``mkldnnGrad`,用于存放`MkldnnLayer`会用到的memory buffer。 并且添加函数cvt(会修改为一个更加合适的函数名),用于处理"CPU device"和"MKL-DNN device"之间memory的相互转化。
102-
6. 在父类`Layer`中的`getOutput`函数中添加一段逻辑,用于判断`deviceId`,并针对device在MKL-DNN和CPU之间不统一的情况,做一个前期转换。 也就是调用`Argument`的cvt函数把output统一到需要的device上。
103-
7. 在原来的`FLAGS`中添加一个`use_mkldnn`的flag,用于选择是否使用MKL-DNN的相关功能。
104-
8. 关于MKLDNN参数的保存。由于MKLDNN参数的格式与PaddlePaddle原有的格式存在不一样的情况,所以需要在保存参数时同时保存该格式信息。目前准备扩展[Header](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/parameter/Parameter.h#L247)里面的`int32_t version`。这个值不管是在v1还是在v2里面,一直保存的是0,所以可以充分利用这个信息,定义一个枚举处理所有MKLDNN的参数格式,从而`MKLDNNLayer`就可以从输入的参数中获取需要的格式信息。
106+
3. 创建`MKLDNNMatrix`,同时继承`CpuMatrix``mkldnn::memory`。用于管理MKL-DNN会用到的相关memory函数、接口以及会用的到格式信息。
107+
4. 创建`MKLDNNBase`,定义一些除了layer和memory相关的类和函数。包括MKL-DNN会用到`MKLDNNStream``CPUEngine`,和未来可能还会用到`FPGAEngine`等。
108+
5. 每个`MKLDNNlayer`都会有`inVal_`,`inGrad_`,`outVal_``outGrad_`,分别代表input value, input gradient,output value和output gradient。他们会存放MKL-DNN用到的internal memory。同时还会定义以*ext*开头的`MKLDNNMatrix`(表示external的memory),主要是在格式与PaddlePaddle默认的`nchw`格式不匹配时,用于转换内存的工作。必要的转换函数也会在`MKLDNNLayer`中提前定义好,每个子类只需要调用定义好的reset buffer函数即可。
109+
6. 每个`MKLDNNlayer`的resetbuffer相关的函数(包括reset input、output的Value和grad),他们会根据输入参数reset internal和external的memory,当然这两者也可以相等,即表示不需要转换。只需要把握一个原则,每个`MKLDNNlayer`的子类,只需要使用internal的memory就可以了,所有external的转换工作在父类的reset函数中都提前准备好了。
110+
7. 一般来说,external的memory会尽量与PaddlePaddle中的`value``grad`共享内存。同时每个`MKLDNNLayer`中的external output value和gradient(也就是`extOutVal_``extOutGrad_`)必须分别与`output_.value``output_.grad`共享内存,因为PaddlePaddle的activation会直接使用`output_.value``output_.grad`。如果不需要external的buffer用于转换,那么internal的buffer也会与他们共享内存。
111+
8. 如果MKL-DNN layer的后面接有cpu device,那么就会使`output_.value``extOutVal_`共享内存,同时数据格式就是`nchw`,这样下一个cpu device就能拿到正确的数据。在有cpu device的时候,external的memory的格式始终是`nchw`或者`nc`
112+
9. 由于MKL-DNN的输出操作都是覆盖data的,不是在原来的数据上累加,所以当网络出现分支时,在`backward`时会需要merge不同layer的梯度。`MKLDNNlayer`中会实现merge的方法,此时每个小分支的input gradient会先临时保存在一个`MKLDNNMatrix`中,由分支处的layer负责求和,并把结果放到这个layer的`output_.grad`中。所以整体上,每个子类并不会需要关心分支的事情,也是在父类都实现好了。
113+
10. 在原来的`FLAGS`中添加一个`use_mkldnn`的flag,用于选择是否使用MKL-DNN的相关功能。
105114

106115
## References
107116

doc/faq/local/index_cn.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ PaddlePaddle支持Sparse的训练,sparse训练需要训练特征是 :code:`spa
9999
利用更多的计算资源
100100
++++++++++++++++++
101101

102-
利用更多的计算资源可以分为一下几个方式来进行\:
102+
利用更多的计算资源可以分为以下几个方式来进行\:
103103

104104
* 单机CPU训练
105105

doc/howto/dev/new_op_cn.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ MulOp(const std::string &type, const framework::VariableNameMap &inputs,
214214

215215
```cpp
216216
// if use Eigen unsupported module before include head files
217-
#define EIGEN_USE_GPU
217+
// #define EIGEN_USE_GPU
218218

219219
namespace ops = paddle::operators;
220220
REGISTER_OP_GPU_KERNEL(mul, ops::MulKernel<paddle::platform::GPUPlace, float>);

paddle/capi/Matrix.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,46 @@ paddle_error paddle_matrix_set_row(paddle_matrix mat,
5454
return kPD_NO_ERROR;
5555
}
5656

57+
PD_API paddle_error paddle_matrix_set_value(paddle_matrix mat,
58+
paddle_real* value) {
59+
if (mat == nullptr || value == nullptr) return kPD_NULLPTR;
60+
auto ptr = cast(mat);
61+
if (ptr->mat == nullptr) return kPD_NULLPTR;
62+
paddle::real* buf = ptr->mat->getRowBuf(0);
63+
size_t width = ptr->mat->getWidth();
64+
size_t height = ptr->mat->getHeight();
65+
if (ptr->mat->useGpu()) {
66+
#ifdef PADDLE_WITH_CUDA
67+
hl_memcpy(buf, value, sizeof(paddle::real) * width * height);
68+
#else
69+
return kPD_NOT_SUPPORTED;
70+
#endif
71+
} else {
72+
std::copy(value, value + width * height, buf);
73+
}
74+
return kPD_NO_ERROR;
75+
}
76+
77+
PD_API paddle_error paddle_matrix_get_value(paddle_matrix mat,
78+
paddle_real* result) {
79+
if (mat == nullptr || result == nullptr) return kPD_NULLPTR;
80+
auto ptr = cast(mat);
81+
if (ptr->mat == nullptr) return kPD_NULLPTR;
82+
paddle::real* buf = ptr->mat->getRowBuf(0);
83+
size_t width = ptr->mat->getWidth();
84+
size_t height = ptr->mat->getHeight();
85+
if (ptr->mat->useGpu()) {
86+
#ifdef PADDLE_WITH_CUDA
87+
hl_memcpy(result, buf, width * height * sizeof(paddle::real));
88+
#else
89+
return kPD_NOT_SUPPORTED;
90+
#endif
91+
} else {
92+
std::copy(buf, buf + width * height, result);
93+
}
94+
return kPD_NO_ERROR;
95+
}
96+
5797
paddle_error paddle_matrix_get_row(paddle_matrix mat,
5898
uint64_t rowID,
5999
paddle_real** rawRowBuffer) {

paddle/capi/examples/model_inference/dense/main.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,20 @@ int main() {
2727
CHECK(paddle_arguments_resize(in_args, 1));
2828

2929
// Create input matrix.
30-
paddle_matrix mat = paddle_matrix_create(/* sample_num */ 1,
30+
paddle_matrix mat = paddle_matrix_create(/* sample_num */ 10,
3131
/* size */ 784,
3232
/* useGPU */ false);
3333
srand(time(0));
34-
paddle_real* array;
3534

36-
// Get First row.
37-
CHECK(paddle_matrix_get_row(mat, 0, &array));
35+
std::vector<paddle_real> input;
36+
input.resize(784 * 10);
3837

39-
for (int i = 0; i < 784; ++i) {
40-
array[i] = rand() / ((float)RAND_MAX);
38+
for (int i = 0; i < input.size(); ++i) {
39+
input[i] = rand() / ((float)RAND_MAX);
4140
}
41+
42+
// Set value for the input matrix
43+
CHECK(paddle_matrix_set_value(mat, input.data()));
4244

4345
CHECK(paddle_arguments_set_value(in_args, 0, mat));
4446

@@ -51,11 +53,17 @@ int main() {
5153

5254
CHECK(paddle_arguments_get_value(out_args, 0, prob));
5355

54-
CHECK(paddle_matrix_get_row(prob, 0, &array));
56+
std::std::vector<paddle_real> result;
57+
int height;
58+
int width;
59+
60+
CHECK(paddle_matrix_get_shape(prob, &height, &width);
61+
result.resize(height * width);
62+
CHECK(paddle_matrix_get_value(prob, result.data()));
5563

5664
printf("Prob: ");
57-
for (int i = 0; i < 10; ++i) {
58-
printf("%.2f ", array[i]);
65+
for (int i = 0; i < height * width; ++i) {
66+
printf("%.2f ", result[i]);
5967
}
6068
printf("\n");
6169

paddle/capi/matrix.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ PD_API paddle_error paddle_matrix_set_row(paddle_matrix mat,
7171
uint64_t rowID,
7272
paddle_real* rowArray);
7373

74+
/**
75+
* @brief paddle_matrix_set_value Set value to matrix.
76+
* @param mat Target Matrix
77+
* @param value Row data.
78+
* @return paddle_error
79+
* @note value should contain enough element of data to init the mat
80+
*/
81+
PD_API paddle_error paddle_matrix_set_value(paddle_matrix mat,
82+
paddle_real* value);
83+
7484
/**
7585
* @brief PDMatGetRow Get raw row buffer from matrix
7686
* @param [in] mat Target matrix
@@ -82,6 +92,15 @@ PD_API paddle_error paddle_matrix_get_row(paddle_matrix mat,
8292
uint64_t rowID,
8393
paddle_real** rawRowBuffer);
8494

95+
/**
96+
* @brief copy data from the matrix
97+
* @param [in] mat Target matrix
98+
* @param [out] result pointer to store the matrix data
99+
* @return paddle_error
100+
* @note the space of the result should allocated before invoke this API
101+
*/
102+
PD_API paddle_error paddle_matrix_get_value(paddle_matrix mat,
103+
paddle_real* result);
85104
/**
86105
* @brief PDMatCreateNone Create None Matrix
87106
* @return

0 commit comments

Comments
 (0)