3 #include "caffe2/core/operator.h" 4 #include "caffe2/core/stats.h" 5 #include "caffe2/core/tensor.h" 11 template <
class... Args>
13 :
Operator(std::forward<Args>(args)...) {}
15 bool RunOnDevice()
override {
16 *OperatorBase::Output<std::unique_ptr<StatRegistry>>(0) =
24 template <
class... Args>
26 :
Operator(std::forward<Args>(args)...),
27 reset_(GetSingleArgument<bool>(
"reset",
true)) {}
29 bool RunOnDevice()
override {
30 auto registry = InputSize() > 0
31 ? OperatorBase::Input<std::unique_ptr<StatRegistry>>(0).
get()
33 auto* keys = Output(0);
34 auto* values = Output(1);
35 auto* timestamps = Output(2);
36 auto data = registry->publish(reset_);
37 keys->Resize(data.size());
38 values->Resize(data.size());
39 timestamps->Resize(data.size());
40 auto* pkeys = keys->template mutable_data<std::string>();
41 auto* pvals = values->template mutable_data<int64_t>();
42 auto* ptimestamps = timestamps->template mutable_data<int64_t>();
44 for (
const auto& stat : data) {
45 pkeys[i] = std::move(stat.key);
46 pvals[i] = stat.value;
48 std::chrono::nanoseconds(stat.ts.time_since_epoch()).count();
60 template <
class... Args>
62 :
Operator(std::forward<Args>(args)...) {}
64 bool RunOnDevice()
override {
65 const auto& keys =
Input(0);
66 const auto& values =
Input(1);
67 auto registry = InputSize() == 3
68 ? OperatorBase::Input<std::unique_ptr<StatRegistry>>(2).
get()
70 CAFFE_ENFORCE_EQ(keys.numel(), values.numel());
72 auto* pkeys = keys.data<std::string>();
73 auto* pvals = values.data<int64_t>();
75 for (
auto& stat : data) {
77 stat.value = pvals[i];
80 registry->update(data);
88 : running_(
false), stat_(name) {}
91 CAFFE_ENFORCE(!running_,
"Called TimerBegin on an already running timer.");
93 start_ = std::chrono::high_resolution_clock::now();
97 CAFFE_ENFORCE(running_,
"Called TimerEnd on a stopped timer.");
98 using namespace std::chrono;
99 auto duration = high_resolution_clock::now() - start_;
100 auto nanos = duration_cast<nanoseconds>(duration).count();
101 CAFFE_EVENT(stat_, time_ns, nanos);
106 CAFFE_ENFORCE(running_,
"Called TimerGet on a stopped timer.");
107 using namespace std::chrono;
108 auto duration = high_resolution_clock::now() - start_;
109 auto nanos = duration_cast<nanoseconds>(duration).count();
115 std::chrono::high_resolution_clock::time_point start_;
118 CAFFE_STAT_CTOR(TimerStat);
119 CAFFE_AVG_EXPORTED_STAT(time_ns);
126 given_name_(GetSingleArgument<std::string>(
128 operator_def.output().Get(0))),
129 timer_([
this]() {
return given_name_; }()) {}
131 bool RunOnDevice()
override {
132 *OperatorBase::Output<TimerInstance*>(0) = &timer_;
138 const std::string given_name_;
143 template <
class... Args>
146 bool RunOnDevice()
override {
147 OperatorBase::Input<TimerInstance*>(0)->end();
153 template <
class... Args>
155 :
Operator(std::forward<Args>(args)...) {}
157 bool RunOnDevice()
override {
158 int64_t nanos = OperatorBase::Input<TimerInstance*>(0)->get_ns();
159 OperatorBase::Input<TimerInstance*>(0)->end();
160 auto* res = Output(0);
162 res->template mutable_data<int64_t>()[0] = nanos;
168 template <
class... Args>
171 bool RunOnDevice()
override {
172 int64_t nanos = OperatorBase::Input<TimerInstance*>(0)->get_ns();
173 auto* res = Output(0);
175 res->template mutable_data<int64_t>()[0] = nanos;
189 OPERATOR_SCHEMA(StatRegistryCreate)
193 Create a StatRegistry object that will contain a map of performance counters 194 keyed by name. A StatRegistry is used to gather and retrieve performance 195 counts throughout the caffe2 codebase. 197 .Output(0, "handle",
"A Blob pointing to the newly created StatRegistry.");
199 OPERATOR_SCHEMA(StatRegistryUpdate)
203 Update the given StatRegistry, or the global StatRegistry, 204 with the values of counters for the given keys. 206 .Input(0, "keys",
"1D string tensor with the key names to update.")
207 .Input(1,
"values",
"1D int64 tensor with the values to update.")
211 "If provided, update the given StatRegistry. " 212 "Otherwise, update the global singleton.");
214 OPERATOR_SCHEMA(StatRegistryExport)
220 "If provided, export values from given StatRegistry." 221 "Otherwise, export values from the global singleton StatRegistry.")
222 .Output(0,
"keys",
"1D string tensor with exported key names")
223 .Output(1,
"values",
"1D int64 tensor with exported values")
224 .Output(2,
"timestamps",
"The unix timestamp at counter retrieval.")
227 "(default true) Whether to atomically reset the counters afterwards.");
229 OPERATOR_SCHEMA(TimerBegin)
233 Start a wallclock timer, returning a scalar tensor containing a pointer to it. The timer is stopped by calling **TimerEnd**. 236 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/stats_ops.cc 239 .Arg("counter_name",
"(*str*): name of the timer object; if not set use output name")
240 .Output(0,
"timer",
"(*Tensor`<ptr>`*): pointer to a timer object");
242 OPERATOR_SCHEMA(TimerEnd)
246 Stop a timer started with **TimerBegin**. Publishes a CAFFE_EVENT. 249 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/stats_ops.cc 252 .Input(0, "timer",
"(*Tensor`<ptr>`*): pointer to a timer object; obtained from **TimerBegin** op");
254 OPERATOR_SCHEMA(TimerGetAndEnd)
258 Queries the current time of a timer in nanos, stops the timer publishing a CAFFE_EVENT. 261 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/stats_ops.cc 265 <summary> <b>Example</b> </summary> 271 workspace.ResetWorkspace() 273 timerbegin_op = core.CreateOperator( 279 timerget_op = core.CreateOperator( 285 timerend_op = core.CreateOperator( 291 timergetandend_op = core.CreateOperator( 297 // Test TimerBegin/TimerGet/TimerEnd 298 workspace.RunOperatorOnce(timerbegin_op) 299 print("timer:", workspace.FetchBlob("timer")) 300 workspace.RunOperatorOnce(timerget_op) 301 print("nanos:", workspace.FetchBlob("nanos")) 302 workspace.RunOperatorOnce(timerend_op) 305 // Test TimerBegin/TimerGetAndEnd 306 workspace.RunOperatorOnce(timerbegin_op) 307 print("timer:", workspace.FetchBlob("timer")) 308 workspace.RunOperatorOnce(timergetandend_op) 309 print("nanos:", workspace.FetchBlob("nanos")) 317 timer: b'timer, a C++ native class of type caffe2::TimerInstance*.' 319 timer: b'timer, a C++ native class of type caffe2::TimerInstance*.' 327 .Input(0, "timer",
"(*Tensor`<ptr>`*): pointer to a timer object; obtained from **TimerBegin** op")
328 .Output(0,
"nanos",
"(*Tensor`<int64>`*): scalar tensor containing time in nanoseconds");
330 OPERATOR_SCHEMA(TimerGet)
334 Queries the current time of a timer object in nanoseconds. 337 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/stats_ops.cc 340 .Input(0, "timer",
"(*Tensor`<ptr>`*): pointer to a timer object; obtained from **TimerBegin** op")
341 .Output(0,
"nanos",
"(*Tensor`<int64>`*): scalar containing time in nanoseconds");
344 CAFFE_KNOWN_TYPE(std::unique_ptr<caffe2::StatRegistry>);
Workspace is a class that holds all the related objects created during runtime: (1) all blobs...
const Tensor & Input(int idx, DeviceType type=CPUContext::GetDeviceType())
Retrieve a non-owning reference to the input at position 'idx' for this operator. ...
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
std::vector< ExportedStatValue > ExportedStatList
Holds names and values of counters exported from a StatRegistry.
static StatRegistry & get()
Retrieve the singleton StatRegistry, which gets populated through the CAFFE_EVENT macro...
Holds a map of atomic counters keyed by name.