Caffe2 - C++ API
A deep learning, cross platform ML framework
net_async_tracing.h
1 
17 #ifndef CAFFE2_CORE_NET_ASYNC_TRACING_H_
18 #define CAFFE2_CORE_NET_ASYNC_TRACING_H_
19 
20 #include "caffe2/core/common.h"
21 #include "caffe2/core/net_async_base.h"
22 #include "caffe2/core/operator.h"
23 #include "caffe2/core/timer.h"
24 
25 C10_DECLARE_string(caffe2_net_async_tracing_filepath);
26 C10_DECLARE_string(caffe2_net_async_names_to_trace);
27 C10_DECLARE_int(caffe2_net_async_tracing_nth);
28 
29 namespace caffe2 {
30 namespace tracing {
31 
32 struct CAFFE2_API TracerEvent {
33  int op_id_ = -1;
34  int task_id_ = -1;
35  int stream_id_ = -1;
36  const char* name_ = nullptr;
37  const char* category_ = nullptr;
38  long timestamp_ = -1.0;
39  bool is_beginning_ = false;
40  long thread_label_ = -1;
41  std::thread::id tid_;
42 };
43 
44 enum TracingField {
45  TRACE_OP,
46  TRACE_TASK,
47  TRACE_STREAM,
48  TRACE_THREAD,
49  TRACE_NAME,
50  TRACE_CATEGORY,
51 };
52 
53 enum class TracingMode {
54  EVERY_K_ITERATIONS,
55  GLOBAL_TIMESLICE,
56 };
57 
58 struct TracingConfig {
59  TracingMode mode{TracingMode::EVERY_K_ITERATIONS};
60  std::string filepath{"/tmp"};
61 
62  // for TracingMode::EVERY_K_ITERATIONS
63  int64_t trace_every_nth_batch = 100;
64  int64_t dump_every_nth_batch = 10000;
65 
66  // for TracingMode::GLOBAL_TIMESLICE
67  int64_t trace_every_n_ms = 2 * 60 * 1000; // 2min
68  int64_t trace_for_n_ms = 1000; // 1sec
69 };
70 
71 class CAFFE2_API Tracer {
72  public:
73  Tracer(
74  const NetBase* net,
75  const std::string& net_name,
77 
78  void recordEvent(const TracerEvent& event);
79  std::string opTraceName(const OperatorBase* op);
80  std::string opBlobsInfo(const OperatorBase& op);
81  std::string serializeEvent(const TracerEvent& event);
82  void linearizeEvents();
83  void renameThreads();
84  void setEnabled(bool enabled);
85  bool isEnabled() const;
86  const TracingConfig& config() {
87  return config_;
88  }
89  int bumpIter();
90  int bumpDumpingIter();
91  // Dump the tracing result to file with given suffix, and then
92  // clear current events.
93  void dumpTracingResultAndClearEvents(const std::string& file_suffix);
94 
95  virtual ~Tracer();
96 
97  private:
98  const NetBase* net_ = nullptr;
99  std::string filename_;
100  std::vector<TracerEvent> events_;
101  std::mutex tracer_mutex_;
102  bool enabled_ = false;
103  Timer timer_;
104  int iter_;
105  int dumping_iter_;
106  TracingConfig config_;
107 
108  friend class TracerGuard;
109 };
110 
111 class CAFFE2_API TracerGuard {
112  public:
113  TracerGuard() {}
114 
115  void init(Tracer* tracer);
116 
117  void addArgument();
118  void addArgument(TracingField field, const char* value);
119  void addArgument(TracingField field, int value);
120 
121  template <typename T, typename... Args>
122  void addArgument(TracingField field, const T& value, const Args&... args) {
123  addArgument(field, value);
124  addArgument(args...);
125  }
126 
127  void recordEventStart();
128 
129  virtual ~TracerGuard();
130 
131  private:
132  bool enabled_ = false;
133  TracerEvent event_;
134  Tracer* tracer_;
135 };
136 
137 // Extract the shard id from name of the form "...shard:123..."
138 // Return -1 if there is no shard found
139 CAFFE2_API int extractShardId(const std::string& name);
140 
141 // Check if the net name is white-listed for tracing (specified via a command
142 // line flag)
143 CAFFE2_API bool isTraceableNetName(const std::string& net_name);
144 
145 CAFFE2_API std::shared_ptr<Tracer> create(
146  const NetBase* net,
147  const std::string& net_name);
148 CAFFE2_API bool startIter(const std::shared_ptr<Tracer>& tracer);
149 
150 } // namespace tracing
151 
152 #define TRACE_NAME_CONCATENATE(s1, s2) s1##s2
153 #define TRACE_ANONYMOUS_NAME(str) TRACE_NAME_CONCATENATE(str, __LINE__)
154 
155 #define TRACE_EVENT_INIT(...) \
156  TRACE_ANONYMOUS_NAME(trace_guard).init(tracer_.get()); \
157  TRACE_ANONYMOUS_NAME(trace_guard).addArgument(__VA_ARGS__); \
158  TRACE_ANONYMOUS_NAME(trace_guard).recordEventStart();
159 
160 // Supposed to be used only once per scope in AsyncNetBase-derived nets
161 #define TRACE_EVENT(...) \
162  tracing::TracerGuard TRACE_ANONYMOUS_NAME(trace_guard); \
163  if (tracer_ && tracer_->isEnabled()) { \
164  TRACE_EVENT_INIT(__VA_ARGS__) \
165  }
166 
167 #define TRACE_EVENT_IF(cond, ...) \
168  tracing::TracerGuard TRACE_ANONYMOUS_NAME(trace_guard); \
169  if (tracer_ && tracer_->isEnabled() && (cond)) { \
170  TRACE_EVENT_INIT(__VA_ARGS__) \
171  }
172 
173 } // namespace caffe2
174 
175 #endif // CAFFE2_CORE_NET_ASYNC_TRACING_H_
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13
A simple timer object for measuring time.
Definition: timer.h:16