From 85404d4cb987f25dd897af2a035f5ec6b8e73c49 Mon Sep 17 00:00:00 2001 From: fengjiayi Date: Sat, 24 Mar 2018 22:54:43 +0800 Subject: [PATCH 01/27] update cpp reader doc --- doc/fluid/design/concepts/cpp_data_feeding.md | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/doc/fluid/design/concepts/cpp_data_feeding.md b/doc/fluid/design/concepts/cpp_data_feeding.md index 8607b40ccb..6ed3f604dc 100644 --- a/doc/fluid/design/concepts/cpp_data_feeding.md +++ b/doc/fluid/design/concepts/cpp_data_feeding.md @@ -113,7 +113,7 @@ To solve this problem, we introduce `ReaderHolder` as a wrapper. It acts as an e To create and invoke readers, some new ops are introduced: -### CreateReaderOp +### Operators That Creates Readers Each reader has its creation op. File readers' creation ops have no input and yield the created file reader as its output. Decorated readers' creation ops take the underlying readers as inputs and then yield new decorated readers. @@ -153,13 +153,17 @@ double_buffer_reader = create_double_buffer_op(batch_reader) The forwarding ops of the corresponding `main_program` would be like this: ``` -while_op { +not_completed = true +pass_count = 0 +while_op(not_completed) { has_next = has_next_op(double_buffer_reader) if_else_op(has_next) { batch_data = read_op(double_buffer_reader) ... (subsequent training ops) } else { reset_op(double_buffer_reader) + increase_op(pass_count) + not_completed = less_than_op(pass_count, reqiured_pass_num) } } ``` @@ -169,3 +173,30 @@ Two important considerations for these programs are as follows: 1. The multiple\_reader is the batch\_reader's underlying reader, and the batch\_reader is the double\_buffer\_reader's underlying reader. `read_op`, `has_next_op` and other reader related ops will only invoke the top-most reader. In this case, it's the double\_buffer\_reader. 2. All readers exist in both `startup_program` and `main_program`. And they are persistable. + +### Simplify Configuration by MultiPassReader + +The Program configuration mentioned above is somehow complicated. Users need to be very similar to concepts of Program and Block to prevent making mistakes in their code. To make the usage of C++ readers more friendly to beginning users, we introduce `MultiPassReader`. + +`MultiPassReader` is a decorated reader. A multi-pass reader is used to continuously yield data for several pass training. It takes the number of passes to run as one of its attributes('pass_num') and maintains a counter to record how many passes it has completed. Each time its underlying reader reaches the EOF, the multi-pass reader checks whether it has completed the training of given number of pass. If not, the underlying reader will be re-initialized and starts a new pass automatically. Before completing the whole training, the return of MultiPassReader's `HasNext()` will always be `true`. + +With `MultiPassReader`, the startup program would be like this: + +``` +multiple_reader = open_files_op(...) +batch_reader = create_batch_reader_op(multiple_reader) +double_buffer_reader = create_double_buffer_op(batch_reader) +multi_pass_reader = create_multi_pass_reader_op(double_buffer_reader) +... (other initializers) +``` + +The forwarding part of the corresponding `main_program` would be like this: + +``` +not_completed = true +while_op(not_completed) { + batch_data = read_op(multi_pass_reader) + ... (subsequent training ops) + not_completed = has_next_op(multi_pass_reader) +} +``` From dd532e2086bc2e05e02b65d4459d2f12de46793a Mon Sep 17 00:00:00 2001 From: fengjiayi Date: Sat, 24 Mar 2018 22:59:53 +0800 Subject: [PATCH 02/27] refine MultiPassReader's doc string --- .../fluid/operators/reader/create_multi_pass_reader_op.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/paddle/fluid/operators/reader/create_multi_pass_reader_op.cc b/paddle/fluid/operators/reader/create_multi_pass_reader_op.cc index 4d4e9fb909..47d9989bc8 100644 --- a/paddle/fluid/operators/reader/create_multi_pass_reader_op.cc +++ b/paddle/fluid/operators/reader/create_multi_pass_reader_op.cc @@ -81,10 +81,10 @@ class CreateMultiPassReaderOpMaker : public DecoratedReaderMakerBase { This operator creates a multi-pass reader. A multi-pass reader is used to yield data for several pass training continuously. - It takes the the number of pass to run as one of its attributes + It takes the number of passes to run as one of its attributes ('pass_num'), and maintains a pass counter to record how many - passes it has completed. When the underlying reader reach the EOF, - the multi-pass reader checks whether it has completed training + passes it has completed. When the underlying reader reaches the + EOF, the multi-pass reader checks whether it has completed training of the given number of pass. If not, the underlying reader will be re-initialized and starts a new pass automatically. )DOC"); From efd7ee8521986e7789ea88ec0e9a2c7ff5c83ca9 Mon Sep 17 00:00:00 2001 From: m3ngyang Date: Sun, 25 Mar 2018 19:35:20 +0800 Subject: [PATCH 03/27] translate Cluster Training and Prediction --- doc/v2/faq/cluster/index_en.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/v2/faq/cluster/index_en.rst b/doc/v2/faq/cluster/index_en.rst index 855b7e8e53..7cbcaeefcb 100644 --- a/doc/v2/faq/cluster/index_en.rst +++ b/doc/v2/faq/cluster/index_en.rst @@ -2,4 +2,15 @@ Cluster Training and Prediction ############################### -TBD +.. contents:: + +1. Network connection errors in the log during muliti-node cluster training +------------------------------------------------ +The errors in the log belong to network connection during mulilti-node cluster training, for example, :code:`Connection reset by peer`. +This kind of error is usually caused by the abnormal exit of the training process in some node, and the others cannot connect with this node any longer. Steps to troubleshoot the problem as follows: + +* Find the first error in the :code:`train.log`, :code:`server.log`, check whether other fault casued the problem, such as FPE, lacking of memory or disk. + +* If network connection gave rise to the first error in the log, this may be caused by the port conflict of the non-exclusive execution. Connect with the operator to check if the current MPI cluster supports jobs submitted with parameter :code:`resource=full`. If so, change the port of job. + +* If the currnet MPI cluster does not support exclusive pattern, ask the operator to replace or update the current cluster. From ce84af638bc6204c30272f3163e7f7b3026bcfec Mon Sep 17 00:00:00 2001 From: fengjiayi Date: Mon, 26 Mar 2018 10:48:54 +0800 Subject: [PATCH 04/27] update --- doc/fluid/design/concepts/cpp_data_feeding.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/fluid/design/concepts/cpp_data_feeding.md b/doc/fluid/design/concepts/cpp_data_feeding.md index 6ed3f604dc..9c44dec4b9 100644 --- a/doc/fluid/design/concepts/cpp_data_feeding.md +++ b/doc/fluid/design/concepts/cpp_data_feeding.md @@ -185,8 +185,8 @@ With `MultiPassReader`, the startup program would be like this: ``` multiple_reader = open_files_op(...) batch_reader = create_batch_reader_op(multiple_reader) -double_buffer_reader = create_double_buffer_op(batch_reader) -multi_pass_reader = create_multi_pass_reader_op(double_buffer_reader) +multi_pass_reader = create_multi_pass_reader_op(batch_reader) +double_buffer_reader = create_double_buffer_op(multi_pass_reader) ... (other initializers) ``` @@ -195,8 +195,8 @@ The forwarding part of the corresponding `main_program` would be like this: ``` not_completed = true while_op(not_completed) { - batch_data = read_op(multi_pass_reader) + batch_data = read_op(double_buffer_reader) ... (subsequent training ops) - not_completed = has_next_op(multi_pass_reader) + not_completed = has_next_op(double_buffer_reader) } ``` From ccfec1bcb15dbfbba9b0ce0087d79eb9206dce48 Mon Sep 17 00:00:00 2001 From: Luo Tao Date: Mon, 26 Mar 2018 21:19:11 +0800 Subject: [PATCH 05/27] remove vars when remove ops --- paddle/fluid/framework/block_desc.cc | 34 ++++++++++++++++--- .../tests/unittests/test_protobuf_descs.py | 27 +++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/paddle/fluid/framework/block_desc.cc b/paddle/fluid/framework/block_desc.cc index 3693bc25d8..4faf9dcf37 100644 --- a/paddle/fluid/framework/block_desc.cc +++ b/paddle/fluid/framework/block_desc.cc @@ -148,14 +148,40 @@ void BlockDesc::RemoveOp(size_t s, size_t e) { return; } need_update_ = true; + std::vector vars1; // input vars from delete ops for (auto it = ops_.begin() + s; it != ops_.begin() + e; it++) { - auto names = (*it)->InputArgumentNames(); - for (auto n : names) { - // TODO(typhoonzero): delete vars if no other op use it. - VLOG(3) << "deleting var " << n; + // delete all output vars + auto out_names = (*it)->OutputArgumentNames(); + for (auto n : out_names) { + vars_.erase(vars_.find(n)); } + // collect all input vars from remove ops + auto in_names = (*it)->InputArgumentNames(); + vars1.insert(vars1.end(), in_names.begin(), in_names.end()); } ops_.erase(ops_.begin() + s, ops_.begin() + e); + + // collect input and output vars from remain ops + std::vector vars2; + for (auto it = ops_.begin(); it != ops_.end(); it++) { + auto in_names = (*it)->InputArgumentNames(); + auto out_names = (*it)->OutputArgumentNames(); + vars2.insert(vars2.end(), in_names.begin(), in_names.end()); + vars2.insert(vars2.end(), out_names.begin(), out_names.end()); + } + + // delete input vars if no other op use it. + std::vector del_vars; + std::sort(vars1.begin(), vars1.end()); + std::unique(vars1.begin(), vars1.end()); + std::sort(vars2.begin(), vars2.end()); + std::unique(vars2.begin(), vars2.end()); + // del_vars = vars1 - vars1 ^ vars2 + std::set_difference(vars1.begin(), vars1.end(), vars2.begin(), vars2.end(), + std::inserter(del_vars, del_vars.end())); + for (auto it = del_vars.begin(); it != del_vars.end(); it++) { + vars_.erase(vars_.find(*it)); + } } std::vector BlockDesc::AllOps() const { diff --git a/python/paddle/fluid/tests/unittests/test_protobuf_descs.py b/python/paddle/fluid/tests/unittests/test_protobuf_descs.py index 309ea2b9b7..871cb76fff 100644 --- a/python/paddle/fluid/tests/unittests/test_protobuf_descs.py +++ b/python/paddle/fluid/tests/unittests/test_protobuf_descs.py @@ -186,6 +186,33 @@ class TestBlockDesc(unittest.TestCase): all_ops.append(block.op(idx)) self.assertEqual(all_ops, [op0, op1, op2]) + def test_remove_op(self): + prog = core.ProgramDesc() + self.assertIsNotNone(prog) + block = prog.block(0) + self.assertIsNotNone(block) + op1 = block.append_op() + op2 = block.append_op() + var1 = block.var("var1") + var2 = block.var("var2") + var3 = block.var("var3") + var4 = block.var("var4") + op1.set_input("X", ["var1", "var2"]) + op1.set_output("Y", ["var3"]) + op2.set_input("X", ["var1"]) + op2.set_output("Y", ["var4"]) + + # remove op1, its input var2 and output var3 will be removed at the same time, + # but its input var1 will not be removed since var1 is also an input for op2. + block.remove_op(0, 1) + + all_ops = [] + for idx in xrange(0, block.op_size()): + all_ops.append(block.op(idx)) + self.assertEqual(all_ops, [op2]) + all_vars = block.all_vars() + self.assertEqual(set(all_vars), {var1, var4}) + if __name__ == '__main__': unittest.main() From f4925755dbf6c5470a6f0436b80acbdd32cf74b1 Mon Sep 17 00:00:00 2001 From: Xi Chen Date: Mon, 26 Mar 2018 16:10:16 -0700 Subject: [PATCH 06/27] fix submit_local's paddle pip name issue --- paddle/scripts/submit_local.sh.in | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/paddle/scripts/submit_local.sh.in b/paddle/scripts/submit_local.sh.in index 80fa0c72af..1283de9d95 100755 --- a/paddle/scripts/submit_local.sh.in +++ b/paddle/scripts/submit_local.sh.in @@ -153,9 +153,15 @@ if [ $? -ne 0 ]; then exit 1 fi -INSTALLED_VERSION=`pip freeze 2>/dev/null | grep '^paddle' | sed 's/.*==//g'` +if [ "@WITH_GPU@" == "ON" ]; then + PADDLE_NAME="paddlepaddle-gpu" +else + PADDLE_NAME="paddlepaddle" +fi + +INSTALLED_VERSION=`pip freeze 2>/dev/null | grep "^${PADDLE_NAME}==" | sed 's/.*==//g'` -if [ -z ${INSTALLED_VERSION} ]; then +if [ -z "${INSTALLED_VERSION}" ]; then INSTALLED_VERSION="0.0.0" # not installed fi cat < Date: Tue, 27 Mar 2018 12:31:02 +0800 Subject: [PATCH 07/27] fix typo --- doc/v2/faq/cluster/index_en.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/v2/faq/cluster/index_en.rst b/doc/v2/faq/cluster/index_en.rst index 7cbcaeefcb..fa942a0962 100644 --- a/doc/v2/faq/cluster/index_en.rst +++ b/doc/v2/faq/cluster/index_en.rst @@ -4,13 +4,13 @@ Cluster Training and Prediction .. contents:: -1. Network connection errors in the log during muliti-node cluster training +1. Network connection errors in the log during multi-node cluster training ------------------------------------------------ -The errors in the log belong to network connection during mulilti-node cluster training, for example, :code:`Connection reset by peer`. -This kind of error is usually caused by the abnormal exit of the training process in some node, and the others cannot connect with this node any longer. Steps to troubleshoot the problem as follows: +There are maybe some errors in the log belonging to network connection problem during multi-node cluster training, for example, :code:`Connection reset by peer`. +This kind of error is usually caused by the abnormal exit of a training process in some node, and the other nodes cannot connect with this node any longer. Steps to troubleshoot the problem are as follows: * Find the first error in the :code:`train.log`, :code:`server.log`, check whether other fault casued the problem, such as FPE, lacking of memory or disk. -* If network connection gave rise to the first error in the log, this may be caused by the port conflict of the non-exclusive execution. Connect with the operator to check if the current MPI cluster supports jobs submitted with parameter :code:`resource=full`. If so, change the port of job. +* If the first error in server.log says "Address already used", this may be caused by the port conflict of the non-exclusive execution. Connect the sys-admin to check if the current MPI cluster supports jobs submitted with parameter :code:`resource=full`. If the current MPI cluster does not support this parameter, change the server port and try agian. -* If the currnet MPI cluster does not support exclusive pattern, ask the operator to replace or update the current cluster. +* If the current MPI cluster does not support exclusive pattern which allows a process to occupy the whole node, ask the administrator to replace or update the this cluster. From 25317bd312124cb3f26a2248c04215591d4e8446 Mon Sep 17 00:00:00 2001 From: qingqing01 Date: Tue, 27 Mar 2018 16:32:31 +0800 Subject: [PATCH 08/27] Make the first device share data with the global scope in parallel_do_op. (#9398) --- paddle/fluid/operators/parallel_do_op.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/paddle/fluid/operators/parallel_do_op.cc b/paddle/fluid/operators/parallel_do_op.cc index 4001b9a130..b28c16b13f 100644 --- a/paddle/fluid/operators/parallel_do_op.cc +++ b/paddle/fluid/operators/parallel_do_op.cc @@ -144,7 +144,12 @@ class ParallelDoOp : public framework::OperatorBase { PADDLE_ENFORCE(scope.FindVar(param)->IsType(), "Only support parameter type as LoDTensor"); auto &src = scope.FindVar(param)->Get(); - for (size_t i = 0; i < sub_scopes.size(); ++i) { + + auto *sub_scope0 = sub_scopes[0]; + auto *dst0 = sub_scope0->Var(param)->GetMutable(); + dst0->ShareDataWith(src); + + for (size_t i = 1; i < sub_scopes.size(); ++i) { auto &place = places[i]; auto *sub_scope = sub_scopes[i]; auto *dst = sub_scope->Var(param)->GetMutable(); From 7f4012247e09aec9c9d912a806bdf6b5dfabe97a Mon Sep 17 00:00:00 2001 From: Luo Tao Date: Tue, 27 Mar 2018 18:55:32 +0800 Subject: [PATCH 09/27] adjust remove rule for variables --- paddle/fluid/framework/block_desc.cc | 73 +++++++++++-------- paddle/fluid/framework/block_desc.h | 5 ++ .../tests/unittests/test_protobuf_descs.py | 9 ++- 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/paddle/fluid/framework/block_desc.cc b/paddle/fluid/framework/block_desc.cc index 4faf9dcf37..fbe08349c3 100644 --- a/paddle/fluid/framework/block_desc.cc +++ b/paddle/fluid/framework/block_desc.cc @@ -147,40 +147,51 @@ void BlockDesc::RemoveOp(size_t s, size_t e) { if (ops_.begin() + s == ops_.end() || ops_.begin() + e == ops_.end()) { return; } + auto get_vars = [](std::deque>::iterator &op, + std::vector &v) { + auto in_names = (*op)->InputArgumentNames(); + v.insert(v.end(), in_names.begin(), in_names.end()); + auto out_names = (*op)->OutputArgumentNames(); + v.insert(v.end(), out_names.begin(), out_names.end()); + std::sort(v.begin(), v.end()); + auto last = std::unique(v.begin(), v.end()); + v.erase(last, v.end()); + }; need_update_ = true; - std::vector vars1; // input vars from delete ops - for (auto it = ops_.begin() + s; it != ops_.begin() + e; it++) { - // delete all output vars - auto out_names = (*it)->OutputArgumentNames(); - for (auto n : out_names) { - vars_.erase(vars_.find(n)); + + for (size_t i = s; i < e; i++) { + // since remove op one by one, every time remove the first op. + auto op = ops_.begin() + s; + + // collect input and output variables from current delete op + std::vector cur_vars; + get_vars(op, cur_vars); + + // remove current op + ops_.erase(ops_.begin() + s); + + // collect input and output variables from other ops + std::vector other_vars; + for (auto it = ops_.begin(); it != ops_.end(); it++) { + get_vars(it, other_vars); } - // collect all input vars from remove ops - auto in_names = (*it)->InputArgumentNames(); - vars1.insert(vars1.end(), in_names.begin(), in_names.end()); - } - ops_.erase(ops_.begin() + s, ops_.begin() + e); - - // collect input and output vars from remain ops - std::vector vars2; - for (auto it = ops_.begin(); it != ops_.end(); it++) { - auto in_names = (*it)->InputArgumentNames(); - auto out_names = (*it)->OutputArgumentNames(); - vars2.insert(vars2.end(), in_names.begin(), in_names.end()); - vars2.insert(vars2.end(), out_names.begin(), out_names.end()); - } - // delete input vars if no other op use it. - std::vector del_vars; - std::sort(vars1.begin(), vars1.end()); - std::unique(vars1.begin(), vars1.end()); - std::sort(vars2.begin(), vars2.end()); - std::unique(vars2.begin(), vars2.end()); - // del_vars = vars1 - vars1 ^ vars2 - std::set_difference(vars1.begin(), vars1.end(), vars2.begin(), vars2.end(), - std::inserter(del_vars, del_vars.end())); - for (auto it = del_vars.begin(); it != del_vars.end(); it++) { - vars_.erase(vars_.find(*it)); + // variables should be deleted + std::vector delete_vars; + // delete_vars = cur_vars - cur_vars ^ other_input_vars + std::set_difference(cur_vars.begin(), cur_vars.end(), other_vars.begin(), + other_vars.end(), + std::inserter(delete_vars, delete_vars.end())); + // remove variables + for (size_t i = 0; i < delete_vars.size(); i++) { + auto name = delete_vars[i]; + auto it = vars_.find(name); + PADDLE_ENFORCE(it != vars_.end(), + "%s is not in variable list, it should not be deleted", + name); + vars_.erase(it); + VLOG(3) << "deleting variable " << name; + } } } diff --git a/paddle/fluid/framework/block_desc.h b/paddle/fluid/framework/block_desc.h index 185f018ac1..468423e0e8 100644 --- a/paddle/fluid/framework/block_desc.h +++ b/paddle/fluid/framework/block_desc.h @@ -89,6 +89,11 @@ class BlockDesc { OpDesc *InsertOp(size_t index); + /* + * Remove Op and its input/output variables. + * Note that for either input or ouput variable, if it is also an input or + * output variable of other ops, we should remain it. + */ void RemoveOp(size_t s, size_t e); std::vector AllOps() const; diff --git a/python/paddle/fluid/tests/unittests/test_protobuf_descs.py b/python/paddle/fluid/tests/unittests/test_protobuf_descs.py index 871cb76fff..da85786d0c 100644 --- a/python/paddle/fluid/tests/unittests/test_protobuf_descs.py +++ b/python/paddle/fluid/tests/unittests/test_protobuf_descs.py @@ -197,13 +197,14 @@ class TestBlockDesc(unittest.TestCase): var2 = block.var("var2") var3 = block.var("var3") var4 = block.var("var4") + var5 = block.var("var5") op1.set_input("X", ["var1", "var2"]) - op1.set_output("Y", ["var3"]) + op1.set_output("Y", ["var3", "var4"]) op2.set_input("X", ["var1"]) - op2.set_output("Y", ["var4"]) + op2.set_output("Y", ["var4", "var5"]) # remove op1, its input var2 and output var3 will be removed at the same time, - # but its input var1 will not be removed since var1 is also an input for op2. + # but its input var1 and output var4 will not be removed since they are used for op2. block.remove_op(0, 1) all_ops = [] @@ -211,7 +212,7 @@ class TestBlockDesc(unittest.TestCase): all_ops.append(block.op(idx)) self.assertEqual(all_ops, [op2]) all_vars = block.all_vars() - self.assertEqual(set(all_vars), {var1, var4}) + self.assertEqual(set(all_vars), {var1, var4, var5}) if __name__ == '__main__': From 587781153eb21ad69e571d012002dd97b93d9a88 Mon Sep 17 00:00:00 2001 From: typhoonzero Date: Tue, 27 Mar 2018 20:41:21 +0800 Subject: [PATCH 10/27] fix slr deser --- paddle/fluid/operators/detail/variable_response.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/paddle/fluid/operators/detail/variable_response.cc b/paddle/fluid/operators/detail/variable_response.cc index 12e8eb0b4d..d0f103c455 100644 --- a/paddle/fluid/operators/detail/variable_response.cc +++ b/paddle/fluid/operators/detail/variable_response.cc @@ -153,6 +153,7 @@ bool VariableResponse::CopySelectRowsData( const platform::DeviceContext& ctx, int length) { auto var = scope_->FindVar(meta_.varname()); auto* slr = var->GetMutable(); + slr->mutable_rows()->resize(length / 8); int64_t* rows_data = slr->mutable_rows()->data(); // copy rows CPU data, GPU data will be copied lazily. From 094d5096899344206892cc2f82b85bfe2bae2bac Mon Sep 17 00:00:00 2001 From: typhoonzero Date: Tue, 27 Mar 2018 20:41:33 +0800 Subject: [PATCH 11/27] fix slr deser --- paddle/fluid/operators/detail/variable_response.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paddle/fluid/operators/detail/variable_response.cc b/paddle/fluid/operators/detail/variable_response.cc index d0f103c455..3787b139a5 100644 --- a/paddle/fluid/operators/detail/variable_response.cc +++ b/paddle/fluid/operators/detail/variable_response.cc @@ -153,7 +153,7 @@ bool VariableResponse::CopySelectRowsData( const platform::DeviceContext& ctx, int length) { auto var = scope_->FindVar(meta_.varname()); auto* slr = var->GetMutable(); - slr->mutable_rows()->resize(length / 8); + slr->mutable_rows()->resize(length / 8); // int64 int64_t* rows_data = slr->mutable_rows()->data(); // copy rows CPU data, GPU data will be copied lazily. From cc1c6afbbf6df880b2954b61cf1afdc9c368597d Mon Sep 17 00:00:00 2001 From: "yi.wu" Date: Tue, 27 Mar 2018 23:17:30 +0800 Subject: [PATCH 12/27] fix slr serde --- .../operators/detail/variable_response.cc | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/paddle/fluid/operators/detail/variable_response.cc b/paddle/fluid/operators/detail/variable_response.cc index 3787b139a5..bdda570343 100644 --- a/paddle/fluid/operators/detail/variable_response.cc +++ b/paddle/fluid/operators/detail/variable_response.cc @@ -48,6 +48,8 @@ bool ReadRaw(::google::protobuf::io::CodedInputStream* input, void* dest, int size) { const void* data = NULL; int size_to_write = 0; + int length = size; + int total_written = 0; if (platform::is_gpu_place(place)) { #ifdef PADDLE_WITH_CUDA @@ -56,16 +58,21 @@ bool ReadRaw(::google::protobuf::io::CodedInputStream* input, platform::CPUPlace cpu; char* p = reinterpret_cast(dest); - while (size > 0) { + while (total_written < length) { if (!input->GetDirectBufferPointer(&data, &size_to_write)) { return false; } - + // NOTE: if raw buffer is large and have two neighbor fields of raw + // buffers GetDirectBufferPointer can get all of them, use length to + // truncate it. + if (total_written + size_to_write > length) { + size_to_write = length - total_written; + } memory::Copy(boost::get(place), reinterpret_cast(p), cpu, data, size_to_write, gpu_dev_ctx.stream()); p += size_to_write; - size -= size_to_write; + total_written += size_to_write; input->Skip(size_to_write); } @@ -77,16 +84,21 @@ bool ReadRaw(::google::protobuf::io::CodedInputStream* input, } char* p = reinterpret_cast(dest); - while (size > 0) { + while (total_written < length) { if (!input->GetDirectBufferPointer(&data, &size_to_write)) { return false; } + // NOTE: if raw buffer is large and have two neighbor fields of raw buffers + // GetDirectBufferPointer can get all of them, use length to truncate it. + if (total_written + size_to_write > length) { + size_to_write = length - total_written; + } // TODO(gongwb): can we avoid copy? platform::CPUPlace cpu; memory::Copy(cpu, reinterpret_cast(p), cpu, data, size_to_write); p += size_to_write; - size -= size_to_write; + total_written += size_to_write; input->Skip(size_to_write); } @@ -234,7 +246,6 @@ int VariableResponse::Parse(Source* source) { if (tag != 0) { return -1; } - return 0; } From 0e7413938a109285e41f3a55650c6a338279c355 Mon Sep 17 00:00:00 2001 From: Xi Chen Date: Tue, 27 Mar 2018 14:32:42 -0700 Subject: [PATCH 13/27] added missing *.pb.h *.pb.cc generation to fix distribute build issue --- cmake/generic.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/generic.cmake b/cmake/generic.cmake index c749c97f13..c0808ac06c 100644 --- a/cmake/generic.cmake +++ b/cmake/generic.cmake @@ -597,6 +597,9 @@ function(grpc_library TARGET_NAME) COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}" -I "${PROTO_PATH}" --plugin=protoc-gen-grpc="${GRPC_CPP_PLUGIN}" "${ABS_PROTO}" + COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} + ARGS --cpp_out "${CMAKE_CURRENT_BINARY_DIR}" -I "${PROTO_PATH}" + "${ABS_PROTO}" DEPENDS "${ABS_PROTO}" ${PROTOBUF_PROTOC_EXECUTABLE} extern_grpc) # FIXME(typhoonzero): grpc generated code do not generate virtual-dtor, mark it From 54a8c04fab9310ef78f0b000ae411fd7ae706ee7 Mon Sep 17 00:00:00 2001 From: Yang Yang Date: Tue, 27 Mar 2018 22:09:43 +0000 Subject: [PATCH 14/27] add inplace attr to bn --- python/paddle/fluid/layers/nn.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/paddle/fluid/layers/nn.py b/python/paddle/fluid/layers/nn.py index 2db4e5d27d..0332556f62 100644 --- a/python/paddle/fluid/layers/nn.py +++ b/python/paddle/fluid/layers/nn.py @@ -1483,6 +1483,7 @@ def batch_norm(input, param_attr=None, bias_attr=None, data_layout='NCHW', + in_place=False, name=None, moving_mean_name=None, moving_variance_name=None): @@ -1538,7 +1539,7 @@ def batch_norm(input, saved_mean = helper.create_tmp_variable(dtype=dtype, stop_gradient=True) saved_variance = helper.create_tmp_variable(dtype=dtype, stop_gradient=True) - batch_norm_out = helper.create_tmp_variable(dtype) + batch_norm_out = input if in_place else helper.create_tmp_variable(dtype) helper.append_op( type="batch_norm", From f34f2d40267ce7334af6092242c7eef83e3f33aa Mon Sep 17 00:00:00 2001 From: Yang Yang Date: Tue, 27 Mar 2018 22:10:32 +0000 Subject: [PATCH 15/27] make bn inplace in img_conv_group by default --- python/paddle/fluid/nets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/fluid/nets.py b/python/paddle/fluid/nets.py index 3b2e1a3073..bbedf6fde0 100644 --- a/python/paddle/fluid/nets.py +++ b/python/paddle/fluid/nets.py @@ -98,7 +98,7 @@ def img_conv_group(input, use_mkldnn=use_mkldnn) if conv_with_batchnorm[i]: - tmp = layers.batch_norm(input=tmp, act=conv_act) + tmp = layers.batch_norm(input=tmp, act=conv_act, in_place=True) drop_rate = conv_batchnorm_drop_rate[i] if abs(drop_rate) > 1e-5: tmp = layers.dropout(x=tmp, dropout_prob=drop_rate) From d4f49355309f257f33ce08c4d680c712ee5cf2a0 Mon Sep 17 00:00:00 2001 From: Xi Chen Date: Tue, 27 Mar 2018 18:56:04 -0700 Subject: [PATCH 16/27] test removal of redundant line --- cmake/generic.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/generic.cmake b/cmake/generic.cmake index c0808ac06c..981da16a45 100644 --- a/cmake/generic.cmake +++ b/cmake/generic.cmake @@ -587,7 +587,6 @@ function(grpc_library TARGET_NAME) get_filename_component(PROTO_WE ${grpc_library_PROTO} NAME_WE) get_filename_component(PROTO_PATH ${ABS_PROTO} PATH) - protobuf_generate_cpp(grpc_proto_srcs grpc_proto_hdrs "${ABS_PROTO}") set(grpc_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/${PROTO_WE}.grpc.pb.cc") set(grpc_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/${PROTO_WE}.grpc.pb.h") cc_library("${TARGET_NAME}_proto" SRCS "${grpc_proto_srcs}") From 06aaea8a64c59467d45f2cf2e4eea3d0e91d946a Mon Sep 17 00:00:00 2001 From: Xi Chen Date: Tue, 27 Mar 2018 19:10:04 -0700 Subject: [PATCH 17/27] Revert "test removal of redundant line" This reverts commit d4f49355309f257f33ce08c4d680c712ee5cf2a0. --- cmake/generic.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/generic.cmake b/cmake/generic.cmake index 981da16a45..c0808ac06c 100644 --- a/cmake/generic.cmake +++ b/cmake/generic.cmake @@ -587,6 +587,7 @@ function(grpc_library TARGET_NAME) get_filename_component(PROTO_WE ${grpc_library_PROTO} NAME_WE) get_filename_component(PROTO_PATH ${ABS_PROTO} PATH) + protobuf_generate_cpp(grpc_proto_srcs grpc_proto_hdrs "${ABS_PROTO}") set(grpc_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/${PROTO_WE}.grpc.pb.cc") set(grpc_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/${PROTO_WE}.grpc.pb.h") cc_library("${TARGET_NAME}_proto" SRCS "${grpc_proto_srcs}") From 1daa96579cd5df393b8f848c72ea9974a8d25b62 Mon Sep 17 00:00:00 2001 From: Xi Chen Date: Tue, 27 Mar 2018 20:14:34 -0700 Subject: [PATCH 18/27] adding comments for this fix --- cmake/generic.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/generic.cmake b/cmake/generic.cmake index c0808ac06c..3fe750f47e 100644 --- a/cmake/generic.cmake +++ b/cmake/generic.cmake @@ -587,6 +587,9 @@ function(grpc_library TARGET_NAME) get_filename_component(PROTO_WE ${grpc_library_PROTO} NAME_WE) get_filename_component(PROTO_PATH ${ABS_PROTO} PATH) + #FIXME(putcn): the follwoing line is supposed to generate *.pb.h and cc, but + # somehow it didn't. line 602 to 604 is to patching this. Leaving this here + # for now to enable dist CI. protobuf_generate_cpp(grpc_proto_srcs grpc_proto_hdrs "${ABS_PROTO}") set(grpc_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/${PROTO_WE}.grpc.pb.cc") set(grpc_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/${PROTO_WE}.grpc.pb.h") From 9a9d67dac28c362b6b2e86ffeec7c68fa1704d01 Mon Sep 17 00:00:00 2001 From: typhoonzero Date: Wed, 28 Mar 2018 16:47:06 +0800 Subject: [PATCH 19/27] fix dist train selected rows height missing --- paddle/fluid/operators/detail/send_recv.proto | 8 ++++---- paddle/fluid/operators/detail/sendrecvop_utils.cc | 1 + paddle/fluid/operators/detail/test_serde.cc | 2 ++ paddle/fluid/operators/detail/variable_response.cc | 11 +++++++++++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/paddle/fluid/operators/detail/send_recv.proto b/paddle/fluid/operators/detail/send_recv.proto index 598aaa4c51..2d33f026e4 100644 --- a/paddle/fluid/operators/detail/send_recv.proto +++ b/paddle/fluid/operators/detail/send_recv.proto @@ -59,12 +59,12 @@ message VariableMessage { // lod details: int64 lod_level = 5; repeated LodData lod = 6; + // selected_rows height, aka. original dim0 + int64 slr_height = 7; // tensor data - bytes serialized = 7; + bytes serialized = 8; // selected_rows data - bytes rows = 8; + bytes rows = 9; } message VoidMessage {} - -message TestMessage { int64 test_1 = 1; } diff --git a/paddle/fluid/operators/detail/sendrecvop_utils.cc b/paddle/fluid/operators/detail/sendrecvop_utils.cc index d7bbf79c50..f318f8ac28 100644 --- a/paddle/fluid/operators/detail/sendrecvop_utils.cc +++ b/paddle/fluid/operators/detail/sendrecvop_utils.cc @@ -108,6 +108,7 @@ void SerializeToByteBuffer(const std::string& name, framework::Variable* var, e.WriteUint64(VarMsg::kDimsFieldNumber, dim); } e.WriteUint64(VarMsg::kLodLevelFieldNumber, 0); + e.WriteUint64(VarMsg::kSlrHeightFieldNumber, slr->height()); auto* tensor = slr->mutable_value(); if (platform::is_gpu_place(ctx.GetPlace())) { #ifdef PADDLE_WITH_CUDA diff --git a/paddle/fluid/operators/detail/test_serde.cc b/paddle/fluid/operators/detail/test_serde.cc index e646c894d1..e9e2dc84ad 100644 --- a/paddle/fluid/operators/detail/test_serde.cc +++ b/paddle/fluid/operators/detail/test_serde.cc @@ -40,6 +40,7 @@ void RunSerdeTestSelectedRows(platform::Place place) { // serialize var to ByteBuffer framework::Variable var; auto* slr = var.GetMutable(); + slr->set_height(1000); auto* tensor = slr->mutable_value(); auto* rows = slr->mutable_rows(); tensor->Resize(framework::make_ddim({2, 10})); @@ -106,6 +107,7 @@ void RunSerdeTestSelectedRows(platform::Place place) { } EXPECT_EQ(rows_data2[0], 3); EXPECT_EQ(rows_data2[1], 10); + EXPECT_EQ(slr2->height(), 1000); } void RunTestLodTensor(platform::Place place, int from_type = 0) { diff --git a/paddle/fluid/operators/detail/variable_response.cc b/paddle/fluid/operators/detail/variable_response.cc index bdda570343..862fd26b54 100644 --- a/paddle/fluid/operators/detail/variable_response.cc +++ b/paddle/fluid/operators/detail/variable_response.cc @@ -68,6 +68,8 @@ bool ReadRaw(::google::protobuf::io::CodedInputStream* input, if (total_written + size_to_write > length) { size_to_write = length - total_written; } + VLOG(3) << "copy raw " << size_to_write + << " bytes, written: " << total_written << ", length: " << length; memory::Copy(boost::get(place), reinterpret_cast(p), cpu, data, size_to_write, gpu_dev_ctx.stream()); @@ -147,6 +149,7 @@ bool VariableResponse::CopySelectRowsTensorData( const platform::DeviceContext& ctx, framework::DDim& dims, int length) { auto var = scope_->FindVar(meta_.varname()); auto* slr = var->GetMutable(); + slr->set_height(meta_.slr_height()); auto* tensor = slr->mutable_value(); tensor->Resize(dims); void* tensor_data = tensor->mutable_data( @@ -348,6 +351,14 @@ int VariableResponse::Parse(Source* source) { } break; } + case sendrecv::VariableMessage::kSlrHeightFieldNumber: { + uint64_t v = 0; + if ((wt != WIRETYPE_VARINT) || !input.ReadVarint64(&v)) { + return tag; + } + meta_.set_slr_height(static_cast(v)); + break; + } case sendrecv::VariableMessage::kSerializedFieldNumber: { PADDLE_ENFORCE((meta_.type() == sendrecv::SELECTED_ROWS || meta_.type() == sendrecv::LOD_TENSOR) && From 2e577379ca8fc67dbb4fc436297cf7ae826b3fa7 Mon Sep 17 00:00:00 2001 From: chengduoZH Date: Wed, 28 Mar 2018 16:52:20 +0800 Subject: [PATCH 20/27] add cos --- paddle/fluid/operators/activation_op.cc | 18 +++++++ paddle/fluid/operators/activation_op.h | 49 +++++++++++++++++++ paddle/function/EigenGemm.cpp | 1 + python/paddle/fluid/layers/ops.py | 1 + .../tests/unittests/test_activation_op.py | 15 ++++++ 5 files changed, 84 insertions(+) diff --git a/paddle/fluid/operators/activation_op.cc b/paddle/fluid/operators/activation_op.cc index 979115eee0..7f4b23c526 100644 --- a/paddle/fluid/operators/activation_op.cc +++ b/paddle/fluid/operators/activation_op.cc @@ -260,6 +260,21 @@ $out = floor(x)$ } }; +class CosOpMaker : public framework::OpProtoAndCheckerMaker { + public: + CosOpMaker(OpProto *proto, OpAttrChecker *op_checker) + : framework::OpProtoAndCheckerMaker(proto, op_checker) { + AddInput("X", "Input of Floor operator"); + AddOutput("Out", "Output of Floor operator"); + AddComment(R"DOC( +Floor Activation Operator. + +$out = cos(x)$ + +)DOC"); + } +}; + class RoundOpMaker : public framework::OpProtoAndCheckerMaker { public: RoundOpMaker(OpProto *proto, OpAttrChecker *op_checker) @@ -561,6 +576,9 @@ REGISTER_OP(ceil, ops::ActivationOp, ops::CeilOpMaker, ceil_grad, REGISTER_OP(floor, ops::ActivationOp, ops::FloorOpMaker, floor_grad, ops::ActivationOpGrad); +REGISTER_OP(cos, ops::ActivationOp, ops::CosOpMaker, cos_grad, + ops::ActivationOpGrad); + REGISTER_OP(round, ops::ActivationOp, ops::RoundOpMaker, round_grad, ops::ActivationOpGrad); diff --git a/paddle/fluid/operators/activation_op.h b/paddle/fluid/operators/activation_op.h index 4c575b4a7b..3bd3f0bb94 100644 --- a/paddle/fluid/operators/activation_op.h +++ b/paddle/fluid/operators/activation_op.h @@ -331,6 +331,54 @@ struct FloorFunctor : public BaseActivationFunctor { } }; +template +struct Sine { + HOSTDEVICE T operator()(const T& val) const { return sin(val); } +}; + +template +struct Cosine { + HOSTDEVICE T operator()(const T& val) const { return cos(val); } +}; + +// cosine'(x) = -sin(x) +template +struct CosGradFunctor : public BaseActivationFunctor { + template + void operator()(Device d, X x, Out out, dOut dout, dX dx) const { + dx.device(d) = -dout * x.unaryExpr(Sine()); + } +}; + +// cosine(x) = cos(x) +template +struct CosFunctor : public BaseActivationFunctor { + template + void operator()(Device d, X x, Out out) const { + out.device(d) = x.unaryExpr(Cosine()); + } +}; + +// sine'(x) = cos(x) +template +struct SinGradFunctor : public BaseActivationFunctor { + template + void operator()(Device d, X x, Out out, dOut dout, dX dx) const { + dx.device(d) = dout * x.unaryExpr(Cosine()); + } +}; + +// sine(x) = sin(x) +template +struct SinFunctor : public BaseActivationFunctor { + template + void operator()(Device d, X x, Out out) const { + out.device(d) = x.unaryExpr(Sine()); + } +}; + // round(x) = [x] template struct RoundFunctor : public BaseActivationFunctor { @@ -782,6 +830,7 @@ struct SwishGradFunctor : public BaseActivationFunctor { __macro(abs, AbsFunctor, AbsGradFunctor); \ __macro(ceil, CeilFunctor, ZeroGradFunctor); \ __macro(floor, FloorFunctor, ZeroGradFunctor); \ + __macro(cos, CosFunctor, CosGradFunctor); \ __macro(round, RoundFunctor, ZeroGradFunctor); \ __macro(reciprocal, ReciprocalFunctor, ReciprocalGradFunctor); \ __macro(log, LogFunctor, LogGradFunctor); \ diff --git a/paddle/function/EigenGemm.cpp b/paddle/function/EigenGemm.cpp index bac4659e62..4c81ebdd31 100644 --- a/paddle/function/EigenGemm.cpp +++ b/paddle/function/EigenGemm.cpp @@ -63,6 +63,7 @@ struct EigenBlasGemm { const EigenMatrix a(const_cast(A), sizeA); const EigenMatrix b(const_cast(B), sizeB); EigenMatrix c(C, sizeC); + Eigen::Tensor ss; typedef typename Eigen::Tensor::DimensionPair DimPair; Eigen::array dims; diff --git a/python/paddle/fluid/layers/ops.py b/python/paddle/fluid/layers/ops.py index f5c6b47d24..ee8de219ee 100644 --- a/python/paddle/fluid/layers/ops.py +++ b/python/paddle/fluid/layers/ops.py @@ -25,6 +25,7 @@ __activations__ = [ 'abs', 'ceil', 'floor', + 'cos', 'round', 'reciprocal', 'log', diff --git a/python/paddle/fluid/tests/unittests/test_activation_op.py b/python/paddle/fluid/tests/unittests/test_activation_op.py index 4a2b35322d..b78fb8a319 100644 --- a/python/paddle/fluid/tests/unittests/test_activation_op.py +++ b/python/paddle/fluid/tests/unittests/test_activation_op.py @@ -14,6 +14,7 @@ import unittest import numpy as np +import math import paddle.fluid.core as core from op_test import OpTest from scipy.special import expit @@ -196,6 +197,20 @@ class TestFloor(OpTest): self.check_grad(['X'], 'Out', max_relative_error=0.007) +class TestCos(OpTest): + def setUp(self): + self.op_type = "cos" + x = np.random.uniform(-1, 1, [4, 4]).astype("float32") + self.inputs = {'X': x} + self.outputs = {'Out': math.cos(self.inputs['X'])} + + def test_check_output(self): + self.check_output() + + def test_check_grad(self): + self.check_grad(['X'], 'Out', max_relative_error=0.007) + + class TestRound(OpTest): def setUp(self): self.op_type = "round" From ce16400daedfa8f793d20d44081db7f417af693a Mon Sep 17 00:00:00 2001 From: "Yang Yang(Tony)" Date: Wed, 28 Mar 2018 21:15:12 -0700 Subject: [PATCH 21/27] make append activation in place by default (#9417) --- python/paddle/fluid/layer_helper.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/python/paddle/fluid/layer_helper.py b/python/paddle/fluid/layer_helper.py index d771837fc5..4341e06596 100644 --- a/python/paddle/fluid/layer_helper.py +++ b/python/paddle/fluid/layer_helper.py @@ -398,7 +398,6 @@ class LayerHelper(object): return input_var if isinstance(act, basestring): act = {'type': act} - tmp = self.create_tmp_variable(dtype=input_var.dtype) if 'use_mkldnn' in self.kwargs: act['use_mkldnn'] = self.kwargs.get('use_mkldnn') @@ -408,9 +407,9 @@ class LayerHelper(object): self.append_op( type=act_type, inputs={"X": [input_var]}, - outputs={"Out": [tmp]}, + outputs={"Out": [input_var]}, attrs=act) - return tmp + return input_var def _get_default_initializer(self, dtype): if dtype is None or dtype_is_floating(dtype) is True: From bdda08d9f2846cd4a5cb407e993be0bc03a674a5 Mon Sep 17 00:00:00 2001 From: chengduoZH Date: Wed, 28 Mar 2018 23:13:38 +0800 Subject: [PATCH 22/27] add sin --- paddle/fluid/framework/CMakeLists.txt | 2 +- paddle/fluid/operators/activation_op.cc | 24 ++++++++++++++++--- paddle/fluid/operators/activation_op.h | 1 + paddle/function/EigenGemm.cpp | 1 - python/paddle/fluid/layers/ops.py | 1 + .../tests/unittests/test_activation_op.py | 17 +++++++++++-- 6 files changed, 39 insertions(+), 7 deletions(-) diff --git a/paddle/fluid/framework/CMakeLists.txt b/paddle/fluid/framework/CMakeLists.txt index a4ea74a6d2..8c8def6bf4 100644 --- a/paddle/fluid/framework/CMakeLists.txt +++ b/paddle/fluid/framework/CMakeLists.txt @@ -100,7 +100,7 @@ cc_test(init_test SRCS init_test.cc DEPS init) cc_test(op_kernel_type_test SRCS op_kernel_type_test.cc DEPS place device_context framework_proto) cc_test(cow_ptr_tests SRCS details/cow_ptr_test.cc) -cc_test(channel_test SRCS channel_test.cc) +# cc_test(channel_test SRCS channel_test.cc) cc_test(tuple_test SRCS tuple_test.cc ) cc_test(concurrency_test SRCS concurrency_test.cc DEPS go_op channel_close_op channel_create_op channel_send_op channel_recv_op sum_op select_op elementwise_add_op compare_op diff --git a/paddle/fluid/operators/activation_op.cc b/paddle/fluid/operators/activation_op.cc index 7f4b23c526..a6d9ce0f04 100644 --- a/paddle/fluid/operators/activation_op.cc +++ b/paddle/fluid/operators/activation_op.cc @@ -264,10 +264,10 @@ class CosOpMaker : public framework::OpProtoAndCheckerMaker { public: CosOpMaker(OpProto *proto, OpAttrChecker *op_checker) : framework::OpProtoAndCheckerMaker(proto, op_checker) { - AddInput("X", "Input of Floor operator"); - AddOutput("Out", "Output of Floor operator"); + AddInput("X", "Input of Cosine operator"); + AddOutput("Out", "Output of Cosine operator"); AddComment(R"DOC( -Floor Activation Operator. +Cosine Activation Operator. $out = cos(x)$ @@ -275,6 +275,21 @@ $out = cos(x)$ } }; +class SinOpMaker : public framework::OpProtoAndCheckerMaker { + public: + SinOpMaker(OpProto *proto, OpAttrChecker *op_checker) + : framework::OpProtoAndCheckerMaker(proto, op_checker) { + AddInput("X", "Input of Sine operator"); + AddOutput("Out", "Output of Sine operator"); + AddComment(R"DOC( +Sine Activation Operator. + +$out = sin(x)$ + +)DOC"); + } +}; + class RoundOpMaker : public framework::OpProtoAndCheckerMaker { public: RoundOpMaker(OpProto *proto, OpAttrChecker *op_checker) @@ -579,6 +594,9 @@ REGISTER_OP(floor, ops::ActivationOp, ops::FloorOpMaker, floor_grad, REGISTER_OP(cos, ops::ActivationOp, ops::CosOpMaker, cos_grad, ops::ActivationOpGrad); +REGISTER_OP(sin, ops::ActivationOp, ops::SinOpMaker, sin_grad, + ops::ActivationOpGrad); + REGISTER_OP(round, ops::ActivationOp, ops::RoundOpMaker, round_grad, ops::ActivationOpGrad); diff --git a/paddle/fluid/operators/activation_op.h b/paddle/fluid/operators/activation_op.h index 3bd3f0bb94..7fbe4efc04 100644 --- a/paddle/fluid/operators/activation_op.h +++ b/paddle/fluid/operators/activation_op.h @@ -831,6 +831,7 @@ struct SwishGradFunctor : public BaseActivationFunctor { __macro(ceil, CeilFunctor, ZeroGradFunctor); \ __macro(floor, FloorFunctor, ZeroGradFunctor); \ __macro(cos, CosFunctor, CosGradFunctor); \ + __macro(sin, SinFunctor, SinGradFunctor); \ __macro(round, RoundFunctor, ZeroGradFunctor); \ __macro(reciprocal, ReciprocalFunctor, ReciprocalGradFunctor); \ __macro(log, LogFunctor, LogGradFunctor); \ diff --git a/paddle/function/EigenGemm.cpp b/paddle/function/EigenGemm.cpp index 4c81ebdd31..bac4659e62 100644 --- a/paddle/function/EigenGemm.cpp +++ b/paddle/function/EigenGemm.cpp @@ -63,7 +63,6 @@ struct EigenBlasGemm { const EigenMatrix a(const_cast(A), sizeA); const EigenMatrix b(const_cast(B), sizeB); EigenMatrix c(C, sizeC); - Eigen::Tensor ss; typedef typename Eigen::Tensor::DimensionPair DimPair; Eigen::array dims; diff --git a/python/paddle/fluid/layers/ops.py b/python/paddle/fluid/layers/ops.py index ee8de219ee..0e5987ee59 100644 --- a/python/paddle/fluid/layers/ops.py +++ b/python/paddle/fluid/layers/ops.py @@ -26,6 +26,7 @@ __activations__ = [ 'ceil', 'floor', 'cos', + 'sin', 'round', 'reciprocal', 'log', diff --git a/python/paddle/fluid/tests/unittests/test_activation_op.py b/python/paddle/fluid/tests/unittests/test_activation_op.py index b78fb8a319..fb162f8b73 100644 --- a/python/paddle/fluid/tests/unittests/test_activation_op.py +++ b/python/paddle/fluid/tests/unittests/test_activation_op.py @@ -14,7 +14,6 @@ import unittest import numpy as np -import math import paddle.fluid.core as core from op_test import OpTest from scipy.special import expit @@ -202,7 +201,21 @@ class TestCos(OpTest): self.op_type = "cos" x = np.random.uniform(-1, 1, [4, 4]).astype("float32") self.inputs = {'X': x} - self.outputs = {'Out': math.cos(self.inputs['X'])} + self.outputs = {'Out': np.cos(self.inputs['X'])} + + def test_check_output(self): + self.check_output() + + def test_check_grad(self): + self.check_grad(['X'], 'Out', max_relative_error=0.007) + + +class TestSin(OpTest): + def setUp(self): + self.op_type = "sin" + x = np.random.uniform(-1, 1, [4, 4]).astype("float32") + self.inputs = {'X': x} + self.outputs = {'Out': np.sin(self.inputs['X'])} def test_check_output(self): self.check_output() From 450be963feb74b591bb232cd2b05aac9b01b23b4 Mon Sep 17 00:00:00 2001 From: typhoonzero Date: Thu, 29 Mar 2018 14:34:45 +0800 Subject: [PATCH 23/27] fix sparse errors --- paddle/fluid/operators/detail/grpc_client.cc | 1 - .../operators/detail/sendrecvop_utils.cc | 2 +- .../fluid/operators/detail/sendrecvop_utils.h | 7 +++++++ paddle/fluid/operators/detail/test_serde.cc | 19 +++++++++++-------- .../operators/detail/variable_response.cc | 9 ++++++--- paddle/fluid/operators/listen_and_serv_op.cc | 2 ++ paddle/fluid/operators/send_op.cc | 4 ++-- 7 files changed, 29 insertions(+), 15 deletions(-) diff --git a/paddle/fluid/operators/detail/grpc_client.cc b/paddle/fluid/operators/detail/grpc_client.cc index e73bbe7537..03b789f326 100644 --- a/paddle/fluid/operators/detail/grpc_client.cc +++ b/paddle/fluid/operators/detail/grpc_client.cc @@ -204,7 +204,6 @@ std::shared_ptr RPCClient::GetChannel(const std::string& ep) { } grpc::ChannelArguments args; - args.SetInt("grpc.testing.fixed_reconnect_backoff_ms", 5000); args.SetCompressionAlgorithm(GRPC_COMPRESS_NONE); args.SetMaxSendMessageSize(std::numeric_limits::max()); args.SetMaxReceiveMessageSize(std::numeric_limits::max()); diff --git a/paddle/fluid/operators/detail/sendrecvop_utils.cc b/paddle/fluid/operators/detail/sendrecvop_utils.cc index f318f8ac28..7e3f015dab 100644 --- a/paddle/fluid/operators/detail/sendrecvop_utils.cc +++ b/paddle/fluid/operators/detail/sendrecvop_utils.cc @@ -155,7 +155,7 @@ void SerializeToByteBuffer(const std::string& name, framework::Variable* var, ProtoEncodeHelper e2((char*)buf, 128); // NOTE: rows is of type int64_t size_t rows_memory_size = - slr->rows().capacity() * framework::SizeOfType(typeid(int64_t)); + slr->rows().size() * framework::SizeOfType(typeid(int64_t)); e2.WriteVarlengthBeginning(VarMsg::kRowsFieldNumber, rows_memory_size); slices[2] = ::grpc::Slice(e2.size()); memcpy(const_cast(slices[2].begin()), e2.data(), e2.size()); diff --git a/paddle/fluid/operators/detail/sendrecvop_utils.h b/paddle/fluid/operators/detail/sendrecvop_utils.h index 3b87562703..b3b2b8469c 100644 --- a/paddle/fluid/operators/detail/sendrecvop_utils.h +++ b/paddle/fluid/operators/detail/sendrecvop_utils.h @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ #pragma once +#include #include #include #include @@ -35,6 +36,12 @@ namespace detail { #define BATCH_BARRIER_MESSAGE "BATCH_BARRIER@RECV" #define FETCH_BARRIER_MESSAGE "FETCH_BARRIER@RECV" +static int64_t GetTimestamp() { + struct timeval tp; + gettimeofday(&tp, NULL); + return tp.tv_sec * 1000 + tp.tv_usec / 1000; +} + typedef void (*DestroyCallback)(void*); void SerializeToByteBuffer(const std::string& name, framework::Variable* var, diff --git a/paddle/fluid/operators/detail/test_serde.cc b/paddle/fluid/operators/detail/test_serde.cc index e9e2dc84ad..ea1670e56f 100644 --- a/paddle/fluid/operators/detail/test_serde.cc +++ b/paddle/fluid/operators/detail/test_serde.cc @@ -43,12 +43,11 @@ void RunSerdeTestSelectedRows(platform::Place place) { slr->set_height(1000); auto* tensor = slr->mutable_value(); auto* rows = slr->mutable_rows(); - tensor->Resize(framework::make_ddim({2, 10})); + tensor->Resize(framework::make_ddim({564, 128})); tensor->mutable_data(place); - int tensor_numel = 2 * 10; + int tensor_numel = 564 * 128; math::set_constant(ctx, tensor, 32.7); - rows->push_back(3); - rows->push_back(10); + for (int i = 0; i < 564; ++i) rows->push_back(i); ::grpc::ByteBuffer msg; operators::detail::SerializeToByteBuffer("myvar", &var, ctx, &msg); @@ -65,6 +64,7 @@ void RunSerdeTestSelectedRows(platform::Place place) { sendrecv::VariableMessage varmsg; EXPECT_TRUE(varmsg.ParseFromString(tmp)); + // deserialize bytebuffer EXPECT_EQ(varmsg.varname(), "myvar"); EXPECT_EQ(varmsg.type(), 1); @@ -75,8 +75,10 @@ void RunSerdeTestSelectedRows(platform::Place place) { for (int i = 0; i < tensor_numel; ++i) { EXPECT_FLOAT_EQ(tensor_data[i], 32.7); } - EXPECT_EQ(rows_data[0], 3); - EXPECT_EQ(rows_data[1], 10); + for (int i = 0; i < 564; ++i) { + EXPECT_EQ(rows_data[i], i); + } + // deserialize zero-copy // framework::Variable var2; // operators::detail::DeserializeFromByteBuffer(msg, ctx, &var2); @@ -105,8 +107,9 @@ void RunSerdeTestSelectedRows(platform::Place place) { for (int i = 0; i < tensor_numel; ++i) { EXPECT_FLOAT_EQ(tensor_data2[i], 32.7); } - EXPECT_EQ(rows_data2[0], 3); - EXPECT_EQ(rows_data2[1], 10); + for (int i = 0; i < rows2->size(); ++i) { + EXPECT_EQ(rows_data2[i], i); + } EXPECT_EQ(slr2->height(), 1000); } diff --git a/paddle/fluid/operators/detail/variable_response.cc b/paddle/fluid/operators/detail/variable_response.cc index 862fd26b54..f59c9b50bb 100644 --- a/paddle/fluid/operators/detail/variable_response.cc +++ b/paddle/fluid/operators/detail/variable_response.cc @@ -68,8 +68,6 @@ bool ReadRaw(::google::protobuf::io::CodedInputStream* input, if (total_written + size_to_write > length) { size_to_write = length - total_written; } - VLOG(3) << "copy raw " << size_to_write - << " bytes, written: " << total_written << ", length: " << length; memory::Copy(boost::get(place), reinterpret_cast(p), cpu, data, size_to_write, gpu_dev_ctx.stream()); @@ -152,6 +150,10 @@ bool VariableResponse::CopySelectRowsTensorData( slr->set_height(meta_.slr_height()); auto* tensor = slr->mutable_value(); tensor->Resize(dims); + PADDLE_ENFORCE_EQ( + tensor->numel(), + length / framework::SizeOfType( + paddle::operators::detail::ToTypeIndex(meta_.data_type()))); void* tensor_data = tensor->mutable_data( ctx.GetPlace(), paddle::operators::detail::ToTypeIndex(meta_.data_type())); @@ -168,7 +170,8 @@ bool VariableResponse::CopySelectRowsData( const platform::DeviceContext& ctx, int length) { auto var = scope_->FindVar(meta_.varname()); auto* slr = var->GetMutable(); - slr->mutable_rows()->resize(length / 8); // int64 + slr->mutable_rows()->resize(length / + framework::SizeOfType(typeid(int64_t))); // int64 int64_t* rows_data = slr->mutable_rows()->data(); // copy rows CPU data, GPU data will be copied lazily. diff --git a/paddle/fluid/operators/listen_and_serv_op.cc b/paddle/fluid/operators/listen_and_serv_op.cc index 08b83375dd..9796fabdb6 100644 --- a/paddle/fluid/operators/listen_and_serv_op.cc +++ b/paddle/fluid/operators/listen_and_serv_op.cc @@ -141,6 +141,7 @@ class ListenAndServOp : public framework::OperatorBase { // and this will still work. std::vector> fs; + double ts = detail::GetTimestamp(); // block0 contains only listen_and_serv op, start run from block1. for (int blkid = 1; blkid < num_blocks - 1; ++blkid) { fs.push_back( @@ -162,6 +163,7 @@ class ListenAndServOp : public framework::OperatorBase { LOG(ERROR) << "run sub program error " << e.what(); } } + VLOG(2) << "run all blocks spent (ms) " << detail::GetTimestamp() - ts; // Reset the received sparse variables, the sum operator would not // sum the input sparse variables which rows is empty at the next diff --git a/paddle/fluid/operators/send_op.cc b/paddle/fluid/operators/send_op.cc index fdf3c06ef0..0752bd1bbd 100644 --- a/paddle/fluid/operators/send_op.cc +++ b/paddle/fluid/operators/send_op.cc @@ -72,7 +72,7 @@ class SendOp : public framework::OperatorBase { for (size_t i = 0; i < ins.size(); i++) { if (NeedSend(scope, ins[i])) { - VLOG(2) << "sending " << ins[i] << " to " << epmap[i]; + VLOG(3) << "sending " << ins[i] << " to " << epmap[i]; rpc_client->AsyncSendVariable(epmap[i], ctx, scope, ins[i]); } else { VLOG(3) << "don't send no-initialied variable: " << ins[i]; @@ -81,7 +81,7 @@ class SendOp : public framework::OperatorBase { PADDLE_ENFORCE(rpc_client->Wait()); for (auto& ep : endpoints) { - VLOG(2) << "batch barrier, ep: " << ep; + VLOG(3) << "batch barrier, ep: " << ep; rpc_client->AsyncSendBatchBarrier(ep); } PADDLE_ENFORCE(rpc_client->Wait()); From f5da16e51b05ac88a9402f256cee0a101c58116d Mon Sep 17 00:00:00 2001 From: Abhinav Arora Date: Wed, 28 Mar 2018 23:57:17 -0700 Subject: [PATCH 24/27] Disabling channel test to debug issue (#9491) --- paddle/fluid/framework/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paddle/fluid/framework/CMakeLists.txt b/paddle/fluid/framework/CMakeLists.txt index a4ea74a6d2..8c8def6bf4 100644 --- a/paddle/fluid/framework/CMakeLists.txt +++ b/paddle/fluid/framework/CMakeLists.txt @@ -100,7 +100,7 @@ cc_test(init_test SRCS init_test.cc DEPS init) cc_test(op_kernel_type_test SRCS op_kernel_type_test.cc DEPS place device_context framework_proto) cc_test(cow_ptr_tests SRCS details/cow_ptr_test.cc) -cc_test(channel_test SRCS channel_test.cc) +# cc_test(channel_test SRCS channel_test.cc) cc_test(tuple_test SRCS tuple_test.cc ) cc_test(concurrency_test SRCS concurrency_test.cc DEPS go_op channel_close_op channel_create_op channel_send_op channel_recv_op sum_op select_op elementwise_add_op compare_op From 241f3c988f87978d05a8b2f516509490b01b5ef5 Mon Sep 17 00:00:00 2001 From: Thuan Nguyen Date: Thu, 29 Mar 2018 00:04:10 -0700 Subject: [PATCH 25/27] Add channel design document (#9463) * Add channel design document * Update channel send/recv state diagram --- doc/fluid/design/concurrent/channel.md | 139 ++++++++++++++++++ .../design/concurrent/images/channel_recv.png | Bin 0 -> 136646 bytes .../design/concurrent/images/channel_send.png | Bin 0 -> 85643 bytes 3 files changed, 139 insertions(+) create mode 100644 doc/fluid/design/concurrent/channel.md create mode 100644 doc/fluid/design/concurrent/images/channel_recv.png create mode 100644 doc/fluid/design/concurrent/images/channel_send.png diff --git a/doc/fluid/design/concurrent/channel.md b/doc/fluid/design/concurrent/channel.md new file mode 100644 index 0000000000..a00a3325e7 --- /dev/null +++ b/doc/fluid/design/concurrent/channel.md @@ -0,0 +1,139 @@ +# Channel Design + +## Introduction + +A Channel is a data structure that allows for synchronous interprocess +communication via message passing. It is a fundemental component of CSP +(communicating sequential processes), and allows for users to pass data +between threads without having to worry about synchronization. + +## How to use it + +Paddle offers python APIs to open and close channels, along with sending +and receiving data to/from a channel. + +### Create a channel + +Creates a new channel that takes in variables of a specific dtype. + +- **fluid.make_channel(dtype, capacity=0)** + - **dtype**: The data type of variables being sent/received through channel + - **capacity**: The capacity of the channel. A capacity of 0 represents + an unbuffered channel. Capacity > 0 represents a buffered channel + +``` +ch = fluid.make_channel(dtype=core.VarDesc.VarType.LOD_TENSOR, 10) +``` + +### Close a channel + +Closes a channel. Any pending senders and receivers will be awoken during +this time. Receivers can still receive from a closed channel, but senders +are not allowed to send any additional data to the channel (Paddle will +raise an exception if users try to send to a closed channel.) + +- **fluid.channel_close(channel)** + +``` +fluid.channel_close(ch) +``` + +### Send data to a channel + +Sends a variable to a channel. Currently, variables of dtype `LoDTensor`, +`LoDRankTable`, `LoDTensorArray`, `SelectedRows`, `ReaderHolder`, and +`ChannelHolder` are supported. + +By default, the data of the Variable is moved from the sender to the receiver, +however the user can optionally copy the data before performing the send. + +- **channel_send(channel, variable, is_copy=False)** + - **channel**: The channel to send the variable to + - **variable**: The variable to send to the channel + - **is_copy**: If set to True, channel_send will perform a variable assign + to copy the source variable to a new variable to be sent. + +``` +ch = fluid.make_channel(dtype=core.VarDesc.VarType.LOD_TENSOR) +var = fill_constant(shape=[1],dtype=core.VarDesc.VarType.INT32, value=100) +fluid.channel_send(ch, var, True) +``` + +### Receive data from a channel + +Receives a variable from a channel. The data of the variable is moved to the +receiving variable. + +- **channel_recv(channel, return_variable)** + - **channel**: The channel to receive the variable from + - **return_variable**: The destination variable used to store the data of the + variable received from the channel + +``` +ch = fluid.make_channel(dtype=core.VarDesc.VarType.LOD_TENSOR) +var = fill_constant(shape=[1],dtype=core.VarDesc.VarType.INT32, value=-1) +fluid.channel_recv(ch, var) +``` + +## How it Works + +Channels provides a simple interface for different threads to share data. +To support the synchronization requirements, channels utilizes a series of +internal queues, locks, and conditional variables. + +### QueueMessage + +QueueMessage encapsulates the state of the channel send/receive operation to be +put in the **sendq/recvq**. It contains a condition variable used to lock the +thread (when there are no available sends/receives). In addition, it contains +a callback function to notify a thread when the QueueMessage is being +processed by the channel. + +### Queues + +- **buff_**: This queue holds the data buffer in a buffered channel. The +capacity is set to the capacity of the channel. This data buffer is not +used in an unbuffered channel. + +- **sendq**: This queue holds the QueueMessage of any pending senders of a +channel. When a thread performs a channel_send operation on the channel, the +channel_send operation will put a new QueueMessage on the sendq and block the +current thread under two conditions: + 1. The channel is buffered and is full + 2. The channel is unbuffered and does not have a receiver + +- **recvq**: This queue holds the QueueMessage of any pending receivers of a +channel. When a thread performs a channel_recv operation on the channel, the +channel_recv operation will put a new QueueMessage on the recvq and block the +current thread under two conditions: + 1. The channel is buffered and there is no data on the buff_ + 2. The channel is unbuffered and does not have a sender + +### State diagram + +#### Channel Send + +

+
+

+ +#### Channel Receive + +

+
+

+ +## Limitations and Considerations + +### Variable Copy + +In golang, variables in channels are copied from the sender to the receiver. +In Paddle, the data from our variables are **moved** from sender to receiver. +As a result, these variables should not be used after they are sent. We +provide a flag in channel_send method to allow users to copy the variable to +be sent before it is sent. + +Please note that this is acheived by adding an **assign** operator and creating +a temporary variable that is sent in place of the original variable. Please +note that **assign** operator has limited support for only certain variables +datatypes. diff --git a/doc/fluid/design/concurrent/images/channel_recv.png b/doc/fluid/design/concurrent/images/channel_recv.png new file mode 100644 index 0000000000000000000000000000000000000000..c06cd15ae7b8a8c94d5742f6675e389081fcf789 GIT binary patch literal 136646 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 Ms>+m0z5V+C0GBe^(EtDd literal 0 HcmV?d00001 diff --git a/doc/fluid/design/concurrent/images/channel_send.png b/doc/fluid/design/concurrent/images/channel_send.png new file mode 100644 index 0000000000000000000000000000000000000000..006ebb4a5a4bcd32c97847e9fb7729a740255f7c GIT binary patch literal 85643 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≧~Mf{j{)ixb>+cKdH*JUJ$i#>as) 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%0A1yekB{qizn<~L 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 WWK+fYxv;^2kGQamQ2AHAfd2#1QGn(E literal 0 HcmV?d00001 From c4886584047122b5b358021a6c21977c259142d0 Mon Sep 17 00:00:00 2001 From: fengjiayi Date: Thu, 29 Mar 2018 15:34:36 +0800 Subject: [PATCH 26/27] follow comments --- doc/fluid/design/concepts/cpp_data_feeding.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/fluid/design/concepts/cpp_data_feeding.md b/doc/fluid/design/concepts/cpp_data_feeding.md index 9c44dec4b9..aabc1ba75a 100644 --- a/doc/fluid/design/concepts/cpp_data_feeding.md +++ b/doc/fluid/design/concepts/cpp_data_feeding.md @@ -113,7 +113,7 @@ To solve this problem, we introduce `ReaderHolder` as a wrapper. It acts as an e To create and invoke readers, some new ops are introduced: -### Operators That Creates Readers +### Operators That Create Readers Each reader has its creation op. File readers' creation ops have no input and yield the created file reader as its output. Decorated readers' creation ops take the underlying readers as inputs and then yield new decorated readers. @@ -168,17 +168,19 @@ while_op(not_completed) { } ``` -Two important considerations for these programs are as follows: +A few important considerations for these programs are as follows: -1. The multiple\_reader is the batch\_reader's underlying reader, and the batch\_reader is the double\_buffer\_reader's underlying reader. `read_op`, `has_next_op` and other reader related ops will only invoke the top-most reader. In this case, it's the double\_buffer\_reader. +1. `not_completed`, `pass_count` and other variables shown above are all Fluid Variables. -2. All readers exist in both `startup_program` and `main_program`. And they are persistable. +2. The multiple\_reader is the batch\_reader's underlying reader, and the batch\_reader is the double\_buffer\_reader's underlying reader. `read_op`, `has_next_op` and other reader related ops will only invoke the top-most reader. In this case, it's the double\_buffer\_reader. + +3. All readers exist in both `startup_program` and `main_program`. And they are persistable. ### Simplify Configuration by MultiPassReader -The Program configuration mentioned above is somehow complicated. Users need to be very similar to concepts of Program and Block to prevent making mistakes in their code. To make the usage of C++ readers more friendly to beginning users, we introduce `MultiPassReader`. +The Program configuration mentioned above is complicated. Users need to be very familiar to concepts of Program and Block to prevent making mistakes in their code. To make the usage of C++ readers more friendly to new users, we introduce `MultiPassReader`. -`MultiPassReader` is a decorated reader. A multi-pass reader is used to continuously yield data for several pass training. It takes the number of passes to run as one of its attributes('pass_num') and maintains a counter to record how many passes it has completed. Each time its underlying reader reaches the EOF, the multi-pass reader checks whether it has completed the training of given number of pass. If not, the underlying reader will be re-initialized and starts a new pass automatically. Before completing the whole training, the return of MultiPassReader's `HasNext()` will always be `true`. +`MultiPassReader` is a decorated reader. A multi-pass reader is used to continuously yield data for several training passes. It takes the number of passes to run as one of its attributes('pass_num') and maintains a counter to record how many passes it has completed. Each time its underlying reader reaches the EOF, the multi-pass reader checks whether it has completed the training of given number of pass. If not, the underlying reader will be re-initialized and starts a new pass automatically. Before completing the whole training, the return of MultiPassReader's `HasNext()` will always be `true`. With `MultiPassReader`, the startup program would be like this: From 8425c2c859b22f263e213d4fed454890b598948c Mon Sep 17 00:00:00 2001 From: dzhwinter Date: Thu, 29 Mar 2018 16:34:33 +0800 Subject: [PATCH 27/27] Speed/sequence op1 (#9217) * "add functors" * "remove old code" * "fix" * "fix ci" * "add details" * "fix ci" * "fix ci" * "fix ci" * "fix ci" * "remove unused code" --- .../fluid/operators/math/sequence_pooling.cc | 112 ++++- .../fluid/operators/math/sequence_pooling.cu | 381 ++++++++++++++---- .../fluid/operators/math/sequence_pooling.h | 20 +- paddle/fluid/operators/sequence_pool_op.h | 102 +---- .../fluid/tests/unittests/test_seq_pool.py | 110 ++--- 5 files changed, 484 insertions(+), 241 deletions(-) diff --git a/paddle/fluid/operators/math/sequence_pooling.cc b/paddle/fluid/operators/math/sequence_pooling.cc index f7a6f2bdf4..5ae42ab973 100644 --- a/paddle/fluid/operators/math/sequence_pooling.cc +++ b/paddle/fluid/operators/math/sequence_pooling.cc @@ -19,8 +19,17 @@ namespace paddle { namespace operators { namespace math { +using Tensor = framework::Tensor; +using LoDTensor = framework::LoDTensor; +template +using EigenVector = framework::EigenVector; +template +using EigenMatrix = framework::EigenMatrix; + template -class MaxSeqPoolFunctor { +class MaxSeqPoolFunctor { public: void operator()(const platform::CPUDeviceContext& context, const framework::LoDTensor& input, framework::Tensor* output, @@ -60,7 +69,7 @@ class MaxSeqPoolFunctor { }; template -class MaxSeqPoolGradFunctor { +class MaxSeqPoolGradFunctor { public: void operator()(const platform::CPUDeviceContext& context, const framework::Tensor& out_grad, @@ -93,10 +102,101 @@ class MaxSeqPoolGradFunctor { } }; -template class MaxSeqPoolFunctor; -template class MaxSeqPoolFunctor; -template class MaxSeqPoolGradFunctor; -template class MaxSeqPoolGradFunctor; +template +class SequencePoolFunctor { + public: + /* max pool has index output */ + void operator()(const platform::CPUDeviceContext& context, + const std::string pooltype, const framework::LoDTensor& input, + framework::Tensor* output, + framework::Tensor* index = nullptr) { + if (pooltype == "MAX") { + math::MaxSeqPoolFunctor max_pool; + max_pool(context, input, output, index); + return; + } + auto lod = input.lod()[0]; + auto& place = *context.eigen_device(); + for (int i = 0; i < static_cast(lod.size()) - 1; ++i) { + Tensor in_t = + input.Slice(static_cast(lod[i]), static_cast(lod[i + 1])); + Tensor out_t = output->Slice(i, i + 1); + int64_t h = static_cast(lod[i + 1] - lod[i]); + int64_t w = input.numel() / input.dims()[0]; + auto in_e = EigenMatrix::From(in_t, framework::make_ddim({h, w})); + auto out_e = EigenVector::Flatten(out_t); + if (pooltype == "AVERAGE") { + out_e.device(place) = in_e.mean(Eigen::array({{0}})); + } else if (pooltype == "SUM") { + out_e.device(place) = in_e.sum(Eigen::array({{0}})); + } else if (pooltype == "SQRT") { + out_e.device(place) = in_e.sum(Eigen::array({{0}})) / + std::sqrt(static_cast(h)); + } else if (pooltype == "LAST") { + out_e.device(place) = in_e.chip(h - 1, 0); + } else if (pooltype == "FIRST") { + out_e.device(place) = in_e.chip(0, 0); + } else { + PADDLE_THROW("unsupported pooling pooltype"); + } + } + } +}; + +template +class SequencePoolGradFunctor { + public: + void operator()(const platform::CPUDeviceContext& context, + const std::string pooltype, const framework::Tensor& out_grad, + framework::LoDTensor* in_grad, + /* max pool has index */ + const framework::Tensor* index = nullptr) { + if (pooltype == "MAX") { + math::MaxSeqPoolGradFunctor max_pool_grad; + max_pool_grad(context, out_grad, *index, in_grad); + return; + } + + if (pooltype == "LAST" || pooltype == "FIRST") { + // set X@Grad be zero at first when pooltype is LAST/FIRST + math::SetConstant functor; + functor(context, in_grad, 0); + } + auto lod = in_grad->lod()[0]; + auto& place = *context.eigen_device(); + for (int i = 0; i < static_cast(lod.size()) - 1; ++i) { + auto in_g_t = in_grad->Slice(static_cast(lod[i]), + static_cast(lod[i + 1])); + auto out_g_t = out_grad.Slice(i, i + 1); + int64_t h = static_cast(lod[i + 1] - lod[i]); + int64_t w = in_grad->numel() / in_grad->dims()[0]; + auto in_g_e = EigenMatrix::From(in_g_t, {h, w}); + auto out_g_e = EigenMatrix::From(out_g_t, {1, w}); + auto out_g_e_v = EigenVector::Flatten(out_g_t); + Eigen::DSizes bcast(h, 1); + + if (pooltype == "AVERAGE") { + in_g_e.device(place) = (out_g_e / static_cast(h)).broadcast(bcast); + } else if (pooltype == "SUM") { + in_g_e.device(place) = (out_g_e).broadcast(bcast); + } else if (pooltype == "SQRT") { + in_g_e.device(place) = + (out_g_e / std::sqrt(static_cast(h))).broadcast(bcast); + } else if (pooltype == "LAST") { + in_g_e.chip(h - 1, 0).device(place) = out_g_e_v; + } else if (pooltype == "FIRST") { + in_g_e.chip(0, 0).device(place) = out_g_e_v; + } else { + PADDLE_THROW("unsupported pooling pooltype"); + } + } + } +}; + +template class SequencePoolFunctor; +template class SequencePoolFunctor; +template class SequencePoolGradFunctor; +template class SequencePoolGradFunctor; } // namespace math } // namespace operators diff --git a/paddle/fluid/operators/math/sequence_pooling.cu b/paddle/fluid/operators/math/sequence_pooling.cu index d61407c020..1935364da3 100644 --- a/paddle/fluid/operators/math/sequence_pooling.cu +++ b/paddle/fluid/operators/math/sequence_pooling.cu @@ -14,6 +14,7 @@ limitations under the License. */ #include "paddle/fluid/operators/math/math_function.h" #include "paddle/fluid/operators/math/sequence_pooling.h" +#include "paddle/fluid/platform/cuda_helper.h" namespace paddle { namespace operators { @@ -22,113 +23,331 @@ namespace math { #define FLT_MAX __FLT_MAX__ template -__global__ void KeMaxSequencePool(const T* input, const size_t* starts, - T* output, int* index, int64_t num_seq, - int64_t dim) { - int dim_idx = threadIdx.x; - int seq_id = blockIdx.x; - if (seq_id >= num_seq) return; - size_t start = starts[seq_id]; - size_t end = starts[seq_id + 1]; - - for (int64_t i = dim_idx; i < dim; i += blockDim.x) { - T max_val = static_cast(-FLT_MAX); - int max_id = -1; - for (size_t step_id = start; step_id < end; step_id++) { - if (max_val < input[step_id * dim + i]) { - max_val = input[step_id * dim + i]; - max_id = step_id; +struct MaxPoolFunctor { + HOSTDEVICE void operator()(const T* input, const size_t start, + const size_t end, const size_t item_dim, T* output, + int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + T max_val = static_cast(-FLT_MAX); + int max_index = -1; + for (int i = start; i < end; ++i) { + if (max_val < input[item_dim * i + tid]) { + max_val = input[item_dim * i + tid]; + max_index = i; + } } + output[tid] = max_val; + index[tid] = max_index; } - output[seq_id * dim + i] = max_val; - index[seq_id * dim + i] = max_id; } -} +}; template -class MaxSeqPoolFunctor { - public: - void operator()(const platform::CUDADeviceContext& context, - const framework::LoDTensor& input, framework::Tensor* output, - framework::Tensor* index) { - auto in_dims = input.dims(); - auto out_dims = output->dims(); - auto idx_dims = index->dims(); - PADDLE_ENFORCE_GT(in_dims.size(), static_cast(1)); - PADDLE_ENFORCE_GT(out_dims.size(), 1); - for (int64_t i = 1; i < in_dims.size(); ++i) { - PADDLE_ENFORCE_EQ(in_dims[i], out_dims[i]); +struct AvgPoolFunctor { + HOSTDEVICE void operator()(const T* input, const size_t start, + const size_t end, const size_t item_dim, T* output, + int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + T val = static_cast(0); + for (int i = start; i < end; ++i) { + val += input[item_dim * i + tid]; + } + // end, start is lod, so end - start != 0 + output[tid] = val / static_cast(end - start); } - PADDLE_ENFORCE_EQ(idx_dims, out_dims); + } +}; - auto starts = input.lod()[0]; - const T* in_data = input.data(); - T* out_data = output->data(); - int* max_index = index->data(); +template +struct SumPoolFunctor { + HOSTDEVICE void operator()(const T* input, const size_t start, + const size_t end, const size_t item_dim, T* output, + int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + T val = static_cast(0); + for (int i = start; i < end; ++i) { + val += input[item_dim * i + tid]; + } + output[tid] = val; + } + } +}; - int64_t num_seq = out_dims[0]; - int64_t dim = output->numel() / num_seq; +template +struct SqrtPoolFunctor { + HOSTDEVICE void operator()(const T* input, const size_t start, + const size_t end, const size_t item_dim, T* output, + int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + T val = static_cast(0); + for (int i = start; i < end; ++i) { + val += input[item_dim * i + tid]; + } + // end, start is lod, so end - start != 0 + output[tid] = val / sqrt(end - start); + } + } +}; - dim3 threads(256, 1); - dim3 grid(num_seq, 1); - auto stream = context.stream(); - KeMaxSequencePool<<>>( - in_data, starts.CUDAData(context.GetPlace()), out_data, max_index, - num_seq, dim); +template +struct LastPoolFunctor { + HOSTDEVICE void operator()(const T* input, const size_t start, + const size_t end, const size_t item_dim, T* output, + int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + output[tid] = input[item_dim * (end - 1) + tid]; + } } }; template -__global__ void KeMaxSequencePoolGrad(const T* out_grad, const int* max_index, - T* in_grad, int64_t num_seq, - int64_t dim) { - int idx = threadIdx.x + blockIdx.x * blockDim.x; - int col_idx = idx % dim; - if (idx < num_seq * dim) { - int step_id = max_index[idx]; - in_grad[step_id * dim + col_idx] = out_grad[idx]; +struct FirstPoolFunctor { + HOSTDEVICE void operator()(const T* input, const size_t start, + const size_t end, const size_t item_dim, T* output, + int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + output[tid] = input[item_dim * start + tid]; + } } +}; + +template +__global__ void sequence_pool_kernel(Range_OP op, const T* input, + const size_t* lod, const size_t lod_size, + const size_t item_dim, T* output, + int* index) { + int bid = blockIdx.x; + if (bid >= lod_size - 1) return; + size_t start = lod[bid]; + size_t end = lod[bid + 1]; + int* index_offset = nullptr; + if (index != nullptr) { + index_offset = &index[bid * item_dim]; + } + op(input, start, end, item_dim, &output[bid * item_dim], index_offset); } template -class MaxSeqPoolGradFunctor { +class SequencePoolFunctor { public: void operator()(const platform::CUDADeviceContext& context, - const framework::Tensor& out_grad, - const framework::Tensor& index, - framework::LoDTensor* in_grad) { - auto og_dims = out_grad.dims(); - auto idx_dims = index.dims(); - auto ig_dims = in_grad->dims(); - PADDLE_ENFORCE_GT(og_dims.size(), static_cast(1)); - PADDLE_ENFORCE_GT(ig_dims.size(), static_cast(1)); - for (int64_t i = 1; i < og_dims.size(); ++i) { - PADDLE_ENFORCE_EQ(og_dims[i], ig_dims[i]); + const std::string pooltype, const framework::LoDTensor& input, + framework::Tensor* output, + framework::Tensor* index = nullptr) { + auto lod = input.lod()[0]; + const size_t item_dim = output->numel() / output->dims()[0]; + dim3 threads(1024, 1); + dim3 grid(lod.size(), 1); + if (pooltype == "MAX") { + sequence_pool_kernel< + T, MaxPoolFunctor><<>>( + MaxPoolFunctor(), input.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + output->mutable_data(context.GetPlace()), index->data()); + } else if (pooltype == "AVERAGE") { + sequence_pool_kernel< + T, AvgPoolFunctor><<>>( + AvgPoolFunctor(), input.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + output->mutable_data(context.GetPlace()), nullptr); + } else if (pooltype == "SUM") { + sequence_pool_kernel< + T, SumPoolFunctor><<>>( + SumPoolFunctor(), input.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + output->mutable_data(context.GetPlace()), nullptr); + } else if (pooltype == "SQRT") { + sequence_pool_kernel< + T, SqrtPoolFunctor><<>>( + SqrtPoolFunctor(), input.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + output->mutable_data(context.GetPlace()), nullptr); + } else if (pooltype == "LAST") { + sequence_pool_kernel< + T, LastPoolFunctor><<>>( + LastPoolFunctor(), input.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + output->mutable_data(context.GetPlace()), nullptr); + } else if (pooltype == "FIRST") { + sequence_pool_kernel< + T, FirstPoolFunctor><<>>( + FirstPoolFunctor(), input.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + output->mutable_data(context.GetPlace()), nullptr); + } else { + PADDLE_THROW("unsupported pooling pooltype"); } - PADDLE_ENFORCE_EQ(idx_dims, og_dims); + } +}; - const T* og_data = out_grad.data(); - const int* max_index = index.data(); - T* ig_data = in_grad->data(); +template +struct MaxPoolGradFunctor { + HOSTDEVICE void operator()(const T* out_grad, const size_t start, + const size_t end, const size_t item_dim, + T* in_grad, const int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + for (int i = start; i < end; ++i) { + if (i == index[tid]) { + in_grad[item_dim * i + tid] = out_grad[tid]; + } else { + in_grad[item_dim * i + tid] = static_cast(0); + } + } + } + } +}; - SetConstant set_zero; - set_zero(context, in_grad, static_cast(0.0)); - int64_t num_seq = og_dims[0]; - int64_t dim = out_grad.numel() / num_seq; +template +struct AvgPoolGradFunctor { + HOSTDEVICE void operator()(const T* out_grad, const size_t start, + const size_t end, const size_t item_dim, + T* in_grad, const int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + for (int i = start; i < end; ++i) { + in_grad[item_dim * i + tid] = out_grad[tid] / (end - start); + } + } + } +}; - unsigned int blocks = (num_seq * dim + 128 - 1) / 128; - dim3 threads(128, 1); - dim3 grid(blocks, 1); - auto stream = context.stream(); - KeMaxSequencePoolGrad<<>>( - og_data, max_index, ig_data, num_seq, dim); +template +struct SumPoolGradFunctor { + HOSTDEVICE void operator()(const T* out_grad, const size_t start, + const size_t end, const size_t item_dim, + T* in_grad, const int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + for (int i = start; i < end; ++i) { + in_grad[item_dim * i + tid] = out_grad[tid]; + } + } + } +}; + +template +struct SqrtPoolGradFunctor { + HOSTDEVICE void operator()(const T* out_grad, const size_t start, + const size_t end, const size_t item_dim, + T* in_grad, const int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + for (int i = start; i < end; ++i) { + in_grad[item_dim * i + tid] = + out_grad[tid] / (sqrt(static_cast(end - start))); + } + } + } +}; + +template +struct LastPoolGradFunctor { + HOSTDEVICE void operator()(const T* out_grad, const size_t start, + const size_t end, const size_t item_dim, + T* in_grad, const int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + for (int i = start; i < end; ++i) { + if (i == end - 1) { + in_grad[item_dim * i + tid] = out_grad[tid]; + } else { + in_grad[item_dim * i + tid] = static_cast(0); + } + } + } + } +}; + +template +struct FirstPoolGradFunctor { + HOSTDEVICE void operator()(const T* out_grad, const size_t start, + const size_t end, const size_t item_dim, + T* in_grad, const int* index) { + for (int tid = threadIdx.x; tid < item_dim; tid += blockDim.x) { + for (int i = start; i < end; ++i) { + if (i == start) { + in_grad[item_dim * i + tid] = out_grad[tid]; + } else { + in_grad[item_dim * i + tid] = static_cast(0); + } + } + } + } +}; + +template +__global__ void sequence_pool_grad_kernel(Range_OP op, const T* out_grad, + const size_t* lod, + const size_t lod_size, + const size_t item_dim, T* in_grad, + const int* index) { + int bid = blockIdx.x; + if (bid >= lod_size - 1) return; + size_t start = lod[bid]; + size_t end = lod[bid + 1]; + const int* index_offset = nullptr; + if (index != nullptr) { + index_offset = &index[bid * item_dim]; + } + op(&out_grad[bid * item_dim], start, end, item_dim, in_grad, index_offset); +} + +template +class SequencePoolGradFunctor { + public: + void operator()(const platform::CUDADeviceContext& context, + const std::string pooltype, const framework::Tensor& out_grad, + framework::LoDTensor* in_grad, + /* max pool has index */ + const framework::Tensor* index = nullptr) { + auto lod = in_grad->lod()[0]; + const size_t item_dim = in_grad->numel() / in_grad->dims()[0]; + dim3 threads(1024, 1); + dim3 grid(lod.size(), 1); + if (pooltype == "MAX") { + sequence_pool_grad_kernel< + T, MaxPoolGradFunctor><<>>( + MaxPoolGradFunctor(), out_grad.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + in_grad->mutable_data(context.GetPlace()), index->data()); + } else if (pooltype == "AVERAGE") { + sequence_pool_grad_kernel< + T, AvgPoolGradFunctor><<>>( + AvgPoolGradFunctor(), out_grad.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + in_grad->mutable_data(context.GetPlace()), nullptr); + } else if (pooltype == "SUM") { + sequence_pool_grad_kernel< + T, SumPoolGradFunctor><<>>( + SumPoolGradFunctor(), out_grad.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + in_grad->mutable_data(context.GetPlace()), nullptr); + } else if (pooltype == "SQRT") { + sequence_pool_grad_kernel< + T, SqrtPoolGradFunctor><<>>( + SqrtPoolGradFunctor(), out_grad.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + in_grad->mutable_data(context.GetPlace()), nullptr); + } else if (pooltype == "LAST") { + sequence_pool_grad_kernel< + T, LastPoolGradFunctor><<>>( + LastPoolGradFunctor(), out_grad.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + in_grad->mutable_data(context.GetPlace()), nullptr); + } else if (pooltype == "FIRST") { + sequence_pool_grad_kernel< + T, FirstPoolGradFunctor><<>>( + FirstPoolGradFunctor(), out_grad.data(), + lod.CUDAData(context.GetPlace()), lod.size(), item_dim, + in_grad->mutable_data(context.GetPlace()), nullptr); + + } else { + PADDLE_THROW("unsupported pooling pooltype"); + } } }; -template class MaxSeqPoolFunctor; -template class MaxSeqPoolFunctor; -template class MaxSeqPoolGradFunctor; -template class MaxSeqPoolGradFunctor; +// sequence pooling +template class SequencePoolFunctor; +template class SequencePoolFunctor; +template class SequencePoolGradFunctor; +template class SequencePoolGradFunctor; } // namespace math } // namespace operators diff --git a/paddle/fluid/operators/math/sequence_pooling.h b/paddle/fluid/operators/math/sequence_pooling.h index ecb76884f6..38e7802229 100644 --- a/paddle/fluid/operators/math/sequence_pooling.h +++ b/paddle/fluid/operators/math/sequence_pooling.h @@ -21,23 +21,23 @@ namespace paddle { namespace operators { namespace math { -#define FLT_MAX __FLT_MAX__ - template -class MaxSeqPoolFunctor { +class SequencePoolFunctor { public: - void operator()(const DeviceContext& context, + /* max pool has index output */ + void operator()(const DeviceContext& context, const std::string pooltype, const framework::LoDTensor& input, framework::Tensor* output, - framework::Tensor* index); + framework::Tensor* index = nullptr); }; -template -class MaxSeqPoolGradFunctor { +template +class SequencePoolGradFunctor { public: - void operator()(const DeviceContext& context, + void operator()(const DeviceContext& context, const std::string pooltype, const framework::Tensor& out_grad, - const framework::Tensor& index, - framework::LoDTensor* in_grad); + framework::LoDTensor* in_grad, + /* max pool has index */ + const framework::Tensor* index = nullptr); }; } // namespace math diff --git a/paddle/fluid/operators/sequence_pool_op.h b/paddle/fluid/operators/sequence_pool_op.h index 8706ff14aa..c58d677c92 100644 --- a/paddle/fluid/operators/sequence_pool_op.h +++ b/paddle/fluid/operators/sequence_pool_op.h @@ -23,12 +23,6 @@ namespace operators { using Tensor = framework::Tensor; using LoDTensor = framework::LoDTensor; -template -using EigenVector = framework::EigenVector; -template -using EigenMatrix = framework::EigenMatrix; template class SequencePoolKernel : public framework::OpKernel { @@ -37,11 +31,13 @@ class SequencePoolKernel : public framework::OpKernel { auto* in = context.Input("X"); auto* out = context.Output("Out"); std::string pooltype = context.Attr("pooltype"); + Tensor* index = nullptr; + if (pooltype == "MAX") { + index = context.Output("MaxIndex"); + } auto dims = in->dims(); auto lod = in->lod(); - int64_t w = in->numel() / dims[0]; - // InferShape by lod PADDLE_ENFORCE_EQ(lod.size(), 1UL, "Only support one level sequence now."); PADDLE_ENFORCE_GE( @@ -50,45 +46,14 @@ class SequencePoolKernel : public framework::OpKernel { "The first dimension of Input(X) must be large than batch size."); dims[0] = lod[0].size() - 1; out->Resize({dims}); - - auto lod_level_0 = lod[0]; - out->mutable_data(context.GetPlace()); - auto& dev_ctx = context.template device_context(); if (pooltype == "MAX") { - math::MaxSeqPoolFunctor max_pool; - auto* index = context.Output("MaxIndex"); index->Resize({dims}); index->mutable_data(context.GetPlace()); - max_pool(dev_ctx, *in, out, index); - return; - } - - auto& place = - *context.template device_context().eigen_device(); - for (int i = 0; i < static_cast(lod_level_0.size()) - 1; ++i) { - Tensor in_t = in->Slice(static_cast(lod_level_0[i]), - static_cast(lod_level_0[i + 1])); - Tensor out_t = out->Slice(i, i + 1); - int64_t h = static_cast(lod_level_0[i + 1] - lod_level_0[i]); - auto in_e = EigenMatrix::From(in_t, framework::make_ddim({h, w})); - auto out_e = EigenVector::Flatten(out_t); - - if (pooltype == "AVERAGE") { - out_e.device(place) = in_e.mean(Eigen::array({{0}})); - } else if (pooltype == "SUM") { - out_e.device(place) = in_e.sum(Eigen::array({{0}})); - } else if (pooltype == "SQRT") { - out_e.device(place) = in_e.sum(Eigen::array({{0}})) / - std::sqrt(static_cast(h)); - } else if (pooltype == "LAST") { - out_e.device(place) = in_e.chip(h - 1, 0); - } else if (pooltype == "FIRST") { - out_e.device(place) = in_e.chip(0, 0); - } else { - PADDLE_THROW("unsupported pooling pooltype"); - } } + math::SequencePoolFunctor pool; + pool(context.template device_context(), pooltype, *in, out, + index); } }; @@ -96,58 +61,17 @@ template class SequencePoolGradKernel : public framework::OpKernel { public: void Compute(const framework::ExecutionContext& context) const override { - auto* in = context.Input("X"); auto* out_g = context.Input(framework::GradVarName("Out")); auto* in_g = context.Output(framework::GradVarName("X")); std::string pooltype = context.Attr("pooltype"); - - auto dims = in->dims(); - auto lod = in->lod()[0]; - int64_t w = in->numel() / dims[0]; - - in_g->mutable_data(context.GetPlace()); - auto& dev_ctx = context.template device_context(); - + const Tensor* index = nullptr; if (pooltype == "MAX") { - math::MaxSeqPoolGradFunctor max_pool_grad; - auto* index = context.Input("MaxIndex"); - max_pool_grad(dev_ctx, *out_g, *index, in_g); - return; - } - - if (pooltype == "LAST" || pooltype == "FIRST") { - // set X@Grad be zero at first when pooltype is LAST/FIRST - math::SetConstant functor; - functor(dev_ctx, in_g, 0); - } - auto& place = - *context.template device_context().eigen_device(); - - for (int i = 0; i < static_cast(lod.size()) - 1; ++i) { - auto in_g_t = - in_g->Slice(static_cast(lod[i]), static_cast(lod[i + 1])); - auto out_g_t = out_g->Slice(i, i + 1); - int64_t h = static_cast(lod[i + 1] - lod[i]); - auto in_g_e = EigenMatrix::From(in_g_t, {h, w}); - auto out_g_e = EigenMatrix::From(out_g_t, {1, w}); - auto out_g_e_v = EigenVector::Flatten(out_g_t); - Eigen::DSizes bcast(h, 1); - - if (pooltype == "AVERAGE") { - in_g_e.device(place) = (out_g_e / static_cast(h)).broadcast(bcast); - } else if (pooltype == "SUM") { - in_g_e.device(place) = (out_g_e).broadcast(bcast); - } else if (pooltype == "SQRT") { - in_g_e.device(place) = - (out_g_e / std::sqrt(static_cast(h))).broadcast(bcast); - } else if (pooltype == "LAST") { - in_g_e.chip(h - 1, 0).device(place) = out_g_e_v; - } else if (pooltype == "FIRST") { - in_g_e.chip(0, 0).device(place) = out_g_e_v; - } else { - PADDLE_THROW("unsupported pooling pooltype"); - } + index = context.Input("MaxIndex"); } + in_g->mutable_data(context.GetPlace()); + math::SequencePoolGradFunctor pool; + pool(context.template device_context(), pooltype, *out_g, + in_g, index); } }; diff --git a/python/paddle/fluid/tests/unittests/test_seq_pool.py b/python/paddle/fluid/tests/unittests/test_seq_pool.py index 0488475721..2e48ef0e88 100644 --- a/python/paddle/fluid/tests/unittests/test_seq_pool.py +++ b/python/paddle/fluid/tests/unittests/test_seq_pool.py @@ -49,6 +49,61 @@ class TestSeqAvgPool(OpTest): self.check_grad(["X"], "Out") +class TestSeqSumPool(TestSeqAvgPool): + def compute(self, x, lod, out): + self.attrs = {'pooltype': "SUM"} + for i in range(4): + sub_x = x[lod[0][i]:lod[0][i + 1], :] + out[i] = sub_x.sum(axis=0) + + +class TestSeqMaxPool(TestSeqAvgPool): + def set_data(self): + self.op_type = 'sequence_pool' + x = np.random.uniform(0.1, 1, [13, 23]).astype('float32') + lod = [[0, 4, 5, 8, 13]] + for i in range(4): + l = lod[0][i + 1] - lod[0][i] + x[lod[0][i] + np.random.randint(l), :] += 2.0 + + self.inputs = {'X': (x, lod)} + + out = np.zeros((4, 23)).astype('float32') + self.outputs = {'Out': out} + return x, lod, out + + def compute(self, x, lod, out): + self.attrs = {'pooltype': "MAX"} + for i in range(4): + sub_x = x[lod[0][i]:lod[0][i + 1], :] + out[i] = np.amax(sub_x, axis=0) + + +class TestSeqSqrtPool(TestSeqAvgPool): + def compute(self, x, lod, out): + self.attrs = {'pooltype': "SQRT"} + for i in range(4): + sub_x = x[lod[0][i]:lod[0][i + 1], :] + len = lod[0][i + 1] - lod[0][i] + out[i] = sub_x.sum(axis=0) / np.sqrt(len) + + +class TestSeqLastPool(TestSeqAvgPool): + def compute(self, x, lod, out): + self.attrs = {'pooltype': "LAST"} + for i in range(4): + sub_x = x[lod[0][i]:lod[0][i + 1], :] + out[i] = sub_x[-1, :] + + +class TestSeqFirstPool(TestSeqAvgPool): + def compute(self, x, lod, out): + self.attrs = {'pooltype': "FIRST"} + for i in range(4): + sub_x = x[lod[0][i]:lod[0][i + 1], :] + out[i] = sub_x[0, :] + + class TestSeqAvgPool2D(TestSeqAvgPool): def set_data(self): self.op_type = 'sequence_pool' @@ -68,14 +123,6 @@ class TestSeqAvgPool2D(TestSeqAvgPool): out[i] = np.reshape(sub_x.mean(axis=0), (3, 17)) -class TestSeqSumPool(TestSeqAvgPool): - def compute(self, x, lod, out): - self.attrs = {'pooltype': "SUM"} - for i in range(4): - sub_x = x[lod[0][i]:lod[0][i + 1], :] - out[i] = sub_x.sum(axis=0) - - class TestSeqSumPool2D(TestSeqAvgPool2D): def compute(self, x, lod, out): self.attrs = {'pooltype': "SUM"} @@ -84,15 +131,6 @@ class TestSeqSumPool2D(TestSeqAvgPool2D): out[i] = np.reshape(sub_x.sum(axis=0), (3, 17)) -class TestSeqSqrtPool(TestSeqAvgPool): - def compute(self, x, lod, out): - self.attrs = {'pooltype': "SQRT"} - for i in range(4): - sub_x = x[lod[0][i]:lod[0][i + 1], :] - len = lod[0][i + 1] - lod[0][i] - out[i] = sub_x.sum(axis=0) / np.sqrt(len) - - class TestSeqSqrtPool2D(TestSeqAvgPool2D): def compute(self, x, lod, out): self.attrs = {'pooltype': "SQRT"} @@ -108,28 +146,6 @@ class TestSeqSqrtPool2D(TestSeqAvgPool2D): self.check_grad(["X"], "Out", max_relative_error=0.06) -class TestSeqMaxPool(TestSeqAvgPool): - def set_data(self): - self.op_type = 'sequence_pool' - x = np.random.uniform(0.1, 1, [13, 23]).astype('float32') - lod = [[0, 4, 5, 8, 13]] - for i in range(4): - l = lod[0][i + 1] - lod[0][i] - x[lod[0][i] + np.random.randint(l), :] += 2.0 - - self.inputs = {'X': (x, lod)} - - out = np.zeros((4, 23)).astype('float32') - self.outputs = {'Out': out} - return x, lod, out - - def compute(self, x, lod, out): - self.attrs = {'pooltype': "MAX"} - for i in range(4): - sub_x = x[lod[0][i]:lod[0][i + 1], :] - out[i] = np.amax(sub_x, axis=0) - - class TestSeqMaxPool2D(TestSeqAvgPool2D): def set_data(self): self.op_type = 'sequence_pool' @@ -151,14 +167,6 @@ class TestSeqMaxPool2D(TestSeqAvgPool2D): out[i] = np.reshape(np.amax(sub_x, axis=0), (3, 11)) -class TestSeqLastPool(TestSeqAvgPool): - def compute(self, x, lod, out): - self.attrs = {'pooltype': "LAST"} - for i in range(4): - sub_x = x[lod[0][i]:lod[0][i + 1], :] - out[i] = sub_x[-1, :] - - class TestSeqLastPool2D(TestSeqAvgPool2D): def compute(self, x, lod, out): self.attrs = {'pooltype': "LAST"} @@ -167,14 +175,6 @@ class TestSeqLastPool2D(TestSeqAvgPool2D): out[i] = np.reshape(sub_x[-1, :], (3, 17)) -class TestSeqFirstPool(TestSeqAvgPool): - def compute(self, x, lod, out): - self.attrs = {'pooltype': "FIRST"} - for i in range(4): - sub_x = x[lod[0][i]:lod[0][i + 1], :] - out[i] = sub_x[0, :] - - class TestSeqFirstPool2D(TestSeqAvgPool2D): def compute(self, x, lod, out): self.attrs = {'pooltype': "FIRST"}