Merge pull request #14827 from YashasSamaga:cuda4dnn-csl-low
[platform/upstream/opencv.git] / modules / dnn / src / cuda4dnn / csl / event.hpp
1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4
5 #ifndef OPENCV_DNN_SRC_CUDA4DNN_CSL_EVENT_HPP
6 #define OPENCV_DNN_SRC_CUDA4DNN_CSL_EVENT_HPP
7
8 #include "error.hpp"
9 #include "stream.hpp"
10
11 #include <opencv2/core/utils/logger.hpp>
12
13 #include <cuda_runtime_api.h>
14
15 namespace cv { namespace dnn { namespace cuda4dnn { namespace csl {
16
17     /** @brief sharable CUDA event
18      *
19      * Event is a smart sharable wrapper for CUDA event handle which ensures that
20      * the handle is destroyed after use.
21      *
22      * @note Moving an Event object to another invalidates the former
23      */
24     class Event {
25     public:
26         Event() noexcept : event{ nullptr } { }
27         Event(const Event&) = delete;
28         Event(Event&& other) noexcept
29             : event{ other.event } {
30             other.event = nullptr;
31         }
32
33         /** if \p create is `true`, a new event will be created; otherwise, an empty event object is created */
34         Event(bool create, bool timing_event = false) : event{nullptr} {
35             if (create) {
36                 unsigned int flags = cudaEventBlockingSync | (timing_event ? 0 : cudaEventDisableTiming);
37                 CUDA4DNN_CHECK_CUDA(cudaEventCreateWithFlags(&event, flags));
38             }
39         }
40
41         ~Event() {
42             try {
43                 if (event != nullptr)
44                     CUDA4DNN_CHECK_CUDA(cudaEventDestroy(event));
45             } catch (const CUDAException& ex) {
46                 std::ostringstream os;
47                 os << "Asynchronous exception caught during CUDA event destruction.\n";
48                 os << ex.what();
49                 os << "Exception will be ignored.\n";
50                 CV_LOG_WARNING(0, os.str().c_str());
51             }
52         }
53
54         Event& operator=(const Event&) noexcept = delete;
55         Event& operator=(Event&& other) noexcept {
56             event = other.event;
57             other.event = nullptr;
58             return *this;
59         }
60
61         /** mark a point in \p stream */
62         void record(const Stream& stream) {
63             CUDA4DNN_CHECK_CUDA(cudaEventRecord(event, stream.get()));
64         }
65
66         /** blocks the caller thread until all operations before the event finish */
67         void synchronize() const { CUDA4DNN_CHECK_CUDA(cudaEventSynchronize(event)); }
68
69         /** returns true if there are operations pending before the event completes */
70         bool busy() const {
71             auto status = cudaEventQuery(event);
72             if (status == cudaErrorNotReady)
73                 return true;
74             CUDA4DNN_CHECK_CUDA(status);
75             return false;
76         }
77
78         cudaEvent_t get() const noexcept { return event; }
79
80         /** returns true if the event is valid */
81         explicit operator bool() const noexcept { return event; }
82
83     private:
84         cudaEvent_t event;
85     };
86
87     /** makes a stream wait on an event */
88     void StreamWaitOnEvent(const Stream& stream, const Event& event) {
89         CUDA4DNN_CHECK_CUDA(cudaStreamWaitEvent(stream.get(), event.get(), 0));
90     }
91
92     /** returns the time elapsed between two events in milliseconds */
93     float TimeElapsedBetweenEvents(const Event& start, const Event& end) {
94         float temp;
95         CUDA4DNN_CHECK_CUDA(cudaEventElapsedTime(&temp, start.get(), end.get()));
96         return temp;
97     }
98
99 }}}} /* namespace cv::dnn::cuda4dnn::csl */
100
101 #endif /* OPENCV_DNN_SRC_CUDA4DNN_CSL_EVENT_HPP */