Not enable frontend plugins if their dependencies aren't set (#1279)
authorРоман Михайлович Русяев/AI Tools Lab /SRR/Staff Engineer/삼성전자 <r.rusyaev@samsung.com>
Fri, 31 Aug 2018 15:10:00 +0000 (18:10 +0300)
committerSergey Vostokov/AI Tools Lab /SRR/Staff Engineer/삼성전자 <s.vostokov@samsung.com>
Fri, 31 Aug 2018 15:10:00 +0000 (18:10 +0300)
* frontend plugins won't be enabled if their dependencies aren't set
* added feature to disable command line options. It is needed to
  disable plugin options if plugins aren't available

Signed-off-by: Roman Rusyaev <r.rusyaev@samsung.com>
contrib/nnc/CMakeLists.txt
contrib/nnc/driver/Driver.cpp
contrib/nnc/driver/Options.cpp
contrib/nnc/include/Definitions.h.in
contrib/nnc/include/support/CommandLine.h
contrib/nnc/plugin/caffe_frontend/CMakeLists.txt
contrib/nnc/plugin/tflite_frontend/CMakeLists.txt
contrib/nnc/support/CommandLine.cpp

index f89e5b9..ee32d41 100644 (file)
@@ -22,6 +22,9 @@ set(NNC_INSTALL_LIB_PATH ${NNC_INSTALL_PATH}/lib) # directory that contains othe
 set(NNC_INSTALL_PLUGIN_PATH ${NNC_INSTALL_LIB_PATH}/plugin) # path to where plugins will be located
 set(NNC_INSTALL_CORE_PATH ${NNC_INSTALL_LIB_PATH}/core) # path to where common part of nnc will be located
 
+#
+# find necessary packages
+#
 find_package(HDF5 COMPONENTS CXX QUIET)
 # defines if hdf5 package was found
 if(HDF5_FOUND)
@@ -30,6 +33,25 @@ else()
   set(NNC_HDF5_SUPPORTED OFF)
 endif()
 
+# Try to get compiled caffe proto and return if not successful
+# Note: this creates a target called "caffeproto" that contains compiled caffe.proto sources,
+#       and after linking with it caffe.pb.h will be available as "caffe/proto/caffe.pb.h"
+nncc_find_package(CaffeProto QUIET)
+if (CaffeProto_FOUND)
+  set(NNC_FRONTEND_CAFFE_ENABLED ON)
+else()
+  set(NNC_FRONTEND_CAFFE_ENABLED OFF)
+endif()
+
+# We need flatbuffer for tflite frontend
+nncc_find_package(FlatBuffers QUIET)
+if (FlatBuffers_FOUND)
+  set(NNC_FRONTEND_TFLITE_ENABLED ON)
+else()
+  set(NNC_FRONTEND_TFLITE_ENABLED OFF)
+endif()
+###
+
 #
 # plugins names
 #
@@ -90,7 +112,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/Definitions.h.in
         ${CMAKE_CURRENT_BINARY_DIR}/include/Definitions.h)
 include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
 
-set(NNC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+set(NNC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}})
 add_subdirectory(support)
 add_subdirectory(core)
 add_subdirectory(plugin)
index 4819ac1..5b2f566 100644 (file)
@@ -38,6 +38,19 @@ static std::string getFrontendPlugin()
 {
   std::string plugin;
 
+  if ( clopt::caffeFrontend.isDisabled() && clopt::tflFrontend.isDisabled() )
+  {
+    throw DriverException("frontends are not available");
+  }
+
+  if ( clopt::caffeFrontend && clopt::tflFrontend )
+  {
+    throw DriverException("only one of the following options are allowed"
+                          " to be set in the same time: '"
+                          + clopt::caffeFrontend.getNames()[0] + "', '"
+                          + clopt::tflFrontend.getNames()[0] + "'");
+  }
+
   if ( clopt::caffeFrontend )
   {
     plugin = NNC_FRONTEND_CAFFE_NAME;
index 068fa0c..d1b16fe 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "support/CommandLine.h"
 #include "option/Options.h"
+#include "Definitions.h"
 
 namespace nncc
 {
@@ -30,11 +31,29 @@ Option<std::string> debugZones(optname("--debug-area"),
 Option<bool> caffeFrontend(optname("--caffe"),
                            overview("treat input file as Caffe model"),
                            false,
-                           optional(true));
+                           optional(true),
+                           optvalues(""),
+                           nullptr,
+                           separators(""),
+#ifdef NNC_FRONTEND_CAFFE_ENABLED
+                           showopt(true)
+#else
+                           showopt(false)
+#endif // NNC_FRONTEND_CAFFE_ENABLED
+                          );
 Option<bool> tflFrontend(optname("--tflite"),
                          overview("treat input file as Tensor Flow Lite model"),
                          false,
-                         optional(true));
+                         optional(true),
+                         optvalues(""),
+                         nullptr,
+                         separators(""),
+#ifdef NNC_FRONTEND_TFLITE_ENABLED
+                         showopt(true)
+#else
+                         showopt(false)
+#endif // NNC_FRONTEND_TFLITE_ENABLED
+                        );
 Option<std::string> target(optname("--target"),
                            overview("select target language to emit for given architecture."
                                     "Valid values are '" NNC_TARGET_X86_CPP "', '" NNC_TARGET_INTERPRETER "'"),
index 2b2425d..73862d5 100644 (file)
  */
 #cmakedefine NNC_HDF5_SUPPORTED
 
+/**
+ * @brief define that TFLite frontend is enabled
+ */
+#cmakedefine NNC_FRONTEND_TFLITE_ENABLED
+
+/**
+ * @brief define that CAFFE frontend is enabled
+ */
+#cmakedefine NNC_FRONTEND_CAFFE_ENABLED
+
 #endif //NNCC_DEFINITIONS_H
index 63d7f6d..6bfdd5a 100644 (file)
@@ -239,6 +239,11 @@ public:
    *        type if verification is not passed
    */
   virtual void runCheckerFunc() = 0;
+
+  /**
+   * @brief is option disabled?
+   */
+   virtual bool isDisabled() const = 0;
 };
 
 /**
@@ -265,6 +270,7 @@ public:
    * @param vals - valid values for option. Other values are interpreted as invalid
    * @param checker - function verifies option
    * @param seps - symbols that separates name option from value (by default is spaces)
+   * @param enabled - if this option is set to false then it won't be shown for users
    */
   explicit Option(const std::vector<std::string> &optnames,
                   const std::string &descr,
@@ -272,7 +278,8 @@ public:
                   bool  is_optional = false,
                   const std::vector<std::string> &vals = std::vector<std::string>(),
                   option_checker_t checker = nullptr,
-                  const std::vector<char> &seps = std::vector<char>());
+                  const std::vector<char> &seps = std::vector<char>(),
+                  bool enabled = true);
 
   // options must not be copyable and assignment
   Option(const Option&) = delete;
@@ -306,6 +313,8 @@ public:
   }
 
   const std::vector<char> &getSeparators() const override { return _seps; }
+
+  bool isDisabled() const override { return !_is_enabled; }
   // end overridden methods
 
 private:
@@ -316,6 +325,7 @@ private:
   std::vector<std::string> _valid_vals; // option can be initialized only by these values
   option_checker_t _checker; // function verifies option and its value
   std::vector<char> _seps; // these symbols separate option name and its value
+  bool _is_enabled;
 };
 
 // the following functions are helpers for users that declare new options
@@ -350,6 +360,11 @@ std::vector<std::string> optvalues(const char *vals);
  * @param seps - chars of separators separated by a comma
  */
 std::vector<char> separators(const char *seps);
+
+/**
+ * @param is_shown - if set to false, then option won't be shown in help message
+ */
+inline bool showopt(bool is_shown) { return is_shown; }
 // end of helper functions
 
 
@@ -425,7 +440,8 @@ Option<T>::Option(const std::vector<std::string> &optnames,
                   bool is_optional,
                   const std::vector<std::string> &vals,
                   option_checker_t checker,
-                  const std::vector<char> &seps)
+                  const std::vector<char> &seps,
+                  bool enabled)
 {
   // save all names
   for ( const auto &n : optnames )
@@ -451,6 +467,10 @@ Option<T>::Option(const std::vector<std::string> &optnames,
   // save checker
   _checker = checker;
 
+  _is_enabled = enabled;
+
+  assert((_is_enabled || _is_optional) && "disabled option can't be required");
+
   // register new option for parser
   CommandLine::getParser()->registerOption(this);
 
index bbb1292..72bb011 100644 (file)
@@ -1,15 +1,9 @@
-# Try to get compiled caffe proto and return if not successful
-# Note: this creates a target called "caffeproto" that contains compiled caffe.proto sources,
-#       and after linking with it caffe.pb.h will be available as "caffe/proto/caffe.pb.h"
-# Note2: DOWNLOAD_CAFFE cmake option should be on
-nncc_find_package(CaffeProto QUIET)
-if(NOT CaffeProto_FOUND)
-  return()
-endif()
-
 ###################
 # Caffe importer  #
 ###################
+if (NOT NNC_FRONTEND_CAFFE_ENABLED)
+  return ()
+endif()
 
 file(GLOB caffe_importer_sources *.cpp)
 file(GLOB caffe_importer_headers *.h)
index d5a3b35..959d07a 100644 (file)
@@ -1,4 +1,6 @@
-nncc_find_package(FlatBuffers OPTIONAL)
+if (NOT NNC_FRONTEND_TFLITE_ENABLED)
+  return ()
+endif()
 
 ###################
 # SCHEMA          #
index 30d9b24..4470858 100644 (file)
@@ -116,9 +116,12 @@ CommandLine *CommandLine::getParser()
 
   for ( const auto opt: _options )
   {
-    len = 0;
-    for ( const auto &n : opt->getNames() ) len += n.length();
-    max_len = (max_len <  len) ? len : max_len;
+    if ( !opt->isDisabled() )
+    {
+      len = 0;
+      for (const auto &n : opt->getNames()) len += n.length();
+      max_len = (max_len < len) ? len : max_len;
+    }
   }
 
   for ( const auto opt: _options )
@@ -126,6 +129,12 @@ CommandLine *CommandLine::getParser()
     const auto &option_descr = opt->getOverview();
     const auto &names = opt->getNames();
 
+    if ( opt->isDisabled() )
+    {
+      // options that are disabled not have to be shown
+      continue;
+    }
+
     std::string option_names(names[0]); // initialize with option name
 
     // add option aliases to option_names and count them length
@@ -190,6 +199,12 @@ BaseOption *CommandLine::findOption(const char *optname)
     }
   }
 
+  if ( it->second->isDisabled() )
+  {
+    // if option is disabled we don't have to recognize it
+    throw BadOption(optname, "");
+  }
+
   return it->second;
 
 } // findOption