Merge pull request #14827 from YashasSamaga:cuda4dnn-csl-low
[platform/upstream/opencv.git] / modules / dnn / src / cuda4dnn / csl / span.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_SPAN_HPP
6 #define OPENCV_DNN_SRC_CUDA4DNN_CSL_SPAN_HPP
7
8 #include "pointer.hpp"
9 #include "nvcc_defs.hpp"
10
11 #include <cstddef>
12 #include <type_traits>
13
14 namespace cv { namespace dnn { namespace cuda4dnn { namespace csl {
15
16     /** @brief provides non-owning mutable access for device arrays
17      *
18      *  const Span<T>/Span<T> provides mutable access to the elements unless T is const qualified
19      *  const Span<T> makes the span immutable but not the elements
20      */
21     template <class T>
22     class Span {
23         static_assert(std::is_standard_layout<T>::value, "T must satisfy StandardLayoutType");
24
25     public:
26         using value_type = T;
27         using size_type = std::size_t;
28         using difference_type = std::ptrdiff_t;
29
30         using pointer = DevicePtr<value_type>;
31         using const_pointer = DevicePtr<typename std::add_const<value_type>::type>;
32         using reference = typename std::add_lvalue_reference<value_type>::type;
33         using const_reference = typename std::add_lvalue_reference<typename std::add_const<value_type>::type>;
34
35         using iterator = pointer;
36         using const_iterator = const_pointer;
37
38         Span() noexcept : ptr{ nullptr }, sz{ 0 } { }
39         CUDA4DNN_HOST_DEVICE Span(pointer first, pointer last) noexcept : ptr{ first }, sz{ last - first } { }
40         CUDA4DNN_HOST_DEVICE Span(pointer first, size_type count) noexcept : ptr{ first }, sz{ count } { }
41
42         CUDA4DNN_HOST_DEVICE size_type size() const noexcept { return sz; }
43         CUDA4DNN_HOST_DEVICE bool empty() const noexcept { return size() == 0; }
44
45         CUDA4DNN_DEVICE reference operator[](difference_type index) const { return ptr[index]; }
46         CUDA4DNN_HOST_DEVICE pointer data() const noexcept { return ptr; }
47
48         template<class U = T, class V = typename std::add_const<U>::type,
49             typename std::enable_if<!std::is_const<U>::value, bool>::type = true>
50             CUDA4DNN_HOST_DEVICE operator Span<V>() const noexcept { return Span<V>{ptr, sz}; }
51
52     private:
53         pointer ptr;
54         size_type sz;
55     };
56
57     /** @brief provides non-owning immutable view for device arrays */
58     template <class T>
59     using View = Span<const T>;
60
61     /** returns true if the address of a span/view is aligned to \p alignment number of elements (not bytes) */
62     template <class T>
63     bool is_address_aligned(View<T> v, std::size_t alignment) {
64         return is_aligned(v.data(), alignment * sizeof(T));
65     }
66
67     /** returns true if the size of a span/view is a multiple of \p alignment */
68     template <class T>
69     bool is_size_aligned(View<T> v, std::size_t alignment) {
70         return v.size() % alignment == 0;
71     }
72
73     /** @brief returns true if the address and the size of the span/view is aligned
74      * \p alignment refers to the number of elements (not bytes)
75      */
76     template <class T>
77     bool is_fully_aligned(View<T> v, std::size_t alignment) {
78         return is_address_aligned(v, alignment) && is_size_aligned(v, alignment);
79     }
80
81 }}}} /* namespace cv::dnn::cuda4dnn::csl */
82
83 #endif /* OPENCV_DNN_SRC_CUDA4DNN_CSL_SPAN_HPP */