[exo] Support TensorConstantPad operation (#8309)
author채성우/On-Device Lab(SR)/Engineer/삼성전자 <sw4670.chae@samsung.com>
Tue, 22 Oct 2019 01:26:38 +0000 (10:26 +0900)
committer박세희/On-Device Lab(SR)/Principal Engineer/삼성전자 <saehie.park@samsung.com>
Tue, 22 Oct 2019 01:26:38 +0000 (10:26 +0900)
* [exo] Support TensorConstantPad operation

This commit supports TensorConstantPad operation in exo.

Signed-off-by: seongwoo <sw4670.chae@samsung.com>
* change vector declaration method.

compiler/exo/src/TFLite/TFLOperationExporter.cpp

index 3024a79..e7edaf8 100644 (file)
@@ -99,6 +99,7 @@ public:
   void visit(loco::EltwiseSqrt *) final;
   void visit(loco::FixedReshape *) final;
   void visit(loco::TensorBroadcast *) final;
+  void visit(loco::TensorConstantPad *) final;
 
   void visit(locoex::COpCall *);
 
@@ -916,6 +917,53 @@ void OperationExporter::visit(loco::TensorBroadcast *)
   throw std::runtime_error("TensorBroadcast should not exist in the graph");
 }
 
+void OperationExporter::visit(loco::TensorConstantPad *node)
+{
+  uint32_t op_idx = gd.registerBuiltinOpcode(tflite::BuiltinOperator_PAD);
+
+  // make padding attribute an input
+  auto padding = node->padding();
+  // get padding vector size
+  int32_t padding_vec_size = padding->rank();
+  // get byte size of vector
+  size_t padding_vec_byte_size = padding_vec_size * sizeof(int32_t) * 2; // [rank, 2]
+  // create vector for data
+  std::vector<int32_t> padding_vec_data(padding_vec_size * 2);
+  // set data
+  for (int32_t i = 0; i < padding_vec_size; i++)
+  {
+    padding_vec_data.at(i * 2) = padding->front(i);
+    padding_vec_data.at(i * 2 + 1) = padding->back(i);
+  }
+  // create FlatBuffer vector
+  auto padding_vec_ptr = builder.CreateVector(reinterpret_cast<uint8_t *>(padding_vec_data.data()),
+                                              padding_vec_byte_size);
+
+  // create buffer
+  auto padding_buffer_ptr = CreateBuffer(builder, padding_vec_ptr);
+  // get buffer id
+  const auto padding_buffer_id = static_cast<uint32_t>(gd._buffers.size());
+
+  gd._buffers.push_back(padding_buffer_ptr);
+
+  // create padding shape vector
+  auto padding_shape_vec_ptr = builder.CreateVector(std::vector<int32_t>{padding_vec_size, 2});
+  // create tensor
+  auto padding_tensor_ptr =
+      CreateTensor(builder, padding_shape_vec_ptr, TensorType_INT32, padding_buffer_id);
+  // get tensor id
+  const auto padding_tensor_id = static_cast<int32_t>(gd._tensors.size());
+
+  gd._tensors.push_back(padding_tensor_ptr);
+
+  std::vector<int32_t> inputs_vec{get_tensor_index(node->input()), padding_tensor_id};
+  std::vector<int32_t> outputs_vec{get_tensor_index(static_cast<loco::Node *>(node))};
+  auto inputs = builder.CreateVector(inputs_vec);
+  auto outputs = builder.CreateVector(outputs_vec);
+  auto op_offset = CreateOperator(builder, op_idx, inputs, outputs);
+  gd._operators.push_back(op_offset);
+}
+
 inline flatbuffers::Offset<flatbuffers::Vector<uint8_t>>
 CreateCOpCallOptions(flatbuffers::FlatBufferBuilder &fbb, locoex::COpCall *copCall)
 {