Skip to content

Commit 44c7beb

Browse files
committed
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into mac_py3
2 parents 671a948 + 01fda93 commit 44c7beb

File tree

124 files changed

+4102
-2558
lines changed

Some content is hidden

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

124 files changed

+4102
-2558
lines changed

cmake/configure.cmake

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,26 @@ if(NOT CMAKE_CROSSCOMPILING)
6262
endif()
6363

6464
if(WIN32)
65-
# windows stupid compile option for all targets.
65+
# windows header option for all targets.
6666
add_definitions(-D_XKEYCHECK_H)
67+
# Use symbols instead of absolute path, reduce the cmake link command length.
68+
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 1)
69+
SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES 1)
70+
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
71+
SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
72+
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1)
73+
SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
74+
SET(CMAKE_C_RESPONSE_FILE_LINK_FLAG "@")
75+
SET(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@")
76+
77+
# Specify the program to use when building static libraries
78+
SET(CMAKE_C_CREATE_STATIC_LIBRARY "<CMAKE_AR> lib <TARGET> <LINK_FLAGS> <OBJECTS>")
79+
SET(CMAKE_CXX_CREATE_STATIC_LIBRARY "<CMAKE_AR> lib <TARGET> <LINK_FLAGS> <OBJECTS>")
80+
81+
# set defination for the dll export
82+
if (NOT MSVC)
83+
message(FATAL "Windows build only support msvc. Which was binded by the nvcc compiler of NVIDIA.")
84+
endif(NOT MSVC)
6785
endif(WIN32)
6886

6987
if(NOT WITH_GOLANG)

cmake/generic.cmake

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,20 @@ function(find_fluid_modules TARGET_NAME)
110110
endif()
111111
endfunction(find_fluid_modules)
112112

113+
# find all third_party modules is used for paddle static library
114+
# for reduce the dependency when building the inference libs.
115+
set_property(GLOBAL PROPERTY FLUID_THIRD_PARTY)
116+
function(find_fluid_thirdparties TARGET_NAME)
117+
get_filename_component(__target_path ${TARGET_NAME} ABSOLUTE)
118+
string(REGEX REPLACE "^${PADDLE_SOURCE_DIR}/" "" __target_path ${__target_path})
119+
string(FIND "${__target_path}" "third_party" pos)
120+
if(pos GREATER 1)
121+
get_property(fluid_ GLOBAL PROPERTY FLUID_THIRD_PARTY)
122+
set(fluid_third_partys ${fluid_third_partys} ${TARGET_NAME})
123+
set_property(GLOBAL PROPERTY FLUID_THIRD_PARTY "${fluid_third_partys}")
124+
endif()
125+
endfunction(find_fluid_thirdparties)
126+
113127
function(merge_static_libs TARGET_NAME)
114128
set(libs ${ARGN})
115129
list(REMOVE_DUPLICATES libs)
@@ -204,18 +218,13 @@ function(merge_static_libs TARGET_NAME)
204218

205219
foreach(lib ${libs})
206220
# Get the file names of the libraries to be merged
207-
#if(NOT $<TARGET_FILE:${lib}> MATCHES "lib.*\\.lib")
208-
# message("library" ${lib})
209-
# set(libfiles ${libfiles} lib$<TARGET_FILE:${lib}>)
210-
#else()
211221
set(libfiles ${libfiles} $<TARGET_FILE:${lib}>)
212-
#endif()
213222
endforeach()
214-
215-
# windows cmd return error in clean env.
216-
# COMMAND del "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${TARGET_NAME}.lib"
223+
# msvc will put libarary in directory of "/Release/xxxlib" by default
224+
# COMMAND cmake -E remove "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${TARGET_NAME}.lib"
217225
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
218-
COMMAND lib /OUT:${CMAKE_CURRENT_BINARY_DIR}/lib${TARGET_NAME}.lib ${libfiles}
226+
COMMAND cmake -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}"
227+
COMMAND lib /OUT:${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/lib${TARGET_NAME}.lib ${libfiles}
219228
)
220229
endif(WIN32)
221230
endfunction(merge_static_libs)

doc/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
Thanks for reading PaddlePaddle documentation.
44

5-
Since **September 17th, 2018**, the **0.15.0 and develop** documentation source has been moved to [Fluiddoc Repo](https://github.com/PaddlePaddle/Paddle) and updated in Fluiddoc Repo.
5+
Since **September 17th, 2018**, the **0.15.0 and develop** documentation source has been moved to [FluidDoc Repo](https://github.com/PaddlePaddle/FluidDoc) and updated there.
66

7-
Please turn to Fluiddoc Repo for the latest documentation.
7+
Please turn to FluidDoc Repo for the latest documentation.

paddle/fluid/API.spec

Lines changed: 39 additions & 55 deletions
Large diffs are not rendered by default.

paddle/fluid/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ if(WITH_INFERENCE)
1313
# NOTE: please add subdirectory inference at last.
1414
add_subdirectory(inference)
1515
endif()
16+
17+
add_subdirectory(train)

paddle/fluid/framework/details/cow_ptr.h

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,41 +20,79 @@ namespace paddle {
2020
namespace framework {
2121
namespace details {
2222

23-
template <class T>
24-
class COWPtr {
23+
// Change it to thread safe flags if needed.
24+
class ThreadUnsafeOwnershipFlags {
2525
public:
26-
typedef std::shared_ptr<T> RefPtr;
26+
explicit ThreadUnsafeOwnershipFlags(bool flag) : flag_(flag) {}
2727

28-
private:
29-
RefPtr m_sp;
28+
ThreadUnsafeOwnershipFlags(const ThreadUnsafeOwnershipFlags& other) = delete;
29+
ThreadUnsafeOwnershipFlags& operator=(
30+
const ThreadUnsafeOwnershipFlags& other) = delete;
31+
ThreadUnsafeOwnershipFlags(ThreadUnsafeOwnershipFlags&& other) = default;
3032

31-
void detach() {
32-
T* tmp = m_sp.get();
33-
if (!(tmp == nullptr || m_sp.unique())) {
34-
m_sp = RefPtr(new T(*tmp));
33+
void SetOwnership(bool flag) { flag_ = flag; }
34+
35+
// Invoke the callback if it is not owned.
36+
template <typename Callback>
37+
void AcquireOwnershipOnce(Callback acquire) {
38+
if (!flag_) {
39+
acquire();
40+
flag_ = true;
3541
}
3642
}
3743

38-
public:
39-
COWPtr() : m_sp(nullptr) {}
40-
explicit COWPtr(T* t) : m_sp(t) {}
41-
explicit COWPtr(const RefPtr& refptr) : m_sp(refptr) {}
44+
private:
45+
bool flag_;
46+
};
4247

43-
const T& Data() const { return operator*(); }
48+
// Copy-On-Write pointer.
49+
// It will hold a T* pointer, and only copy once when `MutableData` is invoked.
50+
//
51+
// The template parameter OwnershipFlags should have:
52+
// * a constructor takes a bool. True if own.
53+
// * SetOwnership(bool flag).
54+
// * AcquireOwnershipOnce(Callback). It will invoke the callback if it is not
55+
// owned.
56+
//
57+
// https://en.wikipedia.org/wiki/Copy-on-write
58+
template <typename T, typename OwnershipFlags = ThreadUnsafeOwnershipFlags>
59+
class COWPtr {
60+
public:
61+
// Ctor from raw pointer.
62+
explicit COWPtr(T* ptr) : payload_(ptr), ownership_{true} {}
4463

45-
T* MutableData() { return operator->(); }
64+
// Move methods. Steal ownership from origin
65+
COWPtr(COWPtr&& other)
66+
: payload_(other.payload_), ownership_{std::move(other.ownership_)} {}
67+
COWPtr& operator=(COWPtr&& origin) = default;
4668

47-
const T& operator*() const { return *m_sp; }
48-
T& operator*() {
49-
detach();
50-
return *m_sp;
69+
// Copy methods. Not own payload
70+
COWPtr(const COWPtr& other) : payload_(other.payload_), ownership_{false} {}
71+
COWPtr& operator=(const COWPtr& other) {
72+
payload_ = other.payload_;
73+
ownership_.SetOwnership(false);
74+
return *this;
5175
}
52-
const T* operator->() const { return m_sp.operator->(); }
53-
T* operator->() {
54-
detach();
55-
return m_sp.operator->();
76+
77+
// Access read only data.
78+
const T& Data() const { return *payload_; }
79+
80+
// Access mutable data. If the data is not owned, the data will be copied
81+
// before.
82+
T* MutableData() {
83+
ownership_.AcquireOwnershipOnce(
84+
[this] { payload_.reset(new T(*payload_)); });
85+
return payload_.get();
5686
}
87+
88+
private:
89+
// Actual data pointer.
90+
std::shared_ptr<T> payload_;
91+
92+
// Ownership flag.
93+
OwnershipFlags ownership_;
5794
};
95+
5896
} // namespace details
5997
} // namespace framework
6098
} // namespace paddle

paddle/fluid/framework/details/cow_ptr_test.cc

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,6 @@ TEST(COWPtr, all) {
3030
ASSERT_EQ(ptr2.Data(), 10);
3131
}
3232

33-
TEST(COWPtr, change_old) {
34-
COWPtr<int> ptr(new int{0});
35-
COWPtr<int> ptr2 = ptr;
36-
*ptr.MutableData() = 10;
37-
ASSERT_EQ(ptr2.Data(), 0);
38-
ASSERT_EQ(ptr.Data(), 10);
39-
}
40-
4133
} // namespace details
4234
} // namespace framework
4335
} // namespace paddle

paddle/fluid/framework/details/multi_devices_graph_pass.cc

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -210,43 +210,6 @@ std::vector<std::string> MultiDevSSAGraphBuilder::FindDistTrainRecvVars(
210210
return recv_vars;
211211
}
212212

213-
bool MultiDevSSAGraphBuilder::IsDistTrainOp(
214-
ir::Node *node, const std::vector<std::string> &send_vars,
215-
const std::vector<std::string> &recv_vars) const {
216-
if (send_vars.size() == 0 || recv_vars.size() == 0) {
217-
return false;
218-
}
219-
220-
/**
221-
* Check any of opvars contains `.block` and in sendvars
222-
*/
223-
auto checker = [](const std::vector<std::string> &opvars,
224-
const std::vector<std::string> &rpc_vars) -> bool {
225-
for (auto &var : opvars) {
226-
// a variable name with the suffix `.block` means it's a splited
227-
// variable by (DistributeTranspiler)
228-
// [python/paddle/fluid/transpiler/distribute_transpiler.py]
229-
if (var.find(".block") != std::string::npos &&
230-
std::find(rpc_vars.begin(), rpc_vars.end(), var) != rpc_vars.end()) {
231-
return true;
232-
}
233-
}
234-
return false;
235-
};
236-
237-
std::vector<std::string> input_var_names;
238-
std::vector<std::string> output_var_names;
239-
for (ir::Node *input : node->inputs) {
240-
input_var_names.push_back(input->Name());
241-
}
242-
for (ir::Node *output : node->outputs) {
243-
output_var_names.push_back(output->Name());
244-
}
245-
246-
return checker(output_var_names, send_vars) ||
247-
checker(input_var_names, recv_vars);
248-
}
249-
250213
size_t MultiDevSSAGraphBuilder::GetAppropriateDeviceID(
251214
const std::vector<std::string> &var_names) const {
252215
int64_t numel_sum = 0;
@@ -370,7 +333,9 @@ std::unique_ptr<ir::Graph> MultiDevSSAGraphBuilder::ApplyImpl(
370333
}
371334
}
372335
is_dist_train = true;
373-
} else if (IsDistTrainOp(node, send_vars, recv_vars)) {
336+
} else if (boost::get<int>(node->Op()->GetAttr(
337+
OpProtoAndCheckerMaker::OpRoleAttrName())) ==
338+
static_cast<int>(OpRole::kDist)) {
374339
int op_dev_id = CreateDistTrainOp(&result, node);
375340
if (node->Op()->Type() == "concat") {
376341
auto origin_param_name = node->Op()->OutputArgumentNames()[0];
@@ -736,6 +701,7 @@ int MultiDevSSAGraphBuilder::CreateDistTrainOp(ir::Graph *result,
736701
.emplace(varname, op_dev_id);
737702
}
738703
} else {
704+
LOG(ERROR) << "got unexpected dist op: " << node->Op()->Type();
739705
PADDLE_THROW(
740706
"the distribute training related op should be in [split_byref, "
741707
"concat].");

paddle/fluid/framework/details/multi_devices_graph_pass.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,6 @@ class MultiDevSSAGraphBuilder : public ir::Pass {
5151
int CreateRPCOp(ir::Graph *result, ir::Node *node) const;
5252
int CreateDistTrainOp(ir::Graph *result, ir::Node *node) const;
5353

54-
/**
55-
* Is this operator as the end-point operator before/after send operator.
56-
*/
57-
bool IsDistTrainOp(ir::Node *node, const std::vector<std::string> &send_vars,
58-
const std::vector<std::string> &recv_vars) const;
59-
6054
std::vector<std::string> FindDistTrainSendVars(
6155
const std::vector<ir::Node *> &nodes) const;
6256

paddle/fluid/framework/details/reference_count_op_handle.h

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "paddle/fluid/framework/details/op_handle_base.h"
2323
#include "paddle/fluid/framework/garbage_collector.h"
2424
#include "paddle/fluid/framework/scope.h"
25+
#include "paddle/fluid/framework/selected_rows.h"
2526
#include "paddle/fluid/framework/tensor.h"
2627

2728
namespace paddle {
@@ -46,17 +47,15 @@ class ReferenceCountOpHandle : public OpHandleBase {
4647
const std::vector<std::string> &var_names,
4748
GarbageCollector<Tensor> *gc,
4849
AtomicReferenceCountMap *ref_cnts)
49-
: OpHandleBase(node),
50-
scope_(scope),
51-
var_names_(var_names),
52-
gc_(gc),
53-
ref_cnts_(ref_cnts) {
50+
: OpHandleBase(node), scope_(scope), gc_(gc), ref_cnts_(ref_cnts) {
5451
dev_ctx_ = static_cast<platform::CUDADeviceContext *>(
5552
platform::DeviceContextPool::Instance().Get(place));
5653
if (IsStreamGarabageCollector()) {
5754
PADDLE_ENFORCE(cudaSetDevice(place.device));
5855
PADDLE_ENFORCE(cudaEventCreateWithFlags(&event_, cudaEventDisableTiming));
5956
}
57+
58+
for (auto &name : var_names) AddVar(name);
6059
}
6160

6261
~ReferenceCountOpHandle() {
@@ -69,19 +68,35 @@ class ReferenceCountOpHandle : public OpHandleBase {
6968

7069
std::string Name() const override { return "reference_count"; }
7170

71+
void AddVar(const std::string &name) {
72+
auto it = var_names_.find(name);
73+
if (it != var_names_.end())
74+
++(it->second);
75+
else
76+
var_names_[name] = 1;
77+
}
78+
7279
protected:
7380
void RunImpl() override {
7481
auto *exec_scope = scope_->FindVar(kLocalExecScopeName)->Get<Scope *>();
75-
std::vector<LoDTensor *> tensors;
76-
for (auto &name : var_names_) {
82+
std::vector<Tensor *> tensors;
83+
for (auto &pair : var_names_) {
84+
auto &name = pair.first;
7785
auto it = ref_cnts_->find(name);
7886
if (it == ref_cnts_->end()) continue;
7987

8088
auto *var = exec_scope->FindVar(name);
81-
if (var == nullptr || !var->IsType<LoDTensor>()) continue;
82-
83-
if (it->second.fetch_sub(1) <= 1) {
84-
tensors.emplace_back(var->GetMutable<LoDTensor>());
89+
if (var == nullptr) continue;
90+
91+
if (var->IsType<LoDTensor>()) {
92+
if (it->second.fetch_sub(pair.second) <= pair.second) {
93+
tensors.emplace_back(var->GetMutable<LoDTensor>());
94+
}
95+
} else if (var->IsType<SelectedRows>()) {
96+
if (it->second.fetch_sub(pair.second) <= pair.second) {
97+
tensors.emplace_back(
98+
var->GetMutable<SelectedRows>()->mutable_value());
99+
}
85100
}
86101
}
87102

@@ -91,7 +106,7 @@ class ReferenceCountOpHandle : public OpHandleBase {
91106
}
92107

93108
private:
94-
void ClearTensors(const std::vector<LoDTensor *> &tensors) {
109+
void ClearTensors(const std::vector<Tensor *> &tensors) {
95110
auto *gc = dynamic_cast<StreamGarbageCollector<Tensor> *>(gc_);
96111
if (gc != nullptr) {
97112
auto compute_stream = dev_ctx_->stream();
@@ -112,7 +127,7 @@ class ReferenceCountOpHandle : public OpHandleBase {
112127

113128
const Scope *scope_;
114129
platform::CUDADeviceContext *dev_ctx_;
115-
std::vector<std::string> var_names_;
130+
std::unordered_map<std::string, int> var_names_;
116131
GarbageCollector<Tensor> *gc_; // not own
117132
AtomicReferenceCountMap *ref_cnts_; // not own
118133
cudaEvent_t event_;

0 commit comments

Comments
 (0)