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