Skip to content

Commit c2feab7

Browse files
committed
Merge branch 'develop' into sparse_vector
2 parents 36ebf00 + abce9eb commit c2feab7

Some content is hidden

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

61 files changed

+1846
-1079
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ COPY ./paddle/scripts/docker/root/ /root/
2222

2323
RUN apt-get update && \
2424
apt-get install -y \
25-
git python-pip python-dev openssh-server bison \
25+
git python-pip python-dev openssh-server bison libnccl-dev \
2626
wget unzip unrar tar xz-utils bzip2 gzip coreutils ntp \
2727
curl sed grep graphviz libjpeg-dev zlib1g-dev \
2828
python-matplotlib gcc-4.8 g++-4.8 \

doc/design/block.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ OpDesc {
189189
inputs = {0} // the index of x in vars of BlockDesc above
190190
outputs = {5, 3} // indices of act and hidden_out in vars of BlockDesc above
191191
attrs {
192-
"memories" : {1} // the index of h
192+
"states" : {1} // the index of h
193193
"step_net" : <above step net>
194194
}
195195
};

paddle/framework/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ cc_test(scope_test SRCS scope_test.cc DEPS scope)
1919
proto_library(framework_proto SRCS framework.proto)
2020

2121
cc_library(attribute SRCS attribute.cc DEPS framework_proto)
22-
cc_library(proto_desc SRCS var_desc.cc op_desc.cc block_desc.cc program_desc.cc DEPS attribute ddim op_info)
2322
cc_test(program_desc_test SRCS program_desc_test.cc DEPS proto_desc)
2423
cc_library(op_proto_maker SRCS op_proto_maker.cc DEPS framework_proto attribute)
2524
cc_test(op_proto_maker_test SRCS op_proto_maker_test.cc DEPS op_proto_maker)
2625
cc_library(op_info SRCS op_info.cc DEPS attribute framework_proto)
27-
cc_library(operator SRCS operator.cc DEPS op_info device_context tensor scope proto_desc glog)
26+
cc_library(operator SRCS operator.cc DEPS op_info device_context tensor scope glog)
2827
cc_test(operator_test SRCS operator_test.cc DEPS operator op_registry)
28+
cc_library(proto_desc SRCS var_desc.cc op_desc.cc block_desc.cc program_desc.cc DEPS attribute ddim op_info operator)
2929

30-
cc_library(op_registry SRCS op_registry.cc DEPS op_proto_maker op_info operator glog)
30+
cc_library(op_registry SRCS op_registry.cc DEPS op_proto_maker op_info operator glog proto_desc)
3131
cc_test(op_registry_test SRCS op_registry_test.cc DEPS op_registry)
3232

3333
py_proto_compile(framework_py_proto SRCS framework.proto)

paddle/framework/backward.cc

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "paddle/framework/block_desc.h"
2323
#include "paddle/framework/op_registry.h"
24+
#include "paddle/operators/dynamic_recurrent_op.h"
2425
#include "paddle/operators/net_op.h"
2526
#include "paddle/operators/recurrent_op.h"
2627

@@ -220,8 +221,7 @@ static std::unique_ptr<OperatorBase> BackwardRecursive(
220221
// process recurrent gradient op as a special operator.
221222
if (forwardOp.Type() == "recurrent") {
222223
// NOTE clean up cycle call somewhere (RNN's stepnet constains itself),
223-
// or
224-
// this will result in infinite loop.
224+
// or this will result in infinite loop.
225225
const auto& rnnop =
226226
*static_cast<const operators::RecurrentOp*>(&forwardOp);
227227
auto rnn_grad_op =
@@ -231,6 +231,18 @@ static std::unique_ptr<OperatorBase> BackwardRecursive(
231231
// create stepnet's gradient op
232232
rnn_grad_op->set_stepnet(
233233
BackwardRecursive(stepnet_op, no_grad_names, grad_to_var, uniq_id));
234+
} else if (forwardOp.Type() == "dynamic_recurrent") {
235+
// NOTE clean up cycle call somewhere (RNN's stepnet constains itself),
236+
// or this will result in infinite loop.
237+
const auto& rnnop =
238+
*static_cast<const operators::DynamicRecurrentOp*>(&forwardOp);
239+
auto rnn_grad_op =
240+
static_cast<operators::DynamicRecurrentGradientOp*>(grad_op.get());
241+
const auto& stepnet_op =
242+
*static_cast<const OperatorBase*>(&rnnop.rnn.GetStepUnit());
243+
// create stepnet's gradient op
244+
rnn_grad_op->rnn.SetStepUnit(
245+
BackwardRecursive(stepnet_op, no_grad_names, grad_to_var, uniq_id));
234246
}
235247

236248
if (net->ops_.empty()) { // Current no aux op is added to network

paddle/framework/block_desc.cc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ bool BlockDescBind::HasVar(const std::string &name) const {
4141
return vars_.find(name) != vars_.end();
4242
}
4343

44+
VarDescBind *BlockDescBind::FindVarRecursive(const std::string &name) const {
45+
auto it = vars_.find(name);
46+
if (it == vars_.end()) {
47+
return Parent() == kNoneBlockIndex ? nullptr
48+
: ParentBlock()->FindVarRecursive(name);
49+
}
50+
return it->second.get();
51+
}
52+
53+
bool BlockDescBind::HasVarRecursive(const std::string &name) const {
54+
return FindVarRecursive(name) != nullptr;
55+
}
56+
4457
std::vector<VarDescBind *> BlockDescBind::AllVars() const {
4558
std::vector<VarDescBind *> res;
4659
for (const auto &p : vars_) {
@@ -97,7 +110,7 @@ void BlockDescBind::Flush() {
97110
}
98111

99112
BlockDescBind *BlockDescBind::ParentBlock() const {
100-
if (this->desc_->parent_idx() == -1) {
113+
if (this->desc_->parent_idx() == kNoneBlockIndex) {
101114
return nullptr;
102115
}
103116
return prog_->Block(static_cast<size_t>(this->desc_->parent_idx()));

paddle/framework/block_desc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ limitations under the License. */
2121
#include <vector>
2222

2323
#include "paddle/framework/op_desc.h"
24+
#include "paddle/framework/proto_desc.h"
2425
#include "paddle/framework/var_desc.h"
2526
#include "paddle/platform/macros.h"
2627

@@ -56,6 +57,10 @@ class BlockDescBind {
5657

5758
bool HasVar(const std::string &var_name) const;
5859

60+
VarDescBind *FindVarRecursive(const std::string &name_bytes) const;
61+
62+
bool HasVarRecursive(const std::string &var_name) const;
63+
5964
std::set<std::string> LocalVarNames() const {
6065
std::set<std::string> var_names;
6166
for (auto &var : vars_) {

paddle/framework/framework.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ message OpProto {
6868

6969
optional bool duplicable = 3 [ default = false ];
7070
optional bool intermediate = 4 [ default = false ];
71+
optional bool dispensable = 5 [ default = false ];
7172
}
7273

7374
// AttrProto describes the C++ type Attribute.

paddle/framework/lod_tensor.cc

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,50 @@ LoD SliceLevels(const LoD& in, size_t level_begin, size_t level_end) {
2525
for (size_t i = level_begin; i < level_end; i++) {
2626
new_lod.emplace_back(in.at(i));
2727
}
28+
// transform the lowest level to absolute offset.
29+
LoD abs_offset_lod = ToAbsOffset(in);
30+
new_lod.back() = abs_offset_lod[level_end - 1];
2831
return new_lod;
2932
}
3033

3134
LoD SliceInLevel(const LoD& in, size_t level, size_t elem_begin,
3235
size_t elem_end) {
33-
// slice the lod.
34-
LoD new_lod;
35-
new_lod.reserve(in.size() - level);
36-
auto start = in.at(level)[elem_begin];
37-
auto end = in.at(level)[elem_end];
38-
39-
for (auto it = in.begin() + level; it != in.end(); it++) {
40-
auto it_begin = std::find(it->begin(), it->end(), start);
41-
auto it_end = std::find(it_begin, it->end(), end);
42-
PADDLE_ENFORCE(it_begin != it->end(), "error in parsing lod info");
43-
PADDLE_ENFORCE(it_end != it->end(), "error in parsing lod info");
44-
new_lod.emplace_back(it_begin, it_end + 1);
45-
// reset offset if tensor is copyed and sliced.
46-
std::transform(new_lod.back().begin(), new_lod.back().end(),
47-
new_lod.back().begin(),
48-
[start](int v) { return v - start; });
49-
PADDLE_ENFORCE_EQ(new_lod.back().front(), 0, "error in slice LoD");
36+
PADDLE_ENFORCE_LT(level, in.size());
37+
PADDLE_ENFORCE_LT(elem_end, in[level].size());
38+
39+
LoD res;
40+
res.resize(in.size() - level);
41+
// copy the first level
42+
res[0].assign(in[level].begin() + elem_begin,
43+
in[level].begin() + elem_end + 1);
44+
for (size_t lvl = 1; lvl < res.size(); lvl++) {
45+
const auto& in_level = in[level + lvl];
46+
const auto& above_level = res[lvl - 1];
47+
auto& out_level = res[lvl];
48+
out_level.assign(in_level.begin() + above_level.front(),
49+
in_level.begin() + above_level.back() + 1);
5050
}
51-
PADDLE_ENFORCE_LE(new_lod.size(), in.size());
52-
return new_lod;
51+
for (size_t lvl = 0; lvl < res.size(); lvl++) {
52+
// to make the first offset equals 0, all the elements minus the first
53+
// element
54+
size_t front = res[lvl].front();
55+
for (auto& ele : res[lvl]) {
56+
ele -= front;
57+
}
58+
}
59+
return res;
60+
}
61+
62+
LoD ToAbsOffset(const LoD& in) {
63+
// the lowest level stores relative offsets
64+
if (in.empty() || in.size() == 1) return in;
65+
LoD result = in;
66+
for (int level = result.size() - 2; level >= 0; level--) {
67+
for (auto& ele : result[level]) {
68+
ele = result[level + 1][ele];
69+
}
70+
}
71+
return result;
5372
}
5473

5574
bool operator==(const LoD& a, const LoD& b) {
@@ -75,17 +94,7 @@ bool operator==(const LoD& a, const LoD& b) {
7594
size_t LoDTensor::NumElements(size_t level, size_t idx) const {
7695
PADDLE_ENFORCE_LT(level, NumLevels());
7796
PADDLE_ENFORCE_LT(idx, NumElements(level));
78-
// the last level of LoD, just return number of records in Tensor
79-
if (level == NumLevels() - 1) {
80-
return lod_[level][idx + 1] - lod_[level][idx];
81-
}
82-
// high level of LoD, and there is another lower level, return number of
83-
// lower-level elements
84-
auto tmp = SliceInLevel(lod_, level, idx, idx + 1);
85-
PADDLE_ENFORCE_GE(tmp.size(), 2);
86-
// there is a 0 as a placeholder stored in LoD, so the number of elements
87-
// equals lod.size() - 1
88-
return tmp[1].size() - 1;
97+
return lod_[level][idx + 1] - lod_[level][idx];
8998
}
9099

91100
void LoDTensor::ShrinkLevels(size_t level_begin, size_t level_end) {

paddle/framework/lod_tensor.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,36 @@ using Vector = thrust::host_vector<
3939
#endif
4040

4141
/*
42-
* 3-level LoD stores
42+
* LoD is short for Level of Details.
4343
*
44-
* 0 10 20
45-
* 0 5 10 15 20
46-
* 0 2 5 7 10 12 15 20
47-
*
48-
* - in a level, each element indicates offset in the underlying Tensor
44+
* - in a level, each element indicates relative offset of the lower level
4945
* - the first element should be 0 and that indicates that this sequence start
5046
* from 0
5147
* - each sequence's begin and end(no-inclusive) is level[id, id+1]
48+
*
49+
* For example:
50+
* 3-level LoD stores
51+
*
52+
* 0 2 3
53+
* 0 2 4 7
54+
* 0 2 5 7 10 12 15 20
5255
*/
5356
using LoD = std::vector<Vector<size_t>>;
5457

58+
/*
59+
* Slice levels from a LoD.
60+
* NOTE the lowest level should always be the absolute offsets of the underlying
61+
* tensor instances. So if higher layers are sliced without the lowest level,
62+
* the lower level of the sliced LoD will be transformed to the absolute offset.
63+
*/
5564
LoD SliceLevels(const LoD& in, size_t level_begin, size_t level_end);
5665

5766
LoD SliceInLevel(const LoD& in, size_t level, size_t elem_begin,
5867
size_t elem_end);
68+
/*
69+
* Transform an LoD from relative offsets to absolute offsets.
70+
*/
71+
LoD ToAbsOffset(const LoD& in);
5972

6073
bool operator==(const LoD& a, const LoD& b);
6174

paddle/framework/lod_tensor_test.cc

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ class LoDTensorTester : public ::testing::Test {
3030
// 0 5 10 15 20
3131
// 0 2 5 7 10 12 15 20
3232
LoD lod;
33-
lod.push_back(std::vector<size_t>{0, 10, 20});
34-
lod.push_back(std::vector<size_t>{0, 5, 10, 15, 20});
33+
lod.push_back(std::vector<size_t>{0, 2, 3});
34+
lod.push_back(std::vector<size_t>{0, 2, 5, 8});
3535
lod.push_back(std::vector<size_t>{0, 2, 5, 7, 10, 12, 15, 17, 20});
3636

3737
ASSERT_EQ(lod.size(), 3UL);
@@ -52,14 +52,14 @@ TEST_F(LoDTensorTester, NumLevels) { ASSERT_EQ(lod_tensor_.NumLevels(), 3UL); }
5252

5353
TEST_F(LoDTensorTester, NumElements) {
5454
ASSERT_EQ(lod_tensor_.NumElements(0), 2UL);
55-
ASSERT_EQ(lod_tensor_.NumElements(1), 4UL);
55+
ASSERT_EQ(lod_tensor_.NumElements(1), 3UL);
5656
ASSERT_EQ(lod_tensor_.NumElements(2), 8UL);
5757
}
5858

5959
TEST_F(LoDTensorTester, NumElements2) {
6060
ASSERT_EQ(lod_tensor_.NumElements(0, 0), 2UL);
61-
ASSERT_EQ(lod_tensor_.NumElements(0, 1), 2UL);
62-
ASSERT_EQ(lod_tensor_.NumElements(1, 1), 2UL);
61+
ASSERT_EQ(lod_tensor_.NumElements(0, 1), 1UL);
62+
ASSERT_EQ(lod_tensor_.NumElements(1, 1), 3UL);
6363
}
6464

6565
TEST_F(LoDTensorTester, ShrinkLevels) {
@@ -68,37 +68,36 @@ TEST_F(LoDTensorTester, ShrinkLevels) {
6868
LoDTensor new_lod_tensor = lod_tensor_;
6969
new_lod_tensor.ShrinkLevels(level, level + 1);
7070
ASSERT_EQ(new_lod_tensor.NumLevels(), 1UL);
71-
ASSERT_EQ(new_lod_tensor.NumElements(0), lod_tensor_.NumElements(level));
7271
ASSERT_EQ(new_lod_tensor.data<float>(), lod_tensor_.data<float>());
7372
}
7473
// shrink 2 level
7574
for (size_t level = 0; level < 2UL; ++level) {
7675
LoDTensor new_lod_tensor = lod_tensor_;
7776
new_lod_tensor.ShrinkLevels(level, level + 2);
77+
// the lowest level's last element should be the tensor's batch_size.
78+
ASSERT_EQ(new_lod_tensor.lod().back().back(),
79+
lod_tensor_.lod().back().back());
7880
ASSERT_EQ(new_lod_tensor.NumLevels(), 2UL);
79-
ASSERT_EQ(new_lod_tensor.NumElements(0), lod_tensor_.NumElements(level));
80-
ASSERT_EQ(new_lod_tensor.NumElements(1),
81-
lod_tensor_.NumElements(level + 1));
8281
ASSERT_EQ(new_lod_tensor.data<float>(), lod_tensor_.data<float>());
8382
}
8483
}
8584

8685
TEST_F(LoDTensorTester, ShrinkInLevel) {
8786
size_t level = 0;
8887
LoDTensor new_lod_tensor = lod_tensor_;
89-
new_lod_tensor.ShrinkInLevel(level, 0, 2);
88+
new_lod_tensor.ShrinkInLevel(level, 0, 1);
9089
EXPECT_EQ(new_lod_tensor.NumLevels(), 3UL);
91-
EXPECT_EQ(new_lod_tensor.NumElements(0), 2UL);
92-
EXPECT_EQ(new_lod_tensor.NumElements(1), 4UL);
93-
EXPECT_EQ(new_lod_tensor.NumElements(2), 8UL);
90+
EXPECT_EQ(new_lod_tensor.NumElements(0), 1UL);
91+
EXPECT_EQ(new_lod_tensor.NumElements(1), 2UL);
92+
EXPECT_EQ(new_lod_tensor.NumElements(2), 5UL);
9493
ASSERT_EQ(new_lod_tensor.data<float>(), lod_tensor_.data<float>());
9594

9695
level = 1;
9796
new_lod_tensor = lod_tensor_;
98-
new_lod_tensor.ShrinkInLevel(level, 0, 2);
97+
new_lod_tensor.ShrinkInLevel(level, 1, 2);
9998
ASSERT_EQ(new_lod_tensor.NumLevels(), 2UL);
100-
ASSERT_EQ(new_lod_tensor.NumElements(0), 2UL);
101-
ASSERT_EQ(new_lod_tensor.NumElements(1), 4UL);
99+
ASSERT_EQ(new_lod_tensor.NumElements(0), 1UL);
100+
ASSERT_EQ(new_lod_tensor.NumElements(1), 3UL);
102101
ASSERT_EQ(new_lod_tensor.data<float>(), lod_tensor_.data<float>());
103102
}
104103

0 commit comments

Comments
 (0)