diff --git a/paddle/framework/attribute.cc b/paddle/framework/attribute.cc index 4c5790693b7e48396e945d09f4fdc72b86aa5978..9eb07acdff1d00dd926f1cee9c24f9f151006d7e 100644 --- a/paddle/framework/attribute.cc +++ b/paddle/framework/attribute.cc @@ -44,7 +44,7 @@ AttrType AttrTypeID>() { return STRINGS; } -Attribute GetAttrValue(const AttrDesc& attr_desc) { +Attribute GetAttrValue(const OpDesc::Attr& attr_desc) { switch (attr_desc.type()) { case paddle::framework::AttrType::INT: { return attr_desc.i(); diff --git a/paddle/framework/attribute.h b/paddle/framework/attribute.h index 3a5820e9c60539e3c771df5da4e82f6c1cae688f..d0419f07ba4dca32236128a2fa7afdc1460f9468 100644 --- a/paddle/framework/attribute.h +++ b/paddle/framework/attribute.h @@ -21,8 +21,7 @@ limitations under the License. */ #include #include -#include "paddle/framework/attribute.pb.h" -#include "paddle/framework/op_desc.pb.h" +#include "paddle/framework/framework.pb.h" #include "paddle/platform/enforce.h" namespace paddle { @@ -37,7 +36,7 @@ typedef std::unordered_map AttributeMap; template AttrType AttrTypeID(); -Attribute GetAttrValue(const AttrDesc& attr_desc); +Attribute GetAttrValue(const OpDesc::Attr& attr_desc); // check whether a value(attribute) fit a certain limit template diff --git a/paddle/framework/ddim.cc b/paddle/framework/ddim.cc index 545c1dcc2a1682839d90194002fdbb748d85e808..0b76a4fdb701ea7435d0da865e928b8da15335c9 100644 --- a/paddle/framework/ddim.cc +++ b/paddle/framework/ddim.cc @@ -284,5 +284,11 @@ DDim::DDim(std::initializer_list init_list) { *this = make_ddim(init_list); } +std::string DDim::DebugString() const { + std::ostringstream ss; + ss << *this; + return ss.str(); +} + } // namespace framework } // namespace paddle diff --git a/paddle/framework/ddim.h b/paddle/framework/ddim.h index 5aa5af0c19be5a209c760282cb1a090fc57a53ad..3ea3b499e5b1015a5b0b107850ac0608735ba729 100644 --- a/paddle/framework/ddim.h +++ b/paddle/framework/ddim.h @@ -73,6 +73,8 @@ struct DDim { DDim operator*(DDim d) const; ssize_t size() const; + + std::string DebugString() const; }; /** diff --git a/paddle/framework/framework.proto b/paddle/framework/framework.proto index 4b6dfec5cbc35c8cfc20c525f965cbec292dc124..490d7bd91bfbd27010c7007b52e713171a8904ac 100644 --- a/paddle/framework/framework.proto +++ b/paddle/framework/framework.proto @@ -40,8 +40,8 @@ message OpDesc { }; message Var { - required string name; // e.g. "X" - optional int dup = 2 [ default = 0 ]; // e.g., "1" + required string op_proto_name = 1; + repeated string var_names = 2; }; required string type = 3; @@ -57,7 +57,7 @@ message OpProto { message Var { required string name = 1; required string comment = 2; - // OpDesc::Var::dup indices the duplica. + optional bool duplicable = 3 [ default = false ]; optional bool intermediate = 4 [ default = false ]; optional bool no_gradient = 5 [ default = false ]; diff --git a/paddle/framework/grad_op_builder.cc b/paddle/framework/grad_op_builder.cc index 6d032fb78f099f5142d64e531d1a03c10ed5e68e..da9613e7763692d5d63eb7eecd350f0b211dc1bc 100644 --- a/paddle/framework/grad_op_builder.cc +++ b/paddle/framework/grad_op_builder.cc @@ -13,12 +13,12 @@ express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "paddle/framework/grad_op_builder.h" -#include "paddle/framework/op_proto.pb.h" +#include "paddle/framework/framework.pb.h" #include "paddle/framework/op_registry.h" namespace paddle { namespace framework { - +/** class OpRegistry; using VarIndexMap = std::unordered_map; @@ -98,6 +98,7 @@ OperatorBase* BuildGradOp(const OperatorBase* op) { TransOpArg(op, grad_op, OpArgType::IN, OpArgType::OUT, out_idx, true); // IG return grad_op; } - +**/ +OperatorBase* BuildGradOp(const OperatorBase* op) { return nullptr; } } // namespace framework } // namespace paddle diff --git a/paddle/framework/op_registry.h b/paddle/framework/op_registry.h index b2813da83d9e4c525e66bb1f79b28769627eaec2..9123e9b56fd068d7df59160e8987bc51bbf511df 100644 --- a/paddle/framework/op_registry.h +++ b/paddle/framework/op_registry.h @@ -20,8 +20,8 @@ limitations under the License. */ #include #include #include "paddle/framework/attribute.h" +#include "paddle/framework/framework.pb.h" #include "paddle/framework/grad_op_builder.h" -#include "paddle/framework/op_desc.pb.h" #include "paddle/framework/scope.h" namespace paddle { @@ -44,25 +44,20 @@ class OpProtoAndCheckerMaker { protected: struct VariableBuilder { - VarProto* var_; - std::function on_multiple_; - std::function on_temporary_; + OpProto::Var* var_; VariableBuilder& SetMultiple() { - var_->set_multiple(true); - on_multiple_(); + var_->set_duplicable(true); return *this; } VariableBuilder& SetTemporary() { - PADDLE_ENFORCE(bool(on_temporary_), "Cannot set temporary"); - var_->set_temporary(true); - on_temporary_(); + var_->set_intermediate(true); return *this; } VariableBuilder& IgnoreGradient() { - var_->set_ignore_gradient(true); + var_->set_no_gradient(true); return *this; } }; @@ -72,8 +67,7 @@ class OpProtoAndCheckerMaker { auto input = proto_->mutable_inputs()->Add(); *input->mutable_name() = name; *input->mutable_comment() = comment; - return VariableBuilder{input, [=] { this->SetHasMultipleInput(); }, - nullptr}; + return VariableBuilder{input}; } VariableBuilder AddOutput(const std::string& name, @@ -81,8 +75,7 @@ class OpProtoAndCheckerMaker { auto output = proto_->mutable_outputs()->Add(); *output->mutable_name() = name; *output->mutable_comment() = comment; - return VariableBuilder{output, [=] { this->SetHasMultipleOutput(); }, - [=] { this->SetHasTemporaryOutput(); }}; + return VariableBuilder{output}; } template @@ -102,53 +95,6 @@ class OpProtoAndCheckerMaker { } private: - void SetHasMultiple(const std::string& in_out, bool* flag) { - if (!*flag) { - AddAttr>(in_out + "_format", - "The multiple index of " + in_out + - "\n" - R"DOC( -This attribute is used by Paddle core framework. Paddle's Op support each input -or output could be a list of variable. This attribute is used to show how that -list organized. - -e.g. - input = ["a", "b", "c", "d", "e", "f"] - input_format = [0, 4, 5, 6] - -means - The number of all input variables this op is six, and they are segmented into - three inputs. - - The first input is input[0:4], second is input[4:5], third is input[5:6]. -)DOC", - /*generated*/ true); - *flag = true; - } - } - - void SetHasMultipleInput() { SetHasMultiple("input", &has_multiple_input_); } - void SetHasMultipleOutput() { - SetHasMultiple("output", &has_multiple_output_); - } - - void SetHasTemporaryOutput() { - if (!has_temporary_output_) { - AddAttr>("temporary_index", - R"DOC(The temporary index of output. - -Not all output of Paddle Op is used by user. For faster computation, each op -could output some its internal state to other op, other op could take that -output to make compute faster. - -Add a mark to which output is temporary is helpful for future optimization. -)DOC", - /*generated*/ true) - .SetDefault(std::vector()); - has_temporary_output_ = true; - } - } - void CheckNoDuplicatedInOutAttrs() { std::unordered_set names; auto checker = [&](const std::string& name) { @@ -169,15 +115,12 @@ Add a mark to which output is temporary is helpful for future optimization. OpProto* proto_; OpAttrChecker* op_checker_; bool validated_{false}; - bool has_multiple_input_{false}; - bool has_multiple_output_{false}; - bool has_temporary_output_{false}; }; class OpRegistry { using OpCreator = std::function; using VarIndexMap = std::unordered_map; - using VarNameList = std::vector; + using VarNameMap = std::unordered_map>; public: template @@ -213,8 +156,8 @@ class OpRegistry { } static std::shared_ptr CreateOp(const std::string& type, - const VarNameList& inputs, - const VarNameList& outputs, + const VarNameMap& inputs, + const VarNameMap& outputs, const AttributeMap& attrs) { auto op_create_it = op_creators().find(type); PADDLE_ENFORCE(op_create_it != op_creators().end(), @@ -230,27 +173,28 @@ class OpRegistry { GenerateTempVariableName(op); - { - auto var_index_it = VarIndexMaps().find(type); - if (var_index_it != VarIndexMaps().end()) { - op->in_out_idxs_ = var_index_it->second; - } - } - op->Init(); return std::shared_ptr(op); } static std::shared_ptr CreateOp(const OpDesc& op_desc) { - std::vector inputs; - inputs.reserve((size_t)op_desc.inputs_size()); - std::copy(op_desc.inputs().begin(), op_desc.inputs().end(), - std::back_inserter(inputs)); + VarNameMap inputs; + for (auto& input : op_desc.inputs()) { + auto& var_names = inputs[input.op_proto_name()]; + auto& var_names_in_proto = input.var_names(); + var_names.reserve(static_cast(var_names_in_proto.size())); + std::copy(var_names_in_proto.begin(), var_names_in_proto.end(), + std::back_inserter(var_names)); + } - std::vector outputs; - outputs.reserve((size_t)op_desc.outputs_size()); - std::copy(op_desc.outputs().begin(), op_desc.outputs().end(), - std::back_inserter(outputs)); + VarNameMap outputs; + for (auto& output : op_desc.outputs()) { + auto& var_names = outputs[output.op_proto_name()]; + auto& var_names_in_proto = output.var_names(); + var_names.reserve(static_cast(var_names_in_proto.size())); + std::copy(var_names_in_proto.begin(), var_names_in_proto.end(), + std::back_inserter(var_names)); + } AttributeMap attrs; for (auto& attr : op_desc.attrs()) { @@ -303,11 +247,13 @@ class OpRegistry { static void GenerateTempVariableName(OperatorBase* op) { static std::atomic gUniqId(0UL); - for (auto& outname : op->outputs_) { - if (outname == kTempVarName) { - outname += op->type_; - outname += "@"; - outname += std::to_string(gUniqId.fetch_add(1)); + for (auto& output : op->outputs_) { + for (auto& output_name : output.second) { + if (output_name == kTempVarName) { + output_name += op->type_; + output_name += "@"; + output_name += std::to_string(gUniqId.fetch_add(1)); + } } } } diff --git a/paddle/framework/operator.cc b/paddle/framework/operator.cc index beb6793289812cfaa6991d28379126ff29fa2547..e69db305b49b8bc77e16b0d5d9f24a25b8a28c29 100644 --- a/paddle/framework/operator.cc +++ b/paddle/framework/operator.cc @@ -34,83 +34,72 @@ ExecutionContext::GetEigenDevice() const { #endif const std::string& OperatorBase::Input(const std::string& name) const { - PADDLE_ENFORCE(in_out_idxs_ != nullptr, - "Input Output Indices could not be nullptr"); - auto it = in_out_idxs_->find(name); - PADDLE_ENFORCE(it != in_out_idxs_->end(), "no key [%s] in in_out_idxs_", + auto it = inputs_.find(name); + PADDLE_ENFORCE(it != inputs_.end(), "Op %s does not have output %s", type_, name); - if (attrs_.count("input_format") == 0) { - return inputs_.at((size_t)it->second); - } else { - const auto& input_format = GetAttr>("input_format"); - int idx = input_format[it->second]; - return inputs_.at((size_t)idx); - } + PADDLE_ENFORCE_EQ(it->second.size(), 1UL, + "Op %s input %s should contain only one variable", type_, + name); + return it->second[0]; } -std::vector OperatorBase::Inputs(const std::string& name) const { - PADDLE_ENFORCE(in_out_idxs_ != nullptr, "IO Idx could not be nullptr"); - auto input_format = GetAttr>("input_format"); - auto offset = in_out_idxs_->at(name); - PADDLE_ENFORCE(input_format.at(static_cast(offset) + 1) <= - static_cast(inputs_.size()), - "Input Out Of Range"); - - return std::vector{ - inputs_.begin() + input_format.at(offset), - inputs_.begin() + input_format.at(offset + 1)}; +const std::vector& OperatorBase::Inputs( + const std::string& name) const { + return inputs_.at(name); } const std::string& OperatorBase::Output(const std::string& name) const { - PADDLE_ENFORCE(in_out_idxs_ != nullptr, "InOut Indice could not be nullptr"); - auto it = in_out_idxs_->find(name); - PADDLE_ENFORCE(it != in_out_idxs_->end(), "no key [%s] in in_out_idxs_", + auto it = outputs_.find(name); + PADDLE_ENFORCE(it != outputs_.end(), "Op %s does not have output %s", type_, name); - if (attrs_.count("output_format") == 0) { - return outputs_.at((size_t)it->second); - } else { - const auto& output_format = GetAttr>("output_format"); - int idx = output_format[it->second]; - return outputs_.at((size_t)idx); - } + PADDLE_ENFORCE_EQ(it->second.size(), 1UL, + "Op %s input %s should contain only one variable", type_, + name); + return it->second[0]; } -std::vector OperatorBase::Outputs(const std::string& name) const { - PADDLE_ENFORCE(in_out_idxs_ != nullptr, "InOut Indice could not be nullptr"); - auto output_format = GetAttr>("output_format"); - auto offset = in_out_idxs_->at(name); - PADDLE_ENFORCE(output_format.at(static_cast(offset) + 1) <= - static_cast(outputs_.size()), - "Output Out of Range"); - return std::vector{ - outputs_.begin() + output_format.at(offset), - outputs_.begin() + output_format.at(offset + 1)}; +const std::vector& OperatorBase::Outputs( + const std::string& name) const { + return outputs_.at(name); } std::string OperatorBase::DebugString() const { std::stringstream ss; - ss << "Op(" << type_ << "), inputs:("; - for (size_t i = 0; i < inputs_.size(); ++i) { - ss << inputs_[i]; - if (i != inputs_.size() - 1) { - ss << ", "; + ss << "Op(" << type_ << "), inputs:{"; + for (auto& input : inputs_) { + ss << input.first << "["; + for (size_t i = 0; i < input.second.size(); ++i) { + ss << input.second[i]; + if (i != input.second.size() - 1) { + ss << ", "; + } } + ss << "]"; } - ss << "), outputs:("; - for (size_t i = 0; i < outputs_.size(); ++i) { - ss << outputs_[i]; - if (i != outputs_.size() - 1) { - ss << ", "; + ss << "}, outputs:{"; + for (auto& output : outputs_) { + ss << output.first << "["; + for (size_t i = 0; i < output.second.size(); ++i) { + ss << output.second[i]; + if (i != output.second.size() - 1) { + ss << ", "; + } } + ss << "]"; } - ss << ")."; + ss << "}."; return ss.str(); } void OperatorBase::Rename(const std::string& old_name, const std::string& new_name) { - std::replace(inputs_.begin(), inputs_.end(), old_name, new_name); - std::replace(outputs_.begin(), outputs_.end(), old_name, new_name); + for (auto& input : inputs_) { + std::replace(input.second.begin(), input.second.end(), old_name, new_name); + } + for (auto& output : outputs_) { + std::replace(output.second.begin(), output.second.end(), old_name, + new_name); + } } } // namespace framework diff --git a/paddle/framework/operator.h b/paddle/framework/operator.h index 9672492d1c2c6a82c37e0a840a4ca9c111de06d8..ec498ce3bd8b5d40c3c3ad081c217c4c7e8dd593 100644 --- a/paddle/framework/operator.h +++ b/paddle/framework/operator.h @@ -21,8 +21,7 @@ limitations under the License. */ #include #include "paddle/framework/attribute.h" -#include "paddle/framework/op_desc.pb.h" -#include "paddle/framework/op_proto.pb.h" +#include "paddle/framework/framework.pb.h" #include "paddle/framework/scope.h" #include "paddle/framework/tensor.h" #include "paddle/platform/device_context.h" @@ -95,13 +94,12 @@ class OperatorBase { const std::string& Input(const std::string& name) const; //! Get a input which has multiple variables. - //! TODO add a vector_view to prevent memory copy. - std::vector Inputs(const std::string& name) const; + const std::vector& Inputs(const std::string& name) const; //! Get a output with argument's name described in `op_proto` const std::string& Output(const std::string& name) const; //! Get an output which has multiple variables. //! TODO add a vector_view to prevent memory copy. - std::vector Outputs(const std::string& name) const; + const std::vector& Outputs(const std::string& name) const; public: std::string type_; @@ -109,13 +107,12 @@ class OperatorBase { // I (Inputs) // O (Outputs) // OG (Output Gradients) - std::vector inputs_; + std::unordered_map> inputs_; + // NOTE: in case of OpGrad, outputs_ contains // IG (Inputs Gradients) - std::vector outputs_; + std::unordered_map> outputs_; AttributeMap attrs_; - // store the arguments' offset described in op_desc. - std::shared_ptr> in_out_idxs_; }; class OperatorContext { @@ -123,16 +120,12 @@ class OperatorContext { OperatorContext(const OperatorBase* op, const Scope& scope) : op_(*op), scope_(scope) {} - size_t InputSize() const { return op_.inputs_.size(); } - - size_t OutputSize() const { return op_.outputs_.size(); } - - const Variable* InputVar(const size_t index) const { - return scope_.FindVar(op_.inputs_.at(index)); + size_t InputSize(const std::string& name) const { + return op_.inputs_.at(name).size(); } - Variable* OutputVar(const size_t index) const { - return scope_.FindVar(op_.outputs_.at(index)); + size_t OutputSize(const std::string& name) const { + return op_.outputs_.at(name).size(); } const Variable* InputVar(const std::string& name) const { @@ -164,24 +157,6 @@ class OperatorContext { return res; } - template - const T* Input(const size_t index) const { - auto var = InputVar(index); - PADDLE_ENFORCE(var != nullptr, "Input(%d) should not be nullptr", index); - return &var->Get(); - } - - template - T* Output(const size_t index) const { - auto var = OutputVar(index); - PADDLE_ENFORCE( - var != nullptr, - "Output(%d) not be nullptr, which means variable [%s] does not " - "exist in scope", - index, op_.outputs_[index]); - return var->GetMutable(); - } - template const T* Input(const std::string& name) const { auto var = InputVar(name); diff --git a/paddle/operators/add_op.cc b/paddle/operators/add_op.cc index d4c05ed483ca56a31dd8ee4d81b54551ae6da0d1..29943002acab6db42dfdad2bc32f4c8725901136 100644 --- a/paddle/operators/add_op.cc +++ b/paddle/operators/add_op.cc @@ -20,15 +20,10 @@ namespace operators { class AddOp : public OperatorWithKernel { protected: void InferShape(const InferShapeContext &ctx) const override { - PADDLE_ENFORCE_EQ(ctx.InputSize(), 2); - PADDLE_ENFORCE_EQ(ctx.OutputSize(), 1); - PADDLE_ENFORCE(ctx.InputVar(0) != nullptr && ctx.InputVar(1) != nullptr, - "Inputs of AddOp must all be set"); - PADDLE_ENFORCE(ctx.OutputVar(0) != nullptr, - "Outputs of AddOp must all be set"); - PADDLE_ENFORCE(ctx.Input(0)->dims() == ctx.Input(1)->dims(), - "Two input of Add Op's dimension must be same."); - ctx.Output(0)->Resize(ctx.Input(0)->dims()); + PADDLE_ENFORCE_EQ(ctx.Input("X")->dims(), + ctx.Input("Y")->dims(), + "Two input of Add Op's dimension must be same."); + ctx.Output("Out")->Resize(ctx.Input("X")->dims()); } }; diff --git a/paddle/operators/add_op.h b/paddle/operators/add_op.h index 9db19a61381fdb11350276d51d3ebbf083672022..9310c1f7edfd2059e5f31486388a17a04359be63 100644 --- a/paddle/operators/add_op.h +++ b/paddle/operators/add_op.h @@ -22,9 +22,9 @@ template class AddKernel : public OpKernel { public: void Compute(const ExecutionContext& context) const override { - auto input0 = context.Input(0); - auto input1 = context.Input(1); - auto output = context.Output(0); + auto* input0 = context.Input("X"); + auto* input1 = context.Input("Y"); + auto* output = context.Output("Out"); output->mutable_data(context.GetPlace()); diff --git a/paddle/operators/cross_entropy_op.cc b/paddle/operators/cross_entropy_op.cc index b0e1b8e41a5320aa14e316a56dbfd01e43c6816b..77c8271fd4ca490afba11abc109f5c4296f0d1fd 100644 --- a/paddle/operators/cross_entropy_op.cc +++ b/paddle/operators/cross_entropy_op.cc @@ -20,19 +20,13 @@ namespace operators { class OnehotCrossEntropyOp : public OperatorWithKernel { protected: void InferShape(const InferShapeContext &ctx) const override { - PADDLE_ENFORCE(ctx.InputSize() == 2, - "Input size of OnehotCrossEntropyOp must be two"); - PADDLE_ENFORCE(ctx.OutputSize() == 1, - "Output size of OnehotCrossEntropyOp must be one"); - PADDLE_ENFORCE(ctx.InputVar(0) != nullptr && ctx.InputVar(1) != nullptr, - "Inputs of OnehotCrossEntropyOp must all be set"); - PADDLE_ENFORCE(ctx.OutputVar(0) != nullptr, - "Outputs of OnehotCrossEntropyOp must all be set"); - PADDLE_ENFORCE(ctx.Input(0)->dims().size() == 2, - "X's dimension must be 2."); - PADDLE_ENFORCE(ctx.Output(0)->dims().size() == 1, - "label's dimension must be 1."); - ctx.Output(0)->Resize({ctx.Input(0)->dims()[0]}); + auto *X = ctx.Input("X"); + auto *label = ctx.Input("label"); + + PADDLE_ENFORCE_EQ(X->dims().size(), 2, "X's dimension must be 2."); + PADDLE_ENFORCE_EQ(label->dims().size(), 1, "label's dimension must be 1."); + PADDLE_ENFORCE_EQ(X->dims()[0], label->dims()[0]); + ctx.Output("Y")->Resize({X->dims()[0]}); } }; diff --git a/paddle/operators/cross_entropy_op.h b/paddle/operators/cross_entropy_op.h index e02e3e2945af13fe283f95f7faa03b2a76d06125..d5e3f29332809a63908ecc896b33d2adff6abe45 100644 --- a/paddle/operators/cross_entropy_op.h +++ b/paddle/operators/cross_entropy_op.h @@ -43,7 +43,7 @@ class OnehotCrossEntropyOpKernel : public OpKernel { void Compute(const ExecutionContext& ctx) const override { auto X = ctx.Input("X"); const T* Xdata = X->data(); - const int* label_data = ctx.Input(1)->data(); + const int* label_data = ctx.Input("label")->data(); auto Y = ctx.Output("Y"); Y->mutable_data(ctx.GetPlace()); diff --git a/paddle/operators/fill_zeros_like_op.cc b/paddle/operators/fill_zeros_like_op.cc index 198b4576c887122fdac1a3fbff5a248a3d9fa0a3..405ed219f0145ec1c3d8a315f39a134d3d9d7643 100644 --- a/paddle/operators/fill_zeros_like_op.cc +++ b/paddle/operators/fill_zeros_like_op.cc @@ -20,16 +20,8 @@ namespace operators { class FillZerosLikeOp : public framework::OperatorWithKernel { protected: void InferShape(const framework::InferShapeContext &ctx) const override { - PADDLE_ENFORCE(ctx.InputSize() == 1UL, - "Input size of FillZerosLikeOp must be one."); - PADDLE_ENFORCE(ctx.OutputSize() == 1UL, - "Output size of AddOp must be one."); - PADDLE_ENFORCE(ctx.InputVar(0) != nullptr, - "Input of FillZerosLikeOp must be set."); - PADDLE_ENFORCE(ctx.OutputVar(0) != nullptr, - "Output of FillZerosLikeOp must be set."); - ctx.Output(0)->Resize( - ctx.Input(0)->dims()); + ctx.Output("Dst")->Resize( + ctx.Input("Src")->dims()); } }; diff --git a/paddle/operators/mean_op.cc b/paddle/operators/mean_op.cc index 8a4981c7be7587a0cc5f72cabe71e05702112ac3..aa5479ceaff379d99a5f7322edac0c5e69816974 100644 --- a/paddle/operators/mean_op.cc +++ b/paddle/operators/mean_op.cc @@ -20,11 +20,9 @@ namespace operators { class MeanOp : public OperatorWithKernel { protected: void InferShape(const InferShapeContext &ctx) const override { - PADDLE_ENFORCE(ctx.InputSize() == 1, "Input size of AddOp must be one"); - PADDLE_ENFORCE(ctx.OutputSize() == 1, "Output size of AddOp must be one"); - PADDLE_ENFORCE(ctx.InputVar(0) != nullptr && ctx.OutputVar(0) != nullptr, - "Input/Output of MeanOp must be initialized."); - ctx.Output(0)->Resize(framework::make_ddim({1})); + PADDLE_ENFORCE(ctx.InputVar("X") != nullptr, + "Input of MeanOp must be initialized."); + ctx.Output("Out")->Resize({1}); } }; diff --git a/paddle/operators/mul_op.cc b/paddle/operators/mul_op.cc index ccab9a994cc7aa9e389bd259e4c7365a06e93aa1..b9099ad4e3d000df45a8df1b6f8f2b27b197d744 100644 --- a/paddle/operators/mul_op.cc +++ b/paddle/operators/mul_op.cc @@ -20,9 +20,8 @@ namespace operators { class MulOp : public OperatorWithKernel { protected: void InferShape(const InferShapeContext &ctx) const override { - PADDLE_ENFORCE(ctx.InputSize() == 2, "The mul op must take two inputs"); - auto dim0 = ctx.Input(0)->dims(); - auto dim1 = ctx.Input(1)->dims(); + auto dim0 = ctx.Input("X")->dims(); + auto dim1 = ctx.Input("Y")->dims(); PADDLE_ENFORCE_EQ(dim0.size(), 2, "input X(%s) should be a tensor with 2 dims, a matrix", ctx.op_.Input("X")); @@ -32,8 +31,7 @@ class MulOp : public OperatorWithKernel { PADDLE_ENFORCE_EQ( dim0[1], dim1[0], "First matrix's width must be equal with second matrix's height."); - PADDLE_ENFORCE_EQ(ctx.OutputSize(), 1, "The mul op takes only one output"); - ctx.Output(0)->Resize({dim0[0], dim1[1]}); + ctx.Output("Out")->Resize({dim0[0], dim1[1]}); } }; diff --git a/paddle/operators/net_op.cc b/paddle/operators/net_op.cc index fbc98e09923bda7f3baee04e02df9076247bff0b..b0746883d0497ec06a46cb7d3aa886b848a2204d 100644 --- a/paddle/operators/net_op.cc +++ b/paddle/operators/net_op.cc @@ -15,6 +15,7 @@ */ #include "paddle/operators/net_op.h" +#include #include "paddle/framework/op_registry.h" namespace paddle { @@ -23,36 +24,39 @@ namespace operators { void NetOp::CompleteAddOp(bool calc) { add_op_done_ = true; if (!calc) return; - std::unordered_set input_set; - std::unordered_set output_set; - std::unordered_set temp_output; + std::set input_set; + std::set output_set; + std::set temp_output; for (auto& op : ops_) { for (auto& ipt : op->inputs_) { - if (!Contains(output_set, ipt)) { // Not other op's output - input_set.insert(ipt); - } else { - temp_output.insert(ipt); + for (auto& var_name : ipt.second) { + if (!Contains(output_set, var_name)) { // Not other op's output + input_set.insert(var_name); + } else { + temp_output.insert(var_name); + } } } for (auto& opt : op->outputs_) { - output_set.insert(opt); + for (auto& var_name : opt.second) { + output_set.insert(var_name); + } } } + auto& inputs = inputs_["all"]; + inputs.reserve(input_set.size()); + std::copy(input_set.begin(), input_set.end(), std::back_inserter(inputs)); + auto& outputs = outputs_["all"]; + outputs.reserve(output_set.size()); + std::copy(output_set.begin(), output_set.end(), std::back_inserter(outputs)); - inputs_.reserve(input_set.size()); - std::copy(input_set.begin(), input_set.end(), std::back_inserter(inputs_)); - std::sort(inputs_.begin(), inputs_.end()); - - outputs_.reserve(output_set.size()); - std::copy(output_set.begin(), output_set.end(), std::back_inserter(outputs_)); - std::sort(outputs_.begin(), outputs_.end()); - + //! TODO figure out how to generate temporary_index in Network. std::vector tmp_index; tmp_index.reserve(temp_output.size()); - int output_len = static_cast(outputs_.size()); + int output_len = static_cast(outputs.size()); for (int i = 0; i < output_len; ++i) { - if (Contains(temp_output, outputs_[i])) { + if (Contains(temp_output, outputs[i])) { tmp_index.push_back(i); } } diff --git a/paddle/operators/net_op.h b/paddle/operators/net_op.h index 6e7af7f02ae23ec65459dfd15d950a43e96fec4d..0342cf4adb831e394935083f77673611d26e2e55 100644 --- a/paddle/operators/net_op.h +++ b/paddle/operators/net_op.h @@ -14,8 +14,7 @@ limitations under the License. */ #pragma once -#include "paddle/framework/op_desc.pb.h" -#include "paddle/framework/op_proto.pb.h" +#include "paddle/framework/framework.pb.h" #include "paddle/framework/op_registry.h" #include "paddle/framework/operator.h" #include "paddle/framework/scope.h" diff --git a/paddle/operators/recurrent_op.cc b/paddle/operators/recurrent_op.cc index 5e9c15ca0e6a7c56611a0fadda6c3c0839f309e6..43c9aa72cd724a792c05501330d1ffee34cde632 100644 --- a/paddle/operators/recurrent_op.cc +++ b/paddle/operators/recurrent_op.cc @@ -89,12 +89,17 @@ void RecurrentAlgorithm::CreateScopes(const Scope& scope) const { // create step net's temp inputs for (auto& input : net_op->inputs_) { // the weight are located in parent scope - if (!step_scope.FindVar(input)) - step_scope.NewVar(input)->GetMutable(); + for (auto& var_name : input.second) { + if (!step_scope.FindVar(var_name)) { + step_scope.NewVar(var_name)->GetMutable(); + } + } } // create stepnet's outputs for (const auto& output : net_op->outputs_) { - step_scope.NewVar(output); + for (auto& var_name : output.second) { + step_scope.NewVar(var_name); + } } step_scopes->emplace_back(&step_scope); } diff --git a/paddle/operators/rowwise_add_op.cc b/paddle/operators/rowwise_add_op.cc index 8d1a36f2b332faad516ced012a409ca428bbf689..c6a1f082138f5a75e2d9cebbe7b547911e952e17 100644 --- a/paddle/operators/rowwise_add_op.cc +++ b/paddle/operators/rowwise_add_op.cc @@ -19,16 +19,14 @@ namespace operators { class RowWiseAddOp : public OperatorWithKernel { protected: void InferShape(const InferShapeContext &ctx) const override { - PADDLE_ENFORCE(ctx.InputSize() == 2UL, - "Two inputs is needed by rowwise add"); - auto dim0 = ctx.Input(0)->dims(); - auto dim1 = ctx.Input(1)->dims(); + auto dim0 = ctx.Input("X")->dims(); + auto dim1 = ctx.Input("b")->dims(); PADDLE_ENFORCE(dim0.size() == 2, "Input 0 must be matrix"); PADDLE_ENFORCE(dim1.size() == 1, "The second input must be vector"); PADDLE_ENFORCE(dim0[1] == dim1[0], "The width of two input must be same"); - PADDLE_ENFORCE(ctx.OutputSize() == 1, "The output size must be 1"); - ctx.Output(0)->Resize(ctx.Input(0)->dims()); + PADDLE_ENFORCE(ctx.OutputSize("Out") == 1, "The output size must be 1"); + ctx.Output("Out")->Resize(ctx.Input("X")->dims()); } }; diff --git a/paddle/operators/rowwise_add_op.h b/paddle/operators/rowwise_add_op.h index b52524c47c7b80d8ddc6a94a4a6d03db8034088d..9e9f9d110c30452439cf4108d4a574b20a581c16 100644 --- a/paddle/operators/rowwise_add_op.h +++ b/paddle/operators/rowwise_add_op.h @@ -25,8 +25,8 @@ class RowWiseAddKernel : public OpKernel { auto out = context.Output(0); out->mutable_data(context.GetPlace()); - auto input = EigenMatrix::From(*context.Input(0)); - auto bias = EigenVector::From(*context.Input(1)); + auto input = EigenMatrix::From(*context.Input("X")); + auto bias = EigenVector::From(*context.Input("b")); auto output = EigenMatrix::From(*out); const int bias_size = bias.dimension(0); diff --git a/paddle/operators/sgd_op.cc b/paddle/operators/sgd_op.cc index 6307583f4ee3f185845690d0e378945d066eae75..659cb41d989489d0e0f8d3cea3f5fb06094d23dc 100644 --- a/paddle/operators/sgd_op.cc +++ b/paddle/operators/sgd_op.cc @@ -20,14 +20,10 @@ namespace operators { class SGDOp : public OperatorWithKernel { protected: void InferShape(const InferShapeContext &ctx) const override { - PADDLE_ENFORCE(ctx.InputSize() == 2, "Input size of SGDOp must be two"); - PADDLE_ENFORCE(ctx.OutputSize() == 1, "Output size of SGDOp must be one"); - PADDLE_ENFORCE(ctx.InputVar(0) != nullptr, "inputs[0] mast be set"); - PADDLE_ENFORCE(ctx.InputVar(1) != nullptr, "inputs[1] mast be set"); - PADDLE_ENFORCE(ctx.OutputVar(0) != nullptr, "outputs[0] mast be set"); - PADDLE_ENFORCE(ctx.Input(0)->dims() == ctx.Input(1)->dims(), - "Two input of SGD Op's dimension must be same."); - ctx.Output(0)->Resize(ctx.Input(0)->dims()); + PADDLE_ENFORCE( + ctx.Input("param")->dims() == ctx.Input("grad")->dims(), + "Two input of SGD Op's dimension must be same."); + ctx.Output("param_out")->Resize(ctx.Input("param")->dims()); } }; diff --git a/paddle/operators/sigmoid_op.cc b/paddle/operators/sigmoid_op.cc index 1eb795faa858796f7a34aa495b43d043fdb5dd43..27904ea0c3c21ec760dfed1b822bd45b586a933d 100644 --- a/paddle/operators/sigmoid_op.cc +++ b/paddle/operators/sigmoid_op.cc @@ -19,9 +19,7 @@ namespace operators { class SigmoidOp : public OperatorWithKernel { protected: void InferShape(const InferShapeContext &ctx) const override { - PADDLE_ENFORCE(ctx.InputSize() == 1, "Sigmoid Op only have one input"); - PADDLE_ENFORCE(ctx.OutputSize() == 1, "Sigmoid Op only have one output"); - ctx.Output(0)->Resize(ctx.Input(0)->dims()); + ctx.Output("Y")->Resize(ctx.Input("X")->dims()); } }; diff --git a/paddle/operators/softmax_op.cc b/paddle/operators/softmax_op.cc index a070458f5e55cf47253ab0df5af7a1163b4f8092..836bce2294f52af3062fe2bde82fb1df2207f54c 100644 --- a/paddle/operators/softmax_op.cc +++ b/paddle/operators/softmax_op.cc @@ -20,12 +20,8 @@ namespace operators { class SoftmaxOp : public OperatorWithKernel { protected: void InferShape(const InferShapeContext &ctx) const override { - PADDLE_ENFORCE(ctx.InputSize() == 1UL, - "Only one input is need for softmax"); PADDLE_ENFORCE(ctx.Input("X")->dims().size() == 2UL, "The input of softmax op must be matrix"); - PADDLE_ENFORCE(ctx.OutputSize() == 1UL, - "Only one output is need for softmax"); ctx.Output("Y")->Resize(ctx.Input("X")->dims()); } }; @@ -43,10 +39,6 @@ class SoftmaxOpMaker : public OpProtoAndCheckerMaker { class SoftmaxOpGrad : public OperatorWithKernel { protected: void InferShape(const InferShapeContext &ctx) const override { - PADDLE_ENFORCE(ctx.InputSize() == 3UL, - "Input of SoftmaxOpGrad should be 3, X, Y, YG"); - PADDLE_ENFORCE(ctx.OutputSize() == 1UL, - "Output of SoftmaxOpGrad should be 1"); PADDLE_ENFORCE(ctx.InputVar("Y") != nullptr, "Input(Y) should not be null"); PADDLE_ENFORCE(ctx.InputVar(framework::GradVarName("Y")) != nullptr, "Input(Y@GRAD) should not be null"); diff --git a/paddle/platform/enforce.h b/paddle/platform/enforce.h index bc0715656a7d61774d53d4a0643ec1c105706085..60ce5822d3ade7ea6fa940db2f002a89263a34ca 100644 --- a/paddle/platform/enforce.h +++ b/paddle/platform/enforce.h @@ -195,12 +195,28 @@ struct CompatibleType { typedef typename std::conditional::type type; }; +template +inline std::string enforce_to_string(const T& val) { + std::ostringstream sout; + sout << val; + return sout.str(); +} +template <> +inline std::string enforce_to_string(const std::string& val) { + return val; +} +template <> +inline std::string enforce_to_string(const char* const& val) { + return std::string(val); +} + #define __PADDLE_BINARY_COMPARE(__VAL0, __VAL1, __CMP, __INV_CMP, ...) \ PADDLE_ENFORCE(__COMPATIBLE_TYPE(__VAL0, __VAL1, __VAL0) \ __CMP __COMPATIBLE_TYPE(__VAL0, __VAL1, __VAL1), \ "enforce %s " #__CMP " %s failed, %s " #__INV_CMP " %s\n%s", \ - #__VAL0, #__VAL1, std::to_string(__VAL0), \ - std::to_string(__VAL1), \ + #__VAL0, #__VAL1, \ + paddle::platform::enforce_to_string(__VAL0), \ + paddle::platform::enforce_to_string(__VAL1), \ paddle::string::Sprintf("" __VA_ARGS__)); #define __COMPATIBLE_TYPE(__VAL0, __VAL1, __VAL) \