summaryrefslogtreecommitdiff
path: root/compiler/tf2tflite
diff options
context:
space:
mode:
author윤현식/On-Device Lab(SR)/Principal Engineer/삼성전자 <hyunsik.yoon@samsung.com>2019-08-12 19:59:29 +0900
committer박종현/On-Device Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>2019-08-12 19:59:29 +0900
commit6e05e0171a4a2dc559cb5ed42af33ada88a2d97b (patch)
tree5e5b6fe4cfe8c6f9c8433c9385db37d96b95b06a /compiler/tf2tflite
parent43a5d8aba6b8ed3cbd7cb441741294672d345db9 (diff)
downloadnnfw-6e05e0171a4a2dc559cb5ed42af33ada88a2d97b.tar.gz
nnfw-6e05e0171a4a2dc559cb5ed42af33ada88a2d97b.tar.bz2
nnfw-6e05e0171a4a2dc559cb5ed42af33ada88a2d97b.zip
[tf2tflite] Loading customop.conf file into ModelSignature (#6406)
* [tf2tflite] Loading customop.conf file into ModelSignature Adds code for loading customop.conf into ModelSignature Signed-off-by: Hyun Sik Yoon <hyunsik.yoon@samsung.com> * 1) class to function 2) remove loco from cmake file 3) remove some headers * fix wrong lambda comment // use argv[5] directly
Diffstat (limited to 'compiler/tf2tflite')
-rw-r--r--compiler/tf2tflite/CMakeLists.txt2
-rw-r--r--compiler/tf2tflite/requires.cmake3
-rw-r--r--compiler/tf2tflite/src/CustomopConfLoader.cpp137
-rw-r--r--compiler/tf2tflite/src/CustomopConfLoader.h32
-rw-r--r--compiler/tf2tflite/src/Driver.cpp5
5 files changed, 177 insertions, 2 deletions
diff --git a/compiler/tf2tflite/CMakeLists.txt b/compiler/tf2tflite/CMakeLists.txt
index 1658d4a2b..872c82a79 100644
--- a/compiler/tf2tflite/CMakeLists.txt
+++ b/compiler/tf2tflite/CMakeLists.txt
@@ -39,6 +39,8 @@ target_link_libraries(tf2tflite PRIVATE exo_tflite)
target_link_libraries(tf2tflite PRIVATE locop)
target_link_libraries(tf2tflite PRIVATE hermes_std)
target_link_libraries(tf2tflite PRIVATE stdex)
+target_link_libraries(tf2tflite PRIVATE angkor cwrap)
+target_link_libraries(tf2tflite PRIVATE tf2tflite_customop_info_proto)
nncc_find_resource(TensorFlowTests)
diff --git a/compiler/tf2tflite/requires.cmake b/compiler/tf2tflite/requires.cmake
index ff9a2cb6d..ce98653d4 100644
--- a/compiler/tf2tflite/requires.cmake
+++ b/compiler/tf2tflite/requires.cmake
@@ -7,3 +7,6 @@ require("locop")
require("tfkit")
require("nnkit")
require("i5diff")
+require("loco")
+require("cwrap")
+require("angkor")
diff --git a/compiler/tf2tflite/src/CustomopConfLoader.cpp b/compiler/tf2tflite/src/CustomopConfLoader.cpp
new file mode 100644
index 000000000..726b06651
--- /dev/null
+++ b/compiler/tf2tflite/src/CustomopConfLoader.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CustomopConfLoader.h"
+
+#include <loco.h>
+#include <cwrap/Fildes.h>
+#include <angkor/TensorShape.h>
+
+#include <CustomOpInfo.pb.h>
+
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/text_format.h>
+
+#include <fcntl.h>
+
+namespace
+{
+bool load_text(const cwrap::Fildes &fildes, tf2tflite::CustomOpInfoDef &def)
+{
+ google::protobuf::io::FileInputStream fis(fildes.get());
+
+ return google::protobuf::TextFormat::Parse(&fis, &def);
+}
+
+angkor::TensorShape convert_shape(const tf2tflite::ShapeProto &shape)
+{
+ angkor::TensorShape to_shape;
+
+ int64_t rank64 = shape.dim_size();
+ assert(rank64 < std::numeric_limits<uint32_t>::max());
+
+ int32_t rank = static_cast<int32_t>(rank64);
+ to_shape.resize(rank);
+
+ for (int32_t d = 0; d < rank; d++)
+ {
+ int64_t dim_value = shape.dim(d).size();
+ assert(dim_value >= 0ULL);
+ assert(dim_value < std::numeric_limits<uint32_t>::max());
+
+ uint32_t dim_value32 = static_cast<uint32_t>(dim_value);
+ to_shape.dim(d) = dim_value32;
+ }
+
+ return to_shape;
+}
+
+loco::DataType convert_dtype(const tf2tflite::DataType &dtype)
+{
+ if (dtype == tf2tflite::DT_FLOAT)
+ return loco::DataType::FLOAT32;
+ else if (dtype == tf2tflite::DT_INT32)
+ return loco::DataType::S32;
+ else
+ throw std::runtime_error("Not yet supported datatype. Cannot convert.");
+}
+
+// Note : the following functions look similar with plier::tf::Convert.h.
+// However, the schema is different.(not "tensorflow::..." but "tf2tflite::...")
+// So, plier::tf cannot be used.
+loco::DataType get_dtype_attr(const tf2tflite::CustomOpDef &custom_op)
+{
+ std::string type_attr_name("dtype");
+
+ assert(custom_op.attr().count(type_attr_name) > 0);
+ const auto &attr = custom_op.attr().at(type_attr_name);
+ assert(attr.value_case() == tf2tflite::AttrValue::kType);
+ auto dtype_def = attr.type();
+
+ return convert_dtype(dtype_def);
+}
+
+angkor::TensorShape get_shape_attr(const tf2tflite::CustomOpDef &custom_op)
+{
+ std::string shape_attr_name("output_shape");
+
+ assert(custom_op.attr().count(shape_attr_name) > 0);
+ const auto &attr = custom_op.attr().at(shape_attr_name);
+ assert(attr.value_case() == tf2tflite::AttrValue::kShape);
+ auto shape_def = attr.shape();
+
+ return convert_shape(shape_def);
+}
+
+void add_customop(tf2tflite::CustomOpInfoDef &def, moco::tf::ModelSignature &sig)
+{
+ for (const auto &custom_op : def.custom_op())
+ {
+ sig.add_customop(custom_op.op());
+
+ auto name = custom_op.name();
+
+ // setting dtype and shape to ModelSignature
+ sig.dtype(name, get_dtype_attr(custom_op));
+ sig.shape(name, get_shape_attr(custom_op));
+ }
+}
+
+} // namespace
+
+namespace tf2tflite
+{
+
+void load_customop_conf(const std::string &path, moco::tf::ModelSignature &sig)
+{
+ CustomOpInfoDef def;
+
+ cwrap::Fildes fildes{open(path.c_str(), O_RDONLY)};
+
+ if (fildes.get() < 0)
+ {
+ throw std::runtime_error{"Error: " + path + " not found"};
+ }
+
+ if (!load_text(fildes, def))
+ {
+ throw std::runtime_error{"Error: Failed to parse prototxt " + path};
+ }
+
+ add_customop(def, sig);
+}
+
+} // namespace tf2tflite
diff --git a/compiler/tf2tflite/src/CustomopConfLoader.h b/compiler/tf2tflite/src/CustomopConfLoader.h
new file mode 100644
index 000000000..da3ab3dc7
--- /dev/null
+++ b/compiler/tf2tflite/src/CustomopConfLoader.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CUSTOMOP_CONF_LOADER_H__
+#define __CUSTOMOP_CONF_LOADER_H__
+
+#include <moco/tf/Frontend.h>
+
+#include <string>
+
+namespace tf2tflite
+{
+
+/// @brief Loads customop.conf into ModelSignature
+void load_customop_conf(const std::string &path, moco::tf::ModelSignature &sig);
+
+} // namespace tf2tflite
+
+#endif // __CUSTOMOP_CONF_LOADER_H__
diff --git a/compiler/tf2tflite/src/Driver.cpp b/compiler/tf2tflite/src/Driver.cpp
index 8174b4429..26d01d86e 100644
--- a/compiler/tf2tflite/src/Driver.cpp
+++ b/compiler/tf2tflite/src/Driver.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "CustomopConfLoader.h"
+
#include <moco/tf/Frontend.h>
#include <exo/TFLExporter.h>
@@ -128,8 +130,7 @@ int main(int argc, char **argv)
{
if (std::string{argv[4]} == "--customop")
{
- // TODO fill info from customop.conf
- throw std::runtime_error("Not yet implemented");
+ tf2tflite::load_customop_conf(argv[5], sig);
}
else
{