1 #include "observers/perf_observer.h" 2 #include "observers/observer_config.h" 5 #include "caffe2/core/common.h" 6 #include "caffe2/core/init.h" 7 #include "caffe2/core/operator.h" 12 bool registerGlobalPerfNetObserverCreator(
int* ,
char*** ) {
13 AddGlobalNetObserverCreator([](NetBase* subject) {
14 return caffe2::make_unique<PerfNetObserver>(subject);
20 REGISTER_CAFFE2_EARLY_INIT_FUNCTION(
21 registerGlobalPerfNetObserverCreator,
22 ®isterGlobalPerfNetObserverCreator,
23 "Caffe2 net global observer creator");
25 PerfNetObserver::PerfNetObserver(NetBase* subject_)
26 : NetObserver(subject_), numRuns_(0) {}
28 PerfNetObserver::~PerfNetObserver() {}
30 void PerfNetObserver::Start() {
31 static int visitCount = 0;
34 int netInitSampleRate = ObserverConfig::getNetInitSampleRate();
35 int netFollowupSampleRate = ObserverConfig::getNetFollowupSampleRate();
36 int netFollowupSampleCount = ObserverConfig::getNetFollowupSampleCount();
37 int operatorNetSampleRatio = ObserverConfig::getOpoeratorNetSampleRatio();
38 int skipIters = ObserverConfig::getSkipIters();
39 int sampleRate = visitCount > 0 ? netFollowupSampleRate : netInitSampleRate;
40 if (skipIters <= numRuns_ && sampleRate > 0 && rand() % sampleRate == 0) {
42 if (visitCount == netFollowupSampleCount) {
45 if (operatorNetSampleRatio > 0 && rand() % operatorNetSampleRatio == 0) {
46 logType_ = PerfNetObserver::OPERATOR_DELAY;
48 logType_ = PerfNetObserver::NET_DELAY;
51 logType_ = PerfNetObserver::NONE;
55 if (logType_ == PerfNetObserver::OPERATOR_DELAY) {
58 const auto& operators = subject_->GetOperators();
59 for (
auto* op : operators) {
60 observerMap_[op] = op->AttachObserver(
61 caffe2::make_unique<PerfOperatorObserver>(op,
this));
65 if (logType_ != PerfNetObserver::NONE) {
71 void PerfNetObserver::Stop() {
72 if (logType_ == PerfNetObserver::NONE) {
75 auto currentRunTime = timer_.MilliSeconds();
76 std::map<std::string, double> delays;
77 delays.insert({
"NET_DELAY", currentRunTime});
78 if (logType_ == PerfNetObserver::OPERATOR_DELAY) {
79 const auto& operators = subject_->GetOperators();
80 for (
int idx = 0; idx < operators.size(); ++idx) {
81 const auto* op = operators[idx];
82 auto name = getObserverName(op, idx);
83 double delay =
static_cast<const PerfOperatorObserver*
>(observerMap_[op])
85 delays.insert({name, delay});
89 for (
auto* op : operators) {
90 op->DetachObserver(observerMap_[op]);
94 ObserverConfig::getReporter()->reportDelay(subject_, delays,
"ms");
97 caffe2::string PerfNetObserver::getObserverName(
const OperatorBase* op,
int idx)
99 string opType = op->has_debug_def() ? op->debug_def().type() :
"NO_TYPE";
101 (op->has_debug_def() ? op->debug_def().name().size()
102 ? op->debug_def().name()
103 : (op->debug_def().output_size() ? op->debug_def().output(0)
106 caffe2::string name =
107 "ID_" + caffe2::to_string(idx) +
"_" + opType +
"_" + displayName;
111 PerfOperatorObserver::PerfOperatorObserver(
113 PerfNetObserver* netObserver)
114 : ObserverBase<OperatorBase>(op),
115 netObserver_(netObserver),
117 CAFFE_ENFORCE(netObserver_,
"Observers can't operate outside of the net");
120 PerfOperatorObserver::~PerfOperatorObserver() {}
122 void PerfOperatorObserver::Start() {
128 milliseconds_ = netObserver_->getTimer().MilliSeconds() - milliseconds_;
131 void PerfOperatorObserver::Stop() {
134 milliseconds_ = netObserver_->getTimer().MilliSeconds() - milliseconds_;
137 double PerfOperatorObserver::getMilliseconds()
const {
138 return milliseconds_;
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...