[circle-inspect] Adding "--conv2d_weight" support (#8879)
author윤현식/On-Device Lab(SR)/Principal Engineer/삼성전자 <hyunsik.yoon@samsung.com>
Mon, 11 Nov 2019 06:20:29 +0000 (15:20 +0900)
committer박세희/On-Device Lab(SR)/Principal Engineer/삼성전자 <saehie.park@samsung.com>
Mon, 11 Nov 2019 06:20:29 +0000 (15:20 +0900)
* [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 <hyunsik.yoon@samsung.com>
* Update compiler/circle-inspect/driver/Driver.cpp

Thanks!

Co-Authored-By: hyunsik-yoon <hyunsik.yoon@samsung.com>
compiler/circle-inspect/driver/Driver.cpp
compiler/circle-inspect/src/Dump.cpp
compiler/circle-inspect/src/Dump.h
compiler/circle-inspect/src/Reader.cpp

index 3c60657..d23cd0f 100644 (file)
@@ -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<circleinspect::DumpOperators>());
   };
 
+  argparse["--conv2d_weight"] = [&](void) {
+    // dump Conv2D, DepthwiseConv2D weight operators
+    return std::move(stdex::make_unique<circleinspect::DumpConv2DWeight>());
+  };
+
   std::vector<std::unique_ptr<circleinspect::DumpInterface>> dumps;
 
   for (int n = 1; n < argc - 1; ++n)
index 13cb75f..fbc092b 100644 (file)
@@ -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<int32_t> &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<int32_t> &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
index fd55db6..6afba83 100644 (file)
@@ -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__
index ed090b4..dbbc7c7 100644 (file)
@@ -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<const uint8_t *>(array->data());
+        if (buff_data != nullptr)
+        {
+          *buff_data = reinterpret_cast<const uint8_t *>(array->data());
+        }
         return size;
       }
     }