mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-14 01:35:36 +00:00
Changes after review with Peter
This commit is contained in:
parent
73cdca3973
commit
584fa0a633
@ -36,41 +36,41 @@ Author: Guido Cossu <guido.cossu@ed.ac.uk>
|
|||||||
#include <Grid/Eigen/unsupported/CXX11/Tensor>
|
#include <Grid/Eigen/unsupported/CXX11/Tensor>
|
||||||
|
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
// TODO Support Grid::complex from GPU port
|
|
||||||
//template<typename T> using Grid_complex = std::complex<T>;
|
|
||||||
|
|
||||||
// Returns original type, except for Grid_complex, where it returns the underlying type
|
|
||||||
//template<typename T> struct RealType { using type = T; };
|
|
||||||
//template<typename T> struct RealType<Grid_complex<T>> { using type = T; };
|
|
||||||
|
|
||||||
namespace EigenIO {
|
namespace EigenIO {
|
||||||
//template<typename T> struct is_complex : public std::false_type {};
|
// EigenIO works for scalars that are not just Grid supported scalars
|
||||||
//template<typename T> struct is_complex<Grid_complex<T>>
|
template<typename T, typename V = void> struct is_complex : public std::false_type {};
|
||||||
//: std::integral_constant<bool, std::is_arithmetic<T>::value> {};
|
// Support all complex types (not just Grid complex types) - even if the definitions overlap (!)
|
||||||
|
template<typename T> struct is_complex< T , typename
|
||||||
|
std::enable_if< ::Grid::is_complex< T >::value>::type> : public std::true_type {};
|
||||||
|
template<typename T> struct is_complex<std::complex<T>, typename
|
||||||
|
std::enable_if<!::Grid::is_complex<std::complex<T>>::value>::type> : public std::true_type {};
|
||||||
|
|
||||||
// Eigen tensors can be composed of arithmetic scalar and complex types
|
// Helpers to support I/O for Eigen tensors of arithmetic scalars, complex types, or Grid tensors
|
||||||
template<typename T> struct is_scalar : std::integral_constant<bool,
|
template<typename T, typename V = void> struct is_scalar : public std::false_type {};
|
||||||
std::is_arithmetic<T>::value || is_complex<T>::value> {};
|
template<typename T> struct is_scalar<T, typename std::enable_if<std::is_arithmetic<T>::value || is_complex<T>::value>::type> : public std::true_type {};
|
||||||
|
|
||||||
// Eigen tensors can also be composed of a limited number of containers
|
|
||||||
// NB: grid tensors (iScalar, iVector, iMatrix) have stricter limits on complex types
|
|
||||||
//template <typename T> struct is_container : public std::false_type {};
|
|
||||||
//template <typename T> struct is_container<iScalar<T>> : public std::true_type {};
|
|
||||||
//template <typename T, int N> struct is_container<iVector<T, N>> : public std::true_type {};
|
|
||||||
//template <typename T, int N> struct is_container<iMatrix<T, N>> : public std::true_type {};
|
|
||||||
//template <typename T, std::size_t N> struct is_container<std::array<T, N>> : public std::true_type {};
|
|
||||||
|
|
||||||
// Is this an Eigen tensor
|
// Is this an Eigen tensor
|
||||||
template<typename T> struct is_tensor : std::integral_constant<bool,
|
template<typename T> struct is_tensor : std::integral_constant<bool,
|
||||||
std::is_base_of<Eigen::TensorBase<T, Eigen::ReadOnlyAccessors>, T>::value> {};
|
std::is_base_of<Eigen::TensorBase<T, Eigen::ReadOnlyAccessors>, T>::value> {};
|
||||||
|
|
||||||
// Is this an Eigen tensor of a supported scalar
|
// Is this an Eigen tensor of a supported scalar
|
||||||
template<typename T, typename C = void> struct is_tensor_of_scalar : public std::false_type {};
|
template<typename T, typename V = void> struct is_tensor_of_scalar : public std::false_type {};
|
||||||
template<typename T> struct is_tensor_of_scalar<T, typename std::enable_if<is_tensor<T>::value && is_scalar<typename T::Scalar>::value, void>::type> : public std::true_type {};
|
template<typename T> struct is_tensor_of_scalar<T, typename std::enable_if<is_tensor<T>::value && is_scalar<typename T::Scalar>::value>::type> : public std::true_type {};
|
||||||
|
|
||||||
// Is this an Eigen tensor of a supported container
|
// Is this an Eigen tensor of a supported container
|
||||||
template<typename T, typename C = void> struct is_tensor_of_container : public std::false_type {};
|
template<typename T, typename V = void> struct is_tensor_of_container : public std::false_type {};
|
||||||
template<typename T> struct is_tensor_of_container<T, typename std::enable_if<is_tensor<T>::value && isGridTensor<typename T::Scalar>::value, void>::type> : public std::true_type {};
|
template<typename T> struct is_tensor_of_container<T, typename std::enable_if<is_tensor<T>::value && isGridTensor<typename T::Scalar>::value>::type> : public std::true_type {};
|
||||||
|
|
||||||
|
// Traits are the default for scalars, or come from GridTypeMapper for GridTensors
|
||||||
|
template<typename T, typename V = void> struct Traits {};
|
||||||
|
template<typename T> struct Traits<T, typename std::enable_if<is_tensor_of_scalar<T>::value>::type> : public GridTypeMapper_Base {
|
||||||
|
using scalar_type = typename T::Scalar;
|
||||||
|
static constexpr bool is_complex = ::Grid::EigenIO::is_complex<scalar_type>::value;
|
||||||
|
};
|
||||||
|
template<typename T> struct Traits<T, typename std::enable_if<is_tensor_of_container<T>::value>::type> : public GridTypeMapper<typename T::Scalar> {
|
||||||
|
using scalar_type = typename GridTypeMapper<typename T::Scalar>::scalar_type;
|
||||||
|
static constexpr bool is_complex = ::Grid::EigenIO::is_complex<scalar_type>::value;
|
||||||
|
};
|
||||||
|
|
||||||
// Is this a fixed-size Eigen tensor
|
// Is this a fixed-size Eigen tensor
|
||||||
template<typename T> struct is_tensor_fixed : public std::false_type {};
|
template<typename T> struct is_tensor_fixed : public std::false_type {};
|
||||||
@ -84,83 +84,9 @@ namespace Grid {
|
|||||||
: public std::true_type {};
|
: public std::true_type {};
|
||||||
|
|
||||||
// Is this a variable-size Eigen tensor
|
// Is this a variable-size Eigen tensor
|
||||||
template<typename T, typename C = void> struct is_tensor_variable : public std::false_type {};
|
template<typename T, typename V = void> struct is_tensor_variable : public std::false_type {};
|
||||||
template<typename T> struct is_tensor_variable<T, typename std::enable_if<is_tensor<T>::value
|
template<typename T> struct is_tensor_variable<T, typename std::enable_if<is_tensor<T>::value
|
||||||
&& !is_tensor_fixed<T>::value, void>::type> : public std::true_type {};
|
&& !is_tensor_fixed<T>::value>::type> : public std::true_type {};
|
||||||
|
|
||||||
// These traits describe the Eigen tensor scalar and container objects supported for IO
|
|
||||||
// Containers are arbitrarily deeply nested compositions of fixed size objects,
|
|
||||||
// ... grid tensors (iScalar, iVector, and iMatrix) and std::array
|
|
||||||
// EigenIO::Traits are not defined for Eigen tensors, but rather their top-level scalar
|
|
||||||
// This is because Eigen tensors have a dynamic size flavour, but the scalars are all fixed size
|
|
||||||
// This allows the traits to all be defined as constexpr
|
|
||||||
/*template <typename T, typename C = void> struct Traits {}; // C needed for specialisation
|
|
||||||
// This defines the bottom level - i.e. it's a description of the underlying scalar
|
|
||||||
template <typename T> struct Traits<T, typename std::enable_if<is_scalar<T>::value, void>::type> {
|
|
||||||
using scalar_type = T; // Type of the underlying scalar
|
|
||||||
using scalar_real = typename RealPart<scalar_type>::type; // real type underlying scalar_type
|
|
||||||
static constexpr unsigned int rank = 0; // The rank of the grid tensor (i.e. how many indices used)
|
|
||||||
//static constexpr unsigned int rank_non_trivial = 0; // As per rank, but excludes those of dimension 1
|
|
||||||
static constexpr unsigned int count = 1; // total number of elements (i.e. product of dimensions)
|
|
||||||
static constexpr std::size_t scalar_size = sizeof(T); // Size of the underlying scalar in bytes
|
|
||||||
static constexpr std::size_t size = scalar_size * count; // total size of elements in bytes
|
|
||||||
static constexpr std::size_t Dimension(unsigned int dim) { return 0; } // Dimension size
|
|
||||||
//static constexpr std::size_t DimensionNT(unsigned int dim) { return 0; } // non-trivial dim size
|
|
||||||
// e.g. iScalar<iVector<Complex,1>>
|
|
||||||
// rank = 2
|
|
||||||
// rank_non_trivial = 0
|
|
||||||
// count = 1
|
|
||||||
// e.g. iVector<iMatrix<Complex,3>,1>
|
|
||||||
// rank = 3
|
|
||||||
// rank_non_trivial = 2
|
|
||||||
// count = 9
|
|
||||||
// e.g. iScalar<iVector<iMatrix<Complex,3>,4>>
|
|
||||||
// rank = 4
|
|
||||||
// rank_non_trivial = 3
|
|
||||||
// count = 36
|
|
||||||
};
|
|
||||||
template <typename T> struct Traits<iScalar<T>> {
|
|
||||||
using scalar_type = typename Traits<T>::scalar_type;
|
|
||||||
using scalar_real = typename RealPart<scalar_type>::type;
|
|
||||||
static constexpr unsigned int rank = 1 + Traits<T>::rank;
|
|
||||||
//static constexpr unsigned int rank_non_trivial = 0 + Traits<T>::rank_non_trivial;
|
|
||||||
static constexpr unsigned int count = 1 * Traits<T>::count;
|
|
||||||
static constexpr std::size_t scalar_size = Traits<T>::scalar_size;
|
|
||||||
static constexpr std::size_t size = scalar_size * count;
|
|
||||||
static constexpr std::size_t Dimension(unsigned int dim) {
|
|
||||||
return ( dim == 0 ) ? 1 : Traits<T>::Dimension(dim - 1); }
|
|
||||||
//static constexpr std::size_t DimensionNT(unsigned int dim) {
|
|
||||||
//return Traits<T>::DimensionNT(dim); }
|
|
||||||
};
|
|
||||||
template <typename T, int N> struct Traits<iVector<T, N>> {
|
|
||||||
using scalar_type = typename Traits<T>::scalar_type;
|
|
||||||
using scalar_real = typename RealPart<scalar_type>::type;
|
|
||||||
static constexpr unsigned int rank = 1 + Traits<T>::rank;
|
|
||||||
//static constexpr unsigned int rank_non_trivial = (N>1 ? 1 : 0) + Traits<T>::rank_non_trivial;
|
|
||||||
static constexpr unsigned int count = N * Traits<T>::count;
|
|
||||||
static constexpr std::size_t scalar_size = Traits<T>::scalar_size;
|
|
||||||
static constexpr std::size_t size = scalar_size * count;
|
|
||||||
static constexpr std::size_t Dimension(unsigned int dim) {
|
|
||||||
return ( dim == 0 ) ? N : Traits<T>::Dimension(dim - 1); }
|
|
||||||
//static constexpr std::size_t DimensionNT(unsigned int dim) {
|
|
||||||
//return ( N == 1 ) ? Traits<T>::DimensionNT(dim) : ( dim == 0 ) ? N : Traits<T>::DimensionNT(dim - 1);
|
|
||||||
//}
|
|
||||||
};
|
|
||||||
template <typename T, int N> struct Traits<iMatrix<T, N>> {
|
|
||||||
using scalar_type = typename Traits<T>::scalar_type;
|
|
||||||
using scalar_real = typename RealPart<scalar_type>::type;
|
|
||||||
static constexpr unsigned int rank = 2 + Traits<T>::rank;
|
|
||||||
//static constexpr unsigned int rank_non_trivial = (N>1 ? 2 : 0) + Traits<T>::rank_non_trivial;
|
|
||||||
static constexpr unsigned int count = N * N * Traits<T>::count;
|
|
||||||
static constexpr std::size_t scalar_size = Traits<T>::scalar_size;
|
|
||||||
static constexpr std::size_t size = scalar_size * count;
|
|
||||||
static constexpr std::size_t Dimension(unsigned int dim) {
|
|
||||||
return ( dim == 0 || dim == 1 ) ? N : Traits<T>::Dimension(dim - 2); }
|
|
||||||
//static constexpr std::size_t DimensionNT(unsigned int dim) {
|
|
||||||
//return ( N == 1 ) ? Traits<T>::DimensionNT(dim) : ( dim == 0 || dim == 1 ) ? N : Traits<T>::DimensionNT(dim - 2);
|
|
||||||
//}
|
|
||||||
};
|
|
||||||
template <typename T, int N> struct Traits<std::array<T, N>> : Traits<iVector<T, N>> {};*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abstract writer/reader classes ////////////////////////////////////////////
|
// Abstract writer/reader classes ////////////////////////////////////////////
|
||||||
@ -177,11 +103,10 @@ namespace Grid {
|
|||||||
void push(const std::string &s);
|
void push(const std::string &s);
|
||||||
void pop(void);
|
void pop(void);
|
||||||
template <typename U>
|
template <typename U>
|
||||||
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
typename std::enable_if<std::is_base_of<Serializable, U>::value>::type
|
||||||
write(const std::string& s, const U &output);
|
write(const std::string& s, const U &output);
|
||||||
template <typename U>
|
template <typename U>
|
||||||
typename std::enable_if<!std::is_base_of<Serializable, U>::value
|
typename std::enable_if<!std::is_base_of<Serializable, U>::value && !EigenIO::is_tensor<U>::value>::type
|
||||||
&& !EigenIO::is_tensor<U>::value, void>::type
|
|
||||||
write(const std::string& s, const U &output);
|
write(const std::string& s, const U &output);
|
||||||
template <typename U>
|
template <typename U>
|
||||||
void write(const std::string &s, const iScalar<U> &output);
|
void write(const std::string &s, const iScalar<U> &output);
|
||||||
@ -190,19 +115,21 @@ namespace Grid {
|
|||||||
template <typename U, int N>
|
template <typename U, int N>
|
||||||
void write(const std::string &s, const iMatrix<U, N> &output);
|
void write(const std::string &s, const iMatrix<U, N> &output);
|
||||||
template <typename ETensor>
|
template <typename ETensor>
|
||||||
typename std::enable_if<EigenIO::is_tensor<ETensor>::value, void>::type
|
typename std::enable_if<EigenIO::is_tensor<ETensor>::value>::type
|
||||||
write(const std::string &s, const ETensor &output);
|
write(const std::string &s, const ETensor &output);
|
||||||
|
|
||||||
// Helper functions for Scalar vs Container specialisations
|
// Helper functions for Scalar vs Container specialisations
|
||||||
template <typename ETensor>
|
template <typename ETensor>
|
||||||
inline typename std::enable_if<EigenIO::is_tensor_of_scalar<ETensor>::value, const typename GridTypeMapper<typename ETensor::Scalar>::scalar_type *>::type
|
inline typename std::enable_if<EigenIO::is_tensor_of_scalar<ETensor>::value,
|
||||||
|
const typename ETensor::Scalar *>::type
|
||||||
getFirstScalar(const ETensor &output)
|
getFirstScalar(const ETensor &output)
|
||||||
{
|
{
|
||||||
return output.data();
|
return output.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ETensor>
|
template <typename ETensor>
|
||||||
inline typename std::enable_if<EigenIO::is_tensor_of_container<ETensor>::value, const typename GridTypeMapper<typename ETensor::Scalar>::scalar_type *>::type
|
inline typename std::enable_if<EigenIO::is_tensor_of_container<ETensor>::value,
|
||||||
|
const typename EigenIO::Traits<ETensor>::scalar_type *>::type
|
||||||
getFirstScalar(const ETensor &output)
|
getFirstScalar(const ETensor &output)
|
||||||
{
|
{
|
||||||
return output.data()->begin();
|
return output.data()->begin();
|
||||||
@ -210,7 +137,7 @@ namespace Grid {
|
|||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
inline typename std::enable_if<EigenIO::is_scalar<S>::value, void>::type
|
inline typename std::enable_if<EigenIO::is_scalar<S>::value, void>::type
|
||||||
copyScalars(typename GridTypeMapper<S>::scalar_type * &pCopy, const S &Source)
|
copyScalars(S * &pCopy, const S &Source)
|
||||||
{
|
{
|
||||||
* pCopy ++ = Source;
|
* pCopy ++ = Source;
|
||||||
}
|
}
|
||||||
@ -268,7 +195,7 @@ namespace Grid {
|
|||||||
// Helper functions for Scalar vs Container specialisations
|
// Helper functions for Scalar vs Container specialisations
|
||||||
template <typename S>
|
template <typename S>
|
||||||
inline typename std::enable_if<EigenIO::is_scalar<S>::value, void>::type
|
inline typename std::enable_if<EigenIO::is_scalar<S>::value, void>::type
|
||||||
copyScalars(S &Dest, const typename GridTypeMapper<S>::scalar_type * &pSource)
|
copyScalars(S &Dest, const S * &pSource)
|
||||||
{
|
{
|
||||||
Dest = * pSource ++;
|
Dest = * pSource ++;
|
||||||
}
|
}
|
||||||
@ -362,7 +289,7 @@ namespace Grid {
|
|||||||
{
|
{
|
||||||
using Index = typename ETensor::Index;
|
using Index = typename ETensor::Index;
|
||||||
using Container = typename ETensor::Scalar; // NB: could be same as scalar
|
using Container = typename ETensor::Scalar; // NB: could be same as scalar
|
||||||
using Traits = GridTypeMapper<Container>;
|
using Traits = EigenIO::Traits<ETensor>;
|
||||||
using Scalar = typename Traits::scalar_type; // type of the underlying scalar
|
using Scalar = typename Traits::scalar_type; // type of the underlying scalar
|
||||||
constexpr unsigned int TensorRank{ETensor::NumIndices};
|
constexpr unsigned int TensorRank{ETensor::NumIndices};
|
||||||
constexpr unsigned int ContainerRank{Traits::Rank}; // Only non-zero for containers
|
constexpr unsigned int ContainerRank{Traits::Rank}; // Only non-zero for containers
|
||||||
@ -386,10 +313,6 @@ namespace Grid {
|
|||||||
Scalar * pCopyBuffer = nullptr;
|
Scalar * pCopyBuffer = nullptr;
|
||||||
const Index TotalNumElements = NumElements * Traits::count;
|
const Index TotalNumElements = NumElements * Traits::count;
|
||||||
if( !CopyData ) {
|
if( !CopyData ) {
|
||||||
/*if constexpr ( ContainerRank == 0 )
|
|
||||||
pWriteBuffer = output.data();
|
|
||||||
else
|
|
||||||
pWriteBuffer = output.data()->begin();*/
|
|
||||||
pWriteBuffer = getFirstScalar( output );
|
pWriteBuffer = getFirstScalar( output );
|
||||||
} else {
|
} else {
|
||||||
// Regardless of the Eigen::Tensor storage order, the copy will be Row Major
|
// Regardless of the Eigen::Tensor storage order, the copy will be Row Major
|
||||||
@ -400,12 +323,6 @@ namespace Grid {
|
|||||||
for( auto &idx : MyIndex ) idx = 0;
|
for( auto &idx : MyIndex ) idx = 0;
|
||||||
for( auto n = 0; n < NumElements; n++ ) {
|
for( auto n = 0; n < NumElements; n++ ) {
|
||||||
const Container & c = output( MyIndex );
|
const Container & c = output( MyIndex );
|
||||||
/*if constexpr ( ContainerRank == 0 )
|
|
||||||
* pCopy ++ = c;
|
|
||||||
else {
|
|
||||||
for( const Scalar &Source : c )
|
|
||||||
* pCopy ++ = Source;
|
|
||||||
}*/
|
|
||||||
copyScalars( pCopy, c );
|
copyScalars( pCopy, c );
|
||||||
// Now increment the index
|
// Now increment the index
|
||||||
for( int i = output.NumDimensions - 1; i >= 0 && ++MyIndex[i] == output.dimension(i); i-- )
|
for( int i = output.NumDimensions - 1; i >= 0 && ++MyIndex[i] == output.dimension(i); i-- )
|
||||||
@ -513,7 +430,7 @@ namespace Grid {
|
|||||||
{
|
{
|
||||||
using Index = typename ETensor::Index;
|
using Index = typename ETensor::Index;
|
||||||
using Container = typename ETensor::Scalar; // NB: could be same as scalar
|
using Container = typename ETensor::Scalar; // NB: could be same as scalar
|
||||||
using Traits = GridTypeMapper<Container>;
|
using Traits = EigenIO::Traits<ETensor>;
|
||||||
using Scalar = typename Traits::scalar_type; // type of the underlying scalar
|
using Scalar = typename Traits::scalar_type; // type of the underlying scalar
|
||||||
constexpr unsigned int TensorRank{ETensor::NumIndices};
|
constexpr unsigned int TensorRank{ETensor::NumIndices};
|
||||||
constexpr unsigned int ContainerRank{Traits::Rank}; // Only non-zero for containers
|
constexpr unsigned int ContainerRank{Traits::Rank}; // Only non-zero for containers
|
||||||
|
@ -865,8 +865,10 @@ template <typename T>
|
|||||||
struct is_simd : public std::false_type {};
|
struct is_simd : public std::false_type {};
|
||||||
template <> struct is_simd<vRealF> : public std::true_type {};
|
template <> struct is_simd<vRealF> : public std::true_type {};
|
||||||
template <> struct is_simd<vRealD> : public std::true_type {};
|
template <> struct is_simd<vRealD> : public std::true_type {};
|
||||||
|
template <> struct is_simd<vRealH> : public std::true_type {};
|
||||||
template <> struct is_simd<vComplexF> : public std::true_type {};
|
template <> struct is_simd<vComplexF> : public std::true_type {};
|
||||||
template <> struct is_simd<vComplexD> : public std::true_type {};
|
template <> struct is_simd<vComplexD> : public std::true_type {};
|
||||||
|
template <> struct is_simd<vComplexH> : public std::true_type {};
|
||||||
template <> struct is_simd<vInteger> : public std::true_type {};
|
template <> struct is_simd<vInteger> : public std::true_type {};
|
||||||
|
|
||||||
template <typename T> using IfSimd = Invoke<std::enable_if<is_simd<T>::value, int> >;
|
template <typename T> using IfSimd = Invoke<std::enable_if<is_simd<T>::value, int> >;
|
||||||
|
@ -42,27 +42,26 @@ namespace Grid {
|
|||||||
//
|
//
|
||||||
class GridTensorBase {};
|
class GridTensorBase {};
|
||||||
|
|
||||||
|
// Too late to remove these traits from Grid Tensors, so inherit from GridTypeMapper
|
||||||
|
#define GridVector_CopyTraits \
|
||||||
|
using element = vtype; \
|
||||||
|
using scalar_type = typename Traits::scalar_type; \
|
||||||
|
using vector_type = typename Traits::vector_type; \
|
||||||
|
using vector_typeD = typename Traits::vector_typeD; \
|
||||||
|
using tensor_reduced = typename Traits::tensor_reduced; \
|
||||||
|
using scalar_object = typename Traits::scalar_object; \
|
||||||
|
using Complexified = typename Traits::Complexified; \
|
||||||
|
using Realified = typename Traits::Realified; \
|
||||||
|
using DoublePrecision = typename Traits::DoublePrecision; \
|
||||||
|
static constexpr int TensorLevel = Traits::TensorLevel
|
||||||
|
|
||||||
template <class vtype>
|
template <class vtype>
|
||||||
class iScalar {
|
class iScalar {
|
||||||
public:
|
public:
|
||||||
vtype _internal;
|
vtype _internal;
|
||||||
|
|
||||||
typedef vtype element;
|
using Traits = GridTypeMapper<iScalar<vtype> >;
|
||||||
typedef typename GridTypeMapper<vtype>::scalar_type scalar_type;
|
GridVector_CopyTraits;
|
||||||
typedef typename GridTypeMapper<vtype>::vector_type vector_type;
|
|
||||||
typedef typename GridTypeMapper<vtype>::vector_typeD vector_typeD;
|
|
||||||
typedef typename GridTypeMapper<vtype>::tensor_reduced tensor_reduced_v;
|
|
||||||
typedef typename GridTypeMapper<vtype>::scalar_object recurse_scalar_object;
|
|
||||||
typedef iScalar<tensor_reduced_v> tensor_reduced;
|
|
||||||
typedef iScalar<recurse_scalar_object> scalar_object;
|
|
||||||
// substitutes a real or complex version with same tensor structure
|
|
||||||
typedef iScalar<typename GridTypeMapper<vtype>::Complexified> Complexified;
|
|
||||||
typedef iScalar<typename GridTypeMapper<vtype>::Realified> Realified;
|
|
||||||
|
|
||||||
// get double precision version
|
|
||||||
typedef iScalar<typename GridTypeMapper<vtype>::DoublePrecision> DoublePrecision;
|
|
||||||
|
|
||||||
static constexpr int TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1;
|
|
||||||
|
|
||||||
// Scalar no action
|
// Scalar no action
|
||||||
// template<int Level> using tensor_reduce_level = typename
|
// template<int Level> using tensor_reduce_level = typename
|
||||||
@ -173,37 +172,10 @@ class iScalar {
|
|||||||
return stream;
|
return stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T = vtype>
|
strong_inline const scalar_type * begin() const { return reinterpret_cast<const scalar_type *>(&_internal); }
|
||||||
typename std::enable_if<!isGridTensor<T>::value, const scalar_type *>::type
|
strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(&_internal); }
|
||||||
strong_inline begin() const { return &_internal; }
|
strong_inline const scalar_type * end() const { return begin() + Traits::count; }
|
||||||
|
strong_inline scalar_type * end() { return begin() + Traits::count; }
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, const scalar_type *>::type
|
|
||||||
strong_inline begin() const { return _internal.begin(); }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<!isGridTensor<T>::value, const scalar_type *>::type
|
|
||||||
strong_inline end() const { return (&_internal) + 1; }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, const scalar_type *>::type
|
|
||||||
strong_inline end() const { return _internal.begin() + sizeof(_internal)/sizeof(scalar_type); }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<!isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline begin() { return &_internal; }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline begin() { return _internal.begin(); }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<!isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline end() { return (&_internal) + 1; }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline end() { return _internal.begin() + sizeof(_internal)/sizeof(scalar_type); }
|
|
||||||
};
|
};
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// Allows to turn scalar<scalar<scalar<double>>>> back to double.
|
// Allows to turn scalar<scalar<scalar<double>>>> back to double.
|
||||||
@ -224,21 +196,8 @@ class iVector {
|
|||||||
public:
|
public:
|
||||||
vtype _internal[N];
|
vtype _internal[N];
|
||||||
|
|
||||||
typedef vtype element;
|
using Traits = GridTypeMapper<iVector<vtype, N> >;
|
||||||
typedef typename GridTypeMapper<vtype>::scalar_type scalar_type;
|
GridVector_CopyTraits;
|
||||||
typedef typename GridTypeMapper<vtype>::vector_type vector_type;
|
|
||||||
typedef typename GridTypeMapper<vtype>::vector_typeD vector_typeD;
|
|
||||||
typedef typename GridTypeMapper<vtype>::tensor_reduced tensor_reduced_v;
|
|
||||||
typedef typename GridTypeMapper<vtype>::scalar_object recurse_scalar_object;
|
|
||||||
typedef iScalar<tensor_reduced_v> tensor_reduced;
|
|
||||||
typedef iVector<recurse_scalar_object, N> scalar_object;
|
|
||||||
|
|
||||||
// substitutes a real or complex version with same tensor structure
|
|
||||||
typedef iVector<typename GridTypeMapper<vtype>::Complexified, N> Complexified;
|
|
||||||
typedef iVector<typename GridTypeMapper<vtype>::Realified, N> Realified;
|
|
||||||
|
|
||||||
// get double precision version
|
|
||||||
typedef iVector<typename GridTypeMapper<vtype>::DoublePrecision, N> DoublePrecision;
|
|
||||||
|
|
||||||
template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
|
template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
|
||||||
* = nullptr>
|
* = nullptr>
|
||||||
@ -248,7 +207,6 @@ class iVector {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr int TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1;
|
|
||||||
iVector(const Zero &z) { *this = zero; };
|
iVector(const Zero &z) { *this = zero; };
|
||||||
iVector() = default;
|
iVector() = default;
|
||||||
/*
|
/*
|
||||||
@ -334,37 +292,10 @@ class iVector {
|
|||||||
// return _internal[i];
|
// return _internal[i];
|
||||||
// }
|
// }
|
||||||
|
|
||||||
template <typename T = vtype>
|
strong_inline const scalar_type * begin() const { return reinterpret_cast<const scalar_type *>(_internal); }
|
||||||
typename std::enable_if<!isGridTensor<T>::value, const scalar_type *>::type
|
strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(_internal); }
|
||||||
strong_inline begin() const { return _internal; }
|
strong_inline const scalar_type * end() const { return begin() + Traits::count; }
|
||||||
|
strong_inline scalar_type * end() { return begin() + Traits::count; }
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, const scalar_type *>::type
|
|
||||||
strong_inline begin() const { return _internal[0].begin(); }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<!isGridTensor<T>::value, const scalar_type *>::type
|
|
||||||
strong_inline end() const { return _internal + N; }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, const scalar_type *>::type
|
|
||||||
strong_inline end() const { return _internal[0].begin() + sizeof(_internal)/sizeof(scalar_type); }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<!isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline begin() { return _internal; }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline begin() { return _internal[0].begin(); }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<!isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline end() { return _internal + N; }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline end() { return _internal[0].begin() + sizeof(_internal)/sizeof(scalar_type); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class vtype, int N>
|
template <class vtype, int N>
|
||||||
@ -372,25 +303,8 @@ class iMatrix {
|
|||||||
public:
|
public:
|
||||||
vtype _internal[N][N];
|
vtype _internal[N][N];
|
||||||
|
|
||||||
typedef vtype element;
|
using Traits = GridTypeMapper<iMatrix<vtype, N> >;
|
||||||
typedef typename GridTypeMapper<vtype>::scalar_type scalar_type;
|
GridVector_CopyTraits;
|
||||||
typedef typename GridTypeMapper<vtype>::vector_type vector_type;
|
|
||||||
typedef typename GridTypeMapper<vtype>::vector_typeD vector_typeD;
|
|
||||||
typedef typename GridTypeMapper<vtype>::tensor_reduced tensor_reduced_v;
|
|
||||||
typedef typename GridTypeMapper<vtype>::scalar_object recurse_scalar_object;
|
|
||||||
|
|
||||||
// substitutes a real or complex version with same tensor structure
|
|
||||||
typedef iMatrix<typename GridTypeMapper<vtype>::Complexified, N> Complexified;
|
|
||||||
typedef iMatrix<typename GridTypeMapper<vtype>::Realified, N> Realified;
|
|
||||||
|
|
||||||
// get double precision version
|
|
||||||
typedef iMatrix<typename GridTypeMapper<vtype>::DoublePrecision, N> DoublePrecision;
|
|
||||||
|
|
||||||
// Tensor removal
|
|
||||||
typedef iScalar<tensor_reduced_v> tensor_reduced;
|
|
||||||
typedef iMatrix<recurse_scalar_object, N> scalar_object;
|
|
||||||
|
|
||||||
static constexpr int TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1;
|
|
||||||
|
|
||||||
iMatrix(const Zero &z) { *this = zero; };
|
iMatrix(const Zero &z) { *this = zero; };
|
||||||
iMatrix() = default;
|
iMatrix() = default;
|
||||||
@ -521,37 +435,10 @@ class iMatrix {
|
|||||||
// return _internal[i][j];
|
// return _internal[i][j];
|
||||||
// }
|
// }
|
||||||
|
|
||||||
template <typename T = vtype>
|
strong_inline const scalar_type * begin() const { return reinterpret_cast<const scalar_type *>(_internal[0]); }
|
||||||
typename std::enable_if<!isGridTensor<T>::value, const scalar_type *>::type
|
strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(_internal[0]); }
|
||||||
strong_inline begin() const { return _internal[0]; }
|
strong_inline const scalar_type * end() const { return begin() + Traits::count; }
|
||||||
|
strong_inline scalar_type * end() { return begin() + Traits::count; }
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, const scalar_type *>::type
|
|
||||||
strong_inline begin() const { return _internal[0][0].begin(); }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<!isGridTensor<T>::value, const scalar_type *>::type
|
|
||||||
strong_inline end() const { return _internal[0] + N * N; }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, const scalar_type *>::type
|
|
||||||
strong_inline end() const { return _internal[0][0].begin() + sizeof(_internal)/sizeof(scalar_type); }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<!isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline begin() { return _internal[0]; }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline begin() { return _internal[0][0].begin(); }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<!isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline end() { return _internal[0] + N * N; }
|
|
||||||
|
|
||||||
template <typename T = vtype>
|
|
||||||
typename std::enable_if<isGridTensor<T>::value, scalar_type *>::type
|
|
||||||
strong_inline end() { return _internal[0][0].begin() + sizeof(_internal)/sizeof(scalar_type); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class v>
|
template <class v>
|
||||||
@ -574,6 +461,3 @@ void vprefetch(const iMatrix<v, N> &vv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
|
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
Author: Christopher Kelly <ckelly@phys.columbia.edu>
|
Author: Christopher Kelly <ckelly@phys.columbia.edu>
|
||||||
|
Author: Michael Marshall <michael.marshall@ed.ac.au>
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
@ -32,14 +33,10 @@ namespace Grid {
|
|||||||
template<class T, int N> class iMatrix;
|
template<class T, int N> class iMatrix;
|
||||||
|
|
||||||
// These are the Grid tensors
|
// These are the Grid tensors
|
||||||
template<typename T> struct isGridTensor
|
template<typename T> struct isGridTensor : public std::false_type { static constexpr bool notvalue = true; };
|
||||||
: public std::false_type { static constexpr bool notvalue = true; };
|
template<class T> struct isGridTensor<iScalar<T>> : public std::true_type { static constexpr bool notvalue = false; };
|
||||||
template<class T> struct isGridTensor<iScalar<T>>
|
template<class T, int N> struct isGridTensor<iVector<T, N>> : public std::true_type { static constexpr bool notvalue = false; };
|
||||||
: public std::true_type { static constexpr bool notvalue = false; };
|
template<class T, int N> struct isGridTensor<iMatrix<T, N>> : public std::true_type { static constexpr bool notvalue = false; };
|
||||||
template<class T, int N> struct isGridTensor<iVector<T, N>>
|
|
||||||
: public std::true_type { static constexpr bool notvalue = false; };
|
|
||||||
template<class T, int N> struct isGridTensor<iMatrix<T, N>>
|
|
||||||
: public std::true_type { static constexpr bool notvalue = false; };
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
// Want to recurse: GridTypeMapper<Matrix<vComplexD> >::scalar_type == ComplexD.
|
// Want to recurse: GridTypeMapper<Matrix<vComplexD> >::scalar_type == ComplexD.
|
||||||
@ -57,20 +54,15 @@ namespace Grid {
|
|||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// This saves repeating common properties for supported Grid Scalar types
|
// This saves repeating common properties for supported Grid Scalar types
|
||||||
template<typename T, typename V=void> struct GridTypeMapper_Base {};
|
|
||||||
// TensorLevel How many nested grid tensors
|
// TensorLevel How many nested grid tensors
|
||||||
// Rank Rank of the grid tensor
|
// Rank Rank of the grid tensor
|
||||||
// count Total number of elements, i.e. product of dimensions
|
// count Total number of elements, i.e. product of dimensions
|
||||||
// scalar_size Size of the underlying fundamental object (tensor_reduced) in bytes
|
|
||||||
// size Total size of all elements in bytes
|
|
||||||
// Dimension(dim) Size of dimension dim
|
// Dimension(dim) Size of dimension dim
|
||||||
template<typename T> struct GridTypeMapper_Base<T> {
|
struct GridTypeMapper_Base {
|
||||||
static constexpr int TensorLevel = 0;
|
static constexpr int TensorLevel = 0;
|
||||||
static constexpr int Rank = 0;
|
static constexpr int Rank = 0;
|
||||||
static constexpr std::size_t count = 1;
|
static constexpr std::size_t count = 1;
|
||||||
static constexpr std::size_t scalar_size = sizeof(T);
|
static constexpr int Dimension(int dim) { return 0; }
|
||||||
static constexpr std::size_t size = scalar_size * count;
|
|
||||||
static constexpr int Dimension(unsigned int dim) { return 0; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -79,7 +71,7 @@ namespace Grid {
|
|||||||
|
|
||||||
template<typename T> struct GridTypeMapper {};
|
template<typename T> struct GridTypeMapper {};
|
||||||
|
|
||||||
template<> struct GridTypeMapper<RealF> : public GridTypeMapper_Base<RealF> {
|
template<> struct GridTypeMapper<RealF> : public GridTypeMapper_Base {
|
||||||
typedef RealF scalar_type;
|
typedef RealF scalar_type;
|
||||||
typedef RealF vector_type;
|
typedef RealF vector_type;
|
||||||
typedef RealD vector_typeD;
|
typedef RealD vector_typeD;
|
||||||
@ -89,7 +81,7 @@ namespace Grid {
|
|||||||
typedef RealF Realified;
|
typedef RealF Realified;
|
||||||
typedef RealD DoublePrecision;
|
typedef RealD DoublePrecision;
|
||||||
};
|
};
|
||||||
template<> struct GridTypeMapper<RealD> : public GridTypeMapper_Base<RealD> {
|
template<> struct GridTypeMapper<RealD> : public GridTypeMapper_Base {
|
||||||
typedef RealD scalar_type;
|
typedef RealD scalar_type;
|
||||||
typedef RealD vector_type;
|
typedef RealD vector_type;
|
||||||
typedef RealD vector_typeD;
|
typedef RealD vector_typeD;
|
||||||
@ -99,7 +91,7 @@ namespace Grid {
|
|||||||
typedef RealD Realified;
|
typedef RealD Realified;
|
||||||
typedef RealD DoublePrecision;
|
typedef RealD DoublePrecision;
|
||||||
};
|
};
|
||||||
template<> struct GridTypeMapper<ComplexF> : public GridTypeMapper_Base<ComplexF> {
|
template<> struct GridTypeMapper<ComplexF> : public GridTypeMapper_Base {
|
||||||
typedef ComplexF scalar_type;
|
typedef ComplexF scalar_type;
|
||||||
typedef ComplexF vector_type;
|
typedef ComplexF vector_type;
|
||||||
typedef ComplexD vector_typeD;
|
typedef ComplexD vector_typeD;
|
||||||
@ -109,7 +101,7 @@ namespace Grid {
|
|||||||
typedef RealF Realified;
|
typedef RealF Realified;
|
||||||
typedef ComplexD DoublePrecision;
|
typedef ComplexD DoublePrecision;
|
||||||
};
|
};
|
||||||
template<> struct GridTypeMapper<ComplexD> : public GridTypeMapper_Base<ComplexD> {
|
template<> struct GridTypeMapper<ComplexD> : public GridTypeMapper_Base {
|
||||||
typedef ComplexD scalar_type;
|
typedef ComplexD scalar_type;
|
||||||
typedef ComplexD vector_type;
|
typedef ComplexD vector_type;
|
||||||
typedef ComplexD vector_typeD;
|
typedef ComplexD vector_typeD;
|
||||||
@ -119,7 +111,7 @@ namespace Grid {
|
|||||||
typedef RealD Realified;
|
typedef RealD Realified;
|
||||||
typedef ComplexD DoublePrecision;
|
typedef ComplexD DoublePrecision;
|
||||||
};
|
};
|
||||||
template<> struct GridTypeMapper<Integer> : public GridTypeMapper_Base<Integer> {
|
template<> struct GridTypeMapper<Integer> : public GridTypeMapper_Base {
|
||||||
typedef Integer scalar_type;
|
typedef Integer scalar_type;
|
||||||
typedef Integer vector_type;
|
typedef Integer vector_type;
|
||||||
typedef Integer vector_typeD;
|
typedef Integer vector_typeD;
|
||||||
@ -130,7 +122,7 @@ namespace Grid {
|
|||||||
typedef void DoublePrecision;
|
typedef void DoublePrecision;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct GridTypeMapper<vRealF> : public GridTypeMapper_Base<vRealF> {
|
template<> struct GridTypeMapper<vRealF> : public GridTypeMapper_Base {
|
||||||
typedef RealF scalar_type;
|
typedef RealF scalar_type;
|
||||||
typedef vRealF vector_type;
|
typedef vRealF vector_type;
|
||||||
typedef vRealD vector_typeD;
|
typedef vRealD vector_typeD;
|
||||||
@ -140,7 +132,7 @@ namespace Grid {
|
|||||||
typedef vRealF Realified;
|
typedef vRealF Realified;
|
||||||
typedef vRealD DoublePrecision;
|
typedef vRealD DoublePrecision;
|
||||||
};
|
};
|
||||||
template<> struct GridTypeMapper<vRealD> : public GridTypeMapper_Base<vRealD> {
|
template<> struct GridTypeMapper<vRealD> : public GridTypeMapper_Base {
|
||||||
typedef RealD scalar_type;
|
typedef RealD scalar_type;
|
||||||
typedef vRealD vector_type;
|
typedef vRealD vector_type;
|
||||||
typedef vRealD vector_typeD;
|
typedef vRealD vector_typeD;
|
||||||
@ -150,7 +142,17 @@ namespace Grid {
|
|||||||
typedef vRealD Realified;
|
typedef vRealD Realified;
|
||||||
typedef vRealD DoublePrecision;
|
typedef vRealD DoublePrecision;
|
||||||
};
|
};
|
||||||
template<> struct GridTypeMapper<vComplexH> : public GridTypeMapper_Base<vComplexH> {
|
template<> struct GridTypeMapper<vRealH> : public GridTypeMapper_Base {
|
||||||
|
typedef RealF scalar_type;
|
||||||
|
typedef vRealH vector_type;
|
||||||
|
typedef vRealD vector_typeD;
|
||||||
|
typedef vRealH tensor_reduced;
|
||||||
|
typedef RealF scalar_object;
|
||||||
|
typedef vComplexH Complexified;
|
||||||
|
typedef vRealH Realified;
|
||||||
|
typedef vRealD DoublePrecision;
|
||||||
|
};
|
||||||
|
template<> struct GridTypeMapper<vComplexH> : public GridTypeMapper_Base {
|
||||||
typedef ComplexF scalar_type;
|
typedef ComplexF scalar_type;
|
||||||
typedef vComplexH vector_type;
|
typedef vComplexH vector_type;
|
||||||
typedef vComplexD vector_typeD;
|
typedef vComplexD vector_typeD;
|
||||||
@ -160,7 +162,7 @@ namespace Grid {
|
|||||||
typedef vRealH Realified;
|
typedef vRealH Realified;
|
||||||
typedef vComplexD DoublePrecision;
|
typedef vComplexD DoublePrecision;
|
||||||
};
|
};
|
||||||
template<> struct GridTypeMapper<vComplexF> : public GridTypeMapper_Base<vComplexF> {
|
template<> struct GridTypeMapper<vComplexF> : public GridTypeMapper_Base {
|
||||||
typedef ComplexF scalar_type;
|
typedef ComplexF scalar_type;
|
||||||
typedef vComplexF vector_type;
|
typedef vComplexF vector_type;
|
||||||
typedef vComplexD vector_typeD;
|
typedef vComplexD vector_typeD;
|
||||||
@ -170,7 +172,7 @@ namespace Grid {
|
|||||||
typedef vRealF Realified;
|
typedef vRealF Realified;
|
||||||
typedef vComplexD DoublePrecision;
|
typedef vComplexD DoublePrecision;
|
||||||
};
|
};
|
||||||
template<> struct GridTypeMapper<vComplexD> : public GridTypeMapper_Base<vComplexD> {
|
template<> struct GridTypeMapper<vComplexD> : public GridTypeMapper_Base {
|
||||||
typedef ComplexD scalar_type;
|
typedef ComplexD scalar_type;
|
||||||
typedef vComplexD vector_type;
|
typedef vComplexD vector_type;
|
||||||
typedef vComplexD vector_typeD;
|
typedef vComplexD vector_typeD;
|
||||||
@ -180,7 +182,7 @@ namespace Grid {
|
|||||||
typedef vRealD Realified;
|
typedef vRealD Realified;
|
||||||
typedef vComplexD DoublePrecision;
|
typedef vComplexD DoublePrecision;
|
||||||
};
|
};
|
||||||
template<> struct GridTypeMapper<vInteger> : public GridTypeMapper_Base<vInteger> {
|
template<> struct GridTypeMapper<vInteger> : public GridTypeMapper_Base {
|
||||||
typedef Integer scalar_type;
|
typedef Integer scalar_type;
|
||||||
typedef vInteger vector_type;
|
typedef vInteger vector_type;
|
||||||
typedef vInteger vector_typeD;
|
typedef vInteger vector_typeD;
|
||||||
@ -192,46 +194,49 @@ namespace Grid {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define GridTypeMapper_RepeatedTypes \
|
#define GridTypeMapper_RepeatedTypes \
|
||||||
typedef typename ObjectTraits::scalar_type scalar_type; \
|
using BaseTraits = GridTypeMapper<T>; \
|
||||||
typedef typename ObjectTraits::vector_type vector_type; \
|
using scalar_type = typename BaseTraits::scalar_type; \
|
||||||
typedef typename ObjectTraits::vector_typeD vector_typeD; \
|
using vector_type = typename BaseTraits::vector_type; \
|
||||||
typedef typename ObjectTraits::tensor_reduced tensor_reduced; \
|
using vector_typeD = typename BaseTraits::vector_typeD; \
|
||||||
typedef typename ObjectTraits::scalar_object scalar_object; \
|
static constexpr int TensorLevel = BaseTraits::TensorLevel + 1
|
||||||
typedef typename ObjectTraits::Complexified Complexified; \
|
|
||||||
typedef typename ObjectTraits::Realified Realified; \
|
|
||||||
typedef typename ObjectTraits::DoublePrecision DoublePrecision; \
|
|
||||||
static constexpr int TensorLevel = BaseTraits::TensorLevel + 1; \
|
|
||||||
static constexpr std::size_t scalar_size = BaseTraits::scalar_size; \
|
|
||||||
static constexpr std::size_t size = scalar_size * count
|
|
||||||
|
|
||||||
template<typename T> struct GridTypeMapper<iScalar<T>> {
|
template<typename T> struct GridTypeMapper<iScalar<T>> {
|
||||||
using ObjectTraits = iScalar<T>;
|
|
||||||
using BaseTraits = GridTypeMapper<T>;
|
|
||||||
static constexpr int Rank = 1 + BaseTraits::Rank;
|
|
||||||
static constexpr std::size_t count = 1 * BaseTraits::count;
|
|
||||||
static constexpr int Dimension(unsigned int dim) {
|
|
||||||
return ( dim == 0 ) ? 1 : BaseTraits::Dimension(dim - 1); }
|
|
||||||
GridTypeMapper_RepeatedTypes;
|
GridTypeMapper_RepeatedTypes;
|
||||||
|
using tensor_reduced = iScalar<typename BaseTraits::tensor_reduced>;
|
||||||
|
using scalar_object = iScalar<typename BaseTraits::scalar_object>;
|
||||||
|
using Complexified = iScalar<typename BaseTraits::Complexified>;
|
||||||
|
using Realified = iScalar<typename BaseTraits::Realified>;
|
||||||
|
using DoublePrecision = iScalar<typename BaseTraits::DoublePrecision>;
|
||||||
|
static constexpr int Rank = BaseTraits::Rank + 1;
|
||||||
|
static constexpr std::size_t count = BaseTraits::count;
|
||||||
|
static constexpr int Dimension(int dim) {
|
||||||
|
return ( dim == 0 ) ? 1 : BaseTraits::Dimension(dim - 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, int N> struct GridTypeMapper<iVector<T, N>> {
|
template<typename T, int N> struct GridTypeMapper<iVector<T, N>> {
|
||||||
using ObjectTraits = iVector<T, N>;
|
|
||||||
using BaseTraits = GridTypeMapper<T>;
|
|
||||||
static constexpr int Rank = 1 + BaseTraits::Rank;
|
|
||||||
static constexpr std::size_t count = N * BaseTraits::count;
|
|
||||||
static constexpr int Dimension(unsigned int dim) {
|
|
||||||
return ( dim == 0 ) ? N : BaseTraits::Dimension(dim - 1); }
|
|
||||||
GridTypeMapper_RepeatedTypes;
|
GridTypeMapper_RepeatedTypes;
|
||||||
|
using tensor_reduced = iScalar<typename BaseTraits::tensor_reduced>;
|
||||||
|
using scalar_object = iVector<typename BaseTraits::scalar_object, N>;
|
||||||
|
using Complexified = iVector<typename BaseTraits::Complexified, N>;
|
||||||
|
using Realified = iVector<typename BaseTraits::Realified, N>;
|
||||||
|
using DoublePrecision = iVector<typename BaseTraits::DoublePrecision, N>;
|
||||||
|
static constexpr int Rank = BaseTraits::Rank + 1;
|
||||||
|
static constexpr std::size_t count = BaseTraits::count * N;
|
||||||
|
static constexpr int Dimension(int dim) {
|
||||||
|
return ( dim == 0 ) ? N : BaseTraits::Dimension(dim - 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, int N> struct GridTypeMapper<iMatrix<T, N>> {
|
template<typename T, int N> struct GridTypeMapper<iMatrix<T, N>> {
|
||||||
using ObjectTraits = iMatrix<T, N>;
|
|
||||||
using BaseTraits = GridTypeMapper<T>;
|
|
||||||
static constexpr int Rank = 2 + BaseTraits::Rank;
|
|
||||||
static constexpr std::size_t count = N * N * BaseTraits::count;
|
|
||||||
static constexpr int Dimension(unsigned int dim) {
|
|
||||||
return ( dim == 0 || dim == 1 ) ? N : BaseTraits::Dimension(dim - 2); }
|
|
||||||
GridTypeMapper_RepeatedTypes;
|
GridTypeMapper_RepeatedTypes;
|
||||||
|
using tensor_reduced = iScalar<typename BaseTraits::tensor_reduced>;
|
||||||
|
using scalar_object = iMatrix<typename BaseTraits::scalar_object, N>;
|
||||||
|
using Complexified = iMatrix<typename BaseTraits::Complexified, N>;
|
||||||
|
using Realified = iMatrix<typename BaseTraits::Realified, N>;
|
||||||
|
using DoublePrecision = iMatrix<typename BaseTraits::DoublePrecision, N>;
|
||||||
|
static constexpr int Rank = BaseTraits::Rank + 2;
|
||||||
|
static constexpr std::size_t count = BaseTraits::count * N * N;
|
||||||
|
static constexpr int Dimension(int dim) {
|
||||||
|
return ( dim == 0 || dim == 1 ) ? N : BaseTraits::Dimension(dim - 2); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Match the index
|
// Match the index
|
||||||
|
@ -35,7 +35,7 @@ namespace Grid {
|
|||||||
template <typename ETensor, typename Lambda>
|
template <typename ETensor, typename Lambda>
|
||||||
typename std::enable_if<EigenIO::is_tensor_of_scalar<ETensor>::value, void>::type
|
typename std::enable_if<EigenIO::is_tensor_of_scalar<ETensor>::value, void>::type
|
||||||
for_all_do_lambda( Lambda lambda, typename ETensor::Scalar &scalar, typename ETensor::Index &Seq,
|
for_all_do_lambda( Lambda lambda, typename ETensor::Scalar &scalar, typename ETensor::Index &Seq,
|
||||||
std::array<std::size_t, ETensor::NumIndices + GridTypeMapper<typename ETensor::Scalar>::Rank> &MyIndex)
|
std::array<std::size_t, ETensor::NumIndices + EigenIO::Traits<ETensor>::Rank> &MyIndex)
|
||||||
{
|
{
|
||||||
lambda( scalar, Seq++, MyIndex );
|
lambda( scalar, Seq++, MyIndex );
|
||||||
}
|
}
|
||||||
@ -44,9 +44,9 @@ namespace Grid {
|
|||||||
template <typename ETensor, typename Lambda>
|
template <typename ETensor, typename Lambda>
|
||||||
typename std::enable_if<EigenIO::is_tensor_of_container<ETensor>::value, void>::type
|
typename std::enable_if<EigenIO::is_tensor_of_container<ETensor>::value, void>::type
|
||||||
for_all_do_lambda( Lambda lambda, typename ETensor::Scalar &container, typename ETensor::Index &Seq,
|
for_all_do_lambda( Lambda lambda, typename ETensor::Scalar &container, typename ETensor::Index &Seq,
|
||||||
std::array<std::size_t, ETensor::NumIndices + GridTypeMapper<typename ETensor::Scalar>::Rank> &MyIndex)
|
std::array<std::size_t, ETensor::NumIndices + EigenIO::Traits<ETensor>::Rank> &MyIndex)
|
||||||
{
|
{
|
||||||
using Traits = GridTypeMapper<typename ETensor::Scalar>;
|
using Traits = EigenIO::Traits<ETensor>;
|
||||||
const auto rank{ETensor::NumIndices};
|
const auto rank{ETensor::NumIndices};
|
||||||
const auto InnerRank = Traits::Rank;
|
const auto InnerRank = Traits::Rank;
|
||||||
for( typename Traits::scalar_type &Source : container ) {
|
for( typename Traits::scalar_type &Source : container ) {
|
||||||
@ -65,11 +65,12 @@ namespace Grid {
|
|||||||
for_all( ETensor &ET, Lambda lambda )
|
for_all( ETensor &ET, Lambda lambda )
|
||||||
{
|
{
|
||||||
using Scalar = typename ETensor::Scalar; // This could be a Container - we'll check later
|
using Scalar = typename ETensor::Scalar; // This could be a Container - we'll check later
|
||||||
|
using Traits = EigenIO::Traits<ETensor>;
|
||||||
const std::size_t NumScalars = ET.size();
|
const std::size_t NumScalars = ET.size();
|
||||||
assert( NumScalars > 0 );
|
assert( NumScalars > 0 );
|
||||||
using Index = typename ETensor::Index;
|
using Index = typename ETensor::Index;
|
||||||
Index ScalarElementCount{1};
|
Index ScalarElementCount{1};
|
||||||
const auto InnerRank = GridTypeMapper<Scalar>::Rank;
|
const auto InnerRank = Traits::Rank;
|
||||||
const auto rank{ETensor::NumIndices};
|
const auto rank{ETensor::NumIndices};
|
||||||
std::array<std::size_t, rank + InnerRank> Dims;
|
std::array<std::size_t, rank + InnerRank> Dims;
|
||||||
for(auto i = 0; i < rank; i++ ) {
|
for(auto i = 0; i < rank; i++ ) {
|
||||||
@ -84,14 +85,13 @@ namespace Grid {
|
|||||||
// If the Scalar is actually a container, add the inner Scalar's dimensions
|
// If the Scalar is actually a container, add the inner Scalar's dimensions
|
||||||
size_t InnerScalarCount{1};
|
size_t InnerScalarCount{1};
|
||||||
for(auto i = 0; i < InnerRank; i++ ) {
|
for(auto i = 0; i < InnerRank; i++ ) {
|
||||||
auto dim = GridTypeMapper<Scalar>::Dimension(i);
|
auto dim = Traits::Dimension(i);
|
||||||
assert( dim > 0 );
|
assert( dim > 0 );
|
||||||
Dims[rank + i] = static_cast<std::size_t>(dim);
|
Dims[rank + i] = static_cast<std::size_t>(dim);
|
||||||
assert( Dims[rank + i] == dim ); // check we didn't lose anything in the conversion
|
assert( Dims[rank + i] == dim ); // check we didn't lose anything in the conversion
|
||||||
InnerScalarCount *= dim;
|
InnerScalarCount *= dim;
|
||||||
}
|
}
|
||||||
assert(GridTypeMapper<Scalar>::count == InnerScalarCount);
|
assert(Traits::count == InnerScalarCount);
|
||||||
assert(GridTypeMapper<Scalar>::size == sizeof( Scalar ));
|
|
||||||
std::array<std::size_t, rank + InnerRank> MyIndex;
|
std::array<std::size_t, rank + InnerRank> MyIndex;
|
||||||
for( auto &idx : MyIndex ) idx = 0;
|
for( auto &idx : MyIndex ) idx = 0;
|
||||||
Index Seq = 0;
|
Index Seq = 0;
|
||||||
@ -119,11 +119,10 @@ namespace Grid {
|
|||||||
// Sequential initialisation of tensors
|
// Sequential initialisation of tensors
|
||||||
// Would have preferred to define template variables for this, but that's c++ 17
|
// Would have preferred to define template variables for this, but that's c++ 17
|
||||||
template <typename ETensor>
|
template <typename ETensor>
|
||||||
typename std::enable_if<EigenIO::is_tensor<ETensor>::value && !is_complex<typename GridTypeMapper<typename ETensor::Scalar>::scalar_type>::value, void>::type
|
typename std::enable_if<EigenIO::is_tensor<ETensor>::value && !EigenIO::Traits<ETensor>::is_complex>::type
|
||||||
SequentialInit( ETensor &ET, typename GridTypeMapper<typename ETensor::Scalar>::scalar_type Inc = 1,
|
SequentialInit( ETensor &ET, typename EigenIO::Traits<ETensor>::scalar_type Inc = 1, unsigned short Precision = 0 )
|
||||||
unsigned short Precision = 0 )
|
|
||||||
{
|
{
|
||||||
using Traits = GridTypeMapper<typename ETensor::Scalar>;
|
using Traits = EigenIO::Traits<ETensor>;
|
||||||
using scalar_type = typename Traits::scalar_type;
|
using scalar_type = typename Traits::scalar_type;
|
||||||
for_all( ET, [&](scalar_type &c, typename ETensor::Index n, const std::array<size_t, ETensor::NumIndices + Traits::Rank> &Dims ) {
|
for_all( ET, [&](scalar_type &c, typename ETensor::Index n, const std::array<size_t, ETensor::NumIndices + Traits::Rank> &Dims ) {
|
||||||
scalar_type x = Inc * static_cast<scalar_type>(n);
|
scalar_type x = Inc * static_cast<scalar_type>(n);
|
||||||
@ -137,11 +136,10 @@ namespace Grid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ETensor>
|
template <typename ETensor>
|
||||||
typename std::enable_if<EigenIO::is_tensor<ETensor>::value && is_complex<typename GridTypeMapper<typename ETensor::Scalar>::scalar_type>::value, void>::type
|
typename std::enable_if<EigenIO::is_tensor<ETensor>::value && EigenIO::Traits<ETensor>::is_complex>::type
|
||||||
SequentialInit( ETensor &ET, typename GridTypeMapper<typename ETensor::Scalar>::scalar_type Inc={1,-1},
|
SequentialInit( ETensor &ET, typename EigenIO::Traits<ETensor>::scalar_type Inc={1,-1}, unsigned short Precision = 0 )
|
||||||
unsigned short Precision = 0 )
|
|
||||||
{
|
{
|
||||||
using Traits = GridTypeMapper<typename ETensor::Scalar>;
|
using Traits = EigenIO::Traits<ETensor>;
|
||||||
using scalar_type = typename Traits::scalar_type;
|
using scalar_type = typename Traits::scalar_type;
|
||||||
for_all( ET, [&](scalar_type &c, typename ETensor::Index n, const std::array<size_t, ETensor::NumIndices + Traits::Rank> &Dims ) {
|
for_all( ET, [&](scalar_type &c, typename ETensor::Index n, const std::array<size_t, ETensor::NumIndices + Traits::Rank> &Dims ) {
|
||||||
auto re = Inc.real();
|
auto re = Inc.real();
|
||||||
@ -167,7 +165,7 @@ namespace Grid {
|
|||||||
typename std::enable_if<EigenIO::is_tensor<T>::value, void>::type
|
typename std::enable_if<EigenIO::is_tensor<T>::value, void>::type
|
||||||
dump_tensor_func(T &t, const char * pName = nullptr)
|
dump_tensor_func(T &t, const char * pName = nullptr)
|
||||||
{
|
{
|
||||||
using Traits = GridTypeMapper<typename T::Scalar>;
|
using Traits = EigenIO::Traits<T>;
|
||||||
const auto rank{T::NumIndices};
|
const auto rank{T::NumIndices};
|
||||||
const auto &dims = t.dimensions();
|
const auto &dims = t.dimensions();
|
||||||
std::cout << "Dumping rank " << rank << ((T::Options & Eigen::RowMajor) ? ", row" : ", column") << "-major tensor ";
|
std::cout << "Dumping rank " << rank << ((T::Options & Eigen::RowMajor) ? ", row" : ", column") << "-major tensor ";
|
||||||
|
@ -110,8 +110,8 @@ void ioTest(const std::string &filename, const O &object, const std::string &nam
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef ComplexD TestScalar;
|
typedef ComplexD TestScalar;
|
||||||
typedef Eigen::TensorFixedSize<Integer, Eigen::Sizes<5,4,3,2,1>> TensorRank5UShort;
|
typedef Eigen::TensorFixedSize<unsigned short, Eigen::Sizes<5,4,3,2,1>> TensorRank5UShort;
|
||||||
typedef Eigen::TensorFixedSize<Integer, Eigen::Sizes<5,4,3,2,1>, Eigen::StorageOptions::RowMajor> TensorRank5UShortAlt;
|
typedef Eigen::TensorFixedSize<unsigned short, Eigen::Sizes<5,4,3,2,1>, Eigen::StorageOptions::RowMajor> TensorRank5UShortAlt;
|
||||||
typedef Eigen::Tensor<TestScalar, 3, Eigen::StorageOptions::RowMajor> TensorRank3;
|
typedef Eigen::Tensor<TestScalar, 3, Eigen::StorageOptions::RowMajor> TensorRank3;
|
||||||
typedef Eigen::TensorFixedSize<TestScalar, Eigen::Sizes<9,4,2>, Eigen::StorageOptions::RowMajor> Tensor_9_4_2;
|
typedef Eigen::TensorFixedSize<TestScalar, Eigen::Sizes<9,4,2>, Eigen::StorageOptions::RowMajor> Tensor_9_4_2;
|
||||||
typedef std::vector<Tensor_9_4_2> aTensor_9_4_2;
|
typedef std::vector<Tensor_9_4_2> aTensor_9_4_2;
|
||||||
@ -157,11 +157,11 @@ public:
|
|||||||
#define TEST_PARAMS( T ) #T, Flag, Precision, filename, pszExtension, TestNum
|
#define TEST_PARAMS( T ) #T, Flag, Precision, filename, pszExtension, TestNum
|
||||||
|
|
||||||
template <typename WTR_, typename RDR_, typename T, typename... IndexTypes>
|
template <typename WTR_, typename RDR_, typename T, typename... IndexTypes>
|
||||||
void EigenTensorTestSingle(const char * MyTypeName, typename GridTypeMapper<typename T::Scalar>::scalar_type Flag,
|
void EigenTensorTestSingle(const char * MyTypeName, typename EigenIO::Traits<T>::scalar_type Flag,
|
||||||
unsigned short Precision, std::string &filename, const char * pszExtension, unsigned int &TestNum,
|
unsigned short Precision, std::string &filename, const char * pszExtension, unsigned int &TestNum,
|
||||||
IndexTypes... otherDims)
|
IndexTypes... otherDims)
|
||||||
{
|
{
|
||||||
using Traits = GridTypeMapper<typename T::Scalar>;
|
using Traits = EigenIO::Traits<T>;
|
||||||
using scalar_type = typename Traits::scalar_type;
|
using scalar_type = typename Traits::scalar_type;
|
||||||
std::unique_ptr<T> pTensor{new T(otherDims...)};
|
std::unique_ptr<T> pTensor{new T(otherDims...)};
|
||||||
SequentialInit( * pTensor, Flag, Precision );
|
SequentialInit( * pTensor, Flag, Precision );
|
||||||
|
Loading…
Reference in New Issue
Block a user