From 7c5d840131782e6f953ace35325f7af50f827a47 Mon Sep 17 00:00:00 2001 From: Megvii Engine Team Date: Wed, 22 Dec 2021 14:05:26 +0800 Subject: [PATCH] refactor(lite): refactor lite example GitOrigin-RevId: 3eac582fb2757742a83a9d52f32246ad59b29401 --- lite/example/cpp_example/CMakeLists.txt | 2 + lite/example/cpp_example/example.h | 49 +------- lite/example/cpp_example/main.cpp | 39 +----- lite/example/cpp_example/mge/basic.cpp | 135 +++++++++++---------- lite/example/cpp_example/mge/cpu_affinity.cpp | 8 +- lite/example/cpp_example/mge/cv/detect_yolox.cpp | 13 +- .../cpp_example/mge/cv/picture_classification.cpp | 8 +- lite/example/cpp_example/mge/device_io.cpp | 15 ++- lite/example/cpp_example/mge/lite_c_interface.cpp | 7 +- .../cpp_example/mge/network_share_weights.cpp | 10 +- lite/example/cpp_example/mge/reset_io.cpp | 13 +- lite/example/cpp_example/mge/user_allocator.cpp | 9 +- lite/example/cpp_example/mge/user_cryption.cpp | 11 +- 13 files changed, 152 insertions(+), 167 deletions(-) diff --git a/lite/example/cpp_example/CMakeLists.txt b/lite/example/cpp_example/CMakeLists.txt index 9012fded..f7227b62 100644 --- a/lite/example/cpp_example/CMakeLists.txt +++ b/lite/example/cpp_example/CMakeLists.txt @@ -1,5 +1,6 @@ file (GLOB_RECURSE SOURCES ./*.cpp) add_executable(lite_examples ${SOURCES}) +target_include_directories(lite_examples PUBLIC ./) if(LITE_BUILD_WITH_RKNPU) #rknn sdk1.0.0 depend on libc++_shared, use gold to remove NEEDED so symbol check @@ -33,6 +34,7 @@ if(LITE_BUILD_WITH_RKNPU) endif() target_link_libraries(lite_examples_depends_shared lite_shared) +target_include_directories(lite_examples_depends_shared PUBLIC ./) if(UNIX) if(APPLE OR ANDROID) diff --git a/lite/example/cpp_example/example.h b/lite/example/cpp_example/example.h index 0e5da8f5..8e07dcb1 100644 --- a/lite/example/cpp_example/example.h +++ b/lite/example/cpp_example/example.h @@ -49,57 +49,20 @@ ExampleFuncMap* get_example_function_map(); bool register_example(std::string example_name, const ExampleFunc& fuction); -template -struct Register; - -#if LITE_BUILD_WITH_MGE - -bool basic_load_from_path(const Args& args); -bool basic_load_from_path_with_loader(const Args& args); -bool basic_load_from_memory(const Args& args); -bool cpu_affinity(const Args& args); -bool network_share_same_weights(const Args& args); -bool reset_input(const Args& args); -bool reset_input_output(const Args& args); -bool config_user_allocator(const Args& args); -bool register_cryption_method(const Args& args); -bool update_cryption_key(const Args& args); -bool async_forward(const Args& args); -bool set_input_callback(const Args& arg); -bool set_output_callback(const Args& arg); - -bool picture_classification(const Args& arg); -bool detect_yolox(const Args& arg); - -#if LITE_WITH_CUDA -bool load_from_path_run_cuda(const Args& args); -bool device_input(const Args& args); -bool device_input_output(const Args& args); -bool pinned_host_input(const Args& args); -#endif -#endif - } // namespace example } // namespace lite -#if LITE_BUILD_WITH_MGE -bool basic_c_interface(const lite::example::Args& args); -bool device_io_c_interface(const lite::example::Args& args); -bool async_c_interface(const lite::example::Args& args); -#endif - #define CONCAT_IMPL(a, b) a##b #define MACRO_CONCAT(a, b) CONCAT_IMPL(a, b) #define REGIST_EXAMPLE(name_, func_) REGIST_EXAMPLE_WITH_NUM(__COUNTER__, name_, func_) -#define REGIST_EXAMPLE_WITH_NUM(number_, name_, func_) \ - template <> \ - struct Register { \ - Register() { register_example(name_, func_); } \ - }; \ - namespace { \ - Register MACRO_CONCAT(example_function_, number_); \ +#define REGIST_EXAMPLE_WITH_NUM(number_, name_, func_) \ + struct Register_##func_ { \ + Register_##func_() { lite::example::register_example(name_, func_); } \ + }; \ + namespace { \ + Register_##func_ MACRO_CONCAT(func_, number_); \ } // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}} diff --git a/lite/example/cpp_example/main.cpp b/lite/example/cpp_example/main.cpp index b479b63d..ff566ccb 100644 --- a/lite/example/cpp_example/main.cpp +++ b/lite/example/cpp_example/main.cpp @@ -60,7 +60,8 @@ bool lite::example::register_example( std::string example_name, const ExampleFunc& fuction) { auto map = get_example_function_map(); if (map->find(example_name) != map->end()) { - printf("Error!!! This example is registed yet\n"); + printf("example_name: %s Error!!! This example is registed yet\n", + example_name.c_str()); return false; } (*map)[example_name] = fuction; @@ -142,41 +143,5 @@ int main(int argc, char** argv) { return -1; } } -namespace lite { -namespace example { - -#if LITE_BUILD_WITH_MGE -#if LITE_WITH_CUDA -REGIST_EXAMPLE("load_from_path_run_cuda", load_from_path_run_cuda); -#endif -REGIST_EXAMPLE("basic_load_from_path", basic_load_from_path); -REGIST_EXAMPLE("basic_load_from_path_with_loader", basic_load_from_path_with_loader); -REGIST_EXAMPLE("basic_load_from_memory", basic_load_from_memory); -REGIST_EXAMPLE("cpu_affinity", cpu_affinity); -REGIST_EXAMPLE("register_cryption_method", register_cryption_method); -REGIST_EXAMPLE("update_cryption_key", update_cryption_key); -REGIST_EXAMPLE("network_share_same_weights", network_share_same_weights); -REGIST_EXAMPLE("reset_input", reset_input); -REGIST_EXAMPLE("reset_input_output", reset_input_output); -REGIST_EXAMPLE("config_user_allocator", config_user_allocator); -REGIST_EXAMPLE("async_forward", async_forward); -REGIST_EXAMPLE("set_input_callback", set_input_callback); -REGIST_EXAMPLE("set_output_callback", set_output_callback); - -REGIST_EXAMPLE("basic_c_interface", basic_c_interface); -REGIST_EXAMPLE("device_io_c_interface", device_io_c_interface); -REGIST_EXAMPLE("async_c_interface", async_c_interface); - -REGIST_EXAMPLE("picture_classification", picture_classification); -REGIST_EXAMPLE("detect_yolox", detect_yolox); - -#if LITE_WITH_CUDA -REGIST_EXAMPLE("device_input", device_input); -REGIST_EXAMPLE("device_input_output", device_input_output); -REGIST_EXAMPLE("pinned_host_input", pinned_host_input); -#endif -#endif -} // namespace example -} // namespace lite // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}} diff --git a/lite/example/cpp_example/mge/basic.cpp b/lite/example/cpp_example/mge/basic.cpp index 55e20270..069ddb93 100644 --- a/lite/example/cpp_example/mge/basic.cpp +++ b/lite/example/cpp_example/mge/basic.cpp @@ -10,7 +10,7 @@ */ #include -#include "../example.h" +#include "example.h" #if LITE_BUILD_WITH_MGE #include @@ -77,61 +77,8 @@ void output_data_info(std::shared_ptr network, size_t output_size) { } } // namespace -#if LITE_WITH_CUDA -bool lite::example::load_from_path_run_cuda(const Args& args) { - std::string network_path = args.model_path; - std::string input_path = args.input_path; - set_log_level(LiteLogLevel::DEBUG); - //! config the network running in CUDA device - lite::Config config{false, -1, LiteDeviceType::LITE_CUDA}; - //! set NetworkIO - NetworkIO network_io; - std::string input_name = "img0_comp_fullface"; - bool is_host = false; - IO device_input{input_name, is_host}; - network_io.inputs.push_back(device_input); - //! create and load the network - std::shared_ptr network = std::make_shared(config, network_io); - network->load_model(network_path); - - std::shared_ptr input_tensor = network->get_input_tensor(0); - Layout input_layout = input_tensor->get_layout(); - - //! read data from numpy data file - auto src_tensor = parse_npy(input_path); - - //! malloc the device memory - auto tensor_device = Tensor(LiteDeviceType::LITE_CUDA, input_layout); - - //! copy to the device memory - tensor_device.copy_from(*src_tensor); - - //! Now the device memory if filled with user input data, set it to the - //! input tensor - input_tensor->reset(tensor_device.get_memory_ptr(), input_layout); - - //! forward - { - lite::Timer ltimer("warmup"); - network->forward(); - network->wait(); - ltimer.print_used_time(0); - } - lite::Timer ltimer("forward_iter"); - for (int i = 0; i < 10; i++) { - ltimer.reset_start(); - network->forward(); - network->wait(); - ltimer.print_used_time(i); - } - //! get the output data or read tensor set in network_in - size_t output_size = network->get_all_output_name().size(); - output_info(network, output_size); - output_data_info(network, output_size); - return true; -} -#endif -bool lite::example::basic_load_from_path(const Args& args) { +namespace { +bool basic_load_from_path(const Args& args) { set_log_level(LiteLogLevel::DEBUG); std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -193,7 +140,7 @@ bool lite::example::basic_load_from_path(const Args& args) { return true; } -bool lite::example::basic_load_from_path_with_loader(const Args& args) { +bool basic_load_from_path_with_loader(const Args& args) { set_log_level(LiteLogLevel::DEBUG); lite::set_loader_lib_path(args.loader_path); std::string network_path = args.model_path; @@ -251,7 +198,7 @@ bool lite::example::basic_load_from_path_with_loader(const Args& args) { return true; } -bool lite::example::basic_load_from_memory(const Args& args) { +bool basic_load_from_memory(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -307,7 +254,7 @@ bool lite::example::basic_load_from_memory(const Args& args) { return true; } -bool lite::example::async_forward(const Args& args) { +bool async_forward(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; Config config; @@ -366,7 +313,7 @@ bool lite::example::async_forward(const Args& args) { return true; } -bool lite::example::set_input_callback(const Args& args) { +bool set_input_callback(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; Config config; @@ -433,7 +380,7 @@ bool lite::example::set_input_callback(const Args& args) { return true; } -bool lite::example::set_output_callback(const Args& args) { +bool set_output_callback(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; Config config; @@ -500,7 +447,73 @@ bool lite::example::set_output_callback(const Args& args) { printf("max=%e, sum=%e\n", max, sum); return true; } +} // namespace + +REGIST_EXAMPLE("basic_load_from_path", basic_load_from_path); +REGIST_EXAMPLE("basic_load_from_path_with_loader", basic_load_from_path_with_loader); +REGIST_EXAMPLE("basic_load_from_memory", basic_load_from_memory); +REGIST_EXAMPLE("async_forward", async_forward); +REGIST_EXAMPLE("set_input_callback", set_input_callback); +REGIST_EXAMPLE("set_output_callback", set_output_callback); + +#if LITE_WITH_CUDA +namespace { +bool load_from_path_run_cuda(const Args& args) { + std::string network_path = args.model_path; + std::string input_path = args.input_path; + set_log_level(LiteLogLevel::DEBUG); + //! config the network running in CUDA device + lite::Config config{false, -1, LiteDeviceType::LITE_CUDA}; + //! set NetworkIO + NetworkIO network_io; + std::string input_name = "img0_comp_fullface"; + bool is_host = false; + IO device_input{input_name, is_host}; + network_io.inputs.push_back(device_input); + //! create and load the network + std::shared_ptr network = std::make_shared(config, network_io); + network->load_model(network_path); + + std::shared_ptr input_tensor = network->get_input_tensor(0); + Layout input_layout = input_tensor->get_layout(); + + //! read data from numpy data file + auto src_tensor = parse_npy(input_path); + + //! malloc the device memory + auto tensor_device = Tensor(LiteDeviceType::LITE_CUDA, input_layout); + + //! copy to the device memory + tensor_device.copy_from(*src_tensor); + + //! Now the device memory if filled with user input data, set it to the + //! input tensor + input_tensor->reset(tensor_device.get_memory_ptr(), input_layout); + + //! forward + { + lite::Timer ltimer("warmup"); + network->forward(); + network->wait(); + ltimer.print_used_time(0); + } + lite::Timer ltimer("forward_iter"); + for (int i = 0; i < 10; i++) { + ltimer.reset_start(); + network->forward(); + network->wait(); + ltimer.print_used_time(i); + } + //! get the output data or read tensor set in network_in + size_t output_size = network->get_all_output_name().size(); + output_info(network, output_size); + output_data_info(network, output_size); + return true; +} +} // namespace +REGIST_EXAMPLE("load_from_path_run_cuda", load_from_path_run_cuda); +#endif #endif // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}} diff --git a/lite/example/cpp_example/mge/cpu_affinity.cpp b/lite/example/cpp_example/mge/cpu_affinity.cpp index ea936bf7..6d47c949 100644 --- a/lite/example/cpp_example/mge/cpu_affinity.cpp +++ b/lite/example/cpp_example/mge/cpu_affinity.cpp @@ -9,13 +9,14 @@ * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -#include "../example.h" +#include "example.h" #if LITE_BUILD_WITH_MGE using namespace lite; using namespace example; -bool lite::example::cpu_affinity(const Args& args) { +namespace { +bool cpu_affinity(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -65,6 +66,9 @@ bool lite::example::cpu_affinity(const Args& args) { printf("max=%e, sum=%e\n", max, sum); return true; } +} // namespace + +REGIST_EXAMPLE("cpu_affinity", cpu_affinity); #endif // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}} diff --git a/lite/example/cpp_example/mge/cv/detect_yolox.cpp b/lite/example/cpp_example/mge/cv/detect_yolox.cpp index b42485c0..e5f77553 100644 --- a/lite/example/cpp_example/mge/cv/detect_yolox.cpp +++ b/lite/example/cpp_example/mge/cv/detect_yolox.cpp @@ -10,7 +10,7 @@ */ #include -#include "../../example.h" +#include "example.h" #if LITE_BUILD_WITH_MGE #include @@ -289,6 +289,10 @@ void decode_outputs( void draw_objects( uint8_t* image, int width, int height, int channel, const std::vector& objects) { + (void)image; + (void)width; + (void)height; + (void)channel; for (size_t i = 0; i < objects.size(); i++) { const Object& obj = objects[i]; @@ -297,9 +301,7 @@ void draw_objects( } } -} // namespace - -bool lite::example::detect_yolox(const Args& args) { +bool detect_yolox(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -332,6 +334,9 @@ bool lite::example::detect_yolox(const Args& args) { stbi_image_free(image); return 0; } +} // namespace + +REGIST_EXAMPLE("detect_yolox", detect_yolox); #endif diff --git a/lite/example/cpp_example/mge/cv/picture_classification.cpp b/lite/example/cpp_example/mge/cv/picture_classification.cpp index 84387e03..970dc080 100644 --- a/lite/example/cpp_example/mge/cv/picture_classification.cpp +++ b/lite/example/cpp_example/mge/cv/picture_classification.cpp @@ -10,7 +10,7 @@ */ #include -#include "../../example.h" +#include "example.h" #if LITE_BUILD_WITH_MGE #include @@ -80,9 +80,8 @@ void classfication_process( } printf("output tensor sum is %f\n", sum); } -} // namespace -bool lite::example::picture_classification(const Args& args) { +bool picture_classification(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -109,6 +108,9 @@ bool lite::example::picture_classification(const Args& args) { class_id, score); return 0; } +} // namespace + +REGIST_EXAMPLE("picture_classification", picture_classification); #endif diff --git a/lite/example/cpp_example/mge/device_io.cpp b/lite/example/cpp_example/mge/device_io.cpp index e7689ef5..fd5626fb 100644 --- a/lite/example/cpp_example/mge/device_io.cpp +++ b/lite/example/cpp_example/mge/device_io.cpp @@ -10,15 +10,17 @@ */ #include -#include "../example.h" +#include "example.h" #if LITE_BUILD_WITH_MGE +#include "misc.h" using namespace lite; using namespace example; #if LITE_WITH_CUDA -bool lite::example::device_input(const Args& args) { +namespace { +bool device_input(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -73,7 +75,7 @@ bool lite::example::device_input(const Args& args) { return true; } -bool lite::example::device_input_output(const Args& args) { +bool device_input_output(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -136,7 +138,7 @@ bool lite::example::device_input_output(const Args& args) { return true; } -bool lite::example::pinned_host_input(const Args& args) { +bool pinned_host_input(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -181,6 +183,11 @@ bool lite::example::pinned_host_input(const Args& args) { printf("max=%e, sum=%e\n", max, sum); return true; } +} // namespace + +REGIST_EXAMPLE("device_input", device_input); +REGIST_EXAMPLE("device_input_output", device_input_output); +REGIST_EXAMPLE("pinned_host_input", pinned_host_input); #endif #endif diff --git a/lite/example/cpp_example/mge/lite_c_interface.cpp b/lite/example/cpp_example/mge/lite_c_interface.cpp index 0424631c..e27e8a59 100644 --- a/lite/example/cpp_example/mge/lite_c_interface.cpp +++ b/lite/example/cpp_example/mge/lite_c_interface.cpp @@ -9,7 +9,7 @@ * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -#include "../example.h" +#include "example.h" #include "misc.h" #if LITE_BUILD_WITH_MGE #include "lite-c/global_c.h" @@ -218,5 +218,10 @@ bool async_c_interface(const lite::example::Args& args) { printf("max=%e, sum=%e\n", max, sum); return true; } + +REGIST_EXAMPLE("basic_c_interface", basic_c_interface); +REGIST_EXAMPLE("device_io_c_interface", device_io_c_interface); +REGIST_EXAMPLE("async_c_interface", async_c_interface); + #endif // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}} diff --git a/lite/example/cpp_example/mge/network_share_weights.cpp b/lite/example/cpp_example/mge/network_share_weights.cpp index 0a117d58..e206d394 100644 --- a/lite/example/cpp_example/mge/network_share_weights.cpp +++ b/lite/example/cpp_example/mge/network_share_weights.cpp @@ -9,13 +9,15 @@ * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -#include "../example.h" +#include "example.h" #if LITE_BUILD_WITH_MGE using namespace lite; using namespace example; -bool lite::example::network_share_same_weights(const Args& args) { +namespace { + +bool network_share_same_weights(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -75,5 +77,9 @@ bool lite::example::network_share_same_weights(const Args& args) { printf("max=%e, sum=%e\n", max, sum); return true; } +} // namespace + +REGIST_EXAMPLE("network_share_same_weights", network_share_same_weights); + #endif // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}} diff --git a/lite/example/cpp_example/mge/reset_io.cpp b/lite/example/cpp_example/mge/reset_io.cpp index cda27726..b6848195 100644 --- a/lite/example/cpp_example/mge/reset_io.cpp +++ b/lite/example/cpp_example/mge/reset_io.cpp @@ -9,13 +9,15 @@ * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -#include "../example.h" +#include "example.h" #if LITE_BUILD_WITH_MGE using namespace lite; using namespace example; -bool lite::example::reset_input(const Args& args) { +namespace { + +bool reset_input(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; lite::Config config; @@ -53,7 +55,7 @@ bool lite::example::reset_input(const Args& args) { return true; } -bool lite::example::reset_input_output(const Args& args) { +bool reset_input_output(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; lite::Config config; @@ -92,5 +94,10 @@ bool lite::example::reset_input_output(const Args& args) { printf("max=%e, sum=%e\n", max, sum); return true; } +} // namespace + +REGIST_EXAMPLE("reset_input", reset_input); +REGIST_EXAMPLE("reset_input_output", reset_input_output); + #endif // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}} diff --git a/lite/example/cpp_example/mge/user_allocator.cpp b/lite/example/cpp_example/mge/user_allocator.cpp index 73b9b41d..7f547435 100644 --- a/lite/example/cpp_example/mge/user_allocator.cpp +++ b/lite/example/cpp_example/mge/user_allocator.cpp @@ -9,7 +9,7 @@ * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -#include "../example.h" +#include "example.h" #if LITE_BUILD_WITH_MGE using namespace lite; using namespace example; @@ -42,9 +42,8 @@ public: #endif }; }; -} // namespace -bool lite::example::config_user_allocator(const Args& args) { +bool config_user_allocator(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -87,5 +86,9 @@ bool lite::example::config_user_allocator(const Args& args) { printf("max=%e, sum=%e\n", max, sum); return true; } +} // namespace + +REGIST_EXAMPLE("config_user_allocator", config_user_allocator); + #endif // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}} diff --git a/lite/example/cpp_example/mge/user_cryption.cpp b/lite/example/cpp_example/mge/user_cryption.cpp index 4a857937..02c8a7ac 100644 --- a/lite/example/cpp_example/mge/user_cryption.cpp +++ b/lite/example/cpp_example/mge/user_cryption.cpp @@ -9,7 +9,7 @@ * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -#include "../example.h" +#include "example.h" #if LITE_BUILD_WITH_MGE using namespace lite; @@ -31,9 +31,8 @@ std::vector decrypt_model( return {}; } } -} // namespace -bool lite::example::register_cryption_method(const Args& args) { +bool register_cryption_method(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -75,7 +74,7 @@ bool lite::example::register_cryption_method(const Args& args) { return true; } -bool lite::example::update_cryption_key(const Args& args) { +bool update_cryption_key(const Args& args) { std::string network_path = args.model_path; std::string input_path = args.input_path; @@ -120,5 +119,9 @@ bool lite::example::update_cryption_key(const Args& args) { printf("max=%e, sum=%e\n", max, sum); return true; } +} // namespace + +REGIST_EXAMPLE("register_cryption_method", register_cryption_method); +REGIST_EXAMPLE("update_cryption_key", update_cryption_key); #endif // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}