From: 박종현/동작제어Lab(SR)/Senior Engineer/삼성전자 Date: Tue, 29 May 2018 08:05:45 +0000 (+0900) Subject: Add 'cli' library (#249) X-Git-Tag: nncc_backup~2657 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4d11c196b26d41ffabbd0c79e6aa702142ba5821;p=platform%2Fcore%2Fml%2Fnnfw.git Add 'cli' library (#249) This commit introduces 'cli' library (under contrib/) and rewrites caffegen, caffekit, tflitekit tools using newly introduced 'cli' library. Signed-off-by: Jonghyun Park --- diff --git a/contrib/caffegen/CMakeLists.txt b/contrib/caffegen/CMakeLists.txt index 9527a66..36256b0 100644 --- a/contrib/caffegen/CMakeLists.txt +++ b/contrib/caffegen/CMakeLists.txt @@ -4,4 +4,5 @@ if(TARGET nncc_frontend_caffe_core) add_executable(caffegen ${SOURCES}) target_include_directories(caffegen PRIVATE include) target_link_libraries(caffegen nncc_foundation nncc_frontend_caffe_core) + target_link_libraries(caffegen cli) endif(TARGET nncc_frontend_caffe_core) diff --git a/contrib/caffegen/include/Command.h b/contrib/caffegen/include/Command.h deleted file mode 100644 index 1ca806a..0000000 --- a/contrib/caffegen/include/Command.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __COMMAND_H__ -#define __COMMAND_H__ - -struct Command -{ - virtual ~Command() = default; - - virtual int run(int argc, char **argv) const = 0; -}; - -#endif // __COMMAND_H__ diff --git a/contrib/caffegen/src/DecodeCommand.cpp b/contrib/caffegen/src/DecodeCommand.cpp index abd62c3..62fc04f 100644 --- a/contrib/caffegen/src/DecodeCommand.cpp +++ b/contrib/caffegen/src/DecodeCommand.cpp @@ -8,7 +8,7 @@ #include -int DecodeCommand::run(int, char **) const +int DecodeCommand::run(int, const char * const *) const { caffe::NetParameter param; diff --git a/contrib/caffegen/src/DecodeCommand.h b/contrib/caffegen/src/DecodeCommand.h index 1fea0c4..284059e 100644 --- a/contrib/caffegen/src/DecodeCommand.h +++ b/contrib/caffegen/src/DecodeCommand.h @@ -1,11 +1,11 @@ #ifndef __DECODE_COMMAND_H__ #define __DECODE_COMMAND_H__ -#include "Command.h" +#include -struct DecodeCommand final : public Command +struct DecodeCommand final : public cli::Command { - int run(int argc, char **argv) const override; + int run(int argc, const char * const *argv) const override; }; #endif // __DECODE_COMMAND_H__ diff --git a/contrib/caffegen/src/Driver.cpp b/contrib/caffegen/src/Driver.cpp index 5581f1a..9e3239f 100644 --- a/contrib/caffegen/src/Driver.cpp +++ b/contrib/caffegen/src/Driver.cpp @@ -2,6 +2,7 @@ #include "EncodeCommand.h" #include "DecodeCommand.h" +#include #include #include @@ -9,11 +10,11 @@ int main(int argc, char **argv) { - std::map> commands; + cli::App app{argv[0]}; - commands["fill"] = nncc::foundation::make_unique(); - commands["encode"] = nncc::foundation::make_unique(); - commands["decode"] = nncc::foundation::make_unique(); + app.insert("fill", nncc::foundation::make_unique()); + app.insert("encode", nncc::foundation::make_unique()); + app.insert("decode", nncc::foundation::make_unique()); - return commands.at(argv[1])->run(argc - 2, argv + 2); + return app.run(argc - 1, argv + 1); } diff --git a/contrib/caffegen/src/EncodeCommand.cpp b/contrib/caffegen/src/EncodeCommand.cpp index 3f7428d..ab4a3b0 100644 --- a/contrib/caffegen/src/EncodeCommand.cpp +++ b/contrib/caffegen/src/EncodeCommand.cpp @@ -8,7 +8,7 @@ #include -int EncodeCommand::run(int, char **) const +int EncodeCommand::run(int, const char * const *) const { caffe::NetParameter param; diff --git a/contrib/caffegen/src/EncodeCommand.h b/contrib/caffegen/src/EncodeCommand.h index 2188297..d1daa8a 100644 --- a/contrib/caffegen/src/EncodeCommand.h +++ b/contrib/caffegen/src/EncodeCommand.h @@ -1,11 +1,11 @@ #ifndef __ENCODE_COMMAND_H__ #define __ENCODE_COMMAND_H__ -#include "Command.h" +#include -struct EncodeCommand final : public Command +struct EncodeCommand final : public cli::Command { - int run(int argc, char **argv) const override; + int run(int argc, const char * const *argv) const override; }; #endif // __ENCODE_COMMAND_H__ diff --git a/contrib/caffegen/src/FillCommand.cpp b/contrib/caffegen/src/FillCommand.cpp index 8fd83b3..09b0499 100644 --- a/contrib/caffegen/src/FillCommand.cpp +++ b/contrib/caffegen/src/FillCommand.cpp @@ -15,7 +15,7 @@ #include #include -int FillCommand::run(int, char **) const +int FillCommand::run(int, const char * const *) const { auto param = nncc::foundation::make_unique<::caffe::NetParameter>(); diff --git a/contrib/caffegen/src/FillCommand.h b/contrib/caffegen/src/FillCommand.h index 1300cef..38f127b 100644 --- a/contrib/caffegen/src/FillCommand.h +++ b/contrib/caffegen/src/FillCommand.h @@ -1,11 +1,11 @@ #ifndef __FILL_COMMAND_H__ #define __FILL_COMMAND_H__ -#include "Command.h" +#include -struct FillCommand final : public Command +struct FillCommand final : public cli::Command { - int run(int argc, char **argv) const override; + int run(int argc, const char * const *argv) const override; }; #endif // __FILL_COMMAND_H__ diff --git a/contrib/caffekit/CMakeLists.txt b/contrib/caffekit/CMakeLists.txt index bf7a887..fa219a1 100644 --- a/contrib/caffekit/CMakeLists.txt +++ b/contrib/caffekit/CMakeLists.txt @@ -8,4 +8,5 @@ file(GLOB_RECURSE SOURCES "src/*.cpp") add_executable(caffekit ${SOURCES}) target_link_libraries(caffekit nncc_foundation) +target_link_libraries(caffekit cli) target_link_libraries(caffekit caffe) diff --git a/contrib/caffekit/src/caffekit.cpp b/contrib/caffekit/src/caffekit.cpp index 23331c3..80467d6 100644 --- a/contrib/caffekit/src/caffekit.cpp +++ b/contrib/caffekit/src/caffekit.cpp @@ -1,21 +1,15 @@ -struct Command -{ - virtual ~Command() = default; - - virtual int run(int argc, char **argv) const = 0; -}; - +#include #include #include -class RunCommand final : public Command +class RunCommand final : public cli::Command { public: - int run(int argc, char **argv) const override; + int run(int argc, const char * const *argv) const override; }; -int RunCommand::run(int argc, char **argv) const +int RunCommand::run(int argc, const char * const *argv) const { // USAGE: HEADER run [.prototxt] ([.caffemodel]) caffe::Net net(argv[0], caffe::TEST); @@ -33,6 +27,7 @@ int RunCommand::run(int argc, char **argv) const } #include +#include #include #include @@ -40,32 +35,9 @@ int RunCommand::run(int argc, char **argv) const int main(int argc, char **argv) { - std::map> commands; - - commands["run"] = nncc::foundation::make_unique(); + cli::App app{argv[0]}; - if (argc < 2) - { - std::cerr << "ERROR: COMMAND is not provided" << std::endl; - std::cerr << std::endl; - std::cerr << "USAGE: " << argv[0] << " [COMMAND] ..." << std::endl; - return 255; - } - - // USAGE: HEADER [command] ... - if (commands.find(argv[1]) == commands.end()) - { - std::cerr << "ERROR: '" << argv[1] << "' is not a valid command" << std::endl; - std::cerr << std::endl; - std::cerr << "USAGE: " << argv[0] << " [COMMAND] ..." << std::endl; - std::cerr << std::endl; - std::cerr << "SUPPORTED COMMANDS:" << std::endl; - for (auto it = commands.begin(); it != commands.end(); ++it) - { - std::cerr << " " << it->first << std::endl; - } - return 255; - } + app.insert("run", nncc::foundation::make_unique()); - return commands.at(argv[1])->run(argc - 2, argv + 2); + return app.run(argc - 1, argv + 1); } diff --git a/contrib/cli/CMakeLists.txt b/contrib/cli/CMakeLists.txt new file mode 100644 index 0000000..41dd1f1 --- /dev/null +++ b/contrib/cli/CMakeLists.txt @@ -0,0 +1,17 @@ +list(APPEND SOURCES "src/App.cpp") +list(APPEND TESTS "src/App.test.cpp") + +add_library(cli ${SOURCES}) +target_include_directories(cli PUBLIC include) + +nncc_find_package(GTest QUIET) + +if(NOT GTest_FOUND) + return() +endif(NOT GTest_FOUND) + +add_executable(cli_test ${TESTS}) +target_link_libraries(cli_test cli) +target_link_libraries(cli_test nncc_foundation) +target_link_libraries(cli_test gtest_main) +add_test(cli_test cli_test) diff --git a/contrib/cli/include/cli/App.h b/contrib/cli/include/cli/App.h new file mode 100644 index 0000000..39ee86d --- /dev/null +++ b/contrib/cli/include/cli/App.h @@ -0,0 +1,31 @@ +#ifndef __CLI_APP_H__ +#define __CLI_APP_H__ + +#include "Command.h" + +#include +#include +#include + +namespace cli +{ + +class App +{ +public: + explicit App(const std::string &name); + +public: + App &insert(const std::string &tag, std::unique_ptr &&command); + +public: + int run(int argc, const char * const *argv) const; + +private: + const std::string _name; + std::map> _commands; +}; + +} // namespace cli + +#endif // __APP_H__ diff --git a/contrib/cli/include/cli/Command.h b/contrib/cli/include/cli/Command.h new file mode 100644 index 0000000..0107188 --- /dev/null +++ b/contrib/cli/include/cli/Command.h @@ -0,0 +1,16 @@ +#ifndef __CLI_COMMAND_H__ +#define __CLI_COMMAND_H__ + +namespace cli +{ + +struct Command +{ + virtual ~Command() = default; + + virtual int run(int argc, const char * const *argv) const = 0; +}; + +} // namespace cli + +#endif // __CLI_COMMAND_H__ diff --git a/contrib/cli/src/App.cpp b/contrib/cli/src/App.cpp new file mode 100644 index 0000000..56119f8 --- /dev/null +++ b/contrib/cli/src/App.cpp @@ -0,0 +1,54 @@ +#include "cli/App.h" + +#include +#include + +namespace cli +{ + +App::App(const std::string &name) : _name{name} +{ + // DO NOTHING +} + +App &App::insert(const std::string &tag, std::unique_ptr &&command) +{ + assert(_commands.find(tag) == _commands.end()); + + _commands[tag] = std::move(command); + + return (*this); +} + +int App::run(int argc, const char * const *argv) const +{ + if (argc < 1) + { + std::cerr << "ERROR: COMMAND is not provided" << std::endl; + std::cerr << std::endl; + std::cerr << "USAGE: " << _name << " [COMMAND] ..." << std::endl; + return 255; + } + + const std::string command{argv[0]}; + + auto it = _commands.find(command); + + if (it == _commands.end()) + { + std::cerr << "ERROR: '" << command << "' is not a valid command" << std::endl; + std::cerr << std::endl; + std::cerr << "USAGE: " << _name << " [COMMAND] ..." << std::endl; + std::cerr << std::endl; + std::cerr << "SUPPORTED COMMANDS:" << std::endl; + for (auto it = _commands.begin(); it != _commands.end(); ++it) + { + std::cerr << " " << it->first << std::endl; + } + return 255; + } + + return it->second->run(argc - 1, argv + 1); +} + +} // namespace cli diff --git a/contrib/cli/src/App.test.cpp b/contrib/cli/src/App.test.cpp new file mode 100644 index 0000000..450dd21 --- /dev/null +++ b/contrib/cli/src/App.test.cpp @@ -0,0 +1,51 @@ +#include "cli/App.h" + +#include + +#include + +class RecordCommand final : public cli::Command +{ +public: + RecordCommand(int ret, std::string &out) : _ret{ret}, _out(out) + { + // DO NOTHING + } + +public: + int run(int argc, const char * const *argv) const override + { + _out += std::to_string(argc); + + for (int n = 0; n < argc; ++n) + { + _out += ";"; + _out += argv[n]; + } + + return _ret; + } + +private: + int const _ret; + std::string &_out; +}; + +TEST(APP, run) +{ + cli::App app("test"); + + std::string args; + app.insert("record", nncc::foundation::make_unique(3, args)); + + const char *argv[] = { + "record", + "hello", + "world" + }; + + int ret = app.run(3, argv); + + ASSERT_EQ(ret, 3); + ASSERT_EQ(args, "2;hello;world"); +} diff --git a/contrib/tflitekit/CMakeLists.txt b/contrib/tflitekit/CMakeLists.txt index 5f95cdf..e990643 100644 --- a/contrib/tflitekit/CMakeLists.txt +++ b/contrib/tflitekit/CMakeLists.txt @@ -8,4 +8,5 @@ file(GLOB_RECURSE SOURCES "src/*.cpp") add_executable(tflitekit ${SOURCES}) target_link_libraries(tflitekit nncc_foundation) +target_link_libraries(tflitekit cli) target_link_libraries(tflitekit tensorflowlite) diff --git a/contrib/tflitekit/src/tflitekit.cpp b/contrib/tflitekit/src/tflitekit.cpp index 1612153..f29cf48 100644 --- a/contrib/tflitekit/src/tflitekit.cpp +++ b/contrib/tflitekit/src/tflitekit.cpp @@ -1,25 +1,19 @@ -struct Command -{ - virtual ~Command() = default; - - virtual int run(int argc, char **argv) const = 0; -}; - #include "tensorflow/contrib/lite/kernels/register.h" #include "tensorflow/contrib/lite/model.h" +#include #include using namespace tflite; using namespace tflite::ops::builtin; -class RunCommand final : public Command +class RunCommand final : public cli::Command { public: - int run(int argc, char **argv) const override; + int run(int argc, const char * const *argv) const override; }; -int RunCommand::run(int argc, char **argv) const +int RunCommand::run(int argc, const char * const *argv) const { // USAGE: HEADER run [.tflite] const auto filename = argv[0]; @@ -52,6 +46,7 @@ int RunCommand::run(int argc, char **argv) const } #include +#include #include #include @@ -59,32 +54,9 @@ int RunCommand::run(int argc, char **argv) const int main(int argc, char **argv) { - std::map> commands; - - commands["run"] = nncc::foundation::make_unique(); - - if (argc < 2) - { - std::cerr << "ERROR: COMMAND is not provided" << std::endl; - std::cerr << std::endl; - std::cerr << "USAGE: " << argv[0] << " [COMMAND] ..." << std::endl; - return 255; - } - - // USAGE: HEADER [command] ... - if (commands.find(argv[1]) == commands.end()) - { - std::cerr << "ERROR: '" << argv[1] << "' is not a valid command" << std::endl; - std::cerr << std::endl; - std::cerr << "USAGE: " << argv[0] << " [COMMAND] ..." << std::endl; - std::cerr << std::endl; - std::cerr << "SUPPORTED COMMANDS:" << std::endl; - for (auto it = commands.begin(); it != commands.end(); ++it) - { - std::cerr << " " << it->first << std::endl; - } - return 255; - } - - return commands.at(argv[1])->run(argc - 2, argv + 2); + cli::App app{argv[0]}; + + app.insert("run", nncc::foundation::make_unique()); + + return app.run(argc - 1, argv + 1); }