MUDA
Loading...
Searching...
No Matches
dense_vector_viewer.h
1#pragma once
2#include <muda/ext/eigen/eigen_core_cxx20.h>
3#include <muda/buffer/buffer_2d_view.h>
4#include <muda/viewer/viewer_base.h>
5#include <cublas_v2.h>
6#include <muda/atomic.h>
7namespace muda
8{
9template <bool IsConst, typename T>
10class DenseVectorViewerBase : public ViewerBase<IsConst>
11{
12 static_assert(std::is_same_v<T, float> || std::is_same_v<T, double>,
13 "now only support real number");
14
16 template <typename U>
17 using auto_const_t = typename Base::template auto_const_t<U>;
18
19 public:
20 using CBufferView = CBufferView<T>;
21 using BufferView = BufferView<T>;
22 using ThisBufferView = std::conditional_t<IsConst, CBufferView, BufferView>;
23
26 using ThisViewer = std::conditional_t<IsConst, ConstViewer, NonConstViewer>;
27
28 using VectorType = Eigen::Vector<T, Eigen::Dynamic>;
29 template <typename U>
30 using MapVectorT =
31 Eigen::Map<U, Eigen::AlignmentType::Unaligned, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>;
32 using MapVector = MapVectorT<VectorType>;
33 using CMapVector = MapVectorT<const VectorType>;
34 using ThisMapVector = std::conditional_t<IsConst, CMapVector, MapVector>;
35
36 protected:
37 auto_const_t<T>* m_data;
38 int m_offset = 0;
39 int m_size = 0;
40 int m_origin_size = 0;
41
42 public:
43 MUDA_GENERIC DenseVectorViewerBase(auto_const_t<T>* data, int offset, int size, int origin_size)
44 : m_data(data)
45 , m_offset(offset)
46 , m_size(size)
47 , m_origin_size(origin_size)
48 {
49 }
50
51 MUDA_GENERIC auto as_const() const
52 {
53 return ConstViewer{m_data, m_offset, m_size, m_origin_size};
54 }
55
56 MUDA_GENERIC operator ConstViewer() const { return as_const(); }
57
58 MUDA_GENERIC auto segment(int offset, int size)
59 {
60 check_segment(offset, size);
61 auto ret = ThisViewer{m_data, m_offset + offset, size, m_origin_size};
62 ret.copy_label(*this);
63 return ret;
64 }
65
66 template <int N>
67 MUDA_GENERIC auto segment(int offset)
68 {
69 return segment(offset, N);
70 }
71
72 MUDA_GENERIC auto segment(int offset, int size) const
73 {
74 return remove_const(*this).segment(offset, size);
75 }
76
77 MUDA_GENERIC const T& operator()(int i) const { return m_data[index(i)]; }
78 MUDA_GENERIC auto_const_t<T>& operator()(int i) { return m_data[index(i)]; }
79
80 template <int N>
81 MUDA_GENERIC auto segment(int offset) const
82 {
83 return remove_const(*this).segment(offset, N);
84 }
85
86 MUDA_GENERIC Eigen::VectorBlock<CMapVector> as_eigen() const
87 {
88 check_data();
89 return CMapVector{m_data,
90 (int)origin_size(),
91 Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>{1, 1}}
92 .segment(m_offset, m_size);
93 }
94
95 MUDA_GENERIC operator Eigen::VectorBlock<CMapVector>() const
96 {
97 return as_eigen();
98 }
99
100 MUDA_GENERIC Eigen::VectorBlock<ThisMapVector> as_eigen()
101 {
102 check_data();
103 return ThisMapVector{m_data,
104 (int)origin_size(),
105 Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>{1, 1}}
106 .segment(m_offset, m_size);
107 }
108
109 MUDA_GENERIC operator Eigen::VectorBlock<ThisMapVector>()
110 {
111 return as_eigen();
112 }
113
114 MUDA_GENERIC auto size() const { return m_size; }
115 MUDA_GENERIC auto offset() const { return m_offset; }
116 MUDA_GENERIC auto origin_data() const { return m_data; }
117 MUDA_GENERIC auto origin_size() const { return m_origin_size; }
118
119
120 protected:
121 MUDA_INLINE MUDA_GENERIC void check_size_matching(int N)
122 {
123 MUDA_KERNEL_ASSERT(m_size == N,
124 "DenseVectorViewerBase [%s:%s]: size not match, yours size=%d, expected size=%d",
125 this->name(),
126 this->kernel_name(),
127 m_size,
128 N);
129 }
130
131 MUDA_INLINE MUDA_GENERIC int index(int i) const
132 {
133 MUDA_KERNEL_ASSERT(origin_data(),
134 "DenseVectorViewerBase [%s:%s]: data is null",
135 this->name(),
136 this->kernel_name());
137 MUDA_KERNEL_ASSERT(i < m_size,
138 "DenseVectorViewerBase [%s:%s]: index out of range, size=%d, yours index=%d",
139 this->name(),
140 this->kernel_name(),
141 m_size,
142 i);
143 return m_offset + i;
144 }
145
146 MUDA_INLINE MUDA_GENERIC void check_data() const
147 {
148 MUDA_KERNEL_ASSERT(origin_data(),
149 "DenseVectorViewerBase [%s:%s]: data is null",
150 this->name(),
151 this->kernel_name());
152 }
153
154 MUDA_INLINE MUDA_GENERIC void check_segment(int offset, int size) const
155 {
156 MUDA_KERNEL_ASSERT(offset + size <= m_size,
157 "DenseVectorViewerBase [%s:%s]: segment out of range, m_size=%d, offset=%d, size=%d",
158 this->name(),
159 this->kernel_name(),
160 m_size,
161 offset,
162 size);
163 }
164};
165
166//template <typename T>
167//using CDenseVectorViewer = DenseVectorViewerBase<true, T>;
168//template <typename T>
169//using DenseVectorViewer = DenseVectorViewerBase<false, T>;
170
171template <typename T>
173{
174 MUDA_VIEWER_COMMON_NAME(CDenseVectorViewer);
175
177 using MapVector = typename Base::MapVector;
178 using CMapVector = typename Base::CMapVector;
179
180 public:
181 using Base::Base;
182
183 MUDA_GENERIC CDenseVectorViewer(const Base& base)
184 : Base(base)
185 {
186 }
187
188 MUDA_GENERIC CDenseVectorViewer segment(int offset, int size) const
189 {
190 return CDenseVectorViewer{Base::segment(offset, size)};
191 }
192
193 template <int N>
194 MUDA_GENERIC auto segment(int offset) const
195 {
196 return segment(offset, N);
197 }
198};
199
200template <typename T>
202{
203 MUDA_VIEWER_COMMON_NAME(DenseVectorViewer);
204
206 using MapVector = typename Base::MapVector;
207 using CMapVector = typename Base::CMapVector;
208
209 public:
210 using Base::Base;
211
212 MUDA_GENERIC DenseVectorViewer(const Base& base)
213 : Base(base)
214 {
215 }
216
217 MUDA_GENERIC DenseVectorViewer segment(int offset, int size)
218 {
219 return DenseVectorViewer{Base::segment(offset, size)};
220 }
221
222 template <int N>
223 MUDA_GENERIC auto segment(int offset)
224 {
225 return segment(offset, N);
226 }
227
228 MUDA_DEVICE T atomic_add(int i, T val)
229 {
230 auto ptr = &this->operator()(i);
231 return muda::atomic_add(ptr, val);
232 }
233
234 template <int N>
235 MUDA_DEVICE Eigen::Vector<T, N> atomic_add(const Eigen::Vector<T, N>& val)
236 {
237 this->check_size_matching(N);
238 Eigen::Vector<T, N> ret;
239#pragma unroll
240 for(int i = 0; i < N; ++i)
241 {
242 ret(i) = atomic_add(i, val(i));
243 }
244 return ret;
245 }
246
247 MUDA_DEVICE T atomic_add(const T& val)
248 {
249 this->check_size_matching(1);
250 T ret = atomic_add(0, val);
251 return ret;
252 }
253
254 template <int N>
255 MUDA_GENERIC DenseVectorViewer& operator=(const Eigen::Vector<T, N>& other)
256 {
257 this->check_size_matching(N);
258#pragma unroll
259 for(int i = 0; i < N; ++i)
260 {
261 this->operator()(i) = other(i);
262 }
263 return *this;
264 }
265};
266} // namespace muda
267
268namespace muda
269{
270template <typename T>
275
276template <typename T>
281} // namespace muda
282
283#include "details/dense_vector_viewer.inl"
Definition dense_vector_viewer.h:173
Definition dense_vector_viewer.h:11
Definition dense_vector_viewer.h:202
Definition viewer_base.h:18
Definition type_modifier.h:22
Definition type_modifier.h:28