#include <ostream>
+#include <algorithm> // min
+#include <iomanip> // setfill
+
namespace tfldump
{
+void dump_buffer(std::ostream &os, const uint8_t *buffer, size_t size, size_t amount)
+{
+ std::ios_base::fmtflags saveflags(os.flags());
+
+ bool second = false;
+ bool ellipsis = amount > 0 && size > 4;
+ size_t count = ellipsis ? std::min(size, amount) : size;
+
+ for (size_t i = 0; i < count; i++)
+ {
+ if (second)
+ {
+ os << " ";
+ }
+
+ os << std::showbase << std::setfill('0') << std::setw(2);
+ os << std::hex << (uint32_t)buffer[i];
+
+ second = true;
+ }
+ if (ellipsis)
+ {
+ os << " ...";
+ }
+
+ os.flags(saveflags);
+}
+
void dump_model(std::ostream &os, const tflite::Model *model)
{
tflread::Reader reader(model);
assert(reader.num_subgraph() == 1);
auto opcodes = reader.opcodes();
+ auto buffers = reader.buffers();
// dump operator_codes
os << "Operator Codes: [order] OpCodeName (OpCode Enum)" << std::endl;
os << std::endl;
// dump buffer
- os << "Buffers:" << std::endl;
+ os << "Buffers: B(index) (length) values, if any" << std::endl;
+ for (uint32_t i = 0; i < buffers->Length(); ++i)
+ {
+ const uint8_t *buff_data;
+ size_t size = reader.buffer_info(i, &buff_data);
+
+ os << "B(" << i << ") (" << size << ") ";
+ if (buff_data != nullptr)
+ {
+ dump_buffer(os, buff_data, size, 16);
+ }
+ os << std::endl;
+ }
+ os << std::endl;
// dump operands(tensors)
os << "Operands:" << std::endl;
Reader::Reader(const tflite::Model *model)
{
_subgraphs = model->subgraphs();
+ _buffers = model->buffers();
auto opcodes = model->operator_codes();
for (const ::tflite::OperatorCode *opcode : *opcodes)
}
}
+size_t Reader::buffer_info(uint32_t buf_idx, const uint8_t **buff_data)
+{
+ *buff_data = nullptr;
+
+ if (buf_idx == 0)
+ return 0;
+
+ if (auto *buffer = (*_buffers)[buf_idx])
+ {
+ if (auto *array = buffer->data())
+ {
+ if (size_t size = array->size())
+ {
+ *buff_data = reinterpret_cast<const uint8_t *>(array->data());
+ return size;
+ }
+ }
+ }
+
+ return 0;
+}
+
} // namespace tflread
{
private:
using TFliteSubGraphs_t = flatbuffers::Vector<flatbuffers::Offset<tflite::SubGraph>>;
+ using TFliteBuffers_t = flatbuffers::Vector<flatbuffers::Offset<tflite::Buffer>>;
public:
Reader(const tflite::Model *model);
public:
const std::vector<const tflite::OperatorCode *> &opcodes() { return _op_codes; }
+ const TFliteBuffers_t *buffers() { return _buffers; }
uint32_t num_subgraph() const { return _subgraphs->Length(); }
+ size_t buffer_info(uint32_t buf_idx, const uint8_t **buff_data);
+
private:
const TFliteSubGraphs_t *_subgraphs;
+ const TFliteBuffers_t *_buffers;
std::vector<const tflite::OperatorCode *> _op_codes;
};