list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(soft_backend)
-set(DRIVER_HEADERS driver/Driver.h)
-set(DRIVER_SOURCES driver/Driver.cpp)
-set(MAIN "driver/main.cpp")
+set(DRIVER_SOURCES driver/main.cpp driver/Driver.cpp)
set(OPTIONS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/driver/Options.cpp)
# add interface header files
###
set(NNC_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}) # root path of installation directory
set(NNC_INSTALL_LIB_PATH ${NNC_INSTALL_PATH}/lib) # directory that contains other directories with shared library
-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
###
#
-# plugins names
-#
-# NOTE. If names of plugins are changed then these
-# variables will have to be also chagned
-if (APPLE)
- set(LIB_SUFFIX ".dylib")
-else()
- set(LIB_SUFFIX ".so")
-endif()
-
-set(NNC_CAFFE_PLUGIN_NAME "libcaffe_importer${LIB_SUFFIX}")
-set(NNC_TFLITE_PLUGIN_NAME "libtflite_import${LIB_SUFFIX}")
-set(NNC_SOFT_CPP_PLUGIN_NAME "libsoft_backend_cpp${LIB_SUFFIX}")
-set(NNC_SOFT_C_PLUGIN_NAME "libsoft_backend_c${LIB_SUFFIX}")
-set(NNC_INTERPRETER_NAME "libnnc_interpreter${LIB_SUFFIX}")
-###
-
-#
# functions
#
-function(install_nnc_plugin PLUGIN)
- install(TARGETS ${PLUGIN} DESTINATION ${NNC_INSTALL_PLUGIN_PATH})
+function(install_nnc_library LIB)
+ install(TARGETS ${LIB} DESTINATION ${NNC_INSTALL_LIB_PATH})
# set external RPATHs
- set_target_properties(${PLUGIN} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
+ set_target_properties(${LIB} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
+ # use paths from build directoris
+ set_target_properties(${LIB} PROPERTIES CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
# set RPATH to core part of nnc
- set_target_properties(${PLUGIN} PROPERTIES INSTALL_RPATH ${NNC_INSTALL_CORE_PATH})
-endfunction(install_nnc_plugin)
-
-function(install_common_library)
- install(TARGETS ${ARGV} DESTINATION ${NNC_INSTALL_CORE_PATH})
-endfunction(install_common_library)
+ set_target_properties(${LIB} PROPERTIES INSTALL_RPATH ${NNC_INSTALL_LIB_PATH})
+endfunction()
#
# end functions
#
#
# Used by unit tests
#
-set(NNC_SOFT_BACKEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}/plugin/soft_backend)
-set(NNC_INTERPRETER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/plugin/interpreter)
-set(NNC_CAFFE_FRONTEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}/plugin/caffe_frontend)
-set(NNC_TFLITE_FRONTEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}/plugin/tflite_frontend)
+set(NNC_SOFT_BACKEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}/passes/soft_backend)
+set(NNC_INTERPRETER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/passes/interpreter)
+set(NNC_CAFFE_FRONTEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}/passes/caffe_frontend)
+set(NNC_TFLITE_FRONTEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}/passes/tflite_frontend)
set(NNC_CORE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/core)
set(NNC_SUPPORT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/support)
-# driver library
-add_nncc_library(nnc_driver SHARED ${DRIVER_HEADERS} ${DRIVER_SOURCES})
-target_link_libraries(nnc_driver PRIVATE nnc_support)
-install_common_library(nnc_driver)
-
# nnc executable
-add_executable(nnc ${MAIN} ${OPTIONS_SRC})
-target_link_libraries(nnc PRIVATE nnc_support nnc_driver)
+add_executable(nnc ${DRIVER_SOURCES} ${OPTIONS_SRC})
+target_link_libraries(nnc PRIVATE nnc_support nnc_pass)
+target_link_libraries(nnc PRIVATE caffe_importer tflite_import soft_backend_cpp soft_backend_c nnc_interpreter)
# configure file that contains extern definitions
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})
add_subdirectory(support)
add_subdirectory(core)
-add_subdirectory(plugin)
+add_subdirectory(pass)
+add_subdirectory(passes)
add_subdirectory(examples)
add_subdirectory(unittests)
add_subdirectory(tests)
# install nnc
install(TARGETS nnc DESTINATION ${NNC_INSTALL_PATH}/bin)
-set_target_properties(nnc PROPERTIES INSTALL_RPATH "${NNC_INSTALL_CORE_PATH};${NNC_INSTALL_PLUGIN_PATH}")
+# TODO when we upgrade our cmake to version 2.12 this is needed to use BUILD_RPATH variable NOCOMMIT
+set_target_properties(nnc PROPERTIES INSTALL_RPATH "${NNC_INSTALL_LIB_PATH}")
set_target_properties(nnc PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
+set_target_properties(nnc PROPERTIES CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
### DESCRIPTION
nnc is a neural network compiler that transforms neural networks of various formats into source or machine code.
-Most functionality of nnc is stored in dynamically linked plugins.
> At this moment only two NN are supported (MobileNet and InceptionV3) in Tensorflow Lite or Caffe format.
### SYNOPSIS
set_target_properties(nnc_core PROPERTIES LINKER_LANGUAGE CXX)
# install nnc core library
-install_common_library(nnc_core)
+install_nnc_library(nnc_core)
-#include "support/PluginManager.h"
+#include "pass/PassManager.h"
+#include "pass/PassData.h"
+
+#include "passes/caffe_frontend/CaffeFrontend.h"
+#include "passes/tflite_frontend/TfliteFrontend.h"
+#include "passes/interpreter/InterpreterPass.h"
+#include "passes/soft_backend/CPPGenerator.h"
+
#include "support/CommandLine.h"
#include "Definitions.h"
#include "option/Options.h"
#include "Driver.h"
using namespace nncc::contrib;
-using namespace nncc::contrib::plugin;
+using namespace nncc::contrib::pass;
+using namespace nncc::contrib::frontend;
+using namespace nncc::contrib::backend;
namespace nncc
{
{
/**
- * @brief run plugin
- * @param plugin_path - absolute path to plugin
- * @param data - plugin input data
- * @return pointer to data that plugin generated
- * @throw PluginException, if errors occured
+ * @brief run all registered passes
+ * @throw PassException, if errors occured
*/
-static void *executePlugin(const std::string &plugin_path, void *data)
+static void *runPasses()
{
- PluginManager pluginManager(plugin_path);
-
- Plugin *plugin = pluginManager.getPlugin();
- void *res = plugin->execute(data);
+ auto registeredPasses = PassManager::getPassManager()->getPasses();
+ PassData passData(nullptr);
- return res;
+ for ( auto &pass : registeredPasses )
+ {
+ passData = pass->run(passData);
+ }
-} // executePlugin
+} // runPasses
/**
- * @return absolute path to frontend plugin
+ * @brief Register frontend pass
* @throw DriverException if errors occurred
*/
-static std::string getFrontendPlugin()
+static void registerFrontendPass()
{
- std::string plugin;
+ Pass *pass;
if ( clopt::caffeFrontend.isDisabled() && clopt::tflFrontend.isDisabled() )
{
if ( clopt::caffeFrontend )
{
- plugin = NNC_FRONTEND_CAFFE_NAME;
+ pass = &caffe::CaffeFrontend::getInstance();
}
else if ( clopt::tflFrontend )
{
- plugin = NNC_FRONTEND_TFLITE_NAME;
+ pass = &tflite::TFLiteFrontend::getInstance();
}
else
{
+ clopt::tflFrontend.getNames()[0] + "'");
}
- return plugin;
+ PassManager::getPassManager()->registerPass(pass);
-} // getFrontendPlugin
+} // registerFrontendPass
/**
- * @return absolute path to backend plugin
+ * @brief Register backend pass
* @throw DriverException if errors occurred
*/
-static std::string getBackendPlugin()
+static void registerBackendPass()
{
- std::string plugin;
-
- assert( clopt::target == NNC_TARGET_X86_CPP || clopt::target == NNC_TARGET_INTERPRETER );
+ Pass *pass;
if ( clopt::target == NNC_TARGET_X86_CPP )
{
- plugin = NNC_BACKEND_SOFT_CPP_NAME;
+ pass = &soft::CPPCodeGenerator::getInstance();
}
else if ( clopt::target == NNC_TARGET_INTERPRETER )
{
- plugin = NNC_BACKEND_INTERPRETER_NAME;
+ pass = &interpreter::InterpreterPass::getInstance();
+
+ } else
+ {
+ assert(false && "invalid option value");
}
- return plugin;
+ PassManager::getPassManager()->registerPass(pass);
-} // getBackendPlugin
+} // registerBackendPass
void Driver::runDriver()
{
- std::string plugin;
- void *plugin_result;
-
- // run frontend plugin
- plugin = getFrontendPlugin();
- plugin_result = executePlugin(plugin, nullptr);
+ // register passes
+ registerFrontendPass();
+ registerBackendPass();
- // run backend plugin
- plugin = getBackendPlugin();
- executePlugin(plugin, plugin_result);
+ // run registered passes
+ runPasses();
} // runDriver
/**
* @brief main method to run compiler driver
* @throw DriverException if errors occurred in driver
- * PluginException if errors occurred in plugins
+ * PassException if errors occurred in passes
*/
static void runDriver();
#include <iostream>
#include <vector>
-#include "support/PluginException.h"
#include "support/CommandLine.h"
+#include "pass/PassException.h"
#include "Driver.h"
#define DEBUG_AREA
using namespace nncc::contrib;
+using namespace nncc::contrib::pass;
int main(int argc, const char *argv[])
{
//
// run compiler pipeline:
//
- // for_each(all_plugins):
- // load plugin
- // execute plugin
- // unload plugin
+ // for_each(all_passes):
+ // run pass
//
Driver::runDriver();
std::cerr << e.reason() << std::endl;
std::cerr << "use --help for more information" << std::endl;
}
- catch ( const PluginException &e )
+ catch ( const PassException &e )
{
- std::cerr << e.what() << std::endl;
+ std::cerr << e.reason() << std::endl;
}
return exit_code;
#include <iostream>
#include "support/CommandLine.h"
-#include "support/PluginException.h"
#include "option/Options.h"
#include "caffe_importer.h"
#include "core/modelIR/graph.h"
#include "core/modelIR/ir_dot_dumper.h"
#include "core/modelIR/ShapeInference.h"
+#include "pass/PassException.h"
using namespace nncc::contrib;
+using namespace nncc::contrib::pass;
using namespace nncc::contrib::clopt;
using namespace nncc::contrib::core::dumper;
g->accept(&dotDumper);
dotDumper.writeDot(std::cout);
- } catch (PluginException &e) {
+ } catch (PassException &e) {
std::cout << "Error: " << e.what() << std::endl;
return -1;
}
+++ /dev/null
-file(GLOB_RECURSE PL_EXAMPLE_PARSE_SRC *.cpp)
-file(GLOB_RECURSE PL_EXAMPLE_PARSE_H)
-
-add_library(some_parser SHARED ${PL_EXAMPLE_PARSE_SRC} ${PL_EXAMPLE_PARSE_H})
-add_library(some_parser_second SHARED ${PL_EXAMPLE_PARSE_SRC} ${PL_EXAMPLE_PARSE_H})
-
-target_link_libraries(some_parser PRIVATE nnc_core nnc_support)
-
-target_link_libraries(some_parser_second PRIVATE nnc_core nnc_support)
+++ /dev/null
-#include <map>
-#include <vector>
-#include <iostream>
-#include "support/PluginInstance.h"
-#include "support/PluginException.h"
-
-using namespace nncc::contrib::plugin;
-
-class SamplePluginInstance : public FrontendPlugin
-{
-public:
- SamplePluginInstance &operator=(const SamplePluginInstance &) = delete;
- SamplePluginInstance(const SamplePluginInstance &) = delete;
-
- static FrontendPlugin &getInstance();
- void *execute(void *data) override;
-
-private:
- SamplePluginInstance() = default;
- ~SamplePluginInstance() override = default;
-};
-
-FrontendPlugin &SamplePluginInstance::getInstance()
-{
- static SamplePluginInstance instance;
- // FIXME: it's necessary to make this printing via debugging system (see issue #893)
- //NNC_DEBUG(dbgs() << std::endl << "!!! plugin (" << pluginName << ") " << __func__ << std::endl);
- return instance;
-}
-
-void *SamplePluginInstance::execute(void *data)
-{
- // FIXME: it's necessary to make this printing via debugging system (see issue #893)
- //std::cout << std::endl << "!!! plugin (" << pluginName << ") " << __func__ << std::endl;
- return data;
-}
-
-extern "C" Plugin *get_instance()
-{
- // FIXME: it's necessary to make this printing via debugging system (see issue #893)
- //std::cout << std::endl << "!!! plugin (" << pluginName << ") " << __func__ << std::endl;
- return &SamplePluginInstance::getInstance();
-}
-
-extern "C" int getSomeBeef()
-{
- return 0xBEEF;
-}
#include <iostream>
#include "support/CommandLine.h"
-#include "support/PluginException.h"
+#include "pass/PassException.h"
#include "option/Options.h"
#include "tflite_v3_importer.h"
#include "core/modelIR/graph.h"
#include "core/modelIR/ShapeInference.h"
using namespace nncc::contrib;
+using namespace nncc::contrib::pass;
using namespace nncc::contrib::clopt;
using namespace nncc::contrib::core::dumper;
g->accept(&dotDumper);
dotDumper.writeDot(std::cout);
- } catch (PluginException &e) {
+ } catch (PassException &e) {
std::cout << "Error: " << e.what() << std::endl;
return -1;
}
#define NNC_ROOT_PATH "@NNC_INSTALL_PATH@"
/**
- * @breif absolute path to directory contains plugins
+ * @breif absolute path to directory contains libraries
*/
-#define NNC_PLUGINS_PATH "@NNC_INSTALL_PLUGIN_PATH@"
-
-/**
- * @brief name of CAFFE frontend plugin
- */
-#define NNC_FRONTEND_CAFFE_NAME "@NNC_CAFFE_PLUGIN_NAME@"
-
-/**
- * @brief name of TensorFlow Lite frontend plugin
- */
-#define NNC_FRONTEND_TFLITE_NAME "@NNC_TFLITE_PLUGIN_NAME@"
-
-/**
- * @brief name of Soft backend plugin which generates C source code
- */
-#define NNC_BACKEND_SOFT_C_NAME "@NNC_SOFT_C_PLUGIN_NAME@"
-
-/**
- * @brief name of Soft backend plugin which generates C++ source code
- */
-#define NNC_BACKEND_SOFT_CPP_NAME "@NNC_SOFT_CPP_PLUGIN_NAME@"
-
-/**
- * @brief name of Interpreter plugin
- */
-#define NNC_BACKEND_INTERPRETER_NAME "@NNC_INTERPRETER_NAME@"
+#define NNC_LIB_PATH "@NNC_INSTALL_LIB_PATH@"
/**
* @brief defines if hdf5 package was found
--- /dev/null
+#ifndef NNCC_PASS_H
+#define NNCC_PASS_H
+
+#include <string>
+
+#include "pass/PassData.h"
+
+namespace nncc
+{
+namespace contrib
+{
+namespace pass
+{
+
+/**
+ * @brief this class represent an interface for all compiler passes like that frontend, backend etc
+ */
+class Pass
+{
+public:
+ Pass() = default;
+
+ // to prevent copy of object
+ Pass &operator=(const Pass &) = delete;
+ Pass(const Pass &) = delete;
+
+ /**
+ * @brief run compiler pass
+ * @param data - data that pass is taken
+ * @return data that can be passed to the next pass
+ * @throw PassException object if errors occured
+ */
+ virtual PassData run(PassData data) = 0;
+
+ virtual ~Pass() = default;
+};
+
+} // namespace pass
+} // namespace contrib
+} // namespace nncc
+
+#endif //NNCC_PASS_H
--- /dev/null
+#ifndef NNCC_PASSDATA_H
+#define NNCC_PASSDATA_H
+
+#include "core/modelIR/graph.h"
+#include "core/modelIR/TensorVariant.h"
+
+using namespace nncc::contrib::core::IR::model;
+
+namespace nncc
+{
+namespace contrib
+{
+namespace pass
+{
+
+/**
+ * @brief class that encapsulate value returned and taken by pass
+ */
+class PassData
+{
+public:
+ PassData(const PassData &) = default;
+
+ PassData(std::nullptr_t data) { _dataContainer.unknown = data; _dataType = PDT::UNKNOWN; }
+
+ /**
+ * @brief Implicit conversion from Graph* to PassData
+ */
+ /* implicit */ PassData(Graph *graph) { _dataContainer.graph = graph; _dataType = PDT::GRAPH; }
+ /**
+ * @brief Implicit conversion from PassData to Graph*
+ */
+ /* implicit */ operator Graph*() const {
+ if ( _dataType != PDT::GRAPH )
+ return nullptr;
+ return _dataContainer.graph;
+ }
+
+ /**
+ * @brief Implicit conversion from Graph* to PassData
+ */
+ /* implicit */ PassData(TensorVariant *tv) { _dataContainer.tensorVariant = tv; _dataType = PDT::TENSOR_VARIANT; }
+ /**
+ * @brief Implicit conversion from PassData to Graph*
+ */
+ /* implicit */ operator TensorVariant*() const {
+ if ( _dataType != PDT::TENSOR_VARIANT )
+ return nullptr;
+ return _dataContainer.tensorVariant;
+ }
+
+private:
+ // types that PassData can contain
+ enum class PDT : char
+ {
+ GRAPH,
+ TENSOR_VARIANT,
+ UNKNOWN
+
+ } _dataType;
+
+ // union contains all pointers to objects that can be returned from passes
+ union
+ {
+ Graph *graph;
+ TensorVariant *tensorVariant;
+ void *unknown;
+
+ } _dataContainer;
+};
+
+} // namespace pass
+} // namespace contrib
+} // namespace nncc
+
+#endif //NNCC_PASSDATA_H
--- /dev/null
+#ifndef NNCC_PASSEXCEPTION_H
+#define NNCC_PASSEXCEPTION_H
+
+#include <exception>
+#include <string>
+
+namespace nncc
+{
+namespace contrib
+{
+namespace pass
+{
+
+/**
+ * @brief objects of this class are to be thrown from Passes if errors are occurred
+ */
+class PassException : public std::exception
+{
+public:
+ PassException() = default;
+ PassException(const PassException &) noexcept {};
+
+ PassException(const std::string &msg) : _msg(msg) {};
+ PassException(const char *msg) : _msg(msg) {};
+
+ /**
+ * @brief get message describes reason why exception was thrown
+ */
+ const std::string &reason() const { return _msg; }
+
+private:
+ std::string _msg;
+};
+
+} // namespace pass
+} // namespace contrib
+} // namespace nncc
+
+#endif //NNCC_PASSEXCEPTION_H
--- /dev/null
+#ifndef __PASS_MANAGER_H__
+#define __PASS_MANAGER_H__
+
+#include <queue>
+
+namespace nncc
+{
+namespace contrib
+{
+namespace pass
+{
+
+// forward declaration
+class Pass;
+
+/**
+ * @brief pass manager class. This class manages running of passes
+ */
+class PassManager
+{
+public:
+ /**
+ * @brief singleton method to get PassManager instance
+ */
+ static PassManager *getPassManager();
+
+ /**
+ * @brief register pass in pass manager
+ * @param pass - registered pass
+ */
+ void registerPass(Pass *pass);
+
+ /**
+ * @brief get all registered passes in order in which they were registered
+ */
+ using Passes = std::vector<Pass *>;
+ Passes getPasses() const { return _passes; }
+
+private:
+ PassManager() = default;
+ ~PassManager() = default;
+
+ // data
+ Passes _passes; // registered passes
+};
+
+} // namespace pass
+} // namespace contrib
+} // namespace nncc
+
+#endif // __PASS_MANAGER_H__
--- /dev/null
+#ifndef NNCC_CAFFEFRONTEND_H
+#define NNCC_CAFFEFRONTEND_H
+
+#include "pass/Pass.h"
+#include "pass/PassData.h"
+
+using namespace nncc::contrib::pass;
+
+namespace nncc
+{
+namespace contrib
+{
+namespace frontend
+{
+namespace caffe
+{
+
+/**
+ * @brief class represent frontend of caffe NN framework
+ */
+class CaffeFrontend : public Pass
+{
+public:
+ CaffeFrontend &operator=(const CaffeFrontend &) = delete;
+ CaffeFrontend(const CaffeFrontend &) = delete;
+
+ CaffeFrontend() = default;
+ ~CaffeFrontend() override = default;
+
+ static Pass &getInstance();
+ PassData run(PassData data) override;
+};
+
+} // namespace caffe
+} // namespace frontend
+} // namespace contrib
+} // namespace nncc
+
+#endif //NNCC_CAFFEFRONTEND_H
--- /dev/null
+#ifndef NNCC_INTERPRETERPASS_H
+#define NNCC_INTERPRETERPASS_H
+
+#include "core/modelIR/TensorVariant.h"
+#include "core/modelIR/Shape.h"
+
+#include "pass/Pass.h"
+#include "pass/PassData.h"
+
+namespace nncc
+{
+namespace contrib
+{
+namespace backend
+{
+namespace interpreter
+{
+
+using namespace nncc::contrib;
+using namespace nncc::contrib::pass;
+
+class InterpreterPass : public Pass
+{
+public:
+ static Pass &getInstance();
+ PassData run(PassData data) override;
+
+ virtual ~InterpreterPass();
+
+private:
+ nncc::contrib::core::ADT::TensorVariant loadInput(const nncc::contrib::core::data::Shape &);
+ nncc::contrib::core::ADT::TensorVariant *_out;
+};
+
+} // namespace interpreter
+} // namespace backend
+} // namespace contrib
+} // namespace nncc
+
+#endif //NNCC_INTERPRETERPASS_H
#define _NNC_SOFT_BACKEND_BASE_GENERATOR_H_
#include "core/modelIR/graph.h"
-#include "support/PluginInstance.h"
+#include "pass/Pass.h"
+#include "pass/PassData.h"
#include <string>
#include <ostream>
+using namespace nncc::contrib::pass;
+
namespace nncc
{
namespace contrib
class Serializer;
-class BaseCodeGenerator: public nncc::contrib::plugin::BackendPlugin
+class BaseCodeGenerator : public Pass
{
public:
- void *execute(void *data) override;
+ PassData run(PassData data) override;
protected:
virtual void formatTensorNames(const ModelAnalyzer &ma) = 0;
#ifndef _NNC_SOFT_BACKEND_C_GENERATOR_H_
#define _NNC_SOFT_BACKEND_C_GENERATOR_H_
-#include "base_generator.h"
+#include "passes/soft_backend/BaseGenerator.h"
+#include "pass/Pass.h"
namespace nncc
{
class CCodeGenerator: public BaseCodeGenerator
{
public:
- CCodeGenerator() = default;
+ static Pass &getInstance();
protected:
void formatTensorNames(const ModelAnalyzer &ma) override;
void materializeHeader(std::ostream &out, const ModelAnalyzer &ma) override;
void materializeCode(std::ostream &out, const ModelAnalyzer &ma, const Serializer &s) override;
+
+private:
+ CCodeGenerator() = default;
};
} // namespace soft
#ifndef _NNC_SOFT_BACKEND_CPP_GENERATOR_H_
#define _NNC_SOFT_BACKEND_CPP_GENERATOR_H_
-#include "base_generator.h"
+#include "passes/soft_backend/BaseGenerator.h"
+#include "pass/Pass.h"
namespace nncc
{
class CPPCodeGenerator: public BaseCodeGenerator
{
public:
- CPPCodeGenerator(): BaseCodeGenerator() {}
+ static Pass &getInstance();
protected:
void formatTensorNames(const ModelAnalyzer &ma) override;
void printGetter(std::ostream &out, const std::string &className, const std::string &setterName, const std::string &varName);
void materializeInferenceSequence(std::ostream &out, const ModelAnalyzer &ma);
void materializeCode(std::ostream &out, const ModelAnalyzer &ma, const Serializer &s) override;
+
+private:
+ CPPCodeGenerator(): BaseCodeGenerator() {}
};
} // namespace soft
--- /dev/null
+#ifndef NNCC_TFLITEFRONTEND_H
+#define NNCC_TFLITEFRONTEND_H
+
+#include "pass/Pass.h"
+#include "pass/PassData.h"
+
+using namespace nncc::contrib::pass;
+
+namespace nncc
+{
+namespace contrib
+{
+namespace frontend
+{
+namespace tflite
+{
+
+/**
+ * @brief class represent frontend of tensor flow lite NN framework
+ */
+class TFLiteFrontend : public Pass
+{
+public:
+ TFLiteFrontend &operator=(const TFLiteFrontend &) = delete;
+ TFLiteFrontend(const TFLiteFrontend &) = delete;
+
+ static Pass &getInstance();
+ PassData run(PassData data) override;
+
+private:
+ TFLiteFrontend() = default;
+ ~TFLiteFrontend() override = default;
+};
+
+} // namespace tflite
+} // namespace frontend
+} // namespace contrib
+} // namespace nncc
+
+#endif //NNCC_TFLITEFRONTEND_H
void checkInFile(const Option<std::string> &);
void checkOutFile(const Option<std::string> &);
void checkOutDir(const Option<std::string> &);
-void checkPluginsPath(const Option<std::string> &);
void checkDebugFile(const Option<std::string> &);
} // namespace clopt
+++ /dev/null
-//
-// Created by v.cherepanov@samsung.com on 04.05.18.
-//
-#ifndef __PLUGIN_EXCEPTION_H__
-#define __PLUGIN_EXCEPTION_H__
-
-#include <string>
-
-namespace nncc
-{
-namespace contrib
-{
-
-class PluginException
-{
-public:
- PluginException(const PluginException &) noexcept {};
-
- explicit PluginException(const std::string &info) { _msg = info; }
-
- /**
- * @brief get message from exception object
- */
- std::string what() const { return _msg; }
-
-private:
- std::string _msg;
-};
-
-
-} // namespace contrib
-} // namespace nncc
-
-#endif // __PLUGIN_EXCEPTION_H__
+++ /dev/null
-#ifndef __PLUGIN_INSTANCE_H__
-#define __PLUGIN_INSTANCE_H__
-
-#include <string>
-#include <memory>
-
-namespace nncc
-{
-namespace contrib
-{
-namespace plugin
-{
-
-//
-// This class and its methods are NOT thread safe
-//
-class Plugin
-{
-public:
- Plugin &operator=(const Plugin &) = delete;
- Plugin(const Plugin &) = delete;
-
- virtual void *execute(void *data) = 0;
-
-protected:
- Plugin() = default;
- virtual ~Plugin() = default;
-};
-
-class FrontendPlugin : public Plugin
-{
-public:
- FrontendPlugin &operator=(const FrontendPlugin &) = delete;
- FrontendPlugin(const FrontendPlugin &) = delete;
-
- void *execute(void *data) override = 0;
-
-protected:
- FrontendPlugin() = default;
- ~FrontendPlugin() override = default;
-};
-
-class BackendPlugin : public Plugin
-{
-public:
- BackendPlugin &operator=(const BackendPlugin &) = delete;
- BackendPlugin (const BackendPlugin &) = delete;
-
- void *execute(void *data) override = 0;
-
-protected:
- BackendPlugin() = default;
- ~BackendPlugin() override = default;
-};
-
-} // namespace plugin
-} // namespace contrib
-} // namespace nncc
-
-#endif // __PLUGIN_INSTANCE_H__
+++ /dev/null
-#ifndef __PLUGIN_MANAGER_H__
-#define __PLUGIN_MANAGER_H__
-
-#include <set>
-#include <vector>
-
-#include "PluginProxy.h"
-
-namespace nncc
-{
-namespace contrib
-{
-namespace plugin
-{
-
-/**
- * @brief plugin manager class
- * this class manages plugin loading, execution and unloading
- */
-class PluginManager
-{
-public:
- /**
- * @param plugin_path - absolute plugin path
- * @throw PluginException if couldn't load plugin
- */
- explicit PluginManager(const std::string &plugin_path);
-
- /**
- * @throw PluginException if couldn't unload plugin
- */
- ~PluginManager() noexcept(false);
-
- /**
- * @brief get plugin
- */
- Plugin *getPlugin();
-
- /**
- * @brief print plugin
- * @param st - output stream
- * @param pm - plugin manager object
- */
- friend std::ostream &operator<<(std::ostream &st, const PluginManager &pm);
-
-private:
- /**
- * @brief load/unload plugin
- */
- void loadPlugin();
- void unloadPlugin();
-
- // data
- std::string _plugin_path; // path to plugin
- std::shared_ptr<PluginProxy> _plugin_proxy; // access to plugin
-};
-
-} // namespace plugin
-} // namespace contrib
-} // namespace nncc
-
-#endif // __PLUGIN_MANAGER_H__
+++ /dev/null
-#ifndef __PLUGIN_PROXY_H__
-#define __PLUGIN_PROXY_H__
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "shared_library.h"
-#include "PluginException.h"
-#include "PluginInstance.h"
-
-namespace nncc
-{
-namespace contrib
-{
-namespace plugin
-{
-
-/**
- * @brief this proxy class provides access to plugins
- */
-class PluginProxy
-{
-public:
- /**
- * @brief factory method that load plugin
- * @param pluginPath - absolute path to plugin
- * @return proxy class instance
- * @throw PluginException if couldn't load plugin library or plugin is inappropriate
- */
- // TODO it is possible to eliminate factory method and create proxy in constructor
- static std::shared_ptr<PluginProxy> create(const std::string &pluginPath);
-
- /**
- * @brief unload plugin
- * @throw PluginException if couldn't unload plugin library
- */
- // TODO it is possible to eliminate this method and do unloading library in destructor
- void remove();
-
- /**
- * @brief get plugin absolute path and plugin name
- */
- const std::string &getPluginPath() const { return _lib->getPath(); }
- const std::string &getPluginName() const { return _pluginName; }
-
- /**
- * @brief get loaded plugin instance
- * @return pointer to plugin (don't need to be freed)
- */
- Plugin *getPluginInstance();
-
- /**
- * @brief name of function that provides information
- * about plugin. Every plugin must contain this function
- */
- static const std::string getInstanceFuncName;
-
-private:
- // only factory method can create class instances
- explicit PluginProxy(const std::string &pluginPath);
-
- friend std::ostream &operator<<(std::ostream &st, const PluginProxy &pl);
-
- // type of function that returns loaded plugin
- using get_instance_t = Plugin* (*)();
-
- // data
- Plugin *_pluginInstance; // pointer to loaded plugin
- std::shared_ptr<SharedLibrary<PluginException>> _lib; // plugin library
- get_instance_t _getInstance; // function from plugin that returns pointer to plugin
- std::string _pluginName; // name of plugin
-};
-
-} // namespace plugin
-} // namespace contrib
-} // namespace nncc
-
-#endif /* __PLUGIN_PROXY_H__ */
+++ /dev/null
-#ifndef NNCC_SHAREDLIBRARY_H
-#define NNCC_SHAREDLIBRARY_H
-
-#include <ostream>
-#include <string>
-#include <dlfcn.h>
-#include <cassert>
-
-namespace nncc
-{
-namespace contrib
-{
-namespace plugin
-{
-
-/**
- * @brief class provides access to shared library
- * @tparam ExceptionT - thrown exception type if errors occur
- */
-template <typename ExceptionT>
-class SharedLibrary
-{
-public:
- explicit SharedLibrary(const std::string &fullPath) : _handle(nullptr), _path(fullPath), _isLoaded(false) {}
-
- /**
- * @brief find function from shared library
- * @param funcName - function name
- * @return pointer to found function
- * @throw ExceptionT if errors occurred
- */
- void *findFunc(const std::string &funcName);
-
- /**
- * @brief unload shared library
- * @throw ExceptionT if couldn't unload library
- */
- void unloadLibrary();
-
- /**
- * @brief get path of shared library
- */
- const std::string& getPath() const { return _path; };
-
-private:
- // load shared library
- void *loadLibrary();
-
- // data
- std::string _path; // path to shared library
- void *_handle; // handle returned by dlopen
- bool _isLoaded;
-};
-
-
-template <typename ExceptionT>
-void *SharedLibrary<ExceptionT>::findFunc(const std::string &funcName)
-{
- if ( !_isLoaded )
- {
- _handle = loadLibrary();
- _isLoaded = true;
- }
-
- // reset errors
- dlerror();
-
- // get function address
- assert(_handle);
- void *func = dlsym(_handle, funcName.c_str());
-
- char *dlsym_error = dlerror();
-
- if ( dlsym_error )
- {
- throw ExceptionT("Cannot load symbol: '" + funcName + "' : " + dlsym_error);
- }
-
- return func;
-
-} // findFunc
-
-template <typename ExceptionT>
-void *SharedLibrary<ExceptionT>::loadLibrary()
-{
-// NNC_DEBUG(dbgs() << "Opening " << _path << std::endl);
-
- // open the library
- void *handle = dlopen(_path.c_str(), RTLD_LAZY);
-
- if ( !handle )
- {
- throw ExceptionT("Cannot open library: '" + _path + "' : " + dlerror());
- }
-
- return handle;
-
-} // loadLibrary
-
-template <typename ExceptionT>
-void SharedLibrary<ExceptionT>::unloadLibrary()
-{
- // reset errors
- dlerror();
-
- // This is a workaround for bug when nnc is received segfault when it can access
- // to vtable from unloaded plugin. When we eliminate plugins it will be fixed
- /*
- // close the library
- if ( dlclose(_handle) )
- {
- throw ExceptionT("Cannot unloaded library: '" + _path + "' : " + dlerror());
- }
- */
-
-} // unloadLibrary
-
-template <typename ExceptionT>
-std::ostream &operator<<(std::ostream &st, const SharedLibrary<ExceptionT> &lib)
-{
- st << lib.getPath();
- return st;
-}
-
-} // namespase plugin
-} // namespace contrib
-} // namespace nncc
-
-#endif // NNCC_SHAREDLIBRARY_H
--- /dev/null
+set(PASS_MANAGER_SRC PassManager.cpp)
+
+add_library(nnc_pass STATIC ${PASS_MANAGER_SRC})
+set_target_properties(nnc_pass PROPERTIES LINKER_LANGUAGE CXX)
--- /dev/null
+#include "pass/PassManager.h"
+
+namespace nncc
+{
+namespace contrib
+{
+namespace pass
+{
+
+PassManager *PassManager::getPassManager()
+{
+ static PassManager passManager;
+
+ return &passManager;
+
+} // getPassManager
+
+
+void PassManager::registerPass(Pass *pass)
+{
+ _passes.push_back(pass);
+
+} // registerPass
+
+} // namespace pass
+} // namespace contrib
+} // namespace nncc
add_nncc_library(caffe_importer SHARED ${caffe_importer_sources}
${caffe_importer_headers})
-set_target_properties(caffe_importer PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${NNC_BINARY_DIR})
target_link_libraries(caffe_importer PUBLIC caffeproto)
target_link_libraries(caffe_importer PUBLIC nn_import_common)
target_link_libraries(caffe_importer PRIVATE nnc_core)
# install caffe frontend library
-install_nnc_plugin(caffe_importer)
+install_nnc_library(caffe_importer)
--- /dev/null
+#include <map>
+#include <vector>
+#include <iostream>
+
+#include "option/Options.h"
+#include "pass/PassException.h"
+#include "passes/caffe_frontend/CaffeFrontend.h"
+
+#include "caffe_importer.h"
+
+using namespace nncc::contrib::pass;
+using namespace nncc::contrib::frontend::caffe;
+
+namespace nncc
+{
+namespace contrib
+{
+namespace frontend
+{
+namespace caffe
+{
+
+Pass &CaffeFrontend::getInstance()
+{
+ static CaffeFrontend instance;
+ return instance;
+}
+
+PassData CaffeFrontend::run(PassData data)
+{
+ (void)data;
+ nncc::contrib::frontend::caffe::CaffeImporter importer{clopt::inputFile};
+
+ bool success = importer.import();
+
+ if (!success)
+ {
+ throw PassException("Could not load model: " + clopt::inputFile + "\n");
+ }
+
+ return reinterpret_cast<Graph *>(importer.createIR());
+}
+
+} // namespace caffe
+} // namespace frontend
+} // namespace contrib
+} // namespace nncc
return util::readProtoFromBinaryFile(modelFilename.c_str(), net.get());
}
-void* CaffeImporter::createIR()
+void *CaffeImporter::createIR()
{
ModelVisitor irCreator;
ModelWalker caffeWalker(&irCreator);
#include "caffe/proto/caffe.pb.h"
-#include "plugin/common_frontend/nn_importer.h"
+#include "passes/common_frontend/nn_importer.h"
namespace nncc
{
explicit CaffeImporter(std::string filename) : modelFilename(std::move(filename)) {};
bool import() override;
- void* createIR() override;
+ void *createIR() override;
void dump() override;
private:
#include "core/modelIR/Shape.h"
#include "core/modelIR/operations/variable_op.h"
#include "core/modelIR/TensorUtil.h"
-#include "support/PluginException.h"
+#include "pass/PassException.h"
-#include "plugin/common_frontend/shape_helper.h"
+#include "passes/common_frontend/shape_helper.h"
#include "caffe_model_visitor.h"
+using namespace nncc::contrib::pass;
+
namespace nncc
{
namespace contrib
}
else
{
- throw PluginException("Encountered unsupported Caffe layer type");
+ throw PassException("Encountered unsupported Caffe layer type");
}
for (auto item : outputs)
{
if (np.input_dim_size() != 0 || np.input_shape_size() != 0)
{
- throw PluginException("Deprecated Caffe input types are not supported");
+ throw PassException("Deprecated Caffe input types are not supported");
}
}
}
else
{
- throw PluginException("No data in Caffe BlobProto, investigate");
+ throw PassException("No data in Caffe BlobProto, investigate");
}
// Create untyped tensor. Note, tensor contents will be *copied* here.
#include "core/modelIR/Index.h"
#include "core/modelIR/ShapeRange.h"
-#include "plugin/common_frontend/shape_helper.h"
+#include "passes/common_frontend/shape_helper.h"
+#include "pass/PassException.h"
#include "caffe_op_creator.h"
+using namespace nncc::contrib::pass;
+
namespace nncc
{
namespace contrib
{
if (opts.has_stride_h() != opts.has_stride_w())
{
- throw PluginException("Conv or Pool layer has only 1 out of 2 2D strides, investigate");
+ throw PassException("Conv or Pool layer has only 1 out of 2 2D strides, investigate");
}
// We already checked that both 2D strides are both present or both are not
return opts.has_stride_h();
{
if (opts.has_kernel_h() != opts.has_kernel_w())
{
- throw PluginException("Pool layer has only 1 out of 2 kernel dimensions, investigate");
+ throw PassException("Pool layer has only 1 out of 2 kernel dimensions, investigate");
}
if (opts.has_kernel_h())
}
else
{
- throw PluginException("Pooling layer doesn't have kernel size data, investigate");
+ throw PassException("Pooling layer doesn't have kernel size data, investigate");
}
}
else if (opts.pool() == PoolingParameter::AVE)
return PoolingType::AVG;
else
- throw PluginException("Unsupported pooling type: " +
+ throw PassException("Unsupported pooling type: " +
PoolingParameter::PoolMethod_Name(opts.pool()));
}
}
else if (axis != 1 && axis != -1)
{
- throw PluginException("Softmax/Concat layer axis param is not 1 or -1, which implies"
+ throw PassException("Softmax/Concat layer axis param is not 1 or -1, which implies"
"unsupported NN architecture.");
}
}
{
if (opts.has_axis() && opts.axis() != 1)
{
- throw PluginException("InnerProduct layer axis param is not supported yet");
+ throw PassException("InnerProduct layer axis param is not supported yet");
}
if (opts.has_transpose() && opts.transpose())
{
- throw PluginException("InnerProduct layer transpose param is not supported yet");
+ throw PassException("InnerProduct layer transpose param is not supported yet");
}
// Add Reshape operation to make sure the input for FC operation has shape [1, fcInputSize]
if (opts.has_global_pooling() && opts.global_pooling())
{
- throw PluginException("Pooling layer global_pooling param is not supported yet");
+ throw PassException("Pooling layer global_pooling param is not supported yet");
}
Shape windowShape = util::getPoolWindowShape(opts);
if (opts.has_axis() || opts.has_num_axes())
{
- throw PluginException("Reshape layer axis and num_axes params are not supported yet");
+ throw PassException("Reshape layer axis and num_axes params are not supported yet");
}
if (!opts.has_shape())
{
- throw PluginException("Reshape layer doesn't have shape parameter");
+ throw PassException("Reshape layer doesn't have shape parameter");
}
Shape newShape = common::ShapeHelper::createShape(opts.shape().dim(), opts.shape().dim_size());
for (unsigned int i = 0; i < newShape.rank(); ++i)
{
if (newShape.dim(i) == 0)
- throw PluginException("Reshape layer zero shape values are not supported yet");
+ throw PassException("Reshape layer zero shape values are not supported yet");
}
outputs[0]->getOperation()->setOutputShape(0, newShape);
if (opts.has_negative_slope())
{
- throw PluginException("ReLU layer negative_slope param is not supported yet.");
+ throw PassException("ReLU layer negative_slope param is not supported yet.");
}
return createOp<ops::ReluOp>(inputs);
#include <vector>
#include <memory>
-#include "support/PluginException.h"
#include "core/modelIR/graph.h"
#include "core/modelIR/ir_node.h"
#include "core/modelIR/TensorVariant.h"
#include <sys/stat.h>
#include <sys/mman.h>
-#include "plugin/common_frontend/model_allocation.h"
+#include "passes/common_frontend/model_allocation.h"
using namespace nncc::contrib::frontend::common;
--- /dev/null
+#include <vector>
+
+#include "passes/common_frontend/shape_helper.h"
+#include "pass/PassException.h"
+
+using namespace nncc::contrib::pass;
+
+namespace nncc
+{
+namespace contrib
+{
+namespace frontend
+{
+namespace common
+{
+
+Shape &ShapeHelper::cutOffBatchDim(Shape &shape)
+{
+ if (shape.dim(0) != 1)
+ {
+ throw PassException{"While attempting to cut off tensor batch dimension (first one),"
+ "found that it is not 1. Check the model being imported, if the first"
+ "dimension of the input is not 1, then it might be not batch, and the"
+ "code needs some restructuring"};
+ }
+
+ for (unsigned int i = 0; i < shape.rank() - 1; ++i)
+ {
+ shape.dim(i) = shape.dim(i + 1);
+ }
+ shape.resize(shape.rank() - 1);
+
+ return shape;
+}
+
+} // namespace common
+} // namespace frontend
+} // namespace contrib
+} // namespace nncc
file(GLOB_RECURSE interp_src ./*.cpp ./*.h)
add_library(nnc_interpreter SHARED ${interp_src})
target_link_libraries(nnc_interpreter PRIVATE nnc_core nnc_support)
-set_target_properties(nnc_interpreter PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${NNC_BINARY_DIR})
if(NNC_HDF5_SUPPORTED)
target_include_directories(nnc_interpreter PRIVATE ${HDF5_INCLUDE_DIRS})
endif(NNC_HDF5_SUPPORTED)
# install interpreter library
-install_nnc_plugin(nnc_interpreter)
\ No newline at end of file
+install_nnc_library(nnc_interpreter)
\ No newline at end of file
#include <cmath>
#include <cassert>
-#include "plugin/interpreter/Interpreter.h"
+#include "passes/interpreter/Interpreter.h"
#include "core/modelIR/operations/fully_connected_op.h"
#include "core/modelIR/operations/softmax_op.h"
#include <H5Cpp.h>
#endif // NNC_HDF5_SUPPORTED
-#include "support/PluginInstance.h"
-
#include "core/modelIR/Shape.h"
-#include "plugin/interpreter/Interpreter.h"
+#include "pass/Pass.h"
+#include "pass/PassData.h"
+#include "pass/PassException.h"
+
+#include "passes/interpreter/Interpreter.h"
+#include "passes/interpreter/InterpreterPass.h"
#include "core/modelIR/ShapeInference.h"
#include "core/modelIR/graph.h"
#include "core/modelIR/ShapeRange.h"
#include "core/modelIR/Tensor.h"
-#include "interpreter_plugin.h"
namespace nncc
{
{
namespace interpreter
{
-namespace plugin
-{
using namespace nncc::contrib;
+using namespace nncc::contrib::pass;
using namespace nncc::contrib::core::data;
using namespace nncc::contrib::core::IR::model;
using nncc::contrib::core::data::Shape;
-using nncc::contrib::plugin::BackendPlugin;
using nncc::contrib::backend::interpreter::core::NNInterpreter;
-BackendPlugin &InterpreterPlugin::getInstance() {
- static InterpreterPlugin instance;
+Pass &InterpreterPass::getInstance() {
+ static InterpreterPass instance;
return instance;
}
}
#endif // NNC_HDF5_SUPPORTED
-void *InterpreterPlugin::execute(void *data) {
+PassData InterpreterPass::run(PassData data)
+{
auto g = static_cast<Graph *>(data);
+ assert(g);
+
ShapeInference shapeInference;
NNInterpreter interpreter;
// Check nodes
auto inputNode = g->getInput(clopt::interInNode);
if (inputNode == nullptr) {
- throw PluginException("input node <" + clopt::interInNode +"> not found" );
+ throw PassException("input node <" + clopt::interInNode +"> not found" );
}
auto outputNode = g->getOutput(clopt::interOutNode);
if (outputNode == nullptr) {
- throw PluginException("output node <" + clopt::interOutNode +"> not found" );
+ throw PassException("output node <" + clopt::interOutNode +"> not found" );
}
auto input = loadInput(inputNode->getOperation()->getOutputShape(0));
return _out;
}
-TensorVariant InterpreterPlugin::loadInput(const Shape &shape)
+TensorVariant InterpreterPass::loadInput(const Shape &shape)
{
auto f = fopen(clopt::interInputData.c_str(), "rb");
assert(f && "Cannot open file");
if (len != tensorSize) {
std::stringstream info;
info << "Wrong input file size <" << clopt::interInputData << "> = " << len << ". Should be :" << tensorSize;
- throw PluginException(info.str());
+ throw PassException(info.str());
}
rewind(f);
return TensorVariant(shape, std::shared_ptr<char>(data, [](const char* d) { delete[] d; }), TensorVariant::DTYPE::FLOAT, sizeof(float));
}
-InterpreterPlugin::~InterpreterPlugin()
+InterpreterPass::~InterpreterPass()
{
delete _out;
}
-} // namespace plugin
} // namespace interpreter
} // namespace backend
} // namespace contrib
} // namespace nncc
-
-extern "C" nncc::contrib::backend::interpreter::plugin::Plugin *get_instance() {
- return &nncc::contrib::backend::interpreter::plugin::InterpreterPlugin::getInstance();
-}
-
-#include "base_generator.h"
+#include "passes/soft_backend/BaseGenerator.h"
#include "model_analyzer.h"
#include "serializer.h"
-#include "support/PluginException.h"
#include "core/modelIR/ShapeInference.h"
#include "option/Options.h"
-
+#include "pass/Pass.h"
+#include "pass/PassData.h"
+#include "pass/PassException.h"
#include "param_constants.def"
#include <sys/stat.h>
using namespace std;
using namespace nncc::contrib;
+using namespace nncc::contrib::pass;
using namespace nncc::contrib::core::IR::model;
namespace nncc
unique_ptr<ofstream> ofs(new ofstream(path));
if (ofs->fail())
{
- throw PluginException("Can not open code output file: " + path);
+ throw PassException("Can not open code output file: " + path);
}
return ofs;
}
int res = mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (res != 0 && errno != EEXIST)
{
- throw PluginException("Failed to create output directory");
+ throw PassException("Failed to create output directory");
}
}
out.write(header, HEADER_LEN);
if (out.fail())
{
- throw PluginException("Failed to write model parameters header");
+ throw PassException("Failed to write model parameters header");
}
auto ¶ms = s.getBuffer();
out.write(params.data(), params.size());
if (out.fail())
{
- throw PluginException("Failed to write model Parameters");
+ throw PassException("Failed to write model Parameters");
}
}
-void *BaseCodeGenerator::execute(void *data)
+PassData BaseCodeGenerator::run(PassData data)
{
- Graph *g = reinterpret_cast<Graph *>(data);
+ auto g = static_cast<Graph *>(data);
+ assert(g);
+
// inference shapes
core::IR::model::ShapeInference si;
g->accept(&si);
-#include "c_generator.h"
+#include "passes/soft_backend/CGenerator.h"
#include "model_analyzer.h"
using namespace std;
// TODO emit C code to out stream
}
+Pass &CCodeGenerator::getInstance()
+{
+ static CCodeGenerator instance;
+ return instance;
+}
+
} // namespace soft
} // namespace backend
} // namespace contrib
} // namespace nncc
-
-extern "C" nncc::contrib::plugin::Plugin *get_instance()
-{
- static nncc::contrib::backend::soft::CCodeGenerator cCodeGenerator;
- return &cCodeGenerator;
-}
-set(SOFT_BACKEND_COMMON_SOURCES base_generator.cpp model_analyzer.cpp serializer.cpp)
+set(SOFT_BACKEND_COMMON_SOURCES BaseGenerator.cpp model_analyzer.cpp serializer.cpp)
set(SOFT_BACKEND_CPP_SOURCES cpp_generator.cpp)
-set(SOFT_BACKEND_C_SOURCES c_generator.cpp)
+set(SOFT_BACKEND_C_SOURCES CGenerator.cpp)
set(DEF_CONV ${NNC_ROOT_SRC_DIR}/utils/def2src.cpp)
file(GLOB_RECURSE SOFT_DEF_SOURCES "*.def")
target_include_directories(soft_backend_common PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(soft_backend_common PRIVATE nnc_support)
target_link_libraries(soft_backend_common PRIVATE nnc_core)
-# This is included because right now common functional is built into nnc_driver
-target_link_libraries(soft_backend_common PRIVATE nnc_driver)
function(make_soft_backend NAME)
add_library(${NAME} SHARED ${ARGN} ${SOFT_GENERATED_SOURCES})
- set_target_properties(${NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${NNC_BINARY_DIR})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(${NAME} PRIVATE soft_backend_common)
target_link_libraries(${NAME} PRIVATE nnc_core)
# install soft backend c++ library
- install_nnc_plugin(${NAME})
+ install_nnc_library(${NAME})
endfunction(make_soft_backend)
make_soft_backend(soft_backend_cpp ${SOFT_BACKEND_CPP_SOURCES})
-#include "cpp_generator.h"
+#include "passes/soft_backend/CPPGenerator.h"
#include "model_analyzer.h"
#include "serializer.h"
-#include "support/PluginException.h"
#include "option/Options.h"
using namespace std;
out << "}";
}
+Pass &CPPCodeGenerator::getInstance()
+{
+ static CPPCodeGenerator cppCodeGenerator;
+ return cppCodeGenerator;
+}
+
} // namespace soft
} // namespace backend
} // namespace contrib
} // namespace nncc
-
-extern "C" nncc::contrib::plugin::Plugin *get_instance()
-{
- static nncc::contrib::backend::soft::CPPCodeGenerator cppCodeGenerator;
- return &cppCodeGenerator;
-}
tflite_ir_visitor.cpp
tflite_op_creator.cpp
tflite_v3_importer.cpp
- tflite_plugin.cpp)
+ tflite_frontend.cpp)
file(GLOB tflite_importer_headers *.h)
set(tflite_import tflite_import)
add_library(${tflite_import} SHARED ${tflite_importer_sources} ${tflite_importer_headers})
-set_target_properties(${tflite_import} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${NNC_BINARY_DIR})
target_link_libraries(${tflite_import} PUBLIC tflite_schema)
target_link_libraries(${tflite_import} PUBLIC flatbuffers)
target_link_libraries(${tflite_import} PUBLIC nnc_core)
# install tflite frontend library
-install_nnc_plugin(tflite_import)
+install_nnc_library(tflite_import)
--- /dev/null
+#include <map>
+#include <vector>
+#include <iostream>
+
+#include "pass/Pass.h"
+#include "pass/PassException.h"
+#include "passes/tflite_frontend/TfliteFrontend.h"
+#include "option/Options.h"
+
+#include "tflite_v3_importer.h"
+
+using namespace nncc::contrib;
+using namespace nncc::contrib::pass;
+
+namespace nncc
+{
+namespace contrib
+{
+namespace frontend
+{
+namespace tflite
+{
+
+Pass &TFLiteFrontend::getInstance()
+{
+ static TFLiteFrontend instance;
+ return instance;
+}
+
+PassData TFLiteFrontend::run(PassData data)
+{
+ nncc::contrib::frontend::tflite::v3::TfliteImporter importer{clopt::inputFile};
+
+ bool success = importer.import();
+
+ if (!success)
+ {
+ throw PassException("Could not load model: " + clopt::inputFile + "\n");
+ }
+
+ return reinterpret_cast<Graph *>(importer.createIR());
+}
+
+} // namespace tflite
+} // namespace frontend
+} // namespace contrib
+} // namespace nncc
#include <algorithm>
#include "schema_v3.h"
-#include "support/PluginException.h"
+#include "pass/PassException.h"
#include "core/modelIR/Shape.h"
#include "core/modelIR/Index.h"
#include "core/modelIR/IndexRange.h"
#include "core/modelIR/TensorUtil.h"
#include "core/modelIR/operations/variable_op.h"
-#include "plugin/common_frontend/shape_helper.h"
+#include "passes/common_frontend/shape_helper.h"
#include "tflite_ir_visitor.h"
#include "tflite_op_creator.h"
+using namespace nncc::contrib::pass;
+
namespace nncc
{
namespace contrib
outputs = opCreator->createSoftmax(inputs, params, op->builtin_options_as<SoftmaxOptions>());
break;
default:
- throw PluginException(
+ throw PassException(
std::string("Encountered unsupported TFLite operator: ") +
EnumNamesBuiltinOperator()[opcode]);
}
}
catch (const std::out_of_range &e)
{
- throw PluginException("Found a TFLite operator with an input tensor for which "
- "a corresponding Model IR node that outputs it was not created.");
+ throw PassException("Found a TFLite operator with an input tensor for which "
+ "a corresponding Model IR node that outputs it was not created.");
}
return inputsForOp;
type = IrTensor::DTYPE::INT;
break;
default:
- throw PluginException(
+ throw PassException(
std::string("Encountered unsupported tensor type ") +
EnumNamesTensorType()[t->type()]);
}
#include "core/modelIR/operations/pool_op.h"
#include "core/modelIR/operations/bias_add_op.h"
#include "core/modelIR/operations/reshape_op.h"
+#include "pass/PassException.h"
+
+using namespace nncc::contrib::pass;
namespace nncc
{
activation = graph->create<ops::CappedReluOp>("", 6);
break;
default:
- throw PluginException(std::string("Encountered unsupported NN activation type: ") +
- EnumNamesActivationFunctionType()[activationType]);
+ throw PassException(std::string("Encountered unsupported NN activation type: ") +
+ EnumNamesActivationFunctionType()[activationType]);
}
assert(input->getOperation()->getNumOutputs() == 1);
#include <memory>
#include <cstdint>
-#include "support/PluginException.h"
#include "core/modelIR/graph.h"
#include "core/modelIR/ir_node.h"
#include "core/modelIR/TensorVariant.h"
#include "core/modelIR/operations/common.h"
#include "schema_v3.h"
-#include "plugin/common_frontend/shape_helper.h"
+#include "passes/common_frontend/shape_helper.h"
namespace nncc
{
#include <string>
#include "schema_v3.h"
-#include "plugin/common_frontend/nn_importer.h"
-#include "plugin/common_frontend/model_allocation.h"
+#include "passes/common_frontend/nn_importer.h"
+#include "passes/common_frontend/model_allocation.h"
namespace nncc
{
+++ /dev/null
-#include <map>
-#include <vector>
-#include <iostream>
-
-#include "support/PluginInstance.h"
-#include "support/PluginException.h"
-#include "option/Options.h"
-
-#include "caffe_importer.h"
-
-namespace
-{
-using namespace nncc::contrib;
-using namespace nncc::contrib::plugin;
-
-class ImporterPlugin : public FrontendPlugin
-{
-public:
- ImporterPlugin &operator=(const ImporterPlugin &) = delete;
- ImporterPlugin(const ImporterPlugin &) = delete;
-
- static FrontendPlugin &getInstance();
- void *execute(void *data) override;
-
-private:
- ImporterPlugin() = default;
- ~ImporterPlugin() override = default;
-};
-
-FrontendPlugin &ImporterPlugin::getInstance()
-{
- static ImporterPlugin instance;
- return instance;
-}
-
-void *ImporterPlugin::execute(void *)
-{
- nncc::contrib::frontend::caffe::CaffeImporter importer{clopt::inputFile};
-
- bool success = importer.import();
-
- if (!success)
- {
- throw nncc::contrib::PluginException("Could not load model: " + clopt::inputFile + "\n");
- }
-
- return importer.createIR();
-}
-
-} // anonymous namespace
-
-extern "C" Plugin *get_instance()
-{
- return &ImporterPlugin::getInstance();
-}
+++ /dev/null
-#include <vector>
-
-#include "plugin/common_frontend/shape_helper.h"
-#include "support/PluginException.h"
-
-namespace nncc
-{
-namespace contrib
-{
-namespace frontend
-{
-namespace common
-{
-
-Shape &ShapeHelper::cutOffBatchDim(Shape &shape)
-{
- if (shape.dim(0) != 1)
- {
- throw PluginException{"While attempting to cut off tensor batch dimension (first one),"
- "found that it is not 1. Check the model being imported, if the first"
- "dimension of the input is not 1, then it might be not batch, and the"
- "code needs some restructuring"};
- }
-
- for (unsigned int i = 0; i < shape.rank() - 1; ++i)
- {
- shape.dim(i) = shape.dim(i + 1);
- }
- shape.resize(shape.rank() - 1);
-
- return shape;
-}
-
-} // namespace common
-} // namespace frontend
-} // namespace contrib
-} // namespace nncc
+++ /dev/null
-#ifndef _NNC_BACKEND_INTERPRETER_PLUGIN_
-#define _NNC_BACKEND_INTERPRETER_PLUGIN_
-
-#include <unordered_map>
-
-#include "support/PluginInstance.h"
-#include "support/PluginException.h"
-
-#include "core/modelIR/TensorVariant.h"
-#include "core/modelIR/Shape.h"
-
-namespace nncc
-{
-namespace contrib
-{
-namespace backend
-{
-namespace interpreter
-{
-namespace plugin
-{
-
-using namespace nncc::contrib;
-using namespace nncc::contrib::plugin;
-
-class InterpreterPlugin : public BackendPlugin {
- public:
- static BackendPlugin &getInstance();
- void *execute(void *data) override;
-
- virtual ~InterpreterPlugin();
-
-private:
- nncc::contrib::core::ADT::TensorVariant loadInput(const nncc::contrib::core::data::Shape &);
- nncc::contrib::core::ADT::TensorVariant *_out;
-};
-
-} // namespace plugin
-} // namespace interpreter
-} // namespace backend
-} // namespace contrib
-} // namespace nncc
-
-#endif //_NNC_BACKEND_INTERPRETER_PLUGIN_
+++ /dev/null
-#include <map>
-#include <vector>
-#include <iostream>
-
-#include "support/PluginInstance.h"
-#include "support/PluginException.h"
-#include "option/Options.h"
-
-#include "tflite_v3_importer.h"
-
-namespace
-{
-using namespace nncc::contrib;
-using namespace nncc::contrib::plugin;
-
-class ImporterPlugin : public FrontendPlugin
-{
-public:
- ImporterPlugin &operator=(const ImporterPlugin &) = delete;
- ImporterPlugin(const ImporterPlugin &) = delete;
-
- static FrontendPlugin &getInstance();
- void *execute(void *data) override;
-
-private:
- ImporterPlugin() = default;
- ~ImporterPlugin() override = default;
-};
-
-FrontendPlugin &ImporterPlugin::getInstance()
-{
- static ImporterPlugin instance;
- return instance;
-}
-
-void *ImporterPlugin::execute(void *)
-{
- nncc::contrib::frontend::tflite::v3::TfliteImporter importer{clopt::inputFile};
-
- bool success = importer.import();
-
- if (!success)
- {
- throw nncc::contrib::PluginException("Could not load model: " + clopt::inputFile + "\n");
- };
-
- return importer.createIR();
-}
-
-} // anonymous namespace
-
-extern "C" Plugin *get_instance()
-{
- return &ImporterPlugin::getInstance();
-}
{
namespace clopt
{
-void checkPluginsPath(const Option<std::string> &plugin_dir)
-{
- auto dir = opendir(plugin_dir.c_str());
-
- if (dir)
- {
- closedir(dir);
- return;
- }
-
- auto err = errno;
-
- switch (err)
- {
- case ENOENT:
- throw BadOption("No such plugins directory");
- case ENOTDIR:
- throw BadOption("Value for plugins path is not directory");
- case EACCES:
- throw BadOption("Has no permission to open plugins directory");
- default:
- throw BadOption("Can not open plugins directory");
- }
-
-} // checkPluginsPath
-
void checkInFile(const Option<std::string> &in_file)
{
if ( in_file.empty() )
set(SUPPORT_SOURCES
CommandLine.cpp
CLOptionChecker.cpp
- Debug.cpp
- PluginManager.cpp
- PluginProxy.cpp)
+ Debug.cpp)
add_library(nnc_support SHARED ${SUPPORT_SOURCES})
set_target_properties(nnc_support PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(nnc_support PRIVATE dl)
-install_common_library(nnc_support)
+install_nnc_library(nnc_support)
+++ /dev/null
-#include <iostream>
-#include <dlfcn.h>
-#include <dirent.h>
-#include <cstring>
-#include <vector>
-#include <exception>
-
-#include "support/PluginProxy.h"
-#include "support/PluginManager.h"
-#include "support/PluginInstance.h"
-#include "option/Options.h"
-
-#include "support/PluginException.h"
-
-//#include "debug.h"
-//#define DEBUG_AREA "plugin"
-
-namespace nncc
-{
-namespace contrib
-{
-namespace plugin
-{
-
-PluginManager::PluginManager(const std::string &plugin_path)
-{
- _plugin_path = plugin_path;
- loadPlugin();
-
-} // PluginManager
-
-PluginManager::~PluginManager() noexcept(false)
-{
- // if exception is already being thrown then we can't throw yet
- // another exception from destructor because std::terminate will
- // be called and terminates program so that we don't unload plugin
- // because this function can throw exception
- if ( !std::uncaught_exception() )
- {
- unloadPlugin();
- }
-
-} // ~PluginManager
-
-void PluginManager::loadPlugin()
-{
- // TODO: we need to move debug to support directory
- //NNC_DEBUG(dbgs() << "Current plugin path is <" << _plugin_path << ">" << std::endl);
- _plugin_proxy = PluginProxy::create(_plugin_path);
-
-} // loadPlugin
-
-void PluginManager::unloadPlugin()
-{
- _plugin_proxy->remove();
-
-} // unloadPlugin
-
-Plugin *PluginManager::getPlugin()
-{
- return _plugin_proxy->getPluginInstance();
-
-} // getPlugin
-
-std::ostream &operator<<(std::ostream &st, const PluginManager &pm)
-{
- st << pm._plugin_path << std::endl;
- return st;
-}
-
-} // namespace plugin
-} // namespace contrib
-} // namespace nncc
+++ /dev/null
-#include <string>
-#include <memory>
-#include <cassert>
-
-#include "support/PluginProxy.h"
-#include "support/shared_library.h"
-
-namespace nncc
-{
-namespace contrib
-{
-namespace plugin
-{
-
-const std::string PluginProxy::getInstanceFuncName = "get_instance";
-
-PluginProxy::PluginProxy(const std::string &pluginPath)
- : _getInstance(nullptr), _lib(nullptr), _pluginInstance(nullptr)
-{
- _lib = std::make_shared<SharedLibrary<PluginException>>(pluginPath);
-
- // get plugin name by path
- auto i = pluginPath.find_last_of('/');
- _pluginName = ( i == std::string::npos ) ? pluginPath : pluginPath.substr(i + 1);
-
-} // PluginProxy
-
-std::shared_ptr<PluginProxy> PluginProxy::create(const std::string &pluginPath)
-{
- auto proxy = std::shared_ptr<PluginProxy>(new PluginProxy(pluginPath));
-
- // get plugin function from shared library
- proxy->_getInstance = (get_instance_t)proxy->_lib->findFunc(getInstanceFuncName);
-
- // call plugin function
- proxy->_pluginInstance = proxy->_getInstance();
-
- if ( !proxy->_pluginInstance )
- throw PluginException("this shared library is not NNC plugin");
-
- return proxy;
-
-} // create
-
-void PluginProxy::remove()
-{
- _lib->unloadLibrary();
-
-} // remove
-
-Plugin *PluginProxy::getPluginInstance()
-{
- assert(_pluginInstance);
- return _pluginInstance;
-
-} // getPluginInstance
-
-std::ostream &operator<<(std::ostream &st, const PluginProxy &pl)
-{
- st << *(pl._lib);
- return st;
-}
-
-} // namespace plugin
-} // namespace contrib
-} // namespace nncc
#include "core/modelIR/operations/softmax_op.h"
#include "core/modelIR/ShapeInference.h"
-#include "plugin/common_frontend/shape_helper.h"
+#include "passes/common_frontend/shape_helper.h"
#include "op_info_generated.h"
#include "graph_creator.h"
#include "core/modelIR/ShapeInference.h"
#include "op_info_generated.h"
-#include "plugin/common_frontend/shape_helper.h"
+#include "passes/common_frontend/shape_helper.h"
#include "graph_creator.h"
using namespace nncc::contrib::frontend::common;
#include "gtest/gtest.h"
#include "op_info_generated.h"
-#include "plugin/interpreter/Interpreter.h"
+#include "passes/interpreter/Interpreter.h"
#include "core/modelIR/graph.h"
#include "op_info_util.h"
#include "graph_creator.h"
#include "core/modelIR/operations/variable_op.h"
#include "core/modelIR/ShapeInference.h"
-#include "cpp_generator.h"
+#include "passes/soft_backend/CPPGenerator.h"
// This header generated and contains array with test_main.def contents
#include "test_main.generated.h"
Graph g;
fillGraph(g);
- nncc::contrib::backend::soft::CPPCodeGenerator().execute(&g);
+ nncc::contrib::backend::soft::CPPCodeGenerator::getInstance().run(&g);
string basePath = outputDir + "/" + artifactName;
-add_subdirectory(module)
+add_subdirectory(pass)
add_subdirectory(core)
add_subdirectory(soft_backend)
add_subdirectory(support)
+++ /dev/null
-file(GLOB_RECURSE TEST_SOURCES "*.cpp")
-
-# Plugin module tests
-add_nncc_test(nnc_module_test ${OPTIONS_SRC} ${TEST_SOURCES} ${HEADERS})
-if (TARGET nnc_module_test)
- nncc_target_link_libraries(nnc_module_test nnc_support dl)
-
- # Set macro in nnc_module_test with some_parser absolute path
- target_compile_definitions(nnc_module_test PRIVATE
- CMAKE_SAMPLE_PLUGIN_ABS_PATH=$<TARGET_FILE:some_parser>
- CMAKE_SAMPLE_PLUGIN_2_ABS_PATH=$<TARGET_FILE:some_parser_second>
- CMAKE_SAMPLE_PLUGIN_DIR_ABS_PATH=$<TARGET_FILE_DIR:some_parser>)
-endif()
+++ /dev/null
-#include <dlfcn.h>
-
-#include "support/CommandLine.h"
-#include "support/PluginManager.h"
-
-#include "gtest/gtest.h"
-
-#define STRING(s) _STRING(s)
-#define _STRING(s) #s
-
-using namespace nncc::contrib;
-using namespace nncc::contrib::plugin;
-
-
-// Test PluginManager loading with unexisting path
-TEST(CONTRIB_NNC, PluginManagerMissingDir)
-{
- try
- {
- PluginManager pluginManager("AAA");
- FAIL();
- }
- catch ( const PluginException &e )
- {
-
- }
-}
-
-// Test PluginManager work with correct configuration
-TEST(CONTRIB_NNC, PluginManager)
-{
- PluginManager pluginManager(STRING(CMAKE_SAMPLE_PLUGIN_ABS_PATH));
-
- // Test operator '<<'
- std::ostringstream os;
- os << pluginManager;
-
- std::string plugin(STRING(CMAKE_SAMPLE_PLUGIN_ABS_PATH) "\n");
- EXPECT_TRUE(os.str() == plugin );
-}
-
-// Test PluginManager that destructor doesn't throw exception
-TEST(SUPPORT_NNC, verifyPluginManagerForLoadPlugin)
-{
- std::string plugin_path{STRING(CMAKE_SAMPLE_PLUGIN_ABS_PATH)};
-
- try
- {
- // load the library
- PluginManager pluginManager(plugin_path);
- }
- catch ( const PluginException &e )
- {
- FAIL();
- }
-
- try
- {
- // load the library
- PluginManager pluginManager(plugin_path);
-
- throw PluginException("test exception");
- }
- catch (const PluginException &e)
- {
- ASSERT_EQ(e.what(), "test exception");
- }
-}
+++ /dev/null
-#include "support/PluginProxy.h"
-#include "support/PluginException.h"
-
-#include "gtest/gtest.h"
-
-#define STRING(s) _STRING(s)
-#define _STRING(s) #s
-
-using namespace nncc::contrib::plugin;
-using namespace nncc::contrib;
-
-void tryCreatePluginProxy(std::string path)
-{
- try
- {
- std::shared_ptr<PluginProxy> pp = PluginProxy::create(path);
- FAIL();
- }
- catch ( PluginException &e ) {}
-}
-
-TEST(CONTRIB_NNC, PluginProxy)
-{
- // Create PluginProxy from path with '/' and without, to visit both execution pathes
- tryCreatePluginProxy("/some/path/pluginName");
- tryCreatePluginProxy("pluginName");
-
- // Create PluginProxy with sample plugin
- std::shared_ptr<PluginProxy> pp = PluginProxy::create(STRING(CMAKE_SAMPLE_PLUGIN_ABS_PATH));
- ASSERT_EQ(pp->getPluginPath(), STRING(CMAKE_SAMPLE_PLUGIN_ABS_PATH));
-#ifdef __APPLE__
- ASSERT_EQ(pp->getPluginName(), "libsome_parser.dylib");
-#else /* __APPLE__ */
- ASSERT_EQ(pp->getPluginName(), "libsome_parser.so");
-#endif /* __APPLE__ */
- ASSERT_NE(pp->getPluginInstance(), nullptr);
-
- // Operator '<<'
- std::ostringstream os;
- os << *pp;
- ASSERT_EQ(os.str(), STRING(CMAKE_SAMPLE_PLUGIN_ABS_PATH));
-}
+++ /dev/null
-#include "support/shared_library.h"
-#include "support/PluginException.h"
-
-#include "gtest/gtest.h"
-
-#define STRING(s) _STRING(s)
-#define _STRING(s) #s
-
-using namespace nncc::contrib;
-using namespace nncc::contrib::plugin;
-
-TEST(CONTRIB_NNC, SharedLibrary)
-{
- // missing so - missing function
- SharedLibrary<PluginException> slMissing("/");
- ASSERT_THROW(slMissing.findFunc("missing_func_name"), PluginException);
-
- // existing so - missing function
- SharedLibrary<PluginException> sl(STRING(CMAKE_SAMPLE_PLUGIN_ABS_PATH));
- ASSERT_THROW(sl.findFunc("missing_func_name"), PluginException);
-
- // existing so - existing function
- typedef int (*fp_t)();
- fp_t getSomeBeef = (fp_t)sl.findFunc("getSomeBeef");
- ASSERT_NE(getSomeBeef, nullptr);
- ASSERT_EQ(getSomeBeef(), 0xBEEF);
-
- // Operator '<<'
- std::ostringstream os;
- os << sl;
- ASSERT_EQ(os.str(), STRING(CMAKE_SAMPLE_PLUGIN_ABS_PATH));
-
-}
--- /dev/null
+file(GLOB_RECURSE TEST_SOURCES "*.cpp")
+
+add_nncc_test(nnc_pass_test ${TEST_SOURCES})
+if (TARGET nnc_pass_test)
+ nncc_target_link_libraries(nnc_pass_test nnc_support nnc_core)
+endif()
--- /dev/null
+#include "pass/PassException.h"
+
+#include "gtest/gtest.h"
+
+using namespace nncc::contrib::pass;
+
+const char *ErrorMsg = "error constructor";
+
+void passErr1() { throw PassException(ErrorMsg); }
+
+void passErr2()
+{
+ try
+ {
+ passErr1();
+ }
+ catch (PassException &e)
+ {
+ throw;
+ }
+}
+
+TEST(CONTRIB_PASS, PassException)
+{
+ try
+ {
+ passErr2();
+ }
+ catch (PassException &e)
+ {
+ ASSERT_TRUE(ErrorMsg == e.reason());
+ return;
+ }
+
+ // should not happen
+ FAIL();
+}
--- /dev/null
+#include <dlfcn.h>
+
+#include "core/modelIR/graph.h"
+#include "support/CommandLine.h"
+#include "pass/Pass.h"
+#include "pass/PassData.h"
+#include "pass/PassException.h"
+
+#include "gtest/gtest.h"
+
+using namespace nncc::contrib;
+using namespace nncc::contrib::pass;
+using namespace nncc::contrib::core::IR::model;
+
+class DummyPass1 : public Pass
+{
+public:
+ PassData run(PassData data) override
+ {
+ auto graph = static_cast<Graph *>(data);
+
+ if ( !graph )
+ {
+ throw PassException();
+ }
+
+ return graph;
+ }
+};
+
+class DummyPass2 : public Pass
+{
+public:
+ PassData run(PassData data) override
+ {
+ auto tv = static_cast<TensorVariant *>(data);
+
+ if ( !tv )
+ {
+ throw PassException();
+ }
+
+ return nullptr;
+ }
+};
+
+TEST(CONTRIB_PASS, PassManager)
+{
+ DummyPass1 pass1;
+ DummyPass2 pass2;
+
+ Graph g;
+ auto res = pass1.run(&g);
+ ASSERT_NE(static_cast<Graph *>(res), nullptr);
+
+ ASSERT_THROW(pass2.run(res), PassException);
+}
#include "core/modelIR/ShapeRange.h"
#include "core/modelIR/ShapeInference.h"
-#include "plugin/interpreter/Interpreter.h"
+#include "passes/interpreter/Interpreter.h"
#include "gtest/gtest.h"
-#include "cpp_generator.h"
+#include "passes/soft_backend/CPPGenerator.h"
#include "core/modelIR/operations/relu_op.h"
-#include "support/PluginException.h"
-
#include <gtest/gtest.h>
#include <fstream>
deleteDir(TEST_DIR);
}
assert(!isFileExists(TEST_DIR) && "remove output dir");
- {
- CPPCodeGenerator gen;
- gen.execute(&g);
- }
+ CPPCodeGenerator::getInstance().run(&g);
checkOutputExists(BASE_NAME);
// test that generator creates output files in existing empty dir
deleteFile(BASE_NAME ".h");
deleteFile(BASE_NAME ".cpp");
deleteFile(BASE_NAME ".params");
- {
- CPPCodeGenerator gen;
- gen.execute(&g);
- }
+ CPPCodeGenerator::getInstance().run(&g);
checkOutputExists(BASE_NAME);
// test that generator rewrites existing files
int res = stat(BASE_NAME ".h", &sBefore);
assert(res == 0);
assert(sBefore.st_size == 0);
- {
- CPPCodeGenerator gen;
- gen.execute(&g);
- }
+ CPPCodeGenerator::getInstance().run(&g);
res = stat(BASE_NAME ".h", &sAfter);
assert(res == 0);
+++ /dev/null
-#include "support/PluginException.h"
-
-#include "gtest/gtest.h"
-
-using namespace nncc::contrib;
-
-std::string pluginErrorMsg = "error constructor";
-
-void pluginErr1() { throw PluginException(pluginErrorMsg); }
-
-void pluginErr2()
-{
- try
- {
- pluginErr1();
- }
- catch (PluginException &e)
- {
- throw;
- }
-}
-
-TEST(CONTRIB_PLUGIN, PluginException)
-{
- try
- {
- pluginErr2();
- }
- catch (PluginException &e)
- {
- ASSERT_TRUE(pluginErrorMsg == e.what());
- return;
- }
-
- // should not happen
- ASSERT_TRUE(false);
-}