Imported Upstream version 1.21.0
[platform/core/ml/nnfw.git] / runtime / onert / core / src / util / EventCollector.cc
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd. 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  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "EventCollector.h"
18
19 // C++ standard libraries
20 #include <chrono>
21
22 // POSIX standard libraries
23 #include <sys/time.h>
24 #include <sys/resource.h>
25
26 namespace
27 {
28
29 std::string timestamp(void)
30 {
31   auto now = std::chrono::steady_clock::now();
32   return std::to_string(
33     std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count());
34 }
35
36 class DurationEventBuilder : public EventCollector::EventVisitor
37 {
38 public:
39   DurationEventBuilder(const std::string &ts) : _ts{ts} {}
40
41   std::unique_ptr<SubgDurationEvent> build(const EventCollector::SubgEvent &evt_collected,
42                                            const std::string &ph) const
43   {
44     auto dur_evt = std::make_unique<SubgDurationEvent>();
45
46     // The following will be set by a child of EventsWriter:
47     // dur_evt.name, dur_evt.tid
48     dur_evt->ph = ph;
49     dur_evt->ts = _ts;
50     dur_evt->tracing_ctx = evt_collected.tracing_ctx;
51
52     dur_evt->session_index = evt_collected.session_index;
53     dur_evt->subg_index = evt_collected.subg_index;
54
55     dur_evt->args = evt_collected.userData;
56     {
57       dur_evt->args.emplace_back("session", std::to_string(evt_collected.session_index));
58       dur_evt->args.emplace_back("subgraph", std::to_string(evt_collected.subg_index));
59     }
60
61     return dur_evt;
62   }
63
64   std::unique_ptr<OpSeqDurationEvent> build(const EventCollector::OpSeqEvent &evt_collected,
65                                             const std::string &ph) const
66   {
67     auto dur_evt = std::make_unique<OpSeqDurationEvent>();
68
69     // The following will be set by a child of EventsWriter:
70     // dur_evt.name, dur_evt.tid
71     dur_evt->ph = ph;
72     dur_evt->ts = _ts;
73     dur_evt->tracing_ctx = evt_collected.tracing_ctx;
74
75     dur_evt->session_index = evt_collected.session_index;
76     dur_evt->subg_index = evt_collected.subg_index;
77
78     dur_evt->backend = evt_collected.backend;
79     dur_evt->op_index = evt_collected.op_index;
80     dur_evt->op_name = evt_collected.op_name;
81
82     dur_evt->args = evt_collected.userData;
83     {
84       dur_evt->args.emplace_back("session", std::to_string(evt_collected.session_index));
85       dur_evt->args.emplace_back("subgraph", std::to_string(evt_collected.subg_index));
86     }
87
88     return dur_evt;
89   }
90
91 private:
92   std::string _ts;
93 };
94
95 #ifdef DEBUG
96 inline void emit_rusage(EventRecorder *rec, const std::string &ts)
97 {
98   struct rusage ru;
99
100   getrusage(RUSAGE_SELF, &ru);
101   {
102     CounterEvent evt;
103
104     evt.name = "maxrss";
105     evt.ph = "C";
106     evt.ts = ts;
107     evt.values["value"] = std::to_string(ru.ru_maxrss);
108
109     rec->emit(evt);
110   }
111
112   {
113     CounterEvent evt;
114
115     evt.name = "minflt";
116     evt.ph = "C";
117     evt.ts = ts;
118     evt.values["value"] = std::to_string(ru.ru_minflt);
119
120     rec->emit(evt);
121   }
122 }
123 #endif
124
125 } // namespace
126
127 template <typename EventT> void EventCollector::onEvent(const EventT &event)
128 {
129   auto ts = timestamp();
130
131   DurationEventBuilder builder(ts);
132
133   switch (event.edge)
134   {
135     case Edge::BEGIN:
136     {
137       auto duration_evt = builder.build(event, "B");
138       _rec->emit(std::move(duration_evt));
139       break;
140     }
141     case Edge::END:
142     {
143       auto duration_evt = builder.build(event, "E");
144       _rec->emit(std::move(duration_evt));
145       break;
146     }
147   }
148
149 // TODO: Add resurece measurement(e.g. RSS)
150 // when ready with low overhead in release build
151 #ifdef DEBUG
152   emit_rusage(_rec, ts);
153 #endif
154 }
155
156 // template instantiation
157 template void EventCollector::onEvent<EventCollector::SubgEvent>(const SubgEvent &event);
158 template void EventCollector::onEvent<EventCollector::OpSeqEvent>(const OpSeqEvent &event);