Caffe2 - C++ API
A deep learning, cross platform ML framework
event.cc
1 #include "caffe2/core/event_cpu.h"
2 
3 namespace caffe2 {
4 
5 CAFFE2_API EventCreateFunction Event::event_creator_[MaxDeviceTypes];
6 CAFFE2_API EventRecordFunction Event::event_recorder_[MaxDeviceTypes];
7 CAFFE2_API EventWaitFunction
8  Event::event_waiter_[MaxDeviceTypes][MaxDeviceTypes];
9 CAFFE2_API EventFinishFunction Event::event_finisher_[MaxDeviceTypes];
10 
11 CAFFE2_API EventQueryFunction Event::event_querier_[MaxDeviceTypes];
12 CAFFE2_API EventErrorMessageFunction
13  Event::event_err_msg_getter_[MaxDeviceTypes];
14 CAFFE2_API EventSetFinishedFunction
15  Event::event_finished_setter_[MaxDeviceTypes];
16 CAFFE2_API EventResetFunction Event::event_resetter_[MaxDeviceTypes];
17 
18 namespace {
19 const std::string kNoError = "No error";
20 }
21 
22 void EventCreateCPU(const DeviceOption& option, Event* event) {
23  event->event_ = std::make_shared<CPUEventWrapper>(option);
24 }
25 
26 void EventRecordCPU(
27  Event* event,
28  const void* /* unused */,
29  const char* err_msg) {
30  auto* wrapper = static_cast<CPUEventWrapper*>(event->event_.get());
31  std::unique_lock<std::mutex> lock(wrapper->mutex_);
32 
33  // Possible state changes:
34  // INITIALIZED -> SCHEDULED or SUCCESS/FAILED
35  // SCHEDULED -> SUCCESS/FAILED
36  // SUCCESS/FAILED - terminal, no further changes to status_/err_msg_
37 
38  CAFFE_ENFORCE(
39  wrapper->status_ != EventStatus::EVENT_SCHEDULED,
40  "Calling Record multiple times");
41 
42  // Event might be in SUCCESS/FAILED state in case an op has
43  // finished async execution part first
44  if (wrapper->status_ == EventStatus::EVENT_INITIALIZED) {
45  if (!err_msg) {
46  wrapper->status_ = EventStatus::EVENT_SCHEDULED;
47  } else {
48  wrapper->err_msg_ = err_msg;
49  wrapper->status_ = EventStatus::EVENT_FAILED;
50  wrapper->cv_completed_.notify_all();
51  }
52  }
53 }
54 
55 void EventFinishCPU(const Event* event) {
56  auto* wrapper = static_cast<CPUEventWrapper*>(event->event_.get());
57  std::unique_lock<std::mutex> lock(wrapper->mutex_);
58  while (wrapper->status_ != EventStatus::EVENT_SUCCESS &&
59  wrapper->status_ != EventStatus::EVENT_FAILED) {
60  wrapper->cv_completed_.wait(lock);
61  }
62 }
63 
64 void EventWaitCPUCPU(const Event* event, void* /* context */) {
65  EventFinishCPU(event);
66 }
67 
68 EventStatus EventQueryCPU(const Event* event) {
69  auto* wrapper = static_cast<CPUEventWrapper*>(event->event_.get());
70  return static_cast<EventStatus>(wrapper->status_.load());
71 }
72 
73 const std::string& EventErrorMessageCPU(const Event* event) {
74  auto* wrapper = static_cast<CPUEventWrapper*>(event->event_.get());
75  if (wrapper->status_ == EventStatus::EVENT_FAILED) {
76  // Failed is a terminal state, not synchronizing,
77  // err_msg_ should not be changed anymore
78  return wrapper->err_msg_;
79  } else {
80  return kNoError;
81  }
82 }
83 
84 void EventSetFinishedCPU(const Event* event, const char* err_msg) {
85  auto* wrapper = static_cast<CPUEventWrapper*>(event->event_.get());
86  std::unique_lock<std::mutex> lock(wrapper->mutex_);
87 
88  CAFFE_ENFORCE(
89  wrapper->status_ == EventStatus::EVENT_INITIALIZED ||
90  wrapper->status_ == EventStatus::EVENT_SCHEDULED,
91  "Calling SetFinished on finished event");
92 
93  if (!err_msg) {
94  wrapper->status_ = EventStatus::EVENT_SUCCESS;
95  } else {
96  wrapper->err_msg_ = err_msg;
97  wrapper->status_ = EventStatus::EVENT_FAILED;
98  }
99  wrapper->cv_completed_.notify_all();
100 }
101 
102 void EventResetCPU(Event* event) {
103  auto* wrapper = static_cast<CPUEventWrapper*>(event->event_.get());
104  std::unique_lock<std::mutex> lock(wrapper->mutex_);
105  wrapper->status_ = EventStatus::EVENT_INITIALIZED;
106  wrapper->err_msg_ = "";
107 }
108 
109 REGISTER_EVENT_CREATE_FUNCTION(CPU, EventCreateCPU);
110 REGISTER_EVENT_RECORD_FUNCTION(CPU, EventRecordCPU);
111 REGISTER_EVENT_WAIT_FUNCTION(CPU, CPU, EventWaitCPUCPU);
112 REGISTER_EVENT_FINISH_FUNCTION(CPU, EventFinishCPU);
113 
114 REGISTER_EVENT_QUERY_FUNCTION(CPU, EventQueryCPU);
115 REGISTER_EVENT_ERROR_MESSAGE_FUNCTION(CPU, EventErrorMessageCPU);
116 REGISTER_EVENT_SET_FINISHED_FUNCTION(CPU, EventSetFinishedCPU);
117 REGISTER_EVENT_RESET_FUNCTION(CPU, EventResetCPU);
118 
119 } // namespace caffe2
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...