Merge pull request #14827 from YashasSamaga:cuda4dnn-csl-low
[platform/upstream/opencv.git] / modules / dnn / src / cuda4dnn / csl / stream.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_STREAM_HPP
6 #define OPENCV_DNN_SRC_CUDA4DNN_CSL_STREAM_HPP
7
8 #include "error.hpp"
9
10 #include <opencv2/core.hpp>
11 #include <opencv2/core/utils/logger.hpp>
12
13 #include <cuda_runtime_api.h>
14
15 #include <memory>
16 #include <sstream>
17 #include <utility>
18
19 namespace cv { namespace dnn { namespace cuda4dnn { namespace csl {
20
21     /** @brief noncopyable smart CUDA stream
22      *
23      * UniqueStream is a smart non-sharable wrapper for CUDA stream handle which ensures that
24      * the handle is destroyed after use. Unless explicitly specified by a constructor argument,
25      * the stream object represents the default stream.
26      */
27     class UniqueStream {
28     public:
29         UniqueStream() noexcept : stream{ 0 } { }
30         UniqueStream(UniqueStream&) = delete;
31         UniqueStream(UniqueStream&& other) noexcept {
32             stream = other.stream;
33             other.stream = 0;
34         }
35
36         UniqueStream(bool create) : stream{ 0 } {
37             if (create) {
38                 CUDA4DNN_CHECK_CUDA(cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking));
39             }
40         }
41
42         ~UniqueStream() {
43             try {
44                 if (stream != 0)
45                     CUDA4DNN_CHECK_CUDA(cudaStreamDestroy(stream));
46             } catch (const CUDAException& ex) {
47                 std::ostringstream os;
48                 os << "Asynchronous exception caught during CUDA stream destruction.\n";
49                 os << ex.what();
50                 os << "Exception will be ignored.\n";
51                 CV_LOG_WARNING(0, os.str().c_str());
52             }
53         }
54
55         UniqueStream& operator=(const UniqueStream&) = delete;
56         UniqueStream& operator=(UniqueStream&& other) noexcept {
57             stream = other.stream;
58             other.stream = 0;
59             return *this;
60         }
61
62         /** returns the raw CUDA stream handle */
63         cudaStream_t get() const noexcept { return stream; }
64
65         void synchronize() const { CUDA4DNN_CHECK_CUDA(cudaStreamSynchronize(stream)); }
66         bool busy() const {
67             auto status = cudaStreamQuery(stream);
68             if (status == cudaErrorNotReady)
69                 return true;
70             CUDA4DNN_CHECK_CUDA(status);
71             return false;
72         }
73
74     private:
75         cudaStream_t stream;
76     };
77
78     /** @brief sharable smart CUDA stream
79      *
80      * Stream is a smart sharable wrapper for CUDA stream handle which ensures that
81      * the handle is destroyed after use. Unless explicitly specified by a constructor argument,
82      * the stream object represents the default stream.
83      *
84      * @note Moving a Stream object to another invalidates the former
85      */
86     class Stream {
87     public:
88         Stream() : stream(std::make_shared<UniqueStream>()) { }
89         Stream(const Stream&) = default;
90         Stream(Stream&&) = default;
91
92         /** if \p create is `true`, a new stream will be created instead of the otherwise default stream */
93         Stream(bool create) : stream(std::make_shared<UniqueStream>(create)) { }
94
95         Stream& operator=(const Stream&) = default;
96         Stream& operator=(Stream&&) = default;
97
98         /** blocks the caller thread until all operations in the stream are complete */
99         void synchronize() const { stream->synchronize(); }
100
101         /** returns true if there are operations pending in the stream */
102         bool busy() const { return stream->busy(); }
103
104         /** returns true if the stream is valid */
105         explicit operator bool() const noexcept { return static_cast<bool>(stream); }
106
107         cudaStream_t get() const noexcept {
108             CV_Assert(stream);
109             return stream->get();
110         }
111
112     private:
113         std::shared_ptr<UniqueStream> stream;
114     };
115
116 }}}} /* namespace cv::dnn::cuda4dnn::csl */
117
118 #endif /* OPENCV_DNN_SRC_CUDA4DNN_CSL_STREAM_HPP */