From e4093339ca2c5a4a55a2865d22df41ecdff05bf7 Mon Sep 17 00:00:00 2001 From: y00500818 Date: Sat, 27 Nov 2021 15:21:15 +0800 Subject: [PATCH] onnx parser st --- parser/onnx/onnx_util.cc | 20 ------- parser/onnx/onnx_util.h | 1 - tests/depends/ops_stub/ops_stub.h | 39 +++++++++++++ tests/st/parser_st_utils.cc | 64 +++++++++++++++++++++ tests/st/parser_st_utils.h | 6 ++ tests/st/testcase/origin_models/onnx_clip_v9.onnx | Bin 0 -> 136 bytes tests/st/testcase/origin_models/onnx_clip_v9.py | 28 +++++++++ .../st/testcase/origin_models/onnx_const_type.onnx | Bin 0 -> 528 bytes tests/st/testcase/test_onnx_parser.cc | 45 +++++++++++++++ 9 files changed, 182 insertions(+), 21 deletions(-) create mode 100644 tests/st/testcase/origin_models/onnx_clip_v9.onnx create mode 100644 tests/st/testcase/origin_models/onnx_clip_v9.py create mode 100644 tests/st/testcase/origin_models/onnx_const_type.onnx diff --git a/parser/onnx/onnx_util.cc b/parser/onnx/onnx_util.cc index 72ba260..d9f036a 100644 --- a/parser/onnx/onnx_util.cc +++ b/parser/onnx/onnx_util.cc @@ -29,17 +29,6 @@ const std::map onnx_data_type_map = { {OnnxDataType::COMPLEX64, ge::DataType::DT_COMPLEX64}, {OnnxDataType::COMPLEX128, ge::DataType::DT_COMPLEX128}, {OnnxDataType::BFLOAT16, ge::DataType::DT_UNDEFINED}, }; - -const std::map onnx_data_type_size_map = { - {OnnxDataType::FLOAT, sizeof(float)}, {OnnxDataType::UINT8, sizeof(uint8_t)}, - {OnnxDataType::INT8, sizeof(int8_t)}, {OnnxDataType::UINT16, sizeof(uint16_t)}, - {OnnxDataType::INT16, sizeof(int16_t)}, {OnnxDataType::INT32, sizeof(int32_t)}, - {OnnxDataType::INT64, sizeof(int64_t)}, {OnnxDataType::STRING, sizeof(std::string)}, - {OnnxDataType::BOOL, sizeof(bool)}, {OnnxDataType::FLOAT16, 2}, - {OnnxDataType::DOUBLE, sizeof(double)}, {OnnxDataType::UINT32, sizeof(uint32_t)}, - {OnnxDataType::UINT64, sizeof(uint64_t)}, {OnnxDataType::COMPLEX64, 8}, - {OnnxDataType::COMPLEX128, 16}, {OnnxDataType::BFLOAT16, 2}, -}; } namespace ge { @@ -52,15 +41,6 @@ ge::DataType OnnxUtil::ConvertOnnxDataType(int64_t onnx_data_type) { } } -int64_t OnnxUtil::CaculateDataSize(int64_t onnx_data_type) { - auto search = onnx_data_type_size_map.find(onnx_data_type); - if (search != onnx_data_type_size_map.end()) { - return search->second; - } else { - return ge::DataType::DT_UNDEFINED; - } -} - void OnnxUtil::GenUniqueSubgraphName(int subgraph_index, const std::string &original_subgraph_name, const std::string &parent_node_name, std::string &unique_subgraph_name) { unique_subgraph_name = parent_node_name + "_" + std::to_string(subgraph_index) + "_" + original_subgraph_name; diff --git a/parser/onnx/onnx_util.h b/parser/onnx/onnx_util.h index c8ffa8c..6fab6fc 100644 --- a/parser/onnx/onnx_util.h +++ b/parser/onnx/onnx_util.h @@ -52,7 +52,6 @@ const char *const kOpTypeInput = "Input"; class OnnxUtil { public: static ge::DataType ConvertOnnxDataType(int64_t onnx_data_type); - static int64_t CaculateDataSize(int64_t onnx_data_type); static void GenUniqueSubgraphName(int subgraph_index, const std::string &original_subgraph_name, const std::string &parent_node_name, std::string &unique_subgraph_name); }; diff --git a/tests/depends/ops_stub/ops_stub.h b/tests/depends/ops_stub/ops_stub.h index de34559..0299df1 100644 --- a/tests/depends/ops_stub/ops_stub.h +++ b/tests/depends/ops_stub/ops_stub.h @@ -19,6 +19,7 @@ #include "external/graph/operator_reg.h" #include "register/op_registry.h" +#include "graph/utils/op_desc_utils.h" namespace ge { // for ir @@ -99,6 +100,14 @@ REG_OP(Abs) .OUTPUT(y, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE, DT_INT32, DT_INT64})) .OP_END_FACTORY_REG(Abs) +REG_OP(PartitionedCall) + .DYNAMIC_INPUT(args, TensorType::ALL()) + .DYNAMIC_OUTPUT(output, TensorType::ALL()) + .GRAPH(f) + .ATTR(config, String, "") + .ATTR(config_proto, String, "") + .ATTR(executor_type, String, "") + .OP_END_FACTORY_REG(PartitionedCall) // for plugin static Status ParseParamsStub(const google::protobuf::Message* op_src, ge::Operator& op_dest) { @@ -127,6 +136,29 @@ static Status ParseSubgraphPostFnIfStub(const std::string& subgraph_name, const }); } +static Status ParseParamsClipV9Stub(const Message* op_src, ge::Operator& op_dest) { + auto opDesc = ge::OpDescUtils::GetOpDescFromOperator(op_dest); + // 1.add dynamic input and out + opDesc->AddDynamicInputDesc("x", 1); + opDesc->AddDynamicOutputDesc("output", 1); + + // 2.set original_type + ge::AttrUtils::SetStr(opDesc, "original_type", "ai.onnx::9::Clip"); + return SUCCESS; +} + +static Status ParseOpToGraphClipV9Stub(const Operator& op, Graph& graph) { + auto data0 = op::Data("data0").set_attr_index(0); + auto abs0 = op::Abs("abs0").set_input_x(data0); + + std::vector inputs{data0}; + std::vector > > output_indexs; + output_indexs.emplace_back(abs0, vector{0}); + graph.SetInputs(inputs).SetOutputs(output_indexs); + return SUCCESS; +} + + // caffe plugin REGISTER_CUSTOM_OP("Data") .FrameworkType(domi::CAFFE) @@ -170,5 +202,12 @@ REGISTER_CUSTOM_OP("Add") .FrameworkType(domi::TENSORFLOW) .OriginOpType("Add") .ParseParamsFn(ParseParamsStub); + + +REGISTER_CUSTOM_OP("PartitionedCall") + .FrameworkType(domi::ONNX) + .OriginOpType({"ai.onnx::9::Clip"}) + .ParseParamsFn(ParseParamsClipV9Stub) + .ParseOpToGraphFn(ParseOpToGraphClipV9Stub); } // namespace ge #endif // MAIN_OPS_STUB_H diff --git a/tests/st/parser_st_utils.cc b/tests/st/parser_st_utils.cc index ba04212..81248df 100644 --- a/tests/st/parser_st_utils.cc +++ b/tests/st/parser_st_utils.cc @@ -16,6 +16,7 @@ #include "st/parser_st_utils.h" #include "framework/common/debug/ge_log.h" +#include namespace ge { void ParerSTestsUtils::ClearParserInnerCtx() { @@ -41,4 +42,67 @@ void ParerSTestsUtils::ClearParserInnerCtx() { ge::GetParserContext().enable_scope_fusion_passes = ""; GELOGI("Clear parser inner context successfully."); } + +MemBuffer* ParerSTestsUtils::MemBufferFromFile(const char *path) { + char path_temp[PATH_MAX + 1] = {0x00}; + if(strlen(path) > PATH_MAX || nullptr == realpath(path, path_temp)) { + return nullptr; + } + FILE *fp = fopen(path_temp, "r+"); + if (fp == nullptr) { + return nullptr; + } + + // get model file length + if (0 != fseek(fp, 0, SEEK_END)) { + fclose(fp); + return nullptr; + } + long file_length = ftell(fp); + if (fseek(fp, 0, SEEK_SET)) { + fclose(fp); + return nullptr; + } + if (file_length <= 0) { + fclose(fp); + return nullptr; + } + + // alloc model buffer + void *data = malloc((unsigned int)file_length); + if (!data) { + fclose(fp); + return nullptr; + } + + // read file into memory + uint32_t read_size = (uint32_t)fread(data, 1, (unsigned int)file_length, fp); + + // check if read success + if ((long)read_size != file_length) { + free(data); + data = nullptr; + fclose(fp); + return nullptr; + } + + // close model file + fclose(fp); + + // create an MemBuffer + MemBuffer* membuf = new MemBuffer(); + if (!membuf) { + free(data); + data = nullptr; + return nullptr; + } + membuf->data = malloc((unsigned int)read_size); + + // set size && data + membuf->size = (uint32_t)read_size; + memcpy((char*)membuf->data, (char*)data, read_size); + free(data); + return membuf; +} + } // namespace ge diff --git a/tests/st/parser_st_utils.h b/tests/st/parser_st_utils.h index 50b6d06..89f3088 100644 --- a/tests/st/parser_st_utils.h +++ b/tests/st/parser_st_utils.h @@ -20,9 +20,15 @@ #include "framework/omg/parser/parser_inner_ctx.h" namespace ge { +struct MemBuffer { + void *data; + uint32_t size; +}; + class ParerSTestsUtils { public: static void ClearParserInnerCtx(); + static MemBuffer* MemBufferFromFile(const char *path); }; } // namespace ge diff --git a/tests/st/testcase/origin_models/onnx_clip_v9.onnx b/tests/st/testcase/origin_models/onnx_clip_v9.onnx new file mode 100644 index 0000000000000000000000000000000000000000..1650087f198f535f5ad155c0ab31d8c6fc092083 GIT binary patch literal 136 zcmV;30C)cg2NDf$ZfJt&0D!-s0Ra*bbY*jNUt?@(a9?9#b7fyvIa(JA0ay|e3J?eZ5)29g q2m=ZN2m}fO2nAvn3ISOX5(*Fq0TK)f0tf>N0tf^O0tf{{0uTv;BpIOq literal 0 KcmV+b0RR6000031 diff --git a/tests/st/testcase/origin_models/onnx_clip_v9.py b/tests/st/testcase/origin_models/onnx_clip_v9.py new file mode 100644 index 0000000..476a0aa --- /dev/null +++ b/tests/st/testcase/origin_models/onnx_clip_v9.py @@ -0,0 +1,28 @@ +import onnx +from onnx import helper +from onnx import AttributeProto, TensorProto, GraphProto + + +def make_clip_V9(): + X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [3, 4, 5]) + Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [3, 4, 5]) + node_def = helper.make_node('Clip', + inputs=['X'], + outputs=['Y'], + max = 1.0, + min = -1.0, + ) + graph = helper.make_graph( + [node_def], + "test_clip_case_V9", + [X], + [Y], + ) + + model = helper.make_model(graph, producer_name="onnx-mul_test") + model.opset_import[0].version = 9 + onnx.save(model, "./onnx_clip_v9.onnx") + + +if __name__ == '__main__': + make_clip_V9() diff --git a/tests/st/testcase/origin_models/onnx_const_type.onnx b/tests/st/testcase/origin_models/onnx_const_type.onnx new file mode 100644 index 0000000000000000000000000000000000000000..342b385d68a9724ab13b97bc15a0a20b24287b8f GIT binary patch literal 528 zcmV+r0`L6@2oex)Zf^)WMm2)3IRb1 z0zxzr0z)(!3Up<2bYEd)WM4EQ13_eD3LFXnK?(vwH4*|tH5v+ZWpi|2VPs@qH6jB+ zWMmQwbY*jNUt@1>b95>W2muHJ5C=K}0Rln-LNF>02muHJ5Dh{CLNQtb0Rk!<2muHJ z5Dp>`004kL000000000$00000LIOfEDi8<(2m%lYG669%0Wv}YLNh8H2muHJ5DP*A zLNrnk00000008hm000000000$Dl7;A2m%lfLIOfHQXl{T00000@IL?m0000000000 z0000006+i$00000003GO3IRb94hjqi2NDPh0tf*L0tfL0%8;j0z)wp4hjqi4H5_n0tf*L0tfL0%8;j z0z)$r4hjqi2oeYi0tf*L0tfL0%8;j0z)+t4hjqi S4-yCp0tf*L0tf;^0uT$PSxi&_ literal 0 KcmV+b0RR6000031 diff --git a/tests/st/testcase/test_onnx_parser.cc b/tests/st/testcase/test_onnx_parser.cc index 4a75808..d863be7 100644 --- a/tests/st/testcase/test_onnx_parser.cc +++ b/tests/st/testcase/test_onnx_parser.cc @@ -24,6 +24,7 @@ #include "st/parser_st_utils.h" #include "external/ge/ge_api_types.h" #include "tests/depends/ops_stub/ops_stub.h" +#include "parser/onnx/onnx_parser.h" namespace ge { class STestOnnxParser : public testing::Test { @@ -128,4 +129,48 @@ TEST_F(STestOnnxParser, onnx_parser_if_node) { auto ret = ge::aclgrphParseONNX(model_file.c_str(), parser_params, graph); EXPECT_EQ(ret, GRAPH_SUCCESS); } + +TEST_F(STestOnnxParser, onnx_parser_expand_one_to_many) { + std::string case_dir = __FILE__; + case_dir = case_dir.substr(0, case_dir.find_last_of("/")); + std::string model_file = case_dir + "/origin_models/onnx_clip_v9.onnx"; + std::map parser_params; + ge::Graph graph; + auto ret = ge::aclgrphParseONNX(model_file.c_str(), parser_params, graph); + EXPECT_EQ(ret, GRAPH_SUCCESS); + + MemBuffer *buffer = ParerSTestsUtils::MemBufferFromFile(model_file.c_str()); + ret = ge::aclgrphParseONNXFromMem(reinterpret_cast(buffer->data), buffer->size, parser_params, graph); + EXPECT_EQ(ret, GRAPH_SUCCESS); +} + +TEST_F(STestOnnxParser, onnx_parser_to_json) { + std::string case_dir = __FILE__; + case_dir = case_dir.substr(0, case_dir.find_last_of("/")); + std::string model_file = case_dir + "/origin_models/onnx_clip_v9.onnx"; + std::map parser_params; + OnnxModelParser onnx_parser; + + const char *json_file = "tmp.json"; + auto ret = onnx_parser.ToJson(model_file.c_str(), json_file); + EXPECT_EQ(ret, SUCCESS); + + const char *json_null = nullptr; + ret = onnx_parser.ToJson(model_file.c_str(), json_null); + EXPECT_EQ(ret, FAILED); + const char *model_null = nullptr; + ret = onnx_parser.ToJson(model_null, json_null); + EXPECT_EQ(ret, FAILED); +} + +TEST_F(STestOnnxParser, onnx_parser_const_data_type) { + std::string case_dir = __FILE__; + case_dir = case_dir.substr(0, case_dir.find_last_of("/")); + std::string model_file = case_dir + "/origin_models/onnx_const_type.onnx"; + std::map parser_params; + ge::Graph graph; + auto ret = ge::aclgrphParseONNX(model_file.c_str(), parser_params, graph); + EXPECT_EQ(ret, GRAPH_SUCCESS); +} + } // namespace ge