diff --git a/src/common/log.h b/src/common/log.h index c5146533d16273e223cc123c132bd137410f48ac..d574818f865ab6b2af748a5b3162b589f396a564 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -85,18 +85,18 @@ struct Print { private: void print(LogLevel level) { - buffer_ << std::endl; + // buffer_ << std::endl; if (level == kLOG_ERROR) { - std::cerr << buffer_.str(); + std::cerr << buffer_.str() << std::endl; } else { - std::cout << buffer_.str(); + std::cout << buffer_.str() << std::endl; } } std::ostringstream buffer_; }; struct ToLog { - ToLog(LogLevel level = kLOG_DEBUG, const std::string &info = "") + explicit ToLog(LogLevel level = kLOG_DEBUG, const std::string &info = "") : level_(level) { unsigned blanks = (unsigned)(level > kLOG_DEBUG ? (level - kLOG_DEBUG) * 4 : 1); diff --git a/src/common/types.cpp b/src/common/types.cpp index 18d7330a81c65338f3442b8fdf80545198187db6..7edfde6f857daad252fc8ef6174417e4f639d093 100644 --- a/src/common/types.cpp +++ b/src/common/types.cpp @@ -81,6 +81,8 @@ const char *G_OP_TYPE_LOGICAL_AND = "logical_and"; const char *G_OP_TYPE_LOGICAL_OR = "logical_or"; const char *G_OP_TYPE_LOGICAL_NOT = "logical_not"; const char *G_OP_TYPE_LOGICAL_XOR = "logical_xor"; +const char *G_OP_TYPE_WRITE_TO_ARRAY = "write_to_array"; +const char *G_OP_TYPE_READ_FROM_ARRAY = "read_from_array"; const char *G_OP_TYPE_QUANTIZE = "quantize"; const char *G_OP_TYPE_DEQUANTIZE = "dequantize"; @@ -189,5 +191,7 @@ std::unordered_map< {G_OP_TYPE_LOGICAL_AND, {{"X", "Y"}, {"Out"}}}, {G_OP_TYPE_LOGICAL_OR, {{"X", "Y"}, {"Out"}}}, {G_OP_TYPE_LOGICAL_XOR, {{"X", "Y"}, {"Out"}}}, - {G_OP_TYPE_LOGICAL_NOT, {{"X"}, {"Out"}}}}; + {G_OP_TYPE_LOGICAL_NOT, {{"X"}, {"Out"}}}, + {G_OP_TYPE_WRITE_TO_ARRAY, {{"X", "I"}, {"Out"}}}, + {G_OP_TYPE_READ_FROM_ARRAY, {{"X", "I"}, {"Out"}}}}; } // namespace paddle_mobile diff --git a/src/common/types.h b/src/common/types.h index 2927e838fc772a8ccfdcc6212efc09ce8bbbdacd..31d8020d4d3a715683f08f0d27e5463f7865abcc 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -170,6 +170,8 @@ extern const char *G_OP_TYPE_LOGICAL_AND; extern const char *G_OP_TYPE_LOGICAL_OR; extern const char *G_OP_TYPE_LOGICAL_NOT; extern const char *G_OP_TYPE_LOGICAL_XOR; +extern const char *G_OP_TYPE_WRITE_TO_ARRAY; +extern const char *G_OP_TYPE_READ_FROM_ARRAY; extern const char *G_OP_TYPE_QUANTIZE; extern const char *G_OP_TYPE_DEQUANTIZE; diff --git a/src/framework/attribute.h b/src/framework/attribute.h index a21e0a4ec321dbfe08f87160cc2f0c159594920d..3bc9284bfa6873b9c3f97071b2f96677937c4206 100644 --- a/src/framework/attribute.h +++ b/src/framework/attribute.h @@ -90,6 +90,10 @@ class Attribute { attr.Set(attr_desc->l); break; } + case PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BLOCK: { + attr.Set(attr_desc->block_idx); + break; + } default: PADDLE_MOBILE_THROW_EXCEPTION("attr type not support"); } diff --git a/src/framework/executor.cpp b/src/framework/executor.cpp index db48534097118f930759ceda6b6e75cb82dcf930..e5b3fadfed0fffb703f8a18a59d3d5e8f4777fa4 100644 --- a/src/framework/executor.cpp +++ b/src/framework/executor.cpp @@ -65,6 +65,7 @@ Executor::Executor(const Program &program, for (int j = 0; j < ops.size(); ++j) { std::shared_ptr op_desc = ops[j]; DLOG << "create op: " << op_desc->Type(); + auto op_handler = OpRegistry::CreateOp( op_desc->Type(), op_desc->GetInputs(), op_desc->GetOutputs(), op_desc->GetAttrMap(), program_.scope); diff --git a/src/framework/load_ops.h b/src/framework/load_ops.h index fca5fd82a09984ae32f354205e62fda1e3c20423..eadef7d6688291af2b44c686d78ba6b950abbbba 100644 --- a/src/framework/load_ops.h +++ b/src/framework/load_ops.h @@ -297,3 +297,12 @@ LOAD_OP1(logical_not, CPU); #ifdef LOGICAL_XOR_OP LOAD_OP1(logical_xor, CPU); #endif +#ifdef WHILE_OP +LOAD_OP1(while, CPU); +#endif +#ifdef WRITE_TO_ARRAY_OP +LOAD_OP1(write_to_array, CPU); +#endif +#ifdef READ_FROM_ARRAY_OP +LOAD_OP1(read_from_array, CPU); +#endif diff --git a/src/framework/lod_tensor.h b/src/framework/lod_tensor.h index bd956c866844760a69a89755c3202f264c962bc3..8c35a48f5fa2f13aeb2474eaf6e369dab09ee6d7 100644 --- a/src/framework/lod_tensor.h +++ b/src/framework/lod_tensor.h @@ -176,6 +176,8 @@ LoDTensor LodExpand(const LoDTensor &source, const LoD &lod, size_t level) { return tensor; } +using LoDTensorArray = std::vector; + // Get the absolute offset of a lod[start_level][start_idx:end_idx] and // relative length of details for every levels(i.e., [start_level: ]). // diff --git a/src/framework/program/op_desc.cpp b/src/framework/program/op_desc.cpp index c8cbe3b608cc0b7e4e57b318756389bc89a3dec0..318dd643bbc1d34cf1ab9bc97218caddd8c8d528 100644 --- a/src/framework/program/op_desc.cpp +++ b/src/framework/program/op_desc.cpp @@ -41,9 +41,7 @@ OpDesc::OpDesc(PaddleMobile__Framework__Proto__OpDesc *desc) { for (int k = 0; k < desc->n_attrs; ++k) { PaddleMobile__Framework__Proto__OpDesc__Attr *attr = desc->attrs[k]; std::string attr_name(attr->name); - if (attr->type != PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BLOCK) { - attrs_[attr_name] = Attribute::GetAttrValue(attr); - } + attrs_[attr_name] = Attribute::GetAttrValue(attr); } } diff --git a/src/operators/controlflow/tensor_array_read_write_op.cpp b/src/operators/controlflow/tensor_array_read_write_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0ea8ac01c65f974988a4fd42d8902cce6b888dc5 --- /dev/null +++ b/src/operators/controlflow/tensor_array_read_write_op.cpp @@ -0,0 +1,43 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#include "operators/controlflow/tensor_array_read_write_op.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WRITE_TO_ARRAY_OP +template +void WriteToArrayOp::InferShape() const {} +#endif // WRITE_TO_ARRAY_OP + +#ifdef READ_FROM_ARRAY_OP +template +void ReadFromArrayOp::InferShape() const {} +#endif // READ_FROM_ARRAY_OP + +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; + +#ifdef PADDLE_MOBILE_CPU +#ifdef WRITE_TO_ARRAY_OP +REGISTER_OPERATOR_CPU(write_to_array, ops::WriteToArrayOp); +#endif // WRITE_TO_ARRAY_OP + +#ifdef READ_FROM_ARRAY_OP +REGISTER_OPERATOR_CPU(read_from_array, ops::ReadFromArrayOp); +#endif // READ_FROM_ARRAY_OP +#endif diff --git a/src/operators/controlflow/tensor_array_read_write_op.h b/src/operators/controlflow/tensor_array_read_write_op.h new file mode 100644 index 0000000000000000000000000000000000000000..21d3ca10ef58780891f20e60d1f19ae0dcc39a23 --- /dev/null +++ b/src/operators/controlflow/tensor_array_read_write_op.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#pragma once + +#include +#include "framework/operator.h" +#include "operators/kernel/tensor_array_read_write_kernel.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WRITE_TO_ARRAY_OP +DECLARE_OPERATOR(WriteToArray, WriteToArrayParam, WriteToArrayKernel); +#endif // WRITE_TO_ARRAY_OP + +#ifdef READ_FROM_ARRAY_OP +DECLARE_OPERATOR(ReadFromArray, ReadFromArrayParam, ReadFromArrayKernel); +#endif // WRITE_TO_ARRAY_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/controlflow/while_op.cpp b/src/operators/controlflow/while_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..06eb7c570999237310a5d6f9c40f678281385cf8 --- /dev/null +++ b/src/operators/controlflow/while_op.cpp @@ -0,0 +1,36 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#include "operators/controlflow/while_op.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WHILE_OP +template +void WhileOp::InferShape() const { + // TODO(hjchen2) +} +#endif // WHILE_OP + +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; + +#ifdef PADDLE_MOBILE_CPU +#ifdef WHILE_OP +REGISTER_OPERATOR_CPU(while, ops::WhileOp); +#endif // WHILE_OP +#endif diff --git a/src/operators/controlflow/while_op.h b/src/operators/controlflow/while_op.h new file mode 100644 index 0000000000000000000000000000000000000000..6f753a08ef6268120085ef250719a4a9b5a04e8d --- /dev/null +++ b/src/operators/controlflow/while_op.h @@ -0,0 +1,30 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#pragma once + +#include +#include "framework/operator.h" +#include "operators/kernel/while_kernel.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WHILE_OP +DECLARE_OPERATOR(While, WhileParam, WhileKernel); +#endif // WHILE_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/kernel/arm/tensor_array_read_write_kernel.cpp b/src/operators/kernel/arm/tensor_array_read_write_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d6b86c34c963808e72a05db08940db97b0212b9 --- /dev/null +++ b/src/operators/kernel/arm/tensor_array_read_write_kernel.cpp @@ -0,0 +1,58 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#include "operators/kernel/tensor_array_read_write_kernel.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WRITE_TO_ARRAY_OP +template <> +bool WriteToArrayKernel::Init(WriteToArrayParam *param) { + return true; +} + +template <> +void WriteToArrayKernel::Compute( + const WriteToArrayParam ¶m) { + int64_t offset = param.index_->data()[0]; + if (offset >= param.output_->size()) { + param.output_->resize(offset); + } + framework::LoDTensor *out_tensor = &(param.output_->at(offset)); + out_tensor->set_lod(param.input_->lod()); + if (param.input_->memory_size() > 0) { + TensorCopy(*(param.input_), out_tensor); + } +} +#endif // WRITE_TO_ARRAY_OP + +#ifdef READ_FROM_ARRAY_OP +template <> +bool ReadFromArrayKernel::Init(ReadFromArrayParam *param) { + return true; +} + +template <> +void ReadFromArrayKernel::Compute( + const ReadFromArrayParam ¶m) { + int64_t offset = param.index_->data()[0]; + if (offset < param.input_->size()) { + TensorCopy(param.input_->at(offset), param.output_); + } +} +#endif // READ_FROM_ARRAY_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/kernel/arm/while_kernel.cpp b/src/operators/kernel/arm/while_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f27a897ffcadbb1ade759f324766ccbfb8dd49d5 --- /dev/null +++ b/src/operators/kernel/arm/while_kernel.cpp @@ -0,0 +1,33 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#include "operators/kernel/while_kernel.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WHILE_OP +template <> +bool WhileKernel::Init(WhileParam *param) { + return true; +} + +template <> +void WhileKernel::Compute(const WhileParam ¶m) { + // TODO(hjchen2) +} +#endif // WHILE_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/kernel/tensor_array_read_write_kernel.h b/src/operators/kernel/tensor_array_read_write_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..8b666c0b40e79bde9c2f101e69f4e5b58aa32d45 --- /dev/null +++ b/src/operators/kernel/tensor_array_read_write_kernel.h @@ -0,0 +1,32 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#pragma once + +#include "framework/operator.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WRITE_TO_ARRAY_OP +DECLARE_KERNEL(WriteToArray, WriteToArrayParam); +#endif // WRITE_TO_ARRAY_OP + +#ifdef READ_FROM_ARRAY_OP +DECLARE_KERNEL(ReadFromArray, ReadFromArrayParam); +#endif // READ_FROM_ARRAY_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/kernel/while_kernel.h b/src/operators/kernel/while_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..72b0f5f7388f10551d91491b605d57de2fd7271e --- /dev/null +++ b/src/operators/kernel/while_kernel.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#pragma once + +#include "framework/operator.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WHILE_OP +template +class WhileParam : public OpParam { + public: + WhileParam(const VariableNameMap &inputs, const VariableNameMap &outputs, + const AttributeMap &attrs, const Scope &scope) + : inputs_(inputs), outputs_(outputs), scope_(scope) { + cond_ = + OpParam::GetVarValue("Condition", inputs, scope); + sub_block_ = OpParam::GetAttr("sub_block", attrs); + } + + public: + framework::LoDTensor *cond_; + int sub_block_; + const VariableNameMap inputs_; + const VariableNameMap outputs_; + const Scope scope_; +}; + +DECLARE_KERNEL(While, WhileParam); +#endif // WHILE_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/op_param.h b/src/operators/op_param.h index 1f20f5505668e79a8453d9b14ef25478fc7e3af7..959bfd7f743401a453ab0169ca773285e2904d4e 100644 --- a/src/operators/op_param.h +++ b/src/operators/op_param.h @@ -2991,5 +2991,63 @@ class LogicalUnaryParam : public OpParam { }; #endif // LOGICAL_NOT_OP +// #ifdef WHILE_OP +// template +// class WhileParam : public OpParam { +// public: +// WhileParam(const VariableNameMap &inputs, +// const VariableNameMap &outputs, const AttributeMap &attrs, +// const Scope &scope) { +// cond_ = OpParam::GetVarValue("Condition", inputs, +// scope); block_desc_ = OpParam::GetAttr("sub_block", attrs); +// } +// +// public: +// framework::LoDTensor *cond_; +// const framework::BlockDesc *block_desc_; +// }; +// #endif // WHILE_OP + +#ifdef WRITE_TO_ARRAY_OP +template +class WriteToArrayParam : public OpParam { + public: + WriteToArrayParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, const AttributeMap &attrs, + const Scope &scope) { + input_ = OpParam::GetVarValue("X", inputs, scope); + index_ = OpParam::GetVarValue("I", inputs, scope); + output_ = + OpParam::GetVarValue("Out", outputs, scope); + } + + public: + framework::LoDTensor *input_; + framework::LoDTensor *index_; + framework::LoDTensorArray *output_; +}; +#endif + +#ifdef READ_FROM_ARRAY_OP +template +class ReadFromArrayParam : public OpParam { + public: + ReadFromArrayParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, const AttributeMap &attrs, + const Scope &scope) { + input_ = + OpParam::GetVarValue("X", inputs, scope); + index_ = OpParam::GetVarValue("I", inputs, scope); + output_ = OpParam::GetVarValue("Out", outputs, scope); + } + + public: + framework::LoDTensorArray *input_; + framework::LoDTensor *index_; + framework::LoDTensor *output_; +}; +#endif + } // namespace operators } // namespace paddle_mobile diff --git a/src/operators/reshape_op.cpp b/src/operators/reshape_op.cpp old mode 100755 new mode 100644 diff --git a/tools/op.cmake b/tools/op.cmake index cf68f2449113589fe99e2278a7d4ba5b62e19c13..65afb07054e107dfc29d27c7ce547f926b318df0 100644 --- a/tools/op.cmake +++ b/tools/op.cmake @@ -285,6 +285,9 @@ if(NOT FOUND_MATCH) set(LOGICAL_OR_OP ON) set(LOGICAL_NOT_OP ON) set(LOGICAL_XOR_OP ON) + set(WHILE_OP ON) + set(WRITE_TO_ARRAY_OP ON) + set(READ_FROM_ARRAY_OP ON) endif() # option(BATCHNORM_OP "" ON) @@ -559,3 +562,13 @@ endif() if (FUSION_DECONVADDRELU_OP) add_definitions(-DFUSION_DECONVADDRELU_OP) endif() + +if (WHILE_OP) + add_definitions(-DWHILE_OP) +endif() +if (WRITE_TO_ARRAY_OP) + add_definitions(-DWRITE_TO_ARRAY_OP) +endif() +if (READ_FROM_ARRAY_OP) + add_definitions(-DREAD_FROM_ARRAY_OP) +endif()