diff --git a/VERSION_NUMBER b/VERSION_NUMBER index d2d61a7e8..e2cac26c1 100755 --- a/VERSION_NUMBER +++ b/VERSION_NUMBER @@ -1 +1 @@ -1.2.2 \ No newline at end of file +1.2.3 \ No newline at end of file diff --git a/paddle2onnx/mapper/exporter.cc b/paddle2onnx/mapper/exporter.cc index baf224699..e06184221 100644 --- a/paddle2onnx/mapper/exporter.cc +++ b/paddle2onnx/mapper/exporter.cc @@ -409,9 +409,9 @@ std::string ModelExporter::Run( } // construct a onnx model proto + auto ir_version = _helper.GetIRVersion(); auto model = std::make_shared(); - // TODO(jiangjiajun) ir version is related to onnx version - model->set_ir_version(ONNX_NAMESPACE::IR_VERSION); + model->set_ir_version(ir_version); auto graph = model->mutable_graph(); graph->set_name("Model from PaddlePaddle."); auto opset_id = model->add_opset_import(); diff --git a/paddle2onnx/mapper/onnx_helper.cc b/paddle2onnx/mapper/onnx_helper.cc index 2e37005af..d0833363d 100755 --- a/paddle2onnx/mapper/onnx_helper.cc +++ b/paddle2onnx/mapper/onnx_helper.cc @@ -17,9 +17,9 @@ #include namespace paddle2onnx { - void AddAttribute(std::shared_ptr node, - const std::string& name, const int64_t& value) { + const std::string &name, + const int64_t &value) { for (int i = 0; i < node->attribute_size(); ++i) { if (node->attribute(i).name() == name) { node->mutable_attribute(i)->set_i(value); @@ -34,12 +34,13 @@ void AddAttribute(std::shared_ptr node, } void AddAttribute(std::shared_ptr node, - const std::string& name, const float& value) { + const std::string &name, + const float &value) { for (int i = 0; i < node->attribute_size(); ++i) { if (node->attribute(i).name() == name) { node->mutable_attribute(i)->set_f(value); node->mutable_attribute(i)->set_type( - ONNX_NAMESPACE::AttributeProto::FLOAT); + ONNX_NAMESPACE::AttributeProto::FLOAT); return; } } @@ -50,7 +51,8 @@ void AddAttribute(std::shared_ptr node, } void AddAttribute(std::shared_ptr node, - const std::string& name, const std::string& value) { + const std::string &name, + const std::string &value) { auto attr = node->add_attribute(); attr->set_name(name); attr->set_s(value); @@ -58,27 +60,29 @@ void AddAttribute(std::shared_ptr node, } void AddAttribute(std::shared_ptr node, - const std::string& name, const std::vector& values) { + const std::string &name, + const std::vector &values) { auto attr = node->add_attribute(); attr->set_name(name); - for (auto& item : values) { + for (auto &item : values) { attr->add_ints(item); } attr->set_type(ONNX_NAMESPACE::AttributeProto::INTS); } void AddAttribute(std::shared_ptr node, - const std::string& name, const std::vector& values) { + const std::string &name, + const std::vector &values) { auto attr = node->add_attribute(); attr->set_name(name); - for (auto& item : values) { + for (auto &item : values) { attr->add_floats(item); } attr->set_type(ONNX_NAMESPACE::AttributeProto::FLOATS); } void AddAttribute(std::shared_ptr node, - const std::string& name, + const std::string &name, ONNX_NAMESPACE::TensorProto_DataType dtype) { auto attr = node->add_attribute(); attr->set_name(name); @@ -88,9 +92,9 @@ void AddAttribute(std::shared_ptr node, ONNX_NAMESPACE::TensorProto_DataType GetOnnxDtype(int32_t paddle_dtype) { Assert((paddle_dtype >= 0 && paddle_dtype <= 6) || paddle_dtype == 20 || - paddle_dtype == 21, + paddle_dtype == 21, "Unknow paddle data type: " + std::to_string(paddle_dtype) + - " While call GetOnnxDtype."); + " While call GetOnnxDtype."); auto onnx_dtype = ONNX_NAMESPACE::TensorProto::FLOAT; if (paddle_dtype == P2ODataType::BOOL) { onnx_dtype = ONNX_NAMESPACE::TensorProto::BOOL; @@ -114,8 +118,8 @@ ONNX_NAMESPACE::TensorProto_DataType GetOnnxDtype(int32_t paddle_dtype) { return onnx_dtype; } -std::shared_ptr MakeConstant(const std::string& name, - const Weight& weight) { +std::shared_ptr MakeConstant(const std::string &name, + const Weight &weight) { auto node = std::make_shared(); node->set_op_type("Constant"); node->add_output(name); @@ -126,7 +130,7 @@ std::shared_ptr MakeConstant(const std::string& name, tensor->set_name(name); auto onnx_dtype = GetOnnxDtype(weight.dtype); tensor->set_data_type(onnx_dtype); - for (auto& dim : weight.shape) { + for (auto &dim : weight.shape) { tensor->add_dims(dim); } tensor->set_raw_data(std::string(weight.buffer.data(), weight.buffer.size())); @@ -161,14 +165,14 @@ std::shared_ptr MakeConstant(const std::string& name, //} std::shared_ptr MakeValueInfo( - const TensorInfo& info) { + const TensorInfo &info) { auto value_info = std::make_shared(); value_info->set_name(info.name); auto type_proto = value_info->mutable_type(); auto tensor_type_proto = type_proto->mutable_tensor_type(); tensor_type_proto->set_elem_type(GetOnnxDtype(info.dtype)); auto shape = tensor_type_proto->mutable_shape(); - for (auto& dim : info.shape) { + for (auto &dim : info.shape) { if (dim < 0) { auto dynamic_dim_name = MapperHelper::Get()->GenName("DynamicDimension"); shape->add_dim()->set_dim_param(dynamic_dim_name); @@ -180,15 +184,16 @@ std::shared_ptr MakeValueInfo( } std::shared_ptr OnnxHelper::MakeValueInfo( - const std::string& name, const int32_t& dtype, - std::vector& shape) { + const std::string &name, + const int32_t &dtype, + std::vector &shape) { auto value_info = std::make_shared(); value_info->set_name(name); auto type_proto = value_info->mutable_type(); auto tensor_type_proto = type_proto->mutable_tensor_type(); tensor_type_proto->set_elem_type(GetOnnxDtype(dtype)); auto shape_proto = tensor_type_proto->mutable_shape(); - for (auto& dim : shape) { + for (auto &dim : shape) { if (dim < 0) { auto dynamic_dim_name = MapperHelper::Get()->GenName("DynamicDimension"); shape_proto->add_dim()->set_dim_param(dynamic_dim_name); @@ -201,8 +206,9 @@ std::shared_ptr OnnxHelper::MakeValueInfo( } std::shared_ptr OnnxHelper::MakeNode( - const std::string& op_type, const std::vector& inputs, - const std::vector& outputs) { + const std::string &op_type, + const std::vector &inputs, + const std::vector &outputs) { #ifdef PADDLE2ONNX_DEBUG P2OLogger(true) << "ONNX Node: " << op_type << std::endl; #endif @@ -225,8 +231,9 @@ std::shared_ptr OnnxHelper::MakeNode( } std::shared_ptr OnnxHelper::MakeNode( - const std::string& op_type, const std::vector& inputs, - int num_outputs) { + const std::string &op_type, + const std::vector &inputs, + int num_outputs) { #ifdef PADDLE2ONNX_DEBUG P2OLogger(true) << "ONNX Node: " << op_type << std::endl; #endif @@ -251,7 +258,7 @@ std::shared_ptr OnnxHelper::MakeNode( return node; } -std::string OnnxHelper::AutoCast(const std::string& input, +std::string OnnxHelper::AutoCast(const std::string &input, int32_t input_paddle_dtype, int32_t to_paddle_dtype) { std::string output = MapperHelper::Get()->GenName("auto.cast"); @@ -264,8 +271,8 @@ std::string OnnxHelper::AutoCast(const std::string& input, return cast_node->output(0); } -std::string OnnxHelper::AutoCast(const std::string& input, - const std::string& output, +std::string OnnxHelper::AutoCast(const std::string &input, + const std::string &output, int32_t input_paddle_dtype, int32_t to_paddle_dtype) { if (input_paddle_dtype == to_paddle_dtype) { @@ -277,7 +284,7 @@ std::string OnnxHelper::AutoCast(const std::string& input, return cast_node->output(0); } -std::string OnnxHelper::ConcatIndices(const std::vector& indices) { +std::string OnnxHelper::ConcatIndices(const std::vector &indices) { std::vector vars; // make sure all the indices be 1-D tensor for (size_t i = 0; i < indices.size(); ++i) { @@ -302,9 +309,11 @@ std::string OnnxHelper::ConcatIndices(const std::vector& indices) { return vars[0]; } -std::string OnnxHelper::Clip(const std::string& input, - const std::string& output, const float& min, - const float& max, const int32_t& in_dtype) { +std::string OnnxHelper::Clip(const std::string &input, + const std::string &output, + const float &min, + const float &max, + const int32_t &in_dtype) { // onnxruntime only supports float input std::string input_name = AutoCast(input, in_dtype, P2ODataType::FP32); if (opset_version < 11) { @@ -324,15 +333,17 @@ std::string OnnxHelper::Clip(const std::string& input, } } -std::string OnnxHelper::Clip(const std::string& input, const float& min, - const float& max, const int32_t& in_dtype) { +std::string OnnxHelper::Clip(const std::string &input, + const float &min, + const float &max, + const int32_t &in_dtype) { std::string output = MapperHelper::Get()->GenName("helper.clip"); return Clip(input, output, min, max, in_dtype); } -std::string OnnxHelper::Squeeze(const std::string& input, - const std::string& output, - const std::vector& axes) { +std::string OnnxHelper::Squeeze(const std::string &input, + const std::string &output, + const std::vector &axes) { if (axes.size() == 0) { auto node = MakeNode("Squeeze", {input}, {output}); } else { @@ -347,17 +358,17 @@ std::string OnnxHelper::Squeeze(const std::string& input, return output; } -std::string OnnxHelper::Squeeze(const std::string& input, - const std::vector& axes) { +std::string OnnxHelper::Squeeze(const std::string &input, + const std::vector &axes) { std::string output = MapperHelper::Get()->GenName("helper.squeeze"); return Squeeze(input, output, axes); } -std::string OnnxHelper::Unsqueeze(const std::string& input, - const std::string& output, - const std::vector& axes) { +std::string OnnxHelper::Unsqueeze(const std::string &input, + const std::string &output, + const std::vector &axes) { Assert(axes.size() >= 0, "OnnxHelper::Unsqueeze Size of axes should > 0"); - for (auto& item : axes) { + for (auto &item : axes) { Assert(item >= 0, "OnnxHelper::Unsqueeze All the elements in axes should >= 0"); } @@ -371,15 +382,15 @@ std::string OnnxHelper::Unsqueeze(const std::string& input, return output; } -std::string OnnxHelper::Unsqueeze(const std::string& input, - const std::vector& axes) { +std::string OnnxHelper::Unsqueeze(const std::string &input, + const std::vector &axes) { std::string output = MapperHelper::Get()->GenName("helper.unsqueeze"); return Unsqueeze(input, output, axes); } -std::string OnnxHelper::Reshape(const std::string& input, - const std::string& output, - const std::vector& shape) { +std::string OnnxHelper::Reshape(const std::string &input, + const std::string &output, + const std::vector &shape) { if (opset_version < 6) { auto node = MakeNode("Reshape", {input}, {output}); AddAttribute(node, "shape", shape); @@ -393,27 +404,27 @@ std::string OnnxHelper::Reshape(const std::string& input, return output; } -std::string OnnxHelper::Reshape(const std::string& input, - const std::vector& shape) { +std::string OnnxHelper::Reshape(const std::string &input, + const std::vector &shape) { std::string output = MapperHelper::Get()->GenName("helper.reshape"); return Reshape(input, output, shape); } -std::string OnnxHelper::Flatten(const std::string& input, - const std::string& output) { +std::string OnnxHelper::Flatten(const std::string &input, + const std::string &output) { return Reshape(input, output, std::vector(1, -1)); } -std::string OnnxHelper::Flatten(const std::string& input) { +std::string OnnxHelper::Flatten(const std::string &input) { std::string output = MapperHelper::Get()->GenName("helper.flatten"); return Flatten(input, output); } -std::string OnnxHelper::Slice(const std::string& input, - const std::string& output, - const std::vector& axes, - const std::vector& starts, - const std::vector& ends) { +std::string OnnxHelper::Slice(const std::string &input, + const std::string &output, + const std::vector &axes, + const std::vector &starts, + const std::vector &ends) { if (opset_version < 10) { auto node = MakeNode("Slice", {input}, {output}); AddAttribute(node, "axes", axes); @@ -429,44 +440,47 @@ std::string OnnxHelper::Slice(const std::string& input, return output; } -std::string OnnxHelper::Slice(const std::string& input, - const std::vector& axes, - const std::vector& starts, - const std::vector& ends) { +std::string OnnxHelper::Slice(const std::string &input, + const std::vector &axes, + const std::vector &starts, + const std::vector &ends) { std::string output = MapperHelper::Get()->GenName("helper.slice"); return Slice(input, output, axes, starts, ends); } -std::string OnnxHelper::Concat(const std::vector& input, - const std::string& output, int64_t axis) { +std::string OnnxHelper::Concat(const std::vector &input, + const std::string &output, + int64_t axis) { auto node = MakeNode("Concat", input, {output}); AddAttribute(node, "axis", axis); return output; } -std::string OnnxHelper::Concat(const std::vector& input, +std::string OnnxHelper::Concat(const std::vector &input, int64_t axis) { auto output = MapperHelper::Get()->GenName("helper.concat"); return Concat(input, output, axis); } -std::string OnnxHelper::Transpose(const std::string& input, - const std::string& output, - const std::vector& perm) { +std::string OnnxHelper::Transpose(const std::string &input, + const std::string &output, + const std::vector &perm) { auto node = MakeNode("Transpose", {input}, {output}); AddAttribute(node, "perm", perm); return output; } -std::string OnnxHelper::Transpose(const std::string& input, - const std::vector& perm) { +std::string OnnxHelper::Transpose(const std::string &input, + const std::vector &perm) { auto output = MapperHelper::Get()->GenName("helper.transpose"); return Transpose(input, output, perm); } std::vector OnnxHelper::Split( - const std::string& input, const std::vector& outputs, - const std::vector& split, int64_t axis) { + const std::string &input, + const std::vector &outputs, + const std::vector &split, + int64_t axis) { Assert(outputs.size() > 0 || split.size() > 0, "OnnxHelper::Split requires the size of outputs or the size of split " "> 0."); @@ -494,8 +508,8 @@ std::vector OnnxHelper::Split( return outputs; } -std::vector OnnxHelper::Split(const std::string& input, - const std::vector& split, +std::vector OnnxHelper::Split(const std::string &input, + const std::vector &split, int64_t axis) { Assert(split.size() > 0, "OnnxHelper::Split requires the size of parameter split > 0."); @@ -506,7 +520,8 @@ std::vector OnnxHelper::Split(const std::string& input, return Split(input, outputs, split, axis); } std::vector OnnxHelper::DtypeAlignment( - const std::vector& input_info, int32_t* out_dtype) { + const std::vector &input_info, + int32_t *out_dtype) { Assert(input_info.size() > 0, "OnnxHelper::DtypeAlignment requires the size of input info > 0."); std::vector input_dtypes; @@ -531,4 +546,44 @@ std::vector OnnxHelper::DtypeAlignment( return casted_node; } -} // namespace paddle2onnx + +ONNX_NAMESPACE::Version OnnxHelper::GetIRVersion() const { + int ir_version = 0; + switch (opset_version) { + case 7: + case 8: + ir_version = 3; + break; + case 9: + ir_version = 4; + break; + case 10: + ir_version = 5; + break; + case 11: + ir_version = 6; + break; + case 12: + case 13: + case 14: + ir_version = 7; + break; + case 15: + case 16: + case 17: + case 18: + ir_version = 8; + break; + case 19: + case 20: + ir_version = 9; + break; + case 21: + ir_version = 10; + break; + default: + Assert(false, "Opset version must be 7-20"); + } + return static_cast(ir_version); +} +} // namespace paddle2onnx diff --git a/paddle2onnx/mapper/onnx_helper.h b/paddle2onnx/mapper/onnx_helper.h index 5958eb38f..4696bca5b 100644 --- a/paddle2onnx/mapper/onnx_helper.h +++ b/paddle2onnx/mapper/onnx_helper.h @@ -24,181 +24,206 @@ #include "paddle2onnx/parser/parser.h" namespace paddle2onnx { - -void AddAttribute(std::shared_ptr node, - const std::string& name, const int64_t& value); -void AddAttribute(std::shared_ptr node, - const std::string& name, const float& value); -void AddAttribute(std::shared_ptr node, - const std::string& name, const std::string& value); +void AddAttribute(std::shared_ptr node, const std::string &name, const int64_t &value); +void AddAttribute(std::shared_ptr node, const std::string &name, const float &value); +void AddAttribute(std::shared_ptr node, const std::string &name, const std::string &value); void AddAttribute(std::shared_ptr node, - const std::string& name, const std::vector& values); + const std::string &name, + const std::vector &values); void AddAttribute(std::shared_ptr node, - const std::string& name, const std::vector& values); + const std::string &name, + const std::vector &values); void AddAttribute(std::shared_ptr node, - const std::string& name, + const std::string &name, ONNX_NAMESPACE::TensorProto_DataType dtype); ONNX_NAMESPACE::TensorProto_DataType GetOnnxDtype(int32_t paddle_dtype); -std::shared_ptr MakeConstant(const std::string& name, - const Weight& weight); -std::shared_ptr MakeValueInfo( - const TensorInfo& info); +std::shared_ptr MakeConstant(const std::string &name, const Weight &weight); +std::shared_ptr MakeValueInfo(const TensorInfo &info); struct QuantizeInfo { - public: - std::vector scale_; - std::vector zeros_; - std::string zeros_node_; - std::string scale_node_; - int64_t quantize_axis_; - - QuantizeInfo() {} - QuantizeInfo(const std::vector& scale, - const std::vector& zeros, const std::string& scale_node, - const std::string& zeros_node, const int64_t& quantize_axis) { - zeros_node_ = zeros_node; - scale_node_ = scale_node; - quantize_axis_ = quantize_axis; - scale_.resize(scale.size()); - memcpy(scale_.data(), scale.data(), scale.size() * sizeof(float)); - zeros_.resize(zeros.size()); - memcpy(zeros_.data(), zeros.data(), zeros.size() * sizeof(int64_t)); - } + public: + std::vector scale_; + std::vector zeros_; + std::string zeros_node_; + std::string scale_node_; + int64_t quantize_axis_; + + QuantizeInfo() = default; + QuantizeInfo(const std::vector &scale, + const std::vector &zeros, + const std::string &scale_node, + const std::string &zeros_node, + const int64_t &quantize_axis) { + zeros_node_ = zeros_node; + scale_node_ = scale_node; + quantize_axis_ = quantize_axis; + scale_.resize(scale.size()); + memcpy(scale_.data(), scale.data(), scale.size() * sizeof(float)); + zeros_.resize(zeros.size()); + memcpy(zeros_.data(), zeros.data(), zeros.size() * sizeof(int64_t)); + } }; class OnnxHelper { - public: - std::vector> nodes; - std::vector> value_infos; - int32_t opset_version = 7; - // Use updated_params to store params that were changed during conversion - std::map updated_params; - // Use quantize_info to record quantization-related information, scale and - // zero information corresponding to each tensor - std::map quantize_info; - - void Clear() { nodes.clear(); } - - void SetOpsetVersion(int32_t op_v) { opset_version = op_v; } - - int32_t GetOpsetVersion() { return opset_version; } - - template - bool TryGetTensorValue(const std::string& name, std::vector* value); - - std::shared_ptr MakeValueInfo( - const std::string& name, const int32_t& dtype, - std::vector& shape); - - std::shared_ptr MakeNode( - const std::string& op_type, const std::vector& inputs, - const std::vector& outputs); - // we use this function to generate some temporary node - // we do not need to define the outputs, because the outputs - // is generate by MapperHelper, which will make sure there's no - // name confict problem - // the parameter `num_outputs` will define the number of output names - std::shared_ptr MakeNode( - const std::string& op_type, const std::vector& inputs, + public: + std::vector > nodes; + std::vector > value_infos; + int32_t opset_version = 7; + // Use updated_params to store params that were changed during conversion + std::map updated_params; + // Use quantize_info to record quantization-related information, scale and + // zero information corresponding to each tensor + std::map quantize_info; + + void Clear() { nodes.clear(); } + + void SetOpsetVersion(int32_t op_v) { opset_version = op_v; } + + int32_t GetOpsetVersion() const { return opset_version; } + + template + bool TryGetTensorValue(const std::string &name, std::vector *value); + + std::shared_ptr MakeValueInfo( + const std::string &name, + const int32_t &dtype, + std::vector &shape); + + std::shared_ptr MakeNode( + const std::string &op_type, + const std::vector &inputs, + const std::vector &outputs); + // we use this function to generate some temporary node + // we do not need to define the outputs, because the outputs + // is generate by MapperHelper, which will make sure there's no + // name confict problem + // the parameter `num_outputs` will define the number of output names + std::shared_ptr MakeNode( + const std::string &op_type, + const std::vector &inputs, int num_outputs = 1); - template - std::string ConstOfShape(const std::string& input, const std::string& output, - ONNX_NAMESPACE::TensorProto_DataType dtype, T value); - template - std::string ConstOfShape(const std::string& input, - ONNX_NAMESPACE::TensorProto_DataType dtype, T value); - - std::string AutoCast(const std::string& input, int32_t input_paddle_dtype, - int32_t to_paddle_dtype); - std::string AutoCast(const std::string& input, const std::string& output, - int32_t input_paddle_dtype, int32_t to_paddle_dtype); - - // Helper function for PaddlePaddle's shape tensor list inputs - // will cast all data type to int64 - // will make sure all inputs to be 1-D tensor - // will concat them as output - std::string ConcatIndices(const std::vector& indices); - std::vector DtypeAlignment( - const std::vector& input_info, int32_t* out_dtype); - std::string Clip(const std::string& input, const float& min, const float& max, - const int32_t& in_dtype); - std::string Clip(const std::string& input, const std::string& output, - const float& min, const float& max, const int32_t& in_dtype); - std::string Squeeze(const std::string& input, - const std::vector& axes); - std::string Squeeze(const std::string& input, const std::string& output, - const std::vector& axes); - std::string Unsqueeze(const std::string& input, - const std::vector& axes); - std::string Unsqueeze(const std::string& input, const std::string& output, - const std::vector& axes); - std::string Reshape(const std::string& input, const std::string& output, - const std::vector& shape); - std::string Reshape(const std::string& input, - const std::vector& shape); - std::string Flatten(const std::string& input, const std::string& output); - std::string Flatten(const std::string& input); - std::string Slice(const std::string& input, const std::string& output, - const std::vector& axes, - const std::vector& starts, - const std::vector& ends); - std::string Slice(const std::string& input, const std::vector& axes, - const std::vector& starts, - const std::vector& ends); - std::string Concat(const std::vector& input, - const std::string& output, int64_t axis); - std::string Concat(const std::vector& input, int64_t axis); - - std::string Transpose(const std::string& input, const std::string& output, - const std::vector& perm); - std::string Transpose(const std::string& input, - const std::vector& perm); - - std::vector Split(const std::string& input, - const std::vector& outputs, - const std::vector& split, - int64_t axis); - std::vector Split(const std::string& input, - const std::vector& split, - int64_t axis); - - template - std::string Constant(const std::string& output, - ONNX_NAMESPACE::TensorProto_DataType dtype, - const std::vector& value); - template - std::string Constant(ONNX_NAMESPACE::TensorProto_DataType dtype, - const std::vector& value); - template - std::string Constant(const std::string& output, - const std::vector& shape, - ONNX_NAMESPACE::TensorProto_DataType dtype, T value); - template - std::string Constant(const std::vector& shape, - ONNX_NAMESPACE::TensorProto_DataType dtype, T value); - - template - std::string Constant(const std::vector& shape, - ONNX_NAMESPACE::TensorProto_DataType dtype, - std::vector& value); - - template - std::string Assign(const std::string& output, - const ONNX_NAMESPACE::TensorProto_DataType& dtype, - const std::vector& shape, - const std::vector& value); - template - std::string Assign(const ONNX_NAMESPACE::TensorProto_DataType& dtype, - const std::vector& shape, - const std::vector& value); + template + std::string ConstOfShape(const std::string &input, + const std::string &output, + ONNX_NAMESPACE::TensorProto_DataType dtype, + T value); + template + std::string ConstOfShape(const std::string &input, + ONNX_NAMESPACE::TensorProto_DataType dtype, + T value); + + std::string AutoCast(const std::string &input, + int32_t input_paddle_dtype, + int32_t to_paddle_dtype); + std::string AutoCast(const std::string &input, + const std::string &output, + int32_t input_paddle_dtype, + int32_t to_paddle_dtype); + + // Helper function for PaddlePaddle's shape tensor list inputs + // will cast all data type to int64 + // will make sure all inputs to be 1-D tensor + // will concat them as output + std::string ConcatIndices(const std::vector &indices); + std::vector DtypeAlignment( + const std::vector &input_info, + int32_t *out_dtype); + std::string Clip(const std::string &input, + const float &min, + const float &max, + const int32_t &in_dtype); + std::string Clip(const std::string &input, + const std::string &output, + const float &min, + const float &max, + const int32_t &in_dtype); + std::string Squeeze(const std::string &input, + const std::vector &axes); + std::string Squeeze(const std::string &input, + const std::string &output, + const std::vector &axes); + std::string Unsqueeze(const std::string &input, + const std::vector &axes); + std::string Unsqueeze(const std::string &input, + const std::string &output, + const std::vector &axes); + std::string Reshape(const std::string &input, + const std::string &output, + const std::vector &shape); + std::string Reshape(const std::string &input, + const std::vector &shape); + std::string Flatten(const std::string &input, const std::string &output); + std::string Flatten(const std::string &input); + std::string Slice(const std::string &input, + const std::string &output, + const std::vector &axes, + const std::vector &starts, + const std::vector &ends); + std::string Slice(const std::string &input, + const std::vector &axes, + const std::vector &starts, + const std::vector &ends); + std::string Concat(const std::vector &input, + const std::string &output, + int64_t axis); + std::string Concat(const std::vector &input, int64_t axis); + + std::string Transpose(const std::string &input, + const std::string &output, + const std::vector &perm); + std::string Transpose(const std::string &input, + const std::vector &perm); + + std::vector Split(const std::string &input, + const std::vector &outputs, + const std::vector &split, + int64_t axis); + std::vector Split(const std::string &input, + const std::vector &split, + int64_t axis); + + template + std::string Constant(const std::string &output, + ONNX_NAMESPACE::TensorProto_DataType dtype, + const std::vector &value); + template + std::string Constant(ONNX_NAMESPACE::TensorProto_DataType dtype, + const std::vector &value); + template + std::string Constant(const std::string &output, + const std::vector &shape, + ONNX_NAMESPACE::TensorProto_DataType dtype, + T value); + template + std::string Constant(const std::vector &shape, + ONNX_NAMESPACE::TensorProto_DataType dtype, + T value); + + template + std::string Constant(const std::vector &shape, + ONNX_NAMESPACE::TensorProto_DataType dtype, + std::vector &value); + + template + std::string Assign(const std::string &output, + const ONNX_NAMESPACE::TensorProto_DataType &dtype, + const std::vector &shape, + const std::vector &value); + template + std::string Assign(const ONNX_NAMESPACE::TensorProto_DataType &dtype, + const std::vector &shape, + const std::vector &value); + + ONNX_NAMESPACE::Version GetIRVersion() const; }; -template -std::string OnnxHelper::Constant(const std::vector& shape, + +template +std::string OnnxHelper::Constant(const std::vector &shape, ONNX_NAMESPACE::TensorProto_DataType dtype, - std::vector& value) { + std::vector &value) { auto node = std::make_shared(); node->set_op_type("Constant"); auto name = MapperHelper::Get()->GenName("const"); @@ -221,30 +246,30 @@ std::string OnnxHelper::Constant(const std::vector& shape, if (dtype == ONNX_NAMESPACE::TensorProto::FLOAT) { std::vector data; data.reserve(numel); - for (auto& i : value) { + for (auto &i : value) { data.push_back(static_cast(i)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 4)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 4)); } else if (dtype == ONNX_NAMESPACE::TensorProto::DOUBLE) { std::vector data; data.reserve(numel); - for (auto& i : value) { + for (auto &i : value) { data.push_back(static_cast(i)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 8)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 8)); } else if (dtype == ONNX_NAMESPACE::TensorProto::INT64) { std::vector data; data.reserve(numel); - for (auto& i : value) { + for (auto &i : value) { data.push_back(static_cast(i)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 8)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 8)); } else if (dtype == ONNX_NAMESPACE::TensorProto::BOOL) { - bool* data = new bool[numel]; + bool *data = new bool[numel]; for (size_t i = 0; i < numel; ++i) { data[i] = static_cast(value[i]); } - tensor->set_raw_data(std::string((const char*)(data), numel)); + tensor->set_raw_data(std::string((const char *)(data), numel)); delete[] data; } else { Assert(false, @@ -255,10 +280,10 @@ std::string OnnxHelper::Constant(const std::vector& shape, return node->output(0); } -template -std::string OnnxHelper::Constant(const std::string& output, +template +std::string OnnxHelper::Constant(const std::string &output, ONNX_NAMESPACE::TensorProto_DataType dtype, - const std::vector& value) { + const std::vector &value) { auto node = std::make_shared(); node->set_op_type("Constant"); node->add_output(output); @@ -277,62 +302,60 @@ std::string OnnxHelper::Constant(const std::string& output, } if (dtype == ONNX_NAMESPACE::TensorProto::FLOAT) { std::vector data; - for (auto& item : value) { + for (auto &item : value) { data.push_back(static_cast(item)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 4)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 4)); } else if (dtype == ONNX_NAMESPACE::TensorProto::DOUBLE) { std::vector data; - for (auto& item : value) { + for (auto &item : value) { data.push_back(static_cast(item)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 8)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 8)); } else if (dtype == ONNX_NAMESPACE::TensorProto::INT64) { std::vector data; - for (auto& item : value) { + for (auto &item : value) { data.push_back(static_cast(item)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 8)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 8)); } else if (dtype == ONNX_NAMESPACE::TensorProto::INT32) { std::vector data; - for (auto& item : value) { + for (auto &item : value) { data.push_back(static_cast(item)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 4)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 4)); } else if (dtype == ONNX_NAMESPACE::TensorProto::BOOL) { - bool* data = new bool[numel]; + bool *data = new bool[numel]; for (size_t i = 0; i < numel; ++i) { data[i] = static_cast(value[i]); } - tensor->set_raw_data(std::string((const char*)(data), numel)); + tensor->set_raw_data(std::string((const char *)(data), numel)); delete[] data; } else if (dtype == ONNX_NAMESPACE::TensorProto::INT8) { std::vector data; data.reserve(numel); - for (auto& i : value) { + for (auto &i : value) { data.push_back(static_cast(i)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel)); } else { Assert(false, - "Only support data type of BOOL/FLOAT/DOUBLE/INT32/INT64/INT8 in " - "Constant " - "function."); + "Only support data type of BOOL/FLOAT/DOUBLE/INT32/INT64/INT8 in Constant function."); } nodes.push_back(node); return output; } -template +template std::string OnnxHelper::Constant(ONNX_NAMESPACE::TensorProto_DataType dtype, - const std::vector& value) { + const std::vector &value) { auto output = MapperHelper::Get()->GenName("helper.constant"); return Constant(output, dtype, value); } -template -std::string OnnxHelper::Constant(const std::string& output, - const std::vector& shape, +template +std::string OnnxHelper::Constant(const std::string &output, + const std::vector &shape, ONNX_NAMESPACE::TensorProto_DataType dtype, T value) { auto node = std::make_shared(); @@ -352,55 +375,54 @@ std::string OnnxHelper::Constant(const std::string& output, tensor->set_data_type(dtype); if (dtype == ONNX_NAMESPACE::TensorProto::FLOAT) { std::vector data(numel, static_cast(value)); - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 4)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 4)); } else if (dtype == ONNX_NAMESPACE::TensorProto::DOUBLE) { std::vector data(numel, static_cast(value)); - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 8)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 8)); } else if (dtype == ONNX_NAMESPACE::TensorProto::INT64) { std::vector data(numel, static_cast(value)); - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 8)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 8)); } else if (dtype == ONNX_NAMESPACE::TensorProto::INT32) { std::vector data(numel, static_cast(value)); - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 4)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 4)); } else if (dtype == ONNX_NAMESPACE::TensorProto::INT8) { std::vector data(numel, static_cast(value)); - tensor->set_raw_data(std::string((const char*)(data.data()), numel)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel)); } else if (dtype == ONNX_NAMESPACE::TensorProto::BOOL) { - bool* data = new bool[numel]; + bool *data = new bool[numel]; for (size_t i = 0; i < numel; ++i) { data[i] = static_cast(value); } - tensor->set_raw_data(std::string((const char*)(data), numel)); + tensor->set_raw_data(std::string((const char *)(data), numel)); delete[] data; } else { Assert( - false, - "Only support data type of BOOL/FLOAT/DOUBLE/INT32/INT64 in Constant " - "function."); + false, + "Only support data type of BOOL/FLOAT/DOUBLE/INT32/INT64 in Constant function."); } nodes.push_back(node); return output; } -template -std::string OnnxHelper::Constant(const std::vector& shape, +template +std::string OnnxHelper::Constant(const std::vector &shape, ONNX_NAMESPACE::TensorProto_DataType dtype, T value) { auto output = MapperHelper::Get()->GenName("helper.constant"); return Constant(output, shape, dtype, value); } -template -std::string OnnxHelper::ConstOfShape(const std::string& input, +template +std::string OnnxHelper::ConstOfShape(const std::string &input, ONNX_NAMESPACE::TensorProto_DataType dtype, T value) { auto output = MapperHelper::Get()->GenName("helper.constofshape"); return ConstOfShape(input, output, dtype, value); } -template -std::string OnnxHelper::ConstOfShape(const std::string& input, - const std::string& output, +template +std::string OnnxHelper::ConstOfShape(const std::string &input, + const std::string &output, ONNX_NAMESPACE::TensorProto_DataType dtype, T value) { auto node = MakeNode("ConstantOfShape", {input}, {output}); @@ -418,29 +440,29 @@ std::string OnnxHelper::ConstOfShape(const std::string& input, tensor->set_data_type(dtype); if (dtype == ONNX_NAMESPACE::TensorProto::FLOAT) { std::vector data(numel, static_cast(value)); - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 4)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 4)); } else if (dtype == ONNX_NAMESPACE::TensorProto::DOUBLE) { std::vector data(numel, static_cast(value)); - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 8)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 8)); } else if (dtype == ONNX_NAMESPACE::TensorProto::INT64) { std::vector data(numel, static_cast(value)); - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 8)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 8)); } else if (dtype == ONNX_NAMESPACE::TensorProto::INT32) { std::vector data(numel, static_cast(value)); - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 4)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 4)); } else { Assert(false, - "Only support data type of FLOAT/DOUBLE/INT64/INT32 in ConstOfShape " - "function."); + "Only support data type of FLOAT/DOUBLE/INT64/INT32 in ConstOfShape function."); } return output; } -template +template std::string OnnxHelper::Assign( - const std::string& output, - const ONNX_NAMESPACE::TensorProto_DataType& dtype, - const std::vector& shape, const std::vector& value) { + const std::string &output, + const ONNX_NAMESPACE::TensorProto_DataType &dtype, + const std::vector &shape, + const std::vector &value) { auto node = std::make_shared(); node->set_op_type("Constant"); node->add_output(output); @@ -450,112 +472,117 @@ std::string OnnxHelper::Assign( auto tensor = attr->mutable_t(); tensor->set_name(output); - int numel = std::accumulate(std::begin(shape), std::end(shape), 1, + int numel = std::accumulate(std::begin(shape), + std::end(shape), + 1, std::multiplies()); Assert(numel == value.size(), - "Numel of value not satisfy the input shape while creating contant " - "tensor."); + "Numel of value not satisfy the input shape while creating contant tensor."); for (size_t i = 0; i < shape.size(); ++i) { tensor->add_dims(shape[i]); } tensor->set_data_type(dtype); if (dtype == ONNX_NAMESPACE::TensorProto::FLOAT) { std::vector data; - for (auto& item : value) { + for (auto &item : value) { data.push_back(static_cast(item)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 4)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 4)); } else if (dtype == ONNX_NAMESPACE::TensorProto::DOUBLE) { std::vector data; - for (auto& item : value) { + for (auto &item : value) { data.push_back(static_cast(item)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 8)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 8)); } else if (dtype == ONNX_NAMESPACE::TensorProto::INT64) { std::vector data; - for (auto& item : value) { + for (auto &item : value) { data.push_back(static_cast(item)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 8)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 8)); } else if (dtype == ONNX_NAMESPACE::TensorProto::INT32) { std::vector data; - for (auto& item : value) { + for (auto &item : value) { data.push_back(static_cast(item)); } - tensor->set_raw_data(std::string((const char*)(data.data()), numel * 4)); + tensor->set_raw_data(std::string((const char *)(data.data()), numel * 4)); } else { Assert(false, - "Only support data type of FLOAT/DOUBLE/INT32/INT64 in Constant " - "function."); + "Only support data type of FLOAT/DOUBLE/INT32/INT64 in Constant function."); } nodes.push_back(node); return output; } -template +template std::string OnnxHelper::Assign( - const ONNX_NAMESPACE::TensorProto_DataType& dtype, - const std::vector& shape, const std::vector& value) { + const ONNX_NAMESPACE::TensorProto_DataType &dtype, + const std::vector &shape, + const std::vector &value) { auto output = MapperHelper::Get()->GenName("helper.constant"); return Assign(output, dtype, shape, value); } -template -bool OnnxHelper::TryGetTensorValue(const std::string& name, - std::vector* value) { +template +bool OnnxHelper::TryGetTensorValue(const std::string &name, std::vector *value) { for (auto iter = nodes.begin(); iter != nodes.end(); iter++) { auto node = *iter; if (node->op_type() != "Constant") { continue; } - if (node->output(0) == name) { - for (auto i = 0; i < node->attribute_size(); i++) { - auto attr = node->attribute(i); - if (attr.name() == "value") { - auto tensor = attr.mutable_t(); - auto dtype = tensor->data_type(); - std::vector shape; - for (int64_t i = 0; i < tensor->dims_size(); i++) { - shape.push_back(tensor->dims(i)); - } - int64_t nums = 1; - for (auto& i : shape) nums *= i; - value->resize(nums); - if (dtype == ONNX_NAMESPACE::TensorProto::INT64) { - std::vector val(nums, 0); - memcpy(val.data(), tensor->raw_data().data(), - nums * sizeof(int64_t)); - value->assign(val.begin(), val.end()); - return true; - } else if (dtype == ONNX_NAMESPACE::TensorProto::INT32) { - std::vector val(nums, 0); - memcpy(val.data(), tensor->raw_data().data(), - nums * sizeof(int32_t)); - value->assign(val.begin(), val.end()); - return true; - } else if (dtype == ONNX_NAMESPACE::TensorProto::FLOAT) { - std::vector val(nums, 0); - memcpy(val.data(), tensor->raw_data().data(), nums * sizeof(float)); - value->assign(val.begin(), val.end()); - return true; - } else if (dtype == ONNX_NAMESPACE::TensorProto::DOUBLE) { - std::vector val(nums, 0); - memcpy(val.data(), tensor->raw_data().data(), - nums * sizeof(double)); - value->assign(val.begin(), val.end()); - return true; - } else { - P2OLogger() << "[WARNING] OnnxHelper function TryGetTensorValue " - "only support get int64_t/int32_t/float/double " - "value from Constant now." - << std::endl; - return false; - } - } + if (node->output(0) != name) { + continue; + } + + for (auto i = 0; i < node->attribute_size(); i++) { + auto attr = node->attribute(i); + if (attr.name() != "value") { + continue; + } + auto tensor = attr.mutable_t(); + auto dtype = tensor->data_type(); + std::vector shape; + for (int64_t i = 0; i < tensor->dims_size(); i++) { + shape.push_back(tensor->dims(i)); + } + int64_t nums = 1; + for (auto &i : shape) nums *= i; + value->resize(nums); + if (dtype == ONNX_NAMESPACE::TensorProto::INT64) { + std::vector val(nums, 0); + memcpy(val.data(), + tensor->raw_data().data(), + nums * sizeof(int64_t)); + value->assign(val.begin(), val.end()); + return true; + } else if (dtype == ONNX_NAMESPACE::TensorProto::INT32) { + std::vector val(nums, 0); + memcpy(val.data(), + tensor->raw_data().data(), + nums * sizeof(int32_t)); + value->assign(val.begin(), val.end()); + return true; + } else if (dtype == ONNX_NAMESPACE::TensorProto::FLOAT) { + std::vector val(nums, 0); + memcpy(val.data(), tensor->raw_data().data(), nums * sizeof(float)); + value->assign(val.begin(), val.end()); + return true; + } else if (dtype == ONNX_NAMESPACE::TensorProto::DOUBLE) { + std::vector val(nums, 0); + memcpy(val.data(), + tensor->raw_data().data(), + nums * sizeof(double)); + value->assign(val.begin(), val.end()); + return true; + } else { + P2OLogger() << + "[WARNING] OnnxHelper function TryGetTensorValue only support get int64_t/int32_t/float/double value from Constant now." + << std::endl; + return false; } } } return false; } -} // namespace paddle2onnx +} // namespace paddle2onnx