From: 윤현식/On-Device Lab(SR)/Principal Engineer/삼성전자 Date: Mon, 11 Nov 2019 06:20:29 +0000 (+0900) Subject: [circle-inspect] Adding "--conv2d_weight" support (#8879) X-Git-Tag: submit/tizen/20191205.083104~317 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=723a4301cc48a95ac92212a104f42831fd18a0f5;p=platform%2Fcore%2Fml%2Fnnfw.git [circle-inspect] Adding "--conv2d_weight" support (#8879) * [circle-inspect] Adding "--conv2d_weight" support This adds "--conv2d_weight" support for circle-inspect. Modified code was from _tfl_inspect_. Signed-off-by: Hyun Sik Yoon * Update compiler/circle-inspect/driver/Driver.cpp Thanks! Co-Authored-By: hyunsik-yoon --- diff --git a/compiler/circle-inspect/driver/Driver.cpp b/compiler/circle-inspect/driver/Driver.cpp index 3c60657..d23cd0f 100644 --- a/compiler/circle-inspect/driver/Driver.cpp +++ b/compiler/circle-inspect/driver/Driver.cpp @@ -35,6 +35,8 @@ int entry(int argc, char **argv) std::cerr << std::endl; std::cerr << "USAGE: " << argv[0] << " [options] [circle]" << std::endl; std::cerr << " --operators : dump operators in circle file" << std::endl; + std::cerr << " --conv2d_weight : dump Conv2D series weight operators in circle file" + << std::endl; return 255; } @@ -46,6 +48,11 @@ int entry(int argc, char **argv) return std::move(stdex::make_unique()); }; + argparse["--conv2d_weight"] = [&](void) { + // dump Conv2D, DepthwiseConv2D weight operators + return std::move(stdex::make_unique()); + }; + std::vector> dumps; for (int n = 1; n < argc - 1; ++n) diff --git a/compiler/circle-inspect/src/Dump.cpp b/compiler/circle-inspect/src/Dump.cpp index 13cb75f..fbc092b 100644 --- a/compiler/circle-inspect/src/Dump.cpp +++ b/compiler/circle-inspect/src/Dump.cpp @@ -43,3 +43,93 @@ void DumpOperators::run(std::ostream &os, const circle::Model *model) } } // namespace circleinspect + +namespace +{ + +const circle::Operator *operator_match_output(circleinspect::Reader &reader, const int32_t tensor) +{ + auto ops = reader.operators(); + + for (uint32_t i = 0; i < ops->Length(); ++i) + { + const auto op = ops->Get(i); + + const std::vector &outputs = circleinspect::as_index_vector(op->outputs()); + + for (auto output : outputs) + { + if (output == tensor) + return op; + } + } + return nullptr; +} + +size_t tensor_buffer_size(circleinspect::Reader &reader, const int32_t tensor_id) +{ + auto tensors = reader.tensors(); + + if (tensor_id < 0 || tensor_id >= tensors->Length()) + { + throw std::runtime_error("Invalid Tensor ID"); + } + + auto tensor = tensors->Get(tensor_id); + auto buffer_id = tensor->buffer(); + + size_t size = reader.buffer_info(buffer_id, nullptr); + + return size; +} + +} // namespace + +namespace circleinspect +{ + +void DumpConv2DWeight::run(std::ostream &os, const circle::Model *model) +{ + circleinspect::Reader reader(model); + + assert(reader.num_subgraph() == 1); + reader.select_subgraph(0); + + auto ops = reader.operators(); + + // dump Conv2D, DepthwiseConv2D and its weight input operator + for (uint32_t i = 0; i < ops->Length(); ++i) + { + const auto op = ops->Get(i); + auto bc = reader.builtin_code(op); + + if (bc == circle::BuiltinOperator_CONV_2D || bc == circle::BuiltinOperator_DEPTHWISE_CONV_2D) + { + const std::vector &inputs = circleinspect::as_index_vector(op->inputs()); + if (inputs.size() < 2) + { + throw std::runtime_error("Operator has invalid input"); + } + auto weight_input = inputs[1]; // Tensor ID of weight input + + const auto op_weight = operator_match_output(reader, weight_input); + const auto buffer_size = tensor_buffer_size(reader, weight_input); + + std::string weight_op_name = "?"; + + if (op_weight == nullptr && buffer_size > 0) + { + weight_op_name = "CONST"; + } + else if (op_weight != nullptr) + { + weight_op_name = reader.opcode_name(op_weight); + } + + auto op_name = reader.opcode_name(op); + os << op_name << "," << weight_op_name << std::endl; + } + } +} + +} // namespace circleinspect diff --git a/compiler/circle-inspect/src/Dump.h b/compiler/circle-inspect/src/Dump.h index fd55db6..6afba83 100644 --- a/compiler/circle-inspect/src/Dump.h +++ b/compiler/circle-inspect/src/Dump.h @@ -42,6 +42,15 @@ public: void run(std::ostream &os, const circle::Model *model); }; +class DumpConv2DWeight final : public DumpInterface +{ +public: + DumpConv2DWeight() = default; + +public: + void run(std::ostream &os, const circle::Model *model); +}; + } // namespace circleinspect #endif // __DUMP_H__ diff --git a/compiler/circle-inspect/src/Reader.cpp b/compiler/circle-inspect/src/Reader.cpp index ed090b4..dbbc7c7 100644 --- a/compiler/circle-inspect/src/Reader.cpp +++ b/compiler/circle-inspect/src/Reader.cpp @@ -87,7 +87,10 @@ Reader::Reader(const circle::Model *model) size_t Reader::buffer_info(uint32_t buf_idx, const uint8_t **buff_data) { - *buff_data = nullptr; + if (buff_data != nullptr) + { + *buff_data = nullptr; + } if (buf_idx == 0) return 0; @@ -98,7 +101,10 @@ size_t Reader::buffer_info(uint32_t buf_idx, const uint8_t **buff_data) { if (size_t size = array->size()) { - *buff_data = reinterpret_cast(array->data()); + if (buff_data != nullptr) + { + *buff_data = reinterpret_cast(array->data()); + } return size; } }