1
0
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:
Michael Marshall 2019-03-07 12:53:34 +00:00
parent 73cdca3973
commit 584fa0a633
6 changed files with 149 additions and 343 deletions

View File

@ -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

View File

@ -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> >;

View File

@ -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

View File

@ -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

View File

@ -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 ";

View File

@ -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 );