Imported Upstream version 1.9.0
[platform/core/ml/nnfw.git] / runtime / libs / benchmark / src / Phases.cpp
1 /*
2  * Copyright 2018 The TensorFlow Authors. All Rights Reserved.
3  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include "benchmark/Phases.h"
19 #include "benchmark/Types.h"
20
21 #include <cassert>
22 #include <chrono>
23 #include <iostream>
24 #include <sys/time.h>
25
26 namespace
27 {
28
29 uint64_t nowMicros()
30 {
31   struct timeval tv;
32   gettimeofday(&tv, nullptr);
33   return static_cast<uint64_t>(tv.tv_sec) * 1e6 + tv.tv_usec;
34 }
35
36 void SleepForMicros(uint64_t micros)
37 {
38   timespec sleep_time;
39   sleep_time.tv_sec = micros / 1e6;
40   micros -= sleep_time.tv_sec * 1e6;
41   sleep_time.tv_nsec = micros * 1e3;
42   nanosleep(&sleep_time, nullptr);
43 }
44 }
45
46 namespace benchmark
47 {
48
49 Phases::Phases(const PhaseOption &option) : _option(option)
50 {
51   if (_option.memory)
52   {
53     _mem_poll = std::make_unique<MemoryPoller>(std::chrono::milliseconds(option.memory_interval),
54                                                option.memory_gpu);
55   }
56 }
57
58 void Phases::run(const std::string &tag, const PhaseFunc &exec, const PhaseFunc *post,
59                  uint32_t loop_num, bool option_disable)
60 {
61   Phase phase{tag, loop_num};
62   PhaseEnum p = getPhaseEnum(tag);
63   for (uint32_t i = 0; i < loop_num; ++i)
64   {
65     if (!option_disable && _option.memory)
66       _mem_poll->start(p);
67
68     uint64_t t = 0u;
69     t = nowMicros();
70
71     exec(phase, i);
72
73     t = nowMicros() - t;
74
75     if (!option_disable && _option.memory)
76       _mem_poll->end(p);
77
78     phase.time.emplace_back(t);
79
80     if (!option_disable && _option.memory)
81     {
82       phase.memory[MemoryType::RSS].emplace_back(_mem_poll->getRssMap().at(p));
83       phase.memory[MemoryType::HWM].emplace_back(_mem_poll->getHwmMap().at(p));
84       phase.memory[MemoryType::PSS].emplace_back(_mem_poll->getPssMap().at(p));
85     }
86
87     if (post)
88       (*post)(phase, i);
89
90     if (_option.run_delay > 0 && p == PhaseEnum::EXECUTE && i != loop_num - 1)
91     {
92       SleepForMicros(_option.run_delay);
93     }
94   }
95
96   if (p == PhaseEnum::END_OF_PHASE)
97   {
98     return;
99   }
100
101   assert(_phases.find(tag) == _phases.end());
102   _phases.emplace(tag, phase);
103 }
104
105 } // namespace benchmark