31 virtual void set_up(
size_t num_workers) = 0;
116 inline void set_up(
size_t num_workers)
override final;
117 inline void on_entry(
size_t worker_id,
TaskView task_view)
override final;
118 inline void on_exit(
size_t worker_id,
TaskView task_view)
override final;
124 inline ChromeObserver::Segment::Segment(
132 inline ChromeObserver::Segment::Segment(
137 name {n}, beg {b},
end {e} {
141 inline void ChromeObserver::set_up(
size_t num_workers) {
142 _timeline.segments.resize(num_workers);
143 _timeline.stacks.resize(num_workers);
145 for(
size_t w=0; w<num_workers; ++w) {
146 _timeline.segments[w].reserve(32);
153 inline void ChromeObserver::on_entry(
size_t w, TaskView) {
158 inline void ChromeObserver::on_exit(
size_t w, TaskView tv) {
159 assert(!_timeline.stacks[w].empty());
161 auto beg = _timeline.stacks[w].top();
162 _timeline.stacks[w].pop();
164 _timeline.segments[w].emplace_back(
171 for(
size_t w=0; w<_timeline.segments.size(); ++w) {
172 _timeline.segments[w].clear();
173 while(!_timeline.stacks[w].empty()) {
174 _timeline.stacks[w].pop();
184 for(first = 0; first<_timeline.segments.size(); ++first) {
185 if(_timeline.segments[first].size() > 0) {
192 for(
size_t w=first; w<_timeline.segments.size(); w++) {
194 if(w != first && _timeline.segments[w].size() > 0) {
198 for(
size_t i=0; i<_timeline.segments[w].size(); i++) {
201 <<
"\"cat\":\"ChromeObserver\",";
205 if(_timeline.segments[w][i].name.empty()) {
209 os << _timeline.segments[w][i].name;
214 os <<
"\"ph\":\"X\"," 216 <<
"\"tid\":" << w <<
',' 218 _timeline.segments[w][i].beg - _timeline.origin
221 _timeline.segments[w][i].end - _timeline.segments[w][i].beg
224 if(i != _timeline.segments[w].size() - 1) {
244 return std::accumulate(
245 _timeline.segments.begin(), _timeline.segments.end(),
size_t{0},
246 [](
size_t sum,
const auto& exe){
247 return sum + exe.size();
323 inline void set_up(
size_t num_workers)
override final;
324 inline void on_entry(
size_t worker_id,
TaskView task_view)
override final;
325 inline void on_exit(
size_t worker_id,
TaskView task_view)
override final;
333 inline TFProfObserver::Segment::Segment(
338 name {n}, type {t}, beg {b} {
342 inline TFProfObserver::Segment::Segment(
348 name {n}, type {t}, beg {b},
end {e} {
352 inline void TFProfObserver::set_up(
size_t num_workers) {
354 _timeline.segments.resize(num_workers);
355 _timeline.stacks.resize(num_workers);
361 inline void TFProfObserver::on_entry(
size_t w, TaskView) {
366 inline void TFProfObserver::on_exit(
size_t w, TaskView tv) {
368 assert(!_timeline.stacks[w].empty());
370 if(_timeline.stacks.size() > _timeline.segments[w].size()){
371 _timeline.segments[w].resize(_timeline.stacks.size());
374 auto beg = _timeline.stacks[w].top();
375 _timeline.stacks[w].pop();
377 _timeline.segments[w][_timeline.stacks[w].size()].emplace_back(
384 for(
size_t w=0; w<_timeline.segments.size(); ++w) {
385 for(
size_t l=0; l<_timeline.segments[w].size(); ++l) {
386 _timeline.segments[w][l].clear();
388 while(!_timeline.stacks[w].empty()) {
389 _timeline.stacks[w].pop();
399 for(first = 0; first<_timeline.segments.size(); ++first) {
400 if(_timeline.segments[first].size() > 0) {
406 if(first == _timeline.segments.size()) {
411 os <<
"{\"executor\":\"" << _uuid <<
"\",\"data\":[";
415 for(
size_t w=first; w<_timeline.segments.size(); w++) {
416 for(
size_t l=0; l<_timeline.segments[w].size(); l++) {
418 if(_timeline.segments[w][l].empty()) {
429 os <<
"{\"worker\":" << w <<
",\"level\":" << l <<
",\"data\":[";
430 for(
size_t i=0; i<_timeline.segments[w][l].size(); ++i) {
432 const auto& s = _timeline.segments[w][l][i];
439 s.beg - _timeline.origin
442 s.end - _timeline.origin
456 os <<
"\"type\":\"" << task_type_to_string(s.type) <<
"\"";
476 return std::accumulate(
477 _timeline.segments.begin(), _timeline.segments.end(),
size_t{0},
478 [](
size_t sum,
const auto& exe){
479 return sum + exe.size();
501 inline const char* observer_type_to_string(ObserverType type) {
504 case TFPROF: val =
"tfprof";
break;
505 case CHROME: val =
"chrome";
break;
506 default: val =
"undefined";
break;
514 using ExecutorObserverInterface = ObserverInterface;
515 using ExecutorObserver = ChromeObserver;
void clear()
clear the timeline data
Definition: observer.hpp:170
void clear()
clear the timeline data
Definition: observer.hpp:383
virtual void on_entry(size_t worker_id, TaskView task_view)=0
method to call before a worker thread executes a closure
std::string dump() const
dump the timelines in JSON to a std::string
Definition: observer.hpp:468
T duration_cast(T... args)
observer designed based on taskflow board format
Definition: observer.hpp:262
virtual void on_exit(size_t worker_id, TaskView task_view)=0
method to call after a worker thread executed a closure
virtual void set_up(size_t num_workers)=0
constructor-like method to call when the executor observer is fully created
class to access task information from the observer interface
Definition: task.hpp:531
size_t num_tasks() const
get the number of total tasks in the observer
Definition: observer.hpp:475
execution interface for running a taskflow graph
Definition: executor.hpp:24
The interface class for creating an executor observer.
Definition: observer.hpp:16
size_t num_tasks() const
get the number of total tasks in the observer
Definition: observer.hpp:243
virtual ~ObserverInterface()=default
virtual destructor
std::string dump() const
dump the timelines in JSON to a std::string
Definition: observer.hpp:236
observer designed based on chrome tracing format
Definition: observer.hpp:58