/*! * \brief Implements the Dense storage vector and matrices * * \author O. Krause * \date 2014 * * * \par Copyright 1995-2015 Shark Development Team * *

* This file is part of Shark. * * * Shark is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Shark is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Shark. If not, see . * */ #ifndef REMORA_DENSE_HPP #define REMORA_DENSE_HPP #include "expression_types.hpp" #include "detail/traits.hpp" #include "detail/proxy_optimizers_fwd.hpp" namespace remora{ /// \brief A dense vector of values of type \c T. /// /// 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 /// to the \f$i\f$-th element of the container. /// The tag descripes whether the vector is residing on a cpu or gpu which change its semantics. /// /// \tparam T the type of object stored in the matrix (like double, float, complex, etc...) /// \tparam Device the device this vector lives on, the default is cpu_tag for a cpu vector template class vector; /// \brief A dense matrix of values of type \c T. /// /// 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 /// 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 /// the container for column major orientation. In a dense matrix all elements are represented in memory in a /// contiguous chunk of memory by definition. /// /// Orientation can also be specified, otherwise a \c row_major is used. /// /// \tparam T the type of object stored in the matrix (like double, float, complex, etc...) /// \tparam Orientation the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major /// \tparam Device the device this matrix lives on, the default is cpu_tag for a cpu matrix template class matrix; /// \brief A proxy to a dense vector of values of type \c T. /// /// Using external memory providing by another vector, references a part of the vector. /// The referenced region is not required to be consecutive, i.e. elements can have a stride larger than one /// /// \tparam T the type of object stored in the matrix (like double, float, complex, etc...) /// \tparam Tag the storage tag. dense_tag by default and continuous_dense_tag if stride is guarantueed to be 1. /// \tparam Device the device this vector lives on, the default is cpu_tag for a cpu vector template class dense_vector_adaptor; /// \brief A proxy to a dense matrix of values of type \c T. /// /// Using external memory providing by another matrix, references a subrange of the matrix /// The referenced region is not required to be consecutive, i.e. a subregion of a matrix can be used /// However, either the row or column indices must be consecutive /// /// \tparam T the type of object stored in the matrix (like double, float, complex, etc...) /// \tparam Orientation the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major /// \tparam Tag the storage tag. dense_tag by default and continuous_dense_tag if the memory region referenced is continuous. /// \tparam Device the device this vector lives on, the default is cpu_tag for a cpu vector template class dense_matrix_adaptor; template class dense_triangular_proxy; /////////////////////////////////// // Adapt memory as vector /////////////////////////////////// /// \brief Converts a chunk of memory into a vector of a given size. template dense_vector_adaptor adapt_vector(std::size_t size, T * v, std::size_t stride = 1){ return dense_vector_adaptor(v,size, stride); } /// \brief Converts a C-style array into a vector. template dense_vector_adaptor adapt_vector(T (&array)[N]){ return dense_vector_adaptor(array,N, 1); } /// \brief Converts a chunk of memory into a matrix of given size. template dense_matrix_adaptor adapt_matrix(std::size_t size1, std::size_t size2, T* data){ return dense_matrix_adaptor(data,size1, size2); } /// \brief Converts a 2D C-style array into a matrix of given size. template dense_matrix_adaptor adapt_matrix(T (&array)[M][N]){ return dense_matrix_adaptor(&(array[0][0]),M,N); } /////////////////////////////////// // Traits /////////////////////////////////// template struct vector_temporary_type{ typedef vector type; }; template struct vector_temporary_type{ typedef vector type; }; template struct matrix_temporary_type{ typedef matrix type; }; template struct matrix_temporary_type{ typedef matrix type; }; template struct matrix_temporary_type{ typedef matrix type; }; template struct matrix_temporary_type{ typedef matrix type; }; ////////////////////////////////// //////Expression Traits /////////////////////////////////// namespace detail{ /////////////////////////////////////////////////// //////Traits For Proxy Expressions /////////////////////////////////////////////////// ////////////////////////VECTOR RANGE////////////////////// template struct vector_range_optimizer >{ typedef dense_vector_adaptor type; static type create(dense_vector_adaptor const& m, std::size_t start, std::size_t end){ auto const& storage = m.raw_storage(); return type(storage.sub_region(start), m.queue(), end - start); } }; ////////////////////////MATRIX TRANSPOSE////////////////////// template struct matrix_transpose_optimizer >{ typedef dense_matrix_adaptor type; static type create(dense_matrix_adaptor const& m){ return type(m.raw_storage(), m.queue(), m.size2(), m.size1()); } }; template struct matrix_transpose_optimizer >{ typedef dense_triangular_proxy type; static type create(dense_triangular_proxy const& m){ return type(m.raw_storage(), m.queue(), m.size2(), m.size1()); } }; ////////////////////////MATRIX ROW////////////////////// template struct matrix_row_optimizer >{ typedef typename std::conditional::value, Tag, dense_tag>::type proxy_tag; typedef dense_vector_adaptor type; static type create(dense_matrix_adaptor const& m, std::size_t i){ auto const& storage = m.raw_storage(); return type(storage.row(i, Orientation()), m.queue(), m.size2()); } }; ////////////////////////MATRIX RANGE////////////////////// template struct matrix_range_optimizer >{ typedef dense_matrix_adaptor type; static type create(dense_matrix_adaptor const& m, std::size_t start1, std::size_t end1, std::size_t start2, std::size_t end2 ){ auto const& storage = m.raw_storage(); return type(storage.sub_region(start1, start2, Orientation()), m.queue(), end1-start1, end2-start2); } }; ////////////////////////MATRIX ROWS////////////////////// template struct matrix_rows_optimizer >{ typedef typename std::conditional< std::is_same::value, Tag, dense_tag >::type proxy_tag; typedef dense_matrix_adaptor type; static type create(dense_matrix_adaptor const& m, std::size_t start, std::size_t end ){ auto const& storage = m.raw_storage(); return type(storage.sub_rows(start, Orientation()), m.queue(), end - start, m.size2()); } }; ////////////////////////MATRIX DIAGONAL////////////////////// template struct matrix_diagonal_optimizer >{ typedef dense_vector_adaptor type; static type create(dense_matrix_adaptor const& m){ return type(m.raw_storage().diag(), m.queue(), std::min(m.size1(), m.size2())); } }; ////////////////////////LINEARIZED MATRIX////////////////////// template struct linearized_matrix_optimizer >{ typedef dense_vector_adaptor type; static type create(dense_matrix_adaptor const& m){ return type(m.raw_storage().linear(), m.queue(), m.size1() * m.size2()); } }; ////////////////////////TO TRIANGULAR////////////////////// template struct triangular_proxy_optimizer, Triangular >{ typedef dense_triangular_proxy type; static type create(dense_matrix_adaptor const& m){ return type(m.raw_storage(), m.queue(), m.size1(), m.size2()); } }; } } //include device dependent implementations #include "cpu/dense.hpp" #ifdef REMORA_USE_GPU #include "gpu/dense.hpp" #endif #endif