/*!
* \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