[moco] import TensorFlow Const for binary encoded (#3492)
author박세희/On-Device Lab(SR)/Principal Engineer/삼성전자 <saehie.park@samsung.com>
Thu, 16 May 2019 03:55:44 +0000 (12:55 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Thu, 16 May 2019 03:55:44 +0000 (12:55 +0900)
This will enable TensorFlow Const conversion where value is given as tensor_content.

Signed-off-by: SaeHie Park <saehie.park@samsung.com>
contrib/moco/lib/frontend/tf/src/Op/Const.cpp
contrib/moco/lib/frontend/tf/src/Op/Const.test.cpp

index bf003a8..bb8ed2d 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <cassert>
 #include <stdexcept>
+#include <string>
 
 namespace
 {
@@ -49,6 +50,15 @@ void read_value_float32(loco::ConstGen *const_node, int num_elements,
       const_node->at<loco::DataType::FLOAT32>(i) = input_tensor.float_val(i);
     }
   }
+  else if (input_tensor.tensor_content().size() == num_elements * sizeof(float))
+  {
+    const std::string &str_content = input_tensor.tensor_content();
+    const float *float_ptr = reinterpret_cast<const float *>(str_content.c_str());
+    for (int32_t i = 0; i < num_elements; i++)
+    {
+      const_node->at<loco::DataType::FLOAT32>(i) = *(float_ptr + i);
+    }
+  }
   else
   {
     throw std::runtime_error("Error: Invalid Const values");
index f90e894..3ca0c19 100644 (file)
@@ -175,3 +175,75 @@ TEST(TensorFlowFrontend, const_float_02)
   ASSERT_EQ(node0->at<loco::DataType::FLOAT32>(4), 1.1f);
   ASSERT_EQ(node0->at<loco::DataType::FLOAT32>(5), 1.1f);
 }
+
+namespace
+{
+// Test case for "input_tensor.tensor_content().size() == num_elements * sizeof(float)"
+// Generated with tfkit tool: "cat ./test.pbtxt | ./tfkit pack"
+
+// clang-format off
+const char *const_float_03_pbtxtdata = STRING_CONTENT(
+node {
+  name: "const/float"
+  op: "Const"
+  attr {
+    key: "dtype"
+    value {
+      type: DT_FLOAT
+    }
+  }
+  attr {
+    key: "value"
+    value {
+      tensor {
+        dtype: DT_FLOAT
+        tensor_shape {
+          dim {
+            size: 2
+          }
+          dim {
+            size: 3
+          }
+        }
+        tensor_content: "\315\314\214?\315\314\014@33S@\315\314\214@\000\000\260@33\323@"
+      }
+    }
+  }
+}
+);
+// clang-format on
+
+} // namespace
+
+TEST(TensorFlowFrontend, const_float_03)
+{
+  moco::tf::Frontend frontend;
+  moco::tf::ModelSignature signature;
+
+  imemstream mempb(const_float_03_pbtxtdata, std::strlen(const_float_03_pbtxtdata));
+
+  signature.add_output("const/float");
+
+  std::unique_ptr<loco::Graph> graph =
+      frontend.load(signature, &mempb, moco::tf::Frontend::FileType::Text);
+
+  loco::Graph::OutputContext *outputs = graph->outputs();
+  ASSERT_EQ(outputs->size(), 1);
+  loco::GraphOutput *output = outputs->at(0);
+  loco::Push *push = output->node();
+
+  loco::Graph::NodeContext *nodes = graph->nodes();
+  ASSERT_EQ(nodes->size(), 2);
+  loco::ConstGen *node0 = dynamic_cast<loco::ConstGen *>(nodes->at(0));
+  ASSERT_NE(node0, nullptr);
+  loco::Push *node1 = dynamic_cast<loco::Push *>(nodes->at(1));
+  ASSERT_EQ(node1, push);
+
+  ASSERT_EQ(node0->size<loco::DataType::FLOAT32>(), 6);
+  ASSERT_EQ(node0->at<loco::DataType::FLOAT32>(0), 1.1f);
+  ASSERT_EQ(node0->at<loco::DataType::FLOAT32>(1), 2.2f);
+  ASSERT_EQ(node0->at<loco::DataType::FLOAT32>(2), 3.3f);
+  ASSERT_EQ(node0->at<loco::DataType::FLOAT32>(3), 4.4f);
+  ASSERT_EQ(node0->at<loco::DataType::FLOAT32>(4), 5.5f);
+  ASSERT_EQ(node0->at<loco::DataType::FLOAT32>(5), 6.6f);
+}