[Util] Add pause option for each iter
authorJiho Chu <jiho.chu@samsung.com>
Thu, 8 Jun 2023 05:45:01 +0000 (14:45 +0900)
committer추지호/SoC Architecture팀(SR)/삼성전자 <jiho.chu@samsung.com>
Wed, 5 Jul 2023 05:21:58 +0000 (14:21 +0900)
This patch adds an pause option.

It stops test at the end of iteration when a pause option is enables.
This can help to impose a stress to the NPU, and other tests can be
simultaneously with stress.

Also, this patch refactors running structures, and profiling.

Signed-off-by: Jiho Chu <jiho.chu@samsung.com>
utils/trinity_test/stress_test.cc
utils/trinity_test/stress_test.h

index 36db4a4b046e33060a4d3015af5ae5758f0d8f67..01de0ff140968d91bf6086fd25e9aba9006d376a 100644 (file)
@@ -17,27 +17,38 @@ void
 StressTester::printUsage (char* argv) {
   std::cout << "Usage: " << argv
             << " [-i NUMBER] [-t] [-s SIZE] [-a NUMBER] [-r] [-m PATH] [-f NUMBER]\n";
-  std::cout << "\t-i # of iter       : number of iteration\n";
-  std::cout << "\t-t                 : [optional] print execution time for every iteration\n\n";
-  std::cout << "\tAlloc Buffer\n";
+  std::cout << "\t-h                 : print usage\n";
+  std::cout << "\t-i # of iter       : number of total test iteration\n";
+  std::cout << "\t-p                 : pause on each iteration\n";
+  std::cout << "\t-t                 : print execution time for every iteration\n\n";
+  std::cout << "\tMemory\n";
   std::cout << "\t-s alloc size      : size of alloc buffer\n";
-  std::cout << "\t-a # of alloc      : number of alloc for one iteration\n";
-  std::cout << "\t-r                 : [optional] alloc size randomly ( range : 1~alloc_size )\n\n";
+  std::cout << "\t-a # of alloc      : number of alloc/free\n";
+  std::cout << "\t-r                 : alloc size randomly ( range : 1~alloc_size )\n\n";
   std::cout << "\tInference\n";
   std::cout << "\t-m model_path      : inference model path\n";
-  std::cout << "\t-f # of inference  : number of inference for one iteration\n";
-  std::cout << "\t-h                 : print usage\n";
+  std::cout << "\t-f # of inference  : number of inference\n";
 }
 
 int
 StressTester::init () {
   int status;
-  if (buffer_size_ == 0 || alloc_num_ == 0 || iter_num_ == 0 || infer_num_ == 0) {
-    std::cerr << "Size of buffer and number of alloc, iteration, inference number and verify term "
-                 "are mandatory"
-              << std::endl;
-    return -1;
+
+  if (model_dir_.empty ()) {
+    status = getnumNPUdeviceByType (NPUCOND_TRIV2_CONN_SOCIP);
+    if (status == 0) {
+      std::cerr << "There is no npu device" << std::endl;
+      return -1;
+    }
+    status = getNPUdeviceByType (&dev_, NPUCOND_TRIV2_CONN_SOCIP, 0);
+    if (status < 0) {
+      std::cerr << "Failed to get npu device" << std::endl;
+      return -1;
+    }
+
+    return 0;
   }
+
   std::string model_path = model_dir_ + "/model.tvn";
   meta_ = getNPUmodel_metadata (model_path.c_str (), false);
   if (meta_ == nullptr) {
@@ -132,48 +143,86 @@ StressTester::init () {
   return 0;
 }
 
+int
+StressTester::run () {
+  int status;
+  clock_t start, finish;
+
+  for (int i = 0; i < iter_num_; i++) {
+    std::cout << "Test Iteration #" << std::to_string (i) << std::endl;
+
+    start = clock ();
+
+    status = runAllocMemory ();
+    if (status < 0) {
+      std::cerr << "Failed to runAllocMemory" << std::endl;
+      return status;
+    }
+
+    status = runInference ();
+    if (status < 0) {
+      std::cerr << "Failed to runInference" << std::endl;
+      return status;
+    }
+
+    if (print_time_) {
+      finish = clock ();
+      std::cout << "Test Iteration duration: " << finish - start << " us" << std::endl;
+    }
+
+    status = cleanup ();
+    if (status < 0) {
+      std::cerr << "Failed to cleanup" << std::endl;
+      return status;
+    }
+
+    if (pause_on_iter_) {
+      std::cout << "Press any key to continue..." << std::endl;
+      std::cin.get ();
+    }
+  }
+
+  return 0;
+}
+
 int
 StressTester::runAllocMemory () {
-  std::vector<generic_buffer*> buffers;
   std::random_device rd;
   std::mt19937 gen (rd ());
   std::uniform_int_distribution<uint64_t> dis (1, buffer_size_);
-  clock_t start, finish, iter_start, iter_finish;
+  clock_t start, finish;
+  int ret;
+
+  if (!buffer_size_ && !alloc_random_)
+    return 0;
+
+  std::cout << "Memory Allocation: " << std::to_string (buffer_size_) << std::endl;
 
   start = clock ();
-  std::cout << "runAllocMemory starts" << std::endl;
-  for (int i = 0; i < iter_num_; i++) {
-    buffers.clear ();
-    iter_start = clock ();
-    for (int j = 0; j < alloc_num_; j++) {
-      generic_buffer* buffer = (generic_buffer*) malloc (sizeof (*buffer));
-
-      if (alloc_random_)
-        buffer->size = dis (gen);
-      else
-        buffer->size = buffer_size_;
-      buffer->type = BUFFER_MAPPED;
-
-      if (allocNPU_genericBuffer (dev_, buffer) < 0) {
-        std::cerr << "Alloc memory error at iter " << i << " alloc " << j << std::endl;
-        free (buffer);
-        return -1;
-      }
-      buffers.push_back (buffer);
-    }
-    for (int j = 0; j < alloc_num_; j++) {
-      generic_buffer* buffer = buffers[j];
-      if (cleanNPU_genericBuffer (dev_, buffer) != 0) {
-        std::cerr << "Clean memory error at iter " << i << "clean " << j << std::endl;
-        return -1;
-      }
+
+  for (int j = 0; j < alloc_num_; j++) {
+    generic_buffer* buffer = (generic_buffer*) malloc (sizeof (*buffer));
+
+    if (alloc_random_)
+      buffer->size = dis (gen);
+    else
+      buffer->size = buffer_size_;
+    buffer->type = BUFFER_MAPPED;
+
+    ret = allocNPU_genericBuffer (dev_, buffer);
+    if (ret < 0) {
+      std::cerr << "Alloc memory error: " << ret << std::endl;
+      free (buffer);
+      return -1;
     }
-    iter_finish = clock ();
-    if (print_time_)
-      std::cout << "iter " << i << " : " << iter_finish - iter_start << " us" << std::endl;
+    buffers_.push_back (buffer);
+  }
+
+  if (print_time_) {
+    finish = clock ();
+    std::cout << "Memory Allocation duration: " << finish - start << " us" << std::endl;
   }
-  finish = clock ();
-  std::cout << "runAllocMemory ends : " << finish - start << " us" << std::endl;
+
   return 0;
 }
 
@@ -182,39 +231,55 @@ StressTester::runInference () {
   std::random_device rd;
   std::mt19937 gen (rd ());
   std::uniform_int_distribution<int> dis (1, buffer_size_);
-  clock_t start, finish, iter_start, iter_finish;
+  clock_t start, finish;
   int status;
   bool success;
 
+  if (model_dir_.empty ())
+    return 0;
+
   start = clock ();
-  std::cout << "runInference starts" << std::endl;
-  for (int i = 0; i < iter_num_; i++) {
-    iter_start = clock ();
-    for (int j = 0; j < infer_num_; j++) {
-      status = submitNPU_request (dev_, req_id_);
-      if (status < 0) {
-        std::cerr << "Failed to submit request : " << status << std::endl;
-        return status;
-      }
-    }
-    iter_finish = clock ();
-    if (print_time_)
-      std::cout << "iter " << i << " : " << iter_finish - iter_start << " us" << std::endl;
-    success = true;
-    for (int j = 0; j < output_.num_buffers; j++) {
-      const char* path = outpath_[j].c_str ();
-      char* buf = static_cast<char*> (output_.bufs[j].addr);
-      size_t size = output_.bufs[j].size;
-
-      if (compare_data (path, buf, size) != 0)
-        success = false;
+
+  std::cout << "runInference: " << model_dir_ << std::endl;
+  for (int j = 0; j < infer_num_; j++) {
+    status = submitNPU_request (dev_, req_id_);
+    if (status < 0) {
+      std::cerr << "Failed to submit request : " << status << std::endl;
+      return status;
     }
-    if (!success) {
+  }
+  success = true;
+  for (int j = 0; j < output_.num_buffers; j++) {
+    const char* path = outpath_[j].c_str ();
+    char* buf = static_cast<char*> (output_.bufs[j].addr);
+    size_t size = output_.bufs[j].size;
+
+    if (compare_data (path, buf, size) != 0)
+      success = false;
+  }
+  if (!success) {
+    return -1;
+  }
+
+  if (print_time_) {
+    finish = clock ();
+    std::cout << "runInference duration: " << finish - start << " us" << std::endl;
+  }
+
+  return 0;
+}
+
+int
+StressTester::cleanup () {
+  int ret;
+  for (auto buffer : buffers_) {
+    ret = cleanNPU_genericBuffer (dev_, buffer);
+    if (ret != 0) {
+      std::cerr << "Clean memory error: " << std::to_string (ret) << std::endl;
       return -1;
     }
   }
-  finish = clock ();
-  std::cout << "runInference ends : " << finish - start << " us" << std::endl;
+
   return 0;
 }
 
@@ -224,7 +289,7 @@ StressTester::parseArgs (int argc, char** argv) {
 
   optind = 0;
   opterr = 0;
-  while ((c = getopt (argc, argv, "i:s:a:rm:f:th")) != -1) {
+  while ((c = getopt (argc, argv, "i:s:a:rm:f:pth")) != -1) {
     switch (c) {
       case 'i':
         setIterNum (optarg);
@@ -244,6 +309,9 @@ StressTester::parseArgs (int argc, char** argv) {
       case 'f':
         setInferNum (optarg);
         break;
+      case 'p':
+        setPauseOnIter (true);
+        break;
       case 't':
         setPrintTime (true);
         break;
@@ -277,15 +345,9 @@ main (int argc, char** argv) {
     return status;
   }
 
-  status = stressTester.runAllocMemory ();
-  if (status < 0) {
-    std::cerr << "Failed to alloc memory" << std::endl;
-    return status;
-  }
-
-  status = stressTester.runInference ();
+  status = stressTester.run ();
   if (status < 0) {
-    std::cerr << "Failed to run inference" << std::endl;
+    std::cerr << "Failed to run" << std::endl;
     return status;
   }
 
index e299797b98a894319514ba7516db390cc009e68a..33d74e7e1f77015260da87c6005ef83c1b09a5ac 100644 (file)
@@ -32,9 +32,10 @@ class StressTester {
         model_id_ (0),
         print_time_ (false),
         alloc_random_ (false),
+        pause_on_iter_(false),
         buffer_size_ (0),
         alloc_num_ (0),
-        iter_num_ (0),
+        iter_num_ (1),
         infer_num_ (0) {
     memset (&input_, '\x00', sizeof (input_buffers));
     memset (&output_, '\x00', sizeof (output_buffers));
@@ -49,11 +50,14 @@ class StressTester {
   void setIterNum (std::string iter_num) { iter_num_ = stoi (iter_num); }
   void setModelPath (std::string model_path) { model_dir_ = model_path; }
   void setInferNum (std::string infer_num) { infer_num_ = stoi (infer_num); }
+  void setPauseOnIter (bool pause_on_iter) { pause_on_iter_ = pause_on_iter; }
   void printUsage (char* argv);
 
   int init ();
+  int run ();
   int runAllocMemory ();
   int runInference ();
+  int cleanup ();
 
  private:
   npudev_h dev_;
@@ -68,6 +72,7 @@ class StressTester {
   uint32_t model_id_;
   bool print_time_;
   bool alloc_random_;
+  bool pause_on_iter_;
   uint64_t buffer_size_;
   int alloc_num_;
   int iter_num_;