--- /dev/null
+# TODO Allow users to force tf2tflite build
+if(NOT TARGET moco_tf_frontend)
+ return()
+endif(NOT TARGET moco_tf_frontend)
+
+if(NOT TARGET nnkit_support_tftestinfo)
+ return()
+endif(NOT TARGET nnkit_support_tftestinfo)
+
+if(NOT TARGET loco_exporter)
+ return()
+endif(NOT TARGET loco_exporter)
+
+file(GLOB_RECURSE SOURCES "src/*.cpp")
+
+add_executable(tf2tflite ${SOURCES})
+target_link_libraries(tf2tflite PRIVATE moco_tf_frontend)
+target_link_libraries(tf2tflite PRIVATE nnkit_support_tftestinfo)
+target_link_libraries(tf2tflite PRIVATE loco_exporter)
--- /dev/null
+#include <moco/tf/Frontend.h>
+#include <LocoExporter.h>
+
+#include <nnkit/support/tftestinfo/TensorInfoParser.h>
+
+#include <cassert>
+
+#include <iostream>
+#include <stdexcept>
+#include <string>
+
+namespace
+{
+
+std::unique_ptr<loco::Graph> import(const moco::tf::ModelSignature &sig, const std::string &path)
+{
+ moco::tf::Frontend frontend;
+ return frontend.load(sig, path.c_str(), moco::tf::Frontend::FileType::Binary);
+}
+
+} // namespace
+
+int main(int argc, char **argv)
+{
+ if (argc != 4)
+ {
+ std::cerr << "ERROR: tf2tflite <path/to/info> <path/to/pb> <path/to/tflite/model>" << std::endl;
+ return 255;
+ }
+
+ std::string info_path{argv[1]};
+ std::string tf_path{argv[2]}; // .pb file
+ std::string tflite_path{argv[3]};
+
+ std::cout << "Read '" << info_path << "'" << std::endl;
+
+ moco::tf::ModelSignature sig;
+ {
+ for (const auto &info : nnkit::support::tftestinfo::parse(info_path.c_str()))
+ {
+ switch (info->kind())
+ {
+ case nnkit::support::tftestinfo::ParsedTensor::Kind::Input:
+ sig.add_input(info->nodeName());
+ break;
+
+ case nnkit::support::tftestinfo::ParsedTensor::Kind::Output:
+ sig.add_output(info->nodeName());
+ break;
+
+ default:
+ throw std::runtime_error{"Unknown kind"};
+ }
+ }
+ }
+
+ std::cout << "Read '" << info_path << "' - Done" << std::endl;
+
+ std::cout << "Import from '" << tf_path << "'" << std::endl;
+ auto g = import(sig, tf_path);
+ std::cout << "Import from '" << tf_path << "' - Done" << std::endl;
+
+ std::cout << "Export into '" << tflite_path << "'" << std::endl;
+ loco_exporter::Exporter(g.get()).dumpToFile(tflite_path.c_str());
+ std::cout << "Export into '" << tflite_path << "' - Done" << std::endl;
+
+ return 0;
+}