test_executor.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*************************************************************************
  2. * Copyright (C) [2020] by Cambricon, Inc. All rights reserved
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  13. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  15. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  18. * THE SOFTWARE.
  19. *************************************************************************/
  20. #include <gtest/gtest.h>
  21. #include <memory>
  22. #include <string>
  23. #include <utility>
  24. #include "cnis/infer_server.h"
  25. #include "cnis/processor.h"
  26. #include "cnrt.h"
  27. #include "core/session.h"
  28. #include "test_base.h"
  29. namespace infer_server {
  30. auto g_empty_preproc_func = [](ModelIO*, const InferData&, const ModelInfo&) { return true; };
  31. class Executor;
  32. using Executor_t = Executor*;
  33. class InferServerPrivate;
  34. #ifdef CNIS_USE_MAGICMIND
  35. static const char* model_url = "http://video.cambricon.com/models/MLU370/resnet50_nhwc_tfu_0.5_int8_fp16.model";
  36. #else
  37. static const char* model_url = "http://video.cambricon.com/models/MLU270/Primary_Detector/ssd/resnet34_ssd.cambricon";
  38. #endif
  39. static SessionDesc ReturnSessionDesc(const std::string& name, std::shared_ptr<Processor> preproc,
  40. size_t batch_timeout, BatchStrategy strategy, uint32_t engine_num) {
  41. SessionDesc desc;
  42. desc.name = name;
  43. desc.model = InferServer::LoadModel(model_url);
  44. if (!desc.model) {
  45. std::cout << "Load Model fail, check it!" << std::endl;
  46. }
  47. desc.strategy = strategy;
  48. desc.postproc = Postprocessor::Create();
  49. desc.batch_timeout = 10;
  50. desc.engine_num = engine_num;
  51. desc.show_perf = true;
  52. desc.priority = 0;
  53. desc.host_input_layout = {infer_server::DataType::FLOAT32, infer_server::DimOrder::NHWC};
  54. desc.host_output_layout = {infer_server::DataType::FLOAT32, infer_server::DimOrder::NHWC};
  55. if (preproc) {
  56. desc.preproc = preproc;
  57. desc.preproc->SetParams<PreprocessorHost::ProcessFunction>("process_function", g_empty_preproc_func);
  58. }
  59. return desc;
  60. }
  61. TEST(InferServerCoreDeathTest, InitExecutorFail) {
  62. PriorityThreadPool tp(nullptr);
  63. SessionDesc desc =
  64. ReturnSessionDesc("test executor", std::make_shared<PreprocessorHost>(), 5, BatchStrategy::DYNAMIC, 1);
  65. // fail init, threadpool == nullptr
  66. ASSERT_DEATH(new Executor(desc, nullptr, 0), "");
  67. // fail init, device_id < 0
  68. ASSERT_DEATH(new Executor(desc, &tp, -1), "");
  69. // fail init, engine_num == 0
  70. ASSERT_DEATH(new Executor(ReturnSessionDesc("test executor", std::make_shared<PreprocessorHost>(), 5,
  71. BatchStrategy::DYNAMIC, 0),
  72. &tp, 0),
  73. "");
  74. // fail init, preproc == nullptr
  75. ASSERT_DEATH(new Executor(ReturnSessionDesc("test executor", nullptr, 5, BatchStrategy::DYNAMIC, 1), &tp, 0), "");
  76. // fail init, batchstrategy unsupported
  77. ASSERT_DEATH(new Executor(ReturnSessionDesc("test executor", std::make_shared<PreprocessorHost>(), 5,
  78. BatchStrategy::SEQUENCE, 1),
  79. &tp, 0),
  80. "");
  81. InferServer::ClearModelCache();
  82. }
  83. TEST(InferServerCore, Executor) {
  84. // Executor init
  85. int device_id = 0;
  86. PriorityThreadPool tp([device_id]() -> bool { return SetCurrentDevice(device_id); }, 3);
  87. SessionDesc desc =
  88. ReturnSessionDesc("test executor", std::make_shared<PreprocessorHost>(), 200, BatchStrategy::STATIC, 1);
  89. // Executor other function
  90. // Link()
  91. std::unique_ptr<Executor> executor(new Executor(desc, &tp, device_id));
  92. std::unique_ptr<Session> session(new Session("init session", executor.get(), false, true));
  93. executor->Link(session.get());
  94. size_t get_session_number = executor->GetSessionNum();
  95. // one session
  96. ASSERT_EQ(get_session_number, 1u);
  97. // GetDesc()
  98. auto get_sessiondesc = executor->GetDesc();
  99. ASSERT_EQ(get_sessiondesc.batch_timeout, desc.batch_timeout);
  100. // GetName()
  101. auto get_sessiondesc_name = executor->GetName();
  102. ASSERT_EQ(get_sessiondesc_name, desc.name);
  103. // GetPriority()
  104. Priority priority_(desc.priority);
  105. auto get_priority = executor->GetPriority();
  106. ASSERT_EQ(get_priority, priority_);
  107. // GetEngineNum()
  108. auto get_engine_num = executor->GetEngineNum();
  109. ASSERT_EQ(get_engine_num, desc.engine_num);
  110. // GetThreadPool(), can't be nullptr
  111. auto get_thread_pool = executor->GetThreadPool();
  112. ASSERT_EQ(get_thread_pool, &tp);
  113. // Upload()
  114. std::promise<void> response_flag;
  115. auto empty_response_func = [](Status, PackagePtr) {};
  116. auto empty_notifier_func = [&response_flag](const RequestControl*) { response_flag.set_value(); };
  117. std::unique_ptr<RequestControl> ctrl(new RequestControl(empty_response_func, empty_notifier_func, "", 0, 1));
  118. int empty_data = 0;
  119. auto input = Package::Create(1);
  120. input->data[0]->Set(empty_data);
  121. input->data[0]->ctrl = ctrl.get();
  122. input->data[0]->index = 0;
  123. EXPECT_TRUE(executor->WaitIfCacheFull(-1)); // Executor::DispatchLoop() will cache_->Pop() the data
  124. ASSERT_TRUE(executor->Upload(std::move(input), ctrl.get())); // cache_num = engine_num * 3
  125. auto ret = response_flag.get_future().wait_for(std::chrono::seconds(1));
  126. EXPECT_EQ(std::future_status::ready, ret);
  127. ASSERT_NO_THROW(executor->Unlink(session.get()));
  128. get_session_number = executor->GetSessionNum();
  129. // no session
  130. ASSERT_EQ(get_session_number, 0u);
  131. }
  132. } // namespace infer_server