Skip to content

Commit 4a64df6

Browse files
committed
Merge branch 'release/0.15.0' of https://github.com/PaddlePaddle/Paddle into v0.15.0-rc0
2 parents e8c6165 + ec9eb22 commit 4a64df6

File tree

93 files changed

+1307
-783
lines changed

Some content is hidden

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

93 files changed

+1307
-783
lines changed

cmake/configure.cmake

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,17 @@ if(WITH_GPU)
103103
endif()
104104
if(WITH_ANAKIN)
105105
if(${CUDA_VERSION_MAJOR} VERSION_LESS 8)
106-
message(FATAL_ERROR "Anakin needs CUDA >= 8.0 to compile")
106+
message(WARNING "Anakin needs CUDA >= 8.0 to compile. Force WITH_ANAKIN=OFF")
107+
set(WITH_ANAKIN OFF CACHE STRING "Anakin is valid only when CUDA >= 8.0." FORCE)
107108
endif()
108109
if(${CUDNN_MAJOR_VERSION} VERSION_LESS 7)
109-
message(FATAL_ERROR "Anakin needs CUDNN >= 7.0 to compile")
110+
message(WARNING "Anakin needs CUDNN >= 7.0 to compile. Force WITH_ANAKIN=OFF")
111+
set(WITH_ANAKIN OFF CACHE STRING "Anakin is valid only when CUDNN >= 7.0." FORCE)
110112
endif()
113+
endif()
114+
if(WITH_ANAKIN)
111115
set(ENV{CUDNN_INCLUDE_DIR} ${CUDNN_INCLUDE_DIR})
112116
set(ENV{CUDNN_LIBRARY} ${CUDNN_LIBRARY})
113-
message(STATUS "cudnn include header is ${CUDNN_INCLUDE_DIR}/cudnn.h")
114-
message(STATUS "cudnn library is ${CUDNN_LIBRARY}")
115117
endif()
116118
elseif(WITH_AMD_GPU)
117119
add_definitions(-DPADDLE_WITH_HIP)

doc/fluid/new_docs/advanced_usage/deploy/native_infer.rst

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ Paddle 预测 API
99

1010
- 头文件 ``paddle_inference_api.h`` 定义了所有的接口
1111
- 库文件\ ``libpaddle_fluid.so`` 或 ``libpaddle_fluid.a``
12-
- 库文件 ``libpaddle_inference_api.so`` 或
13-
``libpaddle_inference_api.a``
1412

1513
编译和依赖可以参考 :ref:`install_or_build_cpp_inference_lib` 。
1614

@@ -97,8 +95,7 @@ engine
9795
CHECK(predictor->Run(slots, &outputs));
9896
// 获取 outputs ...
9997
100-
编译时,联编 ``libpaddle_fluid.a/.so`` 和
101-
``libpaddle_inference_api.a/.so`` 便可。
98+
编译时,联编 ``libpaddle_fluid.a/.so`` 即可。
10299

103100
详细代码参考
104101
------------

paddle/fluid/framework/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ cc_test(cow_ptr_tests SRCS details/cow_ptr_test.cc)
115115
# cc_test(channel_test SRCS channel_test.cc)
116116
cc_test(tuple_test SRCS tuple_test.cc )
117117

118+
cc_test(rw_lock_test SRCS rw_lock_test.cc)
119+
118120
# disable test temporarily.
119121
# TODO https://github.com/PaddlePaddle/Paddle/issues/11971
120122
# cc_test(concurrency_test SRCS concurrency_test.cc DEPS go_op channel_close_op channel_create_op

paddle/fluid/framework/details/multi_devices_graph_pass.cc

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,8 @@ void MultiDevSSAGraphBuilder::CreateDistTrainOp(ir::Graph *result,
763763
// Create RPC related op handles that connects its in ops and out ops.
764764
void MultiDevSSAGraphBuilder::CreateRPCOp(ir::Graph *result,
765765
ir::Node *node) const {
766+
// FIXME(typhoonzero): Cleanup this deps for both sync mode and async mode
767+
// put them into transpiler.
766768
int op_dev_id = -1;
767769
if (node->Op()->Type() == "send") {
768770
// TODO(paddle-dev): getting the first var is not safe.
@@ -771,26 +773,42 @@ void MultiDevSSAGraphBuilder::CreateRPCOp(ir::Graph *result,
771773
"This hack no longer holds, please fix.");
772774
// the variable name which contains .block means it was splited by
773775
// split_byref op
774-
// so that we can balance the variable blocks to all the pserver
775-
// instances.
776776
if (strategy_.reduce_ == BuildStrategy::ReduceStrategy::kAllReduce &&
777777
node->inputs[0]->Name().find(".block") == std::string::npos) {
778778
std::vector<std::string> input_var_names;
779779
for (ir::Node *n : node->inputs) {
780780
input_var_names.push_back(n->Name());
781781
}
782-
op_dev_id = GetAppropriateDeviceID(input_var_names);
782+
auto send_param_grad = boost::get<std::vector<std::string>>(
783+
node->Op()->GetAttr(OpProtoAndCheckerMaker::OpRoleVarAttrName()));
784+
PADDLE_ENFORCE_EQ(send_param_grad.size(), 2U);
785+
op_dev_id = GetAppropriateDeviceID({send_param_grad[1]});
786+
VLOG(10) << "send grad " << input_var_names[0] << " origin "
787+
<< send_param_grad[1] << " place: " << op_dev_id;
783788
for (auto &varname : input_var_names) {
784789
result->Get<ShardedVarDevice>(kShardedVarDevice)
785790
.emplace(varname, op_dev_id);
786791
}
792+
result->Get<ShardedVarDevice>(kShardedVarDevice)
793+
.emplace(send_param_grad[1], op_dev_id);
787794
}
788795
} else if (node->Op()->Type() == "recv") {
789796
std::vector<std::string> output_var_names;
790797
for (ir::Node *n : node->outputs) {
791798
output_var_names.push_back(n->Name());
792799
}
793-
op_dev_id = GetAppropriateDeviceID(output_var_names);
800+
auto recv_param_grad = boost::get<std::vector<std::string>>(
801+
node->Op()->GetAttr(OpProtoAndCheckerMaker::OpRoleVarAttrName()));
802+
// FIXME(typhoonzero): assume each recv op output one param
803+
// Use the same place as send.
804+
if (recv_param_grad.size() == 2U) {
805+
op_dev_id = GetVarDeviceID(*result, recv_param_grad[1]);
806+
VLOG(10) << "recv param " << recv_param_grad[0]
807+
<< " get grad place: " << recv_param_grad[1]
808+
<< " place: " << op_dev_id;
809+
} else {
810+
op_dev_id = GetAppropriateDeviceID(output_var_names);
811+
}
794812
for (auto &varname : output_var_names) {
795813
result->Get<ShardedVarDevice>(kShardedVarDevice)
796814
.emplace(varname, op_dev_id);

paddle/fluid/framework/ir/graph.cc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,15 @@ Graph::Graph(const ProgramDesc &program) : program_(program) {
117117
}
118118
// For output args, always create a new var.
119119
for (auto &each_var_name : op->OutputArgumentNames()) {
120-
ir::Node *var = CreateVarNode(all_vars.at(each_var_name));
120+
ir::Node *var = nullptr;
121+
if (all_vars.count(each_var_name) != 0) {
122+
var = CreateVarNode(all_vars.at(each_var_name));
123+
} else {
124+
// Operation output vars can be @EMPTY@. For example, while_grad
125+
// can have multi @EMPTY@ outputs with no VarDesc.
126+
// TODO(panyx0718): Add a test.
127+
var = CreateEmptyNode(each_var_name, ir::Node::Type::kVariable);
128+
}
121129
var_nodes[each_var_name].push_back(var);
122130
node->outputs.push_back(var);
123131
var->inputs.push_back(node);
@@ -208,7 +216,8 @@ Graph::Graph(const ProgramDesc &program) : program_(program) {
208216
// Add write after write dependence
209217
ir::Node *upstream_op =
210218
(*it_old)->inputs.empty() ? nullptr : (*it_old)->inputs[0];
211-
if (upstream_op) {
219+
// TODO(zcd): Add a test.
220+
if (upstream_op && upstream_op != write_op) {
212221
ir::Node *dep_var = CreateControlDepVar();
213222
write_op->inputs.push_back(dep_var);
214223
upstream_op->outputs.push_back(dep_var);

paddle/fluid/framework/ir/node.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ limitations under the License. */
1717
namespace paddle {
1818
namespace framework {
1919
namespace ir {
20-
const char Node::kControlDepVarName[] = "__control_var";
20+
constexpr char Node::kControlDepVarName[];
2121
} // namespace ir
2222
} // namespace framework
2323
} // namespace paddle

paddle/fluid/framework/ir/node.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace ir {
2727
class Node {
2828
public:
2929
enum class Type { kOperation, kVariable };
30-
static const char kControlDepVarName[];
30+
static constexpr char kControlDepVarName[] = "__control_var";
3131

3232
explicit Node(const std::string& name, Type type)
3333
: name_(name), var_desc_(nullptr), op_desc_(nullptr), type_(type) {}

paddle/fluid/framework/rw_lock.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
#pragma once
16+
17+
#include <pthread.h>
18+
19+
#include "paddle/fluid/platform/enforce.h"
20+
21+
namespace paddle {
22+
namespace framework {
23+
24+
struct RWLock {
25+
RWLock() { pthread_rwlock_init(&lock_, nullptr); }
26+
27+
~RWLock() { pthread_rwlock_destroy(&lock_); }
28+
29+
void RDLock() {
30+
PADDLE_ENFORCE_EQ(pthread_rwlock_rdlock(&lock_), 0,
31+
"acquire read lock failed");
32+
}
33+
34+
void WRLock() {
35+
PADDLE_ENFORCE_EQ(pthread_rwlock_wrlock(&lock_), 0,
36+
"acquire write lock failed");
37+
}
38+
39+
void UNLock() {
40+
PADDLE_ENFORCE_EQ(pthread_rwlock_unlock(&lock_), 0, "unlock failed");
41+
}
42+
43+
private:
44+
pthread_rwlock_t lock_;
45+
};
46+
47+
} // namespace framework
48+
} // namespace paddle
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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 "paddle/fluid/framework/rw_lock.h"
16+
#include <gtest/gtest.h>
17+
#include <chrono> // NOLINT
18+
#include <thread> // NOLINT
19+
#include <vector>
20+
21+
namespace f = paddle::framework;
22+
23+
void f1(f::RWLock *lock) {
24+
lock->RDLock();
25+
lock->UNLock();
26+
}
27+
28+
TEST(RWLOCK, read_read) {
29+
f::RWLock lock;
30+
lock.RDLock();
31+
std::thread t1(f1, &lock);
32+
std::thread t2(f1, &lock);
33+
t1.join();
34+
t2.join();
35+
lock.UNLock();
36+
}
37+
38+
void f2(f::RWLock *lock, std::vector<int> *result) {
39+
lock->RDLock();
40+
ASSERT_EQ(result->size(), 0UL);
41+
lock->UNLock();
42+
}
43+
44+
void f3(f::RWLock *lock, std::vector<int> *result) {
45+
lock->WRLock();
46+
result->push_back(1);
47+
lock->UNLock();
48+
}
49+
50+
TEST(RWLOCK, read_write) {
51+
f::RWLock lock;
52+
std::vector<int> result;
53+
54+
lock.RDLock();
55+
std::thread t1(f2, &lock, &result);
56+
t1.join();
57+
std::thread t2(f3, &lock, &result);
58+
std::this_thread::sleep_for(std::chrono::seconds(1));
59+
ASSERT_EQ(result.size(), 0UL);
60+
lock.UNLock();
61+
t2.join();
62+
ASSERT_EQ(result.size(), 1UL);
63+
}
64+
65+
void f4(f::RWLock *lock, std::vector<int> *result) {
66+
lock->RDLock();
67+
ASSERT_EQ(result->size(), 1UL);
68+
lock->UNLock();
69+
}
70+
71+
TEST(RWLOCK, write_read) {
72+
f::RWLock lock;
73+
std::vector<int> result;
74+
75+
lock.WRLock();
76+
std::thread t1(f4, &lock, &result);
77+
std::this_thread::sleep_for(std::chrono::seconds(1));
78+
result.push_back(1);
79+
lock.UNLock();
80+
t1.join();
81+
}

0 commit comments

Comments
 (0)