From 859473ddb0e591764cab58bf14db6f85ee39216e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EB=B0=95=EC=84=B8=ED=9D=AC/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Principal=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Wed, 5 Dec 2018 13:14:48 +0900 Subject: [PATCH] [tfldump] Dump operators (#2497) * [tfldump] Dump operators This will add part to Dump Operators and related functions Signed-off-by: SaeHie Park * use int32_t --- contrib/tfldump/src/Dump.cpp | 31 ++++++++++++++++++++++++++++++- contrib/tfldump/src/Read.cpp | 27 +++++++++++++++++++++++++++ contrib/tfldump/src/Read.h | 5 +++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/contrib/tfldump/src/Dump.cpp b/contrib/tfldump/src/Dump.cpp index 345a392..6522f99 100644 --- a/contrib/tfldump/src/Dump.cpp +++ b/contrib/tfldump/src/Dump.cpp @@ -102,6 +102,7 @@ void dump_model(std::ostream &os, const tflite::Model *model) auto opcodes = reader.opcodes(); auto buffers = reader.buffers(); auto tensors = reader.tensors(); + auto operators = reader.operators(); // dump operator_codes os << "Operator Codes: [order] OpCodeName (OpCode Enum)" << std::endl; @@ -167,7 +168,35 @@ void dump_model(std::ostream &os, const tflite::Model *model) os << std::endl; // dump operators - os << "Operators:" << std::endl; + os << "Operators: O(operator index) OpCodeName " << std::endl; + os << " I T(tensor index) OperandName <-- as input" << std::endl; + os << " O T(tensor index) OperandName <-- as output" << std::endl; + for (uint32_t i = 0; i < operators->Length(); ++i) + { + const auto op = operators->Get(i); + tflite::BuiltinOperator builtincode = reader.builtin_code(op); + + const std::vector &inputs = tflread::as_index_vector(op->inputs()); + const std::vector &outputs = tflread::as_index_vector(op->outputs()); + auto op_name = reader.opcode_name(op); + + os << "O(" << i << ") " << op_name << " "; + os << std::endl; + + // TODO add dump operator properties by type + + for (auto input : inputs) + { + auto tensor = tensors->Get(input); + os << " I T(" << input << ") " << tflread::tensor_name(tensor) << std::endl; + } + for (auto output : outputs) + { + auto tensor = tensors->Get(output); + os << " O T(" << output << ") " << tflread::tensor_name(tensor) << std::endl; + } + } + os << std::endl; // dump network inputs/outputs os << "Inputs/Outputs:" << std::endl; diff --git a/contrib/tfldump/src/Read.cpp b/contrib/tfldump/src/Read.cpp index 7b23f28..5ad43ce 100644 --- a/contrib/tfldump/src/Read.cpp +++ b/contrib/tfldump/src/Read.cpp @@ -107,9 +107,35 @@ size_t Reader::buffer_info(uint32_t buf_idx, const uint8_t **buff_data) return 0; } +tflite::BuiltinOperator Reader::builtin_code(const tflite::Operator *op) const +{ + uint32_t index = op->opcode_index(); + assert(index < _op_codes.size()); + const tflite::OperatorCode *opcode = _op_codes.at(index); + + return opcode->builtin_code(); +} + +std::string Reader::opcode_name(const tflite::Operator *op) const +{ + uint32_t index = op->opcode_index(); + assert(index < _op_codes.size()); + const tflite::OperatorCode *opcode = _op_codes.at(index); + + if (!is_valid(opcode)) + { + std::ostringstream oss; + oss << "(invalid: " << index << ")"; + return oss.str(); + } + + return tflread::opcode_name(opcode); +} + bool Reader::select_subgraph(uint32_t sgindex) { _tensors = nullptr; + _operators = nullptr; if (_subgraphs->Length() <= sgindex) { @@ -120,6 +146,7 @@ bool Reader::select_subgraph(uint32_t sgindex) const tflite::SubGraph *subgraph = (*_subgraphs)[sgindex]; _tensors = subgraph->tensors(); + _operators = subgraph->operators(); return true; } diff --git a/contrib/tfldump/src/Read.h b/contrib/tfldump/src/Read.h index f9e96ef..00e0096 100644 --- a/contrib/tfldump/src/Read.h +++ b/contrib/tfldump/src/Read.h @@ -51,6 +51,7 @@ private: using TFliteSubGraphs_t = flatbuffers::Vector>; using TFliteBuffers_t = flatbuffers::Vector>; using TFliteTensors_t = flatbuffers::Vector>; + using TFliteOperators_t = flatbuffers::Vector>; public: Reader(const tflite::Model *model); @@ -61,10 +62,13 @@ public: const std::vector &opcodes() { return _op_codes; } const TFliteBuffers_t *buffers() { return _buffers; } const TFliteTensors_t *tensors() { return _tensors; } + const TFliteOperators_t *operators() { return _operators; } uint32_t num_subgraph() const { return _subgraphs->Length(); } size_t buffer_info(uint32_t buf_idx, const uint8_t **buff_data); + tflite::BuiltinOperator builtin_code(const tflite::Operator *op) const; + std::string opcode_name(const tflite::Operator *op) const; public: bool select_subgraph(uint32_t subgraph); @@ -73,6 +77,7 @@ private: const TFliteSubGraphs_t *_subgraphs; const TFliteBuffers_t *_buffers; const TFliteTensors_t *_tensors; + const TFliteOperators_t *_operators; std::vector _op_codes; }; -- 2.7.4