Soft backend plugin (#356)
authorEfimov Alexander/AI Tools Lab/./Samsung Electronics <a.efimov@samsung.com>
Wed, 27 Jun 2018 09:05:26 +0000 (12:05 +0300)
committerSergey Vostokov/AI Tools Lab /SRR/Staff Engineer/삼성전자 <s.vostokov@samsung.com>
Wed, 27 Jun 2018 09:05:26 +0000 (18:05 +0900)
Add initial soft backend to generate C/C++ source code

This commit adds C/C++ emitting backend plugin.
Yet empty

Signed-off-by: Alexander Efimov <a.efimov@samsung.com>
contrib/nnc/libs/backend/CMakeLists.txt
contrib/nnc/libs/backend/soft/CMakeLists.txt [new file with mode: 0644]
contrib/nnc/libs/backend/soft/src/soft_backend.cpp [new file with mode: 0644]

diff --git a/contrib/nnc/libs/backend/soft/CMakeLists.txt b/contrib/nnc/libs/backend/soft/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ad14331
--- /dev/null
@@ -0,0 +1,11 @@
+set(LANG_BACKEND_SOURCES src/soft_backend.cpp)
+
+add_library(soft_backend SHARED ${LANG_BACKEND_SOURCES})
+
+target_link_libraries(soft_backend PRIVATE nncc_core)
+
+target_include_directories(soft_backend PUBLIC include)
+
+target_link_libraries(soft_backend PRIVATE nnc_plugin_core)
+target_link_libraries(soft_backend PRIVATE nncc_foundation)
+target_link_libraries(soft_backend PRIVATE nnc_core)
diff --git a/contrib/nnc/libs/backend/soft/src/soft_backend.cpp b/contrib/nnc/libs/backend/soft/src/soft_backend.cpp
new file mode 100644 (file)
index 0000000..7479624
--- /dev/null
@@ -0,0 +1,173 @@
+#include <map>
+#include <vector>
+#include <iostream>
+#include <cassert>
+
+#include "PluginInstance.h"
+#include "PluginException.h"
+#include "ConfigException.h"
+#include "PluginType.h"
+
+using namespace std;
+using namespace nncc::contrib;
+using namespace nncc::contrib::config;
+using namespace nncc::contrib::plugin;
+
+namespace
+{
+const string pluginName = "soft backend";
+const string pluginVersion = "0.01";
+const string pluginDesc = "Generates source code for selected programming language from IR";
+const PluginType pluginType = typeBackEnd;
+
+// Helpers
+enum class OPT_ID
+{
+  INVALID,
+  TARGET_LANG,
+  OUT_HEADER,
+  OUT_CODE,
+  OUT_MODEL
+};
+
+const char *targetLangOpt = "emit-source";
+const char *outCodeOpt = "out-code";
+const char *outHeaderOpt = "out-header";
+const char *outModelOpt = "out-model";
+
+// general options with some expected value
+const map<string, OPT_ID> opts = {{targetLangOpt, OPT_ID::TARGET_LANG},
+                                  {outCodeOpt, OPT_ID::OUT_CODE},
+                                  {outHeaderOpt, OPT_ID::OUT_HEADER},
+                                  {outModelOpt, OPT_ID::OUT_MODEL}};
+
+// flag options
+const map<string, OPT_ID> flags;
+
+enum class LANG_ID
+{
+  INVALID,
+  C,
+  CPP
+};
+
+const map<string, LANG_ID> langs = {{"c", LANG_ID::C},
+                                    {"c++", LANG_ID::CPP}};
+
+// Plugin implementation
+class SoftBackendInstance : public AbstractPluginInstance
+{
+public:
+  SoftBackendInstance &operator=(const SoftBackendInstance &) = delete;
+  SoftBackendInstance(const SoftBackendInstance &) = delete;
+
+  static AbstractPluginInstance &getInstance();
+  void fillSession() override;
+  void checkConfig() override;
+  void *execute(void *data) override;
+
+  void setParam(const string &name) override;
+  void setParam(const string &name, const string &value) override;
+
+private:
+  LANG_ID _target;
+  string _outHeaderFile;
+  string _outCodeFile;
+  string _outModelFile;
+
+  SoftBackendInstance();
+  ~SoftBackendInstance() override = default;
+};
+
+SoftBackendInstance::SoftBackendInstance(): _target(LANG_ID::INVALID)
+{
+    // EMPTY
+}
+
+AbstractPluginInstance &SoftBackendInstance::getInstance()
+{
+  static SoftBackendInstance instance;
+  return instance;
+}
+
+void SoftBackendInstance::fillSession()
+{
+  const static map<string, string> info = {{"module description", pluginDesc}};
+  const static vector<PluginParam> moduleParams = {{targetLangOpt, "language to emit: c,c++", false},
+                                                   {outCodeOpt, "output file for code", true},
+                                                   {outHeaderOpt, "output file for header", true},
+                                                   {outModelOpt, "output file for model parameters", true}};
+
+  AbstractPluginInstance::fillSessionBase(pluginType, pluginVersion, pluginName);
+
+  for (auto &i : info)
+    getSession()->addInfo(i.first, i.second);
+
+  for (const auto &p: moduleParams)
+    getSession()->registerParam(p);
+}
+
+void SoftBackendInstance::checkConfig()
+{
+  assert(_target != LANG_ID::INVALID && "No target language selected");
+}
+
+void *SoftBackendInstance::execute(void *data)
+{
+  assert(_target != LANG_ID::INVALID);
+  // TODO Implementation here
+  cout << "\n[" << pluginName << "] Plugin executed" << endl;
+  return data;
+}
+
+void SoftBackendInstance::setParam(const string &name)
+{
+  auto optionIt = flags.find(name);
+  (void) optionIt;
+  // plugin do not have flag arguments for now - throw exception
+  throw ConfigException("[" + pluginName + "] Unsupported flag parameter <" + name + ">");
+}
+
+void SoftBackendInstance::setParam(const string &name, const string &value)
+{
+  auto optionIt = opts.find(name);
+  assert(optionIt != opts.end());
+  switch (optionIt->second)
+  {
+    case OPT_ID::TARGET_LANG:
+    {
+      auto langId = langs.find(value);
+      if (langId == langs.end())
+      {
+        string info = "[" + pluginName + "] Unsupported target language <" + value + ">";
+        throw ConfigException(info);
+      }
+      _target = langId->second;
+      break;
+    }
+    case OPT_ID::OUT_HEADER:
+    {
+      _outHeaderFile = value;
+      break;
+    }
+    case OPT_ID::OUT_CODE:
+    {
+      _outCodeFile = value;
+      break;
+    }
+    case OPT_ID::OUT_MODEL:
+    {
+      _outModelFile = value;
+      break;
+    }
+    default:
+      throw ConfigException("[" + pluginName + "] Unsupported parameter <" + name + ">");
+  }
+}
+
+} // unnamed namespace
+
+extern "C" AbstractPluginInstance *get_instance()
+{
+    return &SoftBackendInstance::getInstance();
+}