Skip to content

Commit be26b71

Browse files
authored
Add cpp trainer lib and demo (#10681)
add cpp trainer lib and demo
1 parent f6543a1 commit be26b71

File tree

4 files changed

+282
-0
lines changed

4 files changed

+282
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
cmake_minimum_required(VERSION 3.0)
2+
3+
project(cpp_train_demo CXX C)
4+
5+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
6+
7+
if(NOT DEFINED PADDLE_LIB)
8+
message(FATAL_ERROR "please set PADDLE_LIB with -DPADDLE_LIB=/paddle/lib/dir")
9+
endif()
10+
11+
option(WITH_MKLDNN "Compile PaddlePaddle with MKLDNN" OFF)
12+
option(WITH_MKL "Compile PaddlePaddle with MKL support, default use openblas." OFF)
13+
14+
include_directories("${PADDLE_LIB}")
15+
include_directories("${PADDLE_LIB}/third_party/install/protobuf/include")
16+
include_directories("${PADDLE_LIB}/third_party/install/glog/include")
17+
include_directories("${PADDLE_LIB}/third_party/install/gflags/include")
18+
include_directories("${PADDLE_LIB}/third_party/install/snappy/include")
19+
include_directories("${PADDLE_LIB}/third_party/install/snappystream/include")
20+
include_directories("${PADDLE_LIB}/third_party/install/zlib/include")
21+
22+
include_directories("${PADDLE_LIB}/third_party/boost")
23+
include_directories("${PADDLE_LIB}/third_party/eigen3")
24+
25+
link_directories("${PADDLE_LIB}/third_party/install/snappy/lib")
26+
link_directories("${PADDLE_LIB}/third_party/install/snappystream/lib")
27+
link_directories("${PADDLE_LIB}/third_party/install/protobuf/lib")
28+
link_directories("${PADDLE_LIB}/third_party/install/glog/lib")
29+
link_directories("${PADDLE_LIB}/third_party/install/gflags/lib")
30+
link_directories("${PADDLE_LIB}/third_party/install/zlib/lib")
31+
32+
add_executable(demo_trainer demo_trainer.cc)
33+
34+
if(WITH_MKLDNN)
35+
include_directories("${PADDLE_LIB}/third_party/install/mkldnn/include")
36+
set(MKLDNN_LIB ${PADDLE_LIB}/third_party/install/mkldnn/lib/libmkldnn.so.0)
37+
endif()
38+
39+
if(WITH_MKL)
40+
include_directories("${PADDLE_LIB}/third_party/install/mklml/include")
41+
set(MATH_LIB ${PADDLE_LIB}/third_party/install/mklml/lib/libmklml_intel.so)
42+
else()
43+
if(APPLE)
44+
set(MATH_LIB cblas)
45+
else(APPLE)
46+
set(MATH_LIB ${PADDLE_LIB}/third_party/install/openblas/lib/libopenblas.a)
47+
endif(APPLE)
48+
endif()
49+
50+
if(APPLE)
51+
set(MACOS_LD_FLAGS "-undefined dynamic_lookup -Wl,-all_load -framework CoreFoundation -framework Security")
52+
else(APPLE)
53+
set(ARCHIVE_START "-Wl,--whole-archive")
54+
set(ARCHIVE_END "-Wl,--no-whole-archive")
55+
set(EXTERNAL_LIB "-lrt -ldl -lpthread")
56+
endif(APPLE)
57+
58+
target_link_libraries(demo_trainer
59+
${MACOS_LD_FLAGS}
60+
${ARCHIVE_START}
61+
${PADDLE_LIB}/paddle/fluid/inference/libpaddle_fluid.a
62+
${ARCHIVE_END}
63+
${MATH_LIB}
64+
${MKLDNN_LIB}
65+
glog gflags protobuf snappystream snappy z
66+
${EXTERNAL_LIB})

paddle/fluid/train/demo/README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
### step 1. build paddle lib
3+
4+
```
5+
6+
# WITH_MKL=ON|OFF
7+
# WITH_MKLDNN=ON|OFF
8+
9+
PADDLE_LIB=/paddle/lib/dir
10+
cmake .. -DCMAKE_INSTALL_PREFIX=$PADDLE_LIB \
11+
-DCMAKE_BUILD_TYPE=Release \
12+
-DWITH_FLUID_ONLY=ON \
13+
-DWITH_GPU=OFF \
14+
-DWITH_STYLE_CHECK=OFF \
15+
-DWITH_MKL=OFF \
16+
-DWITH_MKLDNN=OFF
17+
make -j8
18+
make -j8 inference_lib_dist
19+
```
20+
21+
### step 2. generate program desc
22+
```
23+
# please install paddle before run this scripe
24+
pip install --upgrade paddlepaddle-*.whl
25+
python demo_network.py
26+
```
27+
28+
This will generate two program desc files:
29+
- startup_program: used to init all parameters
30+
- main_program: main logic of the network
31+
32+
### step 3. build demo_trainer and run it.
33+
34+
35+
```
36+
# Make a build dir at the same dir of this README.md document.
37+
# The demo dir can be put anywhere.
38+
mkdir build
39+
cd build
40+
41+
# WITH_MKL=ON|OFF
42+
# WITH_MKLDNN=ON|OFF
43+
PADDLE_LIB=/paddle/lib/dir
44+
45+
# PADDLE_LIB is the same with CMAKE_INSTALL_PREFIX when building the lib
46+
cmake .. -DPADDLE_LIB=$PADDLE_LIB \
47+
-DWITH_MKLDNN=OFF \
48+
-DWITH_MKL=OFF
49+
make
50+
51+
# copy startup_program and main_program to this dir
52+
cp ../startup_program .
53+
cp ../main_program .
54+
55+
# run demo cpp trainer
56+
./demo_trainer
57+
58+
```
59+
60+
The output will be:
61+
```
62+
step: 0 loss: 1069.02
63+
step: 1 loss: 1069.02
64+
step: 2 loss: 1069.02
65+
....
66+
```
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import paddle.fluid as fluid
16+
import paddle.fluid.framework as framework
17+
18+
19+
def train_network(with_optimize):
20+
x = fluid.layers.data(name='x', shape=[13], dtype='float32')
21+
y_predict = fluid.layers.fc(input=x, size=1, act=None)
22+
23+
y = fluid.layers.data(name='y', shape=[1], dtype='float32')
24+
cost = fluid.layers.square_error_cost(input=y_predict, label=y)
25+
avg_cost = fluid.layers.mean(cost)
26+
27+
if with_optimize:
28+
sgd_optimizer = fluid.optimizer.SGD(learning_rate=0.00001)
29+
sgd_optimizer.minimize(avg_cost)
30+
else:
31+
fluid.backward.append_backward(avg_cost)
32+
33+
34+
def save_program_desc(network_func):
35+
startup_program = framework.Program()
36+
train_program = framework.Program()
37+
38+
with framework.program_guard(train_program, startup_program):
39+
network_func(with_optimize=False)
40+
41+
with open("startup_program", "w") as f:
42+
f.write(startup_program.desc.serialize_to_string())
43+
with open("main_program", "w") as f:
44+
f.write(train_program.desc.serialize_to_string())
45+
46+
47+
save_program_desc(train_network)
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <fstream>
16+
17+
#include "paddle/fluid/framework/executor.h"
18+
#include "paddle/fluid/framework/init.h"
19+
#include "paddle/fluid/framework/op_registry.h"
20+
#include "paddle/fluid/framework/program_desc.h"
21+
#include "paddle/fluid/framework/tensor_util.h"
22+
#include "paddle/fluid/platform/device_context.h"
23+
#include "paddle/fluid/platform/place.h"
24+
25+
namespace paddle {
26+
namespace train {
27+
28+
void ReadBinaryFile(const std::string& filename, std::string* contents) {
29+
std::ifstream fin(filename, std::ios::in | std::ios::binary);
30+
PADDLE_ENFORCE(static_cast<bool>(fin), "Cannot open file %s", filename);
31+
fin.seekg(0, std::ios::end);
32+
contents->clear();
33+
contents->resize(fin.tellg());
34+
fin.seekg(0, std::ios::beg);
35+
fin.read(&(contents->at(0)), contents->size());
36+
fin.close();
37+
}
38+
39+
std::unique_ptr<paddle::framework::ProgramDesc> Load(
40+
paddle::framework::Executor* executor, const std::string& model_filename) {
41+
VLOG(3) << "loading model from " << model_filename;
42+
std::string program_desc_str;
43+
ReadBinaryFile(model_filename, &program_desc_str);
44+
45+
std::unique_ptr<paddle::framework::ProgramDesc> main_program(
46+
new paddle::framework::ProgramDesc(program_desc_str));
47+
return main_program;
48+
}
49+
50+
} // namespace train
51+
} // namespace paddle
52+
53+
int main() {
54+
paddle::framework::InitDevices(false);
55+
56+
const auto cpu_place = paddle::platform::CPUPlace();
57+
58+
paddle::framework::Executor executor(cpu_place);
59+
paddle::framework::Scope scope;
60+
auto startup_program = paddle::train::Load(&executor, "startup_program");
61+
auto train_program = paddle::train::Load(&executor, "main_program");
62+
63+
std::string loss_name = "";
64+
for (auto op_desc : train_program->Block(0).AllOps()) {
65+
if (op_desc->Type() == "mean") {
66+
loss_name = op_desc->Output("Out")[0];
67+
break;
68+
}
69+
}
70+
71+
PADDLE_ENFORCE_NE(loss_name, "", "loss not found");
72+
73+
// init all parameters
74+
executor.Run(*startup_program.get(), &scope, 0);
75+
76+
// prepare data
77+
auto x_var = scope.Var("x");
78+
auto x_tensor = x_var->GetMutable<paddle::framework::LoDTensor>();
79+
x_tensor->Resize({2, 13});
80+
81+
auto x_data = x_tensor->mutable_data<float>(cpu_place);
82+
for (int i = 0; i < 2 * 13; ++i) {
83+
x_data[i] = static_cast<float>(i);
84+
}
85+
86+
auto y_var = scope.Var("y");
87+
auto y_tensor = y_var->GetMutable<paddle::framework::LoDTensor>();
88+
y_tensor->Resize({2, 1});
89+
auto y_data = y_tensor->mutable_data<float>(cpu_place);
90+
for (int i = 0; i < 2 * 1; ++i) {
91+
y_data[i] = static_cast<float>(i);
92+
}
93+
94+
auto loss_var = scope.Var(loss_name);
95+
96+
for (int i = 0; i < 10; ++i) {
97+
executor.Run(*train_program.get(), &scope, 0, false, true);
98+
std::cout << "step: " << i << " loss: "
99+
<< loss_var->Get<paddle::framework::LoDTensor>().data<float>()[0]
100+
<< std::endl;
101+
}
102+
return 0;
103+
}

0 commit comments

Comments
 (0)