2 * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "exec/ExecutionObservers.h"
21 #include "util/logging.h"
22 #include "exec/IExecutor.h"
23 #include "misc/polymorphic_downcast.h"
24 #include "ir/OpSequence.h"
25 #include "util/EventWriter.h"
33 void ProfileObserver::handleBegin(onert::exec::IExecutor *, const ir::OpSequence *,
34 const onert::backend::Backend *backend)
36 _timer = backend->config()->timer();
37 if (_timer == nullptr)
38 throw std::runtime_error("To profile backend timer() method must be implemented");
39 _timer->handleBegin();
42 void ProfileObserver::handleEnd(IExecutor *exec, const ir::OpSequence *op_seq,
43 const backend::Backend *backend)
46 const auto timer_res = _timer->getTime();
48 // NOTE This assumes there is just one operation in a op_seq
49 const auto &node = _graph.operations().at(op_seq->operations().at(0));
50 auto node_name = node.name();
51 VERBOSE(ProfileInfo) << "Time for " << node_name << " : " << timer_res << std::endl;
54 bool is_quantized = exec->graph().operands().at(node.getInputs().at(0)).typeInfo().type() ==
55 ir::DataType::QUANT_UINT8_ASYMM;
58 for (const auto &ind : (node.getInputs() + node.getOutputs()) | ir::Remove::UNDEFINED)
60 size += exec->graph().operands().at(ind).info().total_size();
62 if (node_name == "Permute")
64 // TODO Change it to updateOperationExecTime()
65 _et->updatePermuteTime(backend, backend, is_quantized, size, timer_res);
69 _et->updateOperationExecTime(backend, node_name, is_quantized, size, timer_res);
73 ChromeTracingObserver::ChromeTracingObserver(const std::string &filepath, const ir::Graph &graph)
74 : _base_filepath(filepath), _recorder{}, _collector{&_recorder}, _graph{graph}
78 ChromeTracingObserver::~ChromeTracingObserver()
82 EventWriter{_recorder}.writeToFiles(_base_filepath);
84 catch (const std::exception &e)
86 std::cerr << "E: Fail to record event in ChromeTracingObserver: " << e.what() << std::endl;
90 void ChromeTracingObserver::handleBegin(IExecutor *)
92 _collector.onEvent(EventCollector::Event{EventCollector::Edge::BEGIN, "runtime", "Graph"});
95 void ChromeTracingObserver::handleBegin(IExecutor *, const ir::OpSequence *op_seq,
96 const backend::Backend *backend)
98 std::string backend_id = backend->config()->id();
99 _collector.onEvent(EventCollector::Event{EventCollector::Edge::BEGIN, backend_id,
100 opSequenceTag(op_seq, _graph.operations())});
103 void ChromeTracingObserver::handleEnd(IExecutor *, const ir::OpSequence *op_seq,
104 const backend::Backend *backend)
106 std::string backend_id = backend->config()->id();
107 _collector.onEvent(EventCollector::Event{EventCollector::Edge::END, backend_id,
108 opSequenceTag(op_seq, _graph.operations())});
111 void ChromeTracingObserver::handleEnd(IExecutor *)
113 _collector.onEvent(EventCollector::Event{EventCollector::Edge::END, "runtime", "Graph"});
116 std::string ChromeTracingObserver::opSequenceTag(const ir::OpSequence *op_seq,
117 const ir::Operations &operations)
119 if (op_seq->size() == 0)
120 return "Empty OpSequence";
122 const auto &first_op_idx = op_seq->operations().at(0);
123 const auto &first_op_node = operations.at(first_op_idx);
124 std::string tag = "$" + std::to_string(first_op_idx.value());
125 tag += " " + first_op_node.name();
126 if (op_seq->size() > 1)
128 tag += " (+" + std::to_string(op_seq->size() - 1) + ")";