dense.hpp
Go to the documentation of this file.
1/*!
2 * \brief Implements the Dense storage vector and matrices
3 *
4 * \author O. Krause
5 * \date 2014
6 *
7 *
8 * \par Copyright 1995-2015 Shark Development Team
9 *
10 * <BR><HR>
11 * This file is part of Shark.
12 * <http://image.diku.dk/shark/>
13 *
14 * Shark is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License as published
16 * by the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Shark is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public License
25 * along with Shark. If not, see <http://www.gnu.org/licenses/>.
26 *
27 */
28#ifndef REMORA_DENSE_HPP
29#define REMORA_DENSE_HPP
30
31#include "expression_types.hpp"
32#include "detail/traits.hpp"
33#include "detail/proxy_optimizers_fwd.hpp"
34namespace remora{
35
36/// \brief A dense vector of values of type \c T.
37///
38/// For a \f$n\f$-dimensional vector \f$v\f$ and \f$0\leq i < n\f$ every element \f$v_i\f$ is mapped
39/// to the \f$i\f$-th element of the container.
40/// The tag descripes whether the vector is residing on a cpu or gpu which change its semantics.
41///
42/// \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
43/// \tparam Device the device this vector lives on, the default is cpu_tag for a cpu vector
44template<class T, class Device = cpu_tag>
45class vector;
46
47
48/// \brief A dense matrix of values of type \c T.
49///
50/// For a \f$(m \times n)\f$-dimensional matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$ m_{i,j} \f$ is mapped to
51/// the \f$(i*n + j)\f$-th element of the container for row major orientation or the \f$ (i + j*m) \f$-th element of
52/// the container for column major orientation. In a dense matrix all elements are represented in memory in a
53/// contiguous chunk of memory by definition.
54///
55/// Orientation can also be specified, otherwise a \c row_major is used.
56///
57/// \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
58/// \tparam Orientation the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
59/// \tparam Device the device this matrix lives on, the default is cpu_tag for a cpu matrix
60template<class T, class Orientation=row_major, class Device = cpu_tag>
61class matrix;
62
63
64/// \brief A proxy to a dense vector of values of type \c T.
65///
66/// Using external memory providing by another vector, references a part of the vector.
67/// The referenced region is not required to be consecutive, i.e. elements can have a stride larger than one
68///
69/// \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
70/// \tparam Tag the storage tag. dense_tag by default and continuous_dense_tag if stride is guarantueed to be 1.
71/// \tparam Device the device this vector lives on, the default is cpu_tag for a cpu vector
72template<class T, class Tag = dense_tag, class Device = cpu_tag>
73class dense_vector_adaptor;
74
75/// \brief A proxy to a dense matrix of values of type \c T.
76///
77/// Using external memory providing by another matrix, references a subrange of the matrix
78/// The referenced region is not required to be consecutive, i.e. a subregion of a matrix can be used
79/// However, either the row or column indices must be consecutive
80///
81/// \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
82/// \tparam Orientation the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
83/// \tparam Tag the storage tag. dense_tag by default and continuous_dense_tag if the memory region referenced is continuous.
84/// \tparam Device the device this vector lives on, the default is cpu_tag for a cpu vector
85template<class T,class Orientation = row_major, class Tag = dense_tag, class Device = cpu_tag>
86class dense_matrix_adaptor;
87
88
89template<class T, class Orientation, class TriangularType, class Device>
90class dense_triangular_proxy;
91
92///////////////////////////////////
93// Adapt memory as vector
94///////////////////////////////////
95
96/// \brief Converts a chunk of memory into a vector of a given size.
97template <class T>
98dense_vector_adaptor<T, continuous_dense_tag, cpu_tag> adapt_vector(std::size_t size, T * v, std::size_t stride = 1){
99 return dense_vector_adaptor<T, continuous_dense_tag, cpu_tag>(v,size, stride);
100}
101
102/// \brief Converts a C-style array into a vector.
103template <class T, std::size_t N>
104dense_vector_adaptor<T, continuous_dense_tag, cpu_tag> adapt_vector(T (&array)[N]){
105 return dense_vector_adaptor<T, continuous_dense_tag, cpu_tag>(array,N, 1);
106}
107
108/// \brief Converts a chunk of memory into a matrix of given size.
109template <class T>
110dense_matrix_adaptor<T, row_major, continuous_dense_tag, cpu_tag> adapt_matrix(std::size_t size1, std::size_t size2, T* data){
111 return dense_matrix_adaptor<T, row_major, continuous_dense_tag, cpu_tag>(data,size1, size2);
112}
113
114/// \brief Converts a 2D C-style array into a matrix of given size.
115template <class T, std::size_t M, std::size_t N>
116dense_matrix_adaptor<T, row_major, continuous_dense_tag, cpu_tag> adapt_matrix(T (&array)[M][N]){
117 return dense_matrix_adaptor<T, row_major, continuous_dense_tag, cpu_tag>(&(array[0][0]),M,N);
118}
119
120///////////////////////////////////
121// Traits
122///////////////////////////////////
123
124template<class T, class Device>
125struct vector_temporary_type<T,dense_tag, Device>{
126 typedef vector<T, Device> type;
127};
128
129template<class T, class Device>
130struct vector_temporary_type<T,continuous_dense_tag, Device>{
131 typedef vector<T, Device> type;
132};
133
134template<class T, class L, class Device>
135struct matrix_temporary_type<T,L,dense_tag, Device>{
136 typedef matrix<T,L, Device> type;
137};
138template<class T, class L, class Device>
139struct matrix_temporary_type<T,L,continuous_dense_tag, Device>{
140 typedef matrix<T,L, Device> type;
141};
142
143template<class T, class Device>
144struct matrix_temporary_type<T,unknown_orientation,dense_tag, Device>{
145 typedef matrix<T,row_major, Device> type;
146};
147
148template<class T, class Device>
149struct matrix_temporary_type<T,unknown_orientation,continuous_dense_tag, Device>{
150 typedef matrix<T,row_major, Device> type;
151};
152
153//////////////////////////////////
154//////Expression Traits
155///////////////////////////////////
156
157namespace detail{
158
159
160///////////////////////////////////////////////////
161//////Traits For Proxy Expressions
162///////////////////////////////////////////////////
163
164
165////////////////////////VECTOR RANGE//////////////////////
166template<class T, class Tag, class Device>
167struct vector_range_optimizer<dense_vector_adaptor<T, Tag, Device> >{
168 typedef dense_vector_adaptor<T, Tag, Device> type;
169
170 static type create(dense_vector_adaptor<T, Tag, Device> const& m, std::size_t start, std::size_t end){
171 auto const& storage = m.raw_storage();
172 return type(storage.sub_region(start), m.queue(), end - start);
173 }
174};
175
176////////////////////////MATRIX TRANSPOSE//////////////////////
177template<class T, class Orientation, class Tag, class Device>
178struct matrix_transpose_optimizer<dense_matrix_adaptor<T,Orientation, Tag, Device> >{
179 typedef dense_matrix_adaptor<T,typename Orientation::transposed_orientation, Tag, Device> type;
180
181 static type create(dense_matrix_adaptor<T,Orientation, Tag, Device> const& m){
182 return type(m.raw_storage(), m.queue(), m.size2(), m.size1());
183 }
184};
185
186template<class T, class Orientation, class Triangular, class Device>
187struct matrix_transpose_optimizer<dense_triangular_proxy<T, Orientation, Triangular, Device> >{
188 typedef dense_triangular_proxy<T, typename Orientation::transposed_orientation, Triangular, Device> type;
189
190 static type create(dense_triangular_proxy<T, Orientation, Triangular, Device> const& m){
191 return type(m.raw_storage(), m.queue(), m.size2(), m.size1());
192 }
193};
194
195////////////////////////MATRIX ROW//////////////////////
196template<class T, class Orientation, class Tag, class Device>
197struct matrix_row_optimizer<dense_matrix_adaptor<T,Orientation, Tag, Device> >{
198 typedef typename std::conditional<std::is_same<Orientation, row_major>::value, Tag, dense_tag>::type proxy_tag;
199 typedef dense_vector_adaptor<T, proxy_tag, Device> type;
200
201 static type create(dense_matrix_adaptor<T,Orientation, Tag, Device> const& m, std::size_t i){
202 auto const& storage = m.raw_storage();
203 return type(storage.row(i, Orientation()), m.queue(), m.size2());
204 }
205};
206
207
208////////////////////////MATRIX RANGE//////////////////////
209template<class T, class Orientation, class Tag, class Device>
210struct matrix_range_optimizer<dense_matrix_adaptor<T,Orientation, Tag, Device> >{
211 typedef dense_matrix_adaptor<T, Orientation, dense_tag, Device> type;
212
213 static type create(dense_matrix_adaptor<T,Orientation, Tag, Device> const& m,
214 std::size_t start1, std::size_t end1,
215 std::size_t start2, std::size_t end2
216 ){
217 auto const& storage = m.raw_storage();
218 return type(storage.sub_region(start1, start2, Orientation()), m.queue(), end1-start1, end2-start2);
219 }
220};
221////////////////////////MATRIX ROWS//////////////////////
222template<class T, class Orientation, class Tag, class Device>
223struct matrix_rows_optimizer<dense_matrix_adaptor<T,Orientation, Tag, Device> >{
224 typedef typename std::conditional<
225 std::is_same<Orientation, row_major>::value,
226 Tag,
227 dense_tag
228 >::type proxy_tag;
229 typedef dense_matrix_adaptor<T, Orientation, proxy_tag, Device> type;
230
231 static type create(dense_matrix_adaptor<T,Orientation, Tag, Device> const& m,
232 std::size_t start, std::size_t end
233 ){
234 auto const& storage = m.raw_storage();
235 return type(storage.sub_rows(start, Orientation()), m.queue(), end - start, m.size2());
236 }
237};
238
239////////////////////////MATRIX DIAGONAL//////////////////////
240template<class T, class Orientation, class Tag, class Device>
241struct matrix_diagonal_optimizer<dense_matrix_adaptor<T,Orientation, Tag, Device> >{
242 typedef dense_vector_adaptor<T, dense_tag, Device> type;
243
244 static type create(dense_matrix_adaptor<T,Orientation, Tag, Device> const& m){
245 return type(m.raw_storage().diag(), m.queue(), std::min(m.size1(), m.size2()));
246 }
247};
248
249////////////////////////LINEARIZED MATRIX//////////////////////
250
251template<class T, class Orientation, class Device>
252struct linearized_matrix_optimizer<dense_matrix_adaptor<T,Orientation, continuous_dense_tag, Device> >{
253 typedef dense_vector_adaptor<T, continuous_dense_tag, Device> type;
254
255 static type create(dense_matrix_adaptor<T,Orientation, continuous_dense_tag, Device> const& m){
256 return type(m.raw_storage().linear(), m.queue(), m.size1() * m.size2());
257 }
258};
259
260
261////////////////////////TO TRIANGULAR//////////////////////
262
263template<class T, class Orientation, class Tag, class Device, class Triangular>
264struct triangular_proxy_optimizer<dense_matrix_adaptor<T,Orientation, Tag, Device>, Triangular >{
265 typedef dense_triangular_proxy<T, Orientation, Triangular, Device> type;
266
267 static type create(dense_matrix_adaptor<T,Orientation, Tag, Device> const& m){
268 return type(m.raw_storage(), m.queue(), m.size1(), m.size2());
269 }
270};
271
272
273}
274
275}
276
277//include device dependent implementations
278#include "cpu/dense.hpp"
279#ifdef REMORA_USE_GPU
280#include "gpu/dense.hpp"
281#endif
282
283#endif