diff --git a/Grid/serialisation/BaseIO.h b/Grid/serialisation/BaseIO.h index 4d9bd9e0..043762ea 100644 --- a/Grid/serialisation/BaseIO.h +++ b/Grid/serialisation/BaseIO.h @@ -36,41 +36,41 @@ Author: Guido Cossu #include namespace Grid { - // TODO Support Grid::complex from GPU port - //template using Grid_complex = std::complex; - - // Returns original type, except for Grid_complex, where it returns the underlying type - //template struct RealType { using type = T; }; - //template struct RealType> { using type = T; }; - namespace EigenIO { - //template struct is_complex : public std::false_type {}; - //template struct is_complex> - //: std::integral_constant::value> {}; + // EigenIO works for scalars that are not just Grid supported scalars + template struct is_complex : public std::false_type {}; + // Support all complex types (not just Grid complex types) - even if the definitions overlap (!) + template struct is_complex< T , typename + std::enable_if< ::Grid::is_complex< T >::value>::type> : public std::true_type {}; + template struct is_complex, typename + std::enable_if>::value>::type> : public std::true_type {}; - // Eigen tensors can be composed of arithmetic scalar and complex types - template struct is_scalar : std::integral_constant::value || is_complex::value> {}; - - // 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 struct is_container : public std::false_type {}; - //template struct is_container> : public std::true_type {}; - //template struct is_container> : public std::true_type {}; - //template struct is_container> : public std::true_type {}; - //template struct is_container> : public std::true_type {}; + // Helpers to support I/O for Eigen tensors of arithmetic scalars, complex types, or Grid tensors + template struct is_scalar : public std::false_type {}; + template struct is_scalar::value || is_complex::value>::type> : public std::true_type {}; // Is this an Eigen tensor template struct is_tensor : std::integral_constant, T>::value> {}; // Is this an Eigen tensor of a supported scalar - template struct is_tensor_of_scalar : public std::false_type {}; - template struct is_tensor_of_scalar::value && is_scalar::value, void>::type> : public std::true_type {}; + template struct is_tensor_of_scalar : public std::false_type {}; + template struct is_tensor_of_scalar::value && is_scalar::value>::type> : public std::true_type {}; // Is this an Eigen tensor of a supported container - template struct is_tensor_of_container : public std::false_type {}; - template struct is_tensor_of_container::value && isGridTensor::value, void>::type> : public std::true_type {}; + template struct is_tensor_of_container : public std::false_type {}; + template struct is_tensor_of_container::value && isGridTensor::value>::type> : public std::true_type {}; + + // Traits are the default for scalars, or come from GridTypeMapper for GridTensors + template struct Traits {}; + template struct Traits::value>::type> : public GridTypeMapper_Base { + using scalar_type = typename T::Scalar; + static constexpr bool is_complex = ::Grid::EigenIO::is_complex::value; + }; + template struct Traits::value>::type> : public GridTypeMapper { + using scalar_type = typename GridTypeMapper::scalar_type; + static constexpr bool is_complex = ::Grid::EigenIO::is_complex::value; + }; // Is this a fixed-size Eigen tensor template struct is_tensor_fixed : public std::false_type {}; @@ -84,83 +84,9 @@ namespace Grid { : public std::true_type {}; // Is this a variable-size Eigen tensor - template struct is_tensor_variable : public std::false_type {}; + template struct is_tensor_variable : public std::false_type {}; template struct is_tensor_variable::value - && !is_tensor_fixed::value, void>::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 struct Traits {}; // C needed for specialisation - // This defines the bottom level - i.e. it's a description of the underlying scalar - template struct Traits::value, void>::type> { - using scalar_type = T; // Type of the underlying scalar - using scalar_real = typename RealPart::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> - // rank = 2 - // rank_non_trivial = 0 - // count = 1 - // e.g. iVector,1> - // rank = 3 - // rank_non_trivial = 2 - // count = 9 - // e.g. iScalar,4>> - // rank = 4 - // rank_non_trivial = 3 - // count = 36 - }; - template struct Traits> { - using scalar_type = typename Traits::scalar_type; - using scalar_real = typename RealPart::type; - static constexpr unsigned int rank = 1 + Traits::rank; - //static constexpr unsigned int rank_non_trivial = 0 + Traits::rank_non_trivial; - static constexpr unsigned int count = 1 * Traits::count; - static constexpr std::size_t scalar_size = Traits::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::Dimension(dim - 1); } - //static constexpr std::size_t DimensionNT(unsigned int dim) { - //return Traits::DimensionNT(dim); } - }; - template struct Traits> { - using scalar_type = typename Traits::scalar_type; - using scalar_real = typename RealPart::type; - static constexpr unsigned int rank = 1 + Traits::rank; - //static constexpr unsigned int rank_non_trivial = (N>1 ? 1 : 0) + Traits::rank_non_trivial; - static constexpr unsigned int count = N * Traits::count; - static constexpr std::size_t scalar_size = Traits::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::Dimension(dim - 1); } - //static constexpr std::size_t DimensionNT(unsigned int dim) { - //return ( N == 1 ) ? Traits::DimensionNT(dim) : ( dim == 0 ) ? N : Traits::DimensionNT(dim - 1); - //} - }; - template struct Traits> { - using scalar_type = typename Traits::scalar_type; - using scalar_real = typename RealPart::type; - static constexpr unsigned int rank = 2 + Traits::rank; - //static constexpr unsigned int rank_non_trivial = (N>1 ? 2 : 0) + Traits::rank_non_trivial; - static constexpr unsigned int count = N * N * Traits::count; - static constexpr std::size_t scalar_size = Traits::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::Dimension(dim - 2); } - //static constexpr std::size_t DimensionNT(unsigned int dim) { - //return ( N == 1 ) ? Traits::DimensionNT(dim) : ( dim == 0 || dim == 1 ) ? N : Traits::DimensionNT(dim - 2); - //} - }; - template struct Traits> : Traits> {};*/ + && !is_tensor_fixed::value>::type> : public std::true_type {}; } // Abstract writer/reader classes //////////////////////////////////////////// @@ -177,11 +103,10 @@ namespace Grid { void push(const std::string &s); void pop(void); template - typename std::enable_if::value, void>::type + typename std::enable_if::value>::type write(const std::string& s, const U &output); template - typename std::enable_if::value - && !EigenIO::is_tensor::value, void>::type + typename std::enable_if::value && !EigenIO::is_tensor::value>::type write(const std::string& s, const U &output); template void write(const std::string &s, const iScalar &output); @@ -190,19 +115,21 @@ namespace Grid { template void write(const std::string &s, const iMatrix &output); template - typename std::enable_if::value, void>::type + typename std::enable_if::value>::type write(const std::string &s, const ETensor &output); // Helper functions for Scalar vs Container specialisations template - inline typename std::enable_if::value, const typename GridTypeMapper::scalar_type *>::type + inline typename std::enable_if::value, + const typename ETensor::Scalar *>::type getFirstScalar(const ETensor &output) { return output.data(); } template - inline typename std::enable_if::value, const typename GridTypeMapper::scalar_type *>::type + inline typename std::enable_if::value, + const typename EigenIO::Traits::scalar_type *>::type getFirstScalar(const ETensor &output) { return output.data()->begin(); @@ -210,7 +137,7 @@ namespace Grid { template inline typename std::enable_if::value, void>::type - copyScalars(typename GridTypeMapper::scalar_type * &pCopy, const S &Source) + copyScalars(S * &pCopy, const S &Source) { * pCopy ++ = Source; } @@ -268,7 +195,7 @@ namespace Grid { // Helper functions for Scalar vs Container specialisations template inline typename std::enable_if::value, void>::type - copyScalars(S &Dest, const typename GridTypeMapper::scalar_type * &pSource) + copyScalars(S &Dest, const S * &pSource) { Dest = * pSource ++; } @@ -362,7 +289,7 @@ namespace Grid { { using Index = typename ETensor::Index; using Container = typename ETensor::Scalar; // NB: could be same as scalar - using Traits = GridTypeMapper; + using Traits = EigenIO::Traits; using Scalar = typename Traits::scalar_type; // type of the underlying scalar constexpr unsigned int TensorRank{ETensor::NumIndices}; constexpr unsigned int ContainerRank{Traits::Rank}; // Only non-zero for containers @@ -386,10 +313,6 @@ namespace Grid { Scalar * pCopyBuffer = nullptr; const Index TotalNumElements = NumElements * Traits::count; if( !CopyData ) { - /*if constexpr ( ContainerRank == 0 ) - pWriteBuffer = output.data(); - else - pWriteBuffer = output.data()->begin();*/ pWriteBuffer = getFirstScalar( output ); } else { // 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 n = 0; n < NumElements; n++ ) { const Container & c = output( MyIndex ); - /*if constexpr ( ContainerRank == 0 ) - * pCopy ++ = c; - else { - for( const Scalar &Source : c ) - * pCopy ++ = Source; - }*/ copyScalars( pCopy, c ); // Now increment the index 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 Container = typename ETensor::Scalar; // NB: could be same as scalar - using Traits = GridTypeMapper; + using Traits = EigenIO::Traits; using Scalar = typename Traits::scalar_type; // type of the underlying scalar constexpr unsigned int TensorRank{ETensor::NumIndices}; constexpr unsigned int ContainerRank{Traits::Rank}; // Only non-zero for containers diff --git a/Grid/simd/Grid_vector_types.h b/Grid/simd/Grid_vector_types.h index b34e056d..707af211 100644 --- a/Grid/simd/Grid_vector_types.h +++ b/Grid/simd/Grid_vector_types.h @@ -10,6 +10,7 @@ Author: Azusa Yamaguchi Author: Guido Cossu Author: Peter Boyle Author: neo +Author: Michael Marshall 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 @@ -865,8 +866,10 @@ template struct is_simd : public std::false_type {}; template <> struct is_simd : public std::true_type {}; template <> struct is_simd : public std::true_type {}; +template <> struct is_simd : public std::true_type {}; template <> struct is_simd : public std::true_type {}; template <> struct is_simd : public std::true_type {}; +template <> struct is_simd : public std::true_type {}; template <> struct is_simd : public std::true_type {}; template using IfSimd = Invoke::value, int> >; diff --git a/Grid/tensors/Tensor_class.h b/Grid/tensors/Tensor_class.h index c87503c6..d59640df 100644 --- a/Grid/tensors/Tensor_class.h +++ b/Grid/tensors/Tensor_class.h @@ -5,6 +5,7 @@ Copyright (C) 2015 Author: Azusa Yamaguchi Author: Peter Boyle +Author: Michael Marshall 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 @@ -42,27 +43,26 @@ namespace Grid { // 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 iScalar { public: vtype _internal; - typedef vtype element; - typedef typename GridTypeMapper::scalar_type scalar_type; - typedef typename GridTypeMapper::vector_type vector_type; - typedef typename GridTypeMapper::vector_typeD vector_typeD; - typedef typename GridTypeMapper::tensor_reduced tensor_reduced_v; - typedef typename GridTypeMapper::scalar_object recurse_scalar_object; - typedef iScalar tensor_reduced; - typedef iScalar scalar_object; - // substitutes a real or complex version with same tensor structure - typedef iScalar::Complexified> Complexified; - typedef iScalar::Realified> Realified; - - // get double precision version - typedef iScalar::DoublePrecision> DoublePrecision; - - static constexpr int TensorLevel = GridTypeMapper::TensorLevel + 1; + using Traits = GridTypeMapper >; + GridVector_CopyTraits; // Scalar no action // template using tensor_reduce_level = typename @@ -173,37 +173,10 @@ class iScalar { return stream; }; - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline begin() const { return &_internal; } - - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline begin() const { return _internal.begin(); } - - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline end() const { return (&_internal) + 1; } - - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline end() const { return _internal.begin() + sizeof(_internal)/sizeof(scalar_type); } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline begin() { return &_internal; } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline begin() { return _internal.begin(); } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline end() { return (&_internal) + 1; } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline end() { return _internal.begin() + sizeof(_internal)/sizeof(scalar_type); } + strong_inline const scalar_type * begin() const { return reinterpret_cast(&_internal); } + strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(&_internal); } + strong_inline const scalar_type * end() const { return begin() + Traits::count; } + strong_inline scalar_type * end() { return begin() + Traits::count; } }; /////////////////////////////////////////////////////////// // Allows to turn scalar>>> back to double. @@ -224,22 +197,9 @@ class iVector { public: vtype _internal[N]; - typedef vtype element; - typedef typename GridTypeMapper::scalar_type scalar_type; - typedef typename GridTypeMapper::vector_type vector_type; - typedef typename GridTypeMapper::vector_typeD vector_typeD; - typedef typename GridTypeMapper::tensor_reduced tensor_reduced_v; - typedef typename GridTypeMapper::scalar_object recurse_scalar_object; - typedef iScalar tensor_reduced; - typedef iVector scalar_object; + using Traits = GridTypeMapper >; + GridVector_CopyTraits; - // substitutes a real or complex version with same tensor structure - typedef iVector::Complexified, N> Complexified; - typedef iVector::Realified, N> Realified; - - // get double precision version - typedef iVector::DoublePrecision, N> DoublePrecision; - template ::value, T>::type * = nullptr> strong_inline auto operator=(T arg) -> iVector { @@ -248,7 +208,6 @@ class iVector { return *this; } - static constexpr int TensorLevel = GridTypeMapper::TensorLevel + 1; iVector(const Zero &z) { *this = zero; }; iVector() = default; /* @@ -334,37 +293,10 @@ class iVector { // return _internal[i]; // } - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline begin() const { return _internal; } - - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline begin() const { return _internal[0].begin(); } - - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline end() const { return _internal + N; } - - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline end() const { return _internal[0].begin() + sizeof(_internal)/sizeof(scalar_type); } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline begin() { return _internal; } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline begin() { return _internal[0].begin(); } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline end() { return _internal + N; } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline end() { return _internal[0].begin() + sizeof(_internal)/sizeof(scalar_type); } + strong_inline const scalar_type * begin() const { return reinterpret_cast(_internal); } + strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(_internal); } + strong_inline const scalar_type * end() const { return begin() + Traits::count; } + strong_inline scalar_type * end() { return begin() + Traits::count; } }; template @@ -372,25 +304,8 @@ class iMatrix { public: vtype _internal[N][N]; - typedef vtype element; - typedef typename GridTypeMapper::scalar_type scalar_type; - typedef typename GridTypeMapper::vector_type vector_type; - typedef typename GridTypeMapper::vector_typeD vector_typeD; - typedef typename GridTypeMapper::tensor_reduced tensor_reduced_v; - typedef typename GridTypeMapper::scalar_object recurse_scalar_object; - - // substitutes a real or complex version with same tensor structure - typedef iMatrix::Complexified, N> Complexified; - typedef iMatrix::Realified, N> Realified; - - // get double precision version - typedef iMatrix::DoublePrecision, N> DoublePrecision; - - // Tensor removal - typedef iScalar tensor_reduced; - typedef iMatrix scalar_object; - - static constexpr int TensorLevel = GridTypeMapper::TensorLevel + 1; + using Traits = GridTypeMapper >; + GridVector_CopyTraits; iMatrix(const Zero &z) { *this = zero; }; iMatrix() = default; @@ -521,37 +436,10 @@ class iMatrix { // return _internal[i][j]; // } - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline begin() const { return _internal[0]; } - - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline begin() const { return _internal[0][0].begin(); } - - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline end() const { return _internal[0] + N * N; } - - template - typename std::enable_if::value, const scalar_type *>::type - strong_inline end() const { return _internal[0][0].begin() + sizeof(_internal)/sizeof(scalar_type); } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline begin() { return _internal[0]; } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline begin() { return _internal[0][0].begin(); } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline end() { return _internal[0] + N * N; } - - template - typename std::enable_if::value, scalar_type *>::type - strong_inline end() { return _internal[0][0].begin() + sizeof(_internal)/sizeof(scalar_type); } + strong_inline const scalar_type * begin() const { return reinterpret_cast(_internal[0]); } + strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(_internal[0]); } + strong_inline const scalar_type * end() const { return begin() + Traits::count; } + strong_inline scalar_type * end() { return begin() + Traits::count; } }; template @@ -574,6 +462,3 @@ void vprefetch(const iMatrix &vv) { } } #endif - - - diff --git a/Grid/tensors/Tensor_traits.h b/Grid/tensors/Tensor_traits.h index d4854768..9cb93e17 100644 --- a/Grid/tensors/Tensor_traits.h +++ b/Grid/tensors/Tensor_traits.h @@ -5,6 +5,7 @@ Author: Azusa Yamaguchi Author: Peter Boyle Author: Christopher Kelly +Author: Michael Marshall 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 the Free Software Foundation; either version 2 of the License, or @@ -32,14 +33,10 @@ namespace Grid { template class iMatrix; // These are the Grid tensors - template struct isGridTensor - : public std::false_type { static constexpr bool notvalue = true; }; - template struct isGridTensor> - : public std::true_type { static constexpr bool notvalue = false; }; - template struct isGridTensor> - : public std::true_type { static constexpr bool notvalue = false; }; - template struct isGridTensor> - : public std::true_type { static constexpr bool notvalue = false; }; + template struct isGridTensor : public std::false_type { static constexpr bool notvalue = true; }; + template struct isGridTensor> : public std::true_type { static constexpr bool notvalue = false; }; + template struct isGridTensor> : public std::true_type { static constexpr bool notvalue = false; }; + template struct isGridTensor> : public std::true_type { static constexpr bool notvalue = false; }; ////////////////////////////////////////////////////////////////////////////////// // Want to recurse: GridTypeMapper >::scalar_type == ComplexD. @@ -57,20 +54,15 @@ namespace Grid { ////////////////////////////////////////////////////////////////////////////////// // This saves repeating common properties for supported Grid Scalar types - template struct GridTypeMapper_Base {}; // TensorLevel How many nested grid tensors // Rank Rank of the grid tensor // 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 - template struct GridTypeMapper_Base { + struct GridTypeMapper_Base { static constexpr int TensorLevel = 0; static constexpr int Rank = 0; static constexpr std::size_t count = 1; - static constexpr std::size_t scalar_size = sizeof(T); - static constexpr std::size_t size = scalar_size * count; - static constexpr int Dimension(unsigned int dim) { return 0; } + static constexpr int Dimension(int dim) { return 0; } }; ////////////////////////////////////////////////////////////////////////////////// @@ -79,7 +71,7 @@ namespace Grid { template struct GridTypeMapper {}; - template<> struct GridTypeMapper : public GridTypeMapper_Base { + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef RealF scalar_type; typedef RealF vector_type; typedef RealD vector_typeD; @@ -89,7 +81,7 @@ namespace Grid { typedef RealF Realified; typedef RealD DoublePrecision; }; - template<> struct GridTypeMapper : public GridTypeMapper_Base { + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef RealD scalar_type; typedef RealD vector_type; typedef RealD vector_typeD; @@ -99,7 +91,7 @@ namespace Grid { typedef RealD Realified; typedef RealD DoublePrecision; }; - template<> struct GridTypeMapper : public GridTypeMapper_Base { + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef ComplexF scalar_type; typedef ComplexF vector_type; typedef ComplexD vector_typeD; @@ -109,7 +101,7 @@ namespace Grid { typedef RealF Realified; typedef ComplexD DoublePrecision; }; - template<> struct GridTypeMapper : public GridTypeMapper_Base { + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef ComplexD scalar_type; typedef ComplexD vector_type; typedef ComplexD vector_typeD; @@ -119,7 +111,7 @@ namespace Grid { typedef RealD Realified; typedef ComplexD DoublePrecision; }; - template<> struct GridTypeMapper : public GridTypeMapper_Base { + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef Integer scalar_type; typedef Integer vector_type; typedef Integer vector_typeD; @@ -130,7 +122,7 @@ namespace Grid { typedef void DoublePrecision; }; - template<> struct GridTypeMapper : public GridTypeMapper_Base { + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef RealF scalar_type; typedef vRealF vector_type; typedef vRealD vector_typeD; @@ -140,7 +132,7 @@ namespace Grid { typedef vRealF Realified; typedef vRealD DoublePrecision; }; - template<> struct GridTypeMapper : public GridTypeMapper_Base { + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef RealD scalar_type; typedef vRealD vector_type; typedef vRealD vector_typeD; @@ -150,7 +142,17 @@ namespace Grid { typedef vRealD Realified; typedef vRealD DoublePrecision; }; - template<> struct GridTypeMapper : public GridTypeMapper_Base { + template<> struct GridTypeMapper : 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 : public GridTypeMapper_Base { typedef ComplexF scalar_type; typedef vComplexH vector_type; typedef vComplexD vector_typeD; @@ -160,7 +162,7 @@ namespace Grid { typedef vRealH Realified; typedef vComplexD DoublePrecision; }; - template<> struct GridTypeMapper : public GridTypeMapper_Base { + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef ComplexF scalar_type; typedef vComplexF vector_type; typedef vComplexD vector_typeD; @@ -170,7 +172,7 @@ namespace Grid { typedef vRealF Realified; typedef vComplexD DoublePrecision; }; - template<> struct GridTypeMapper : public GridTypeMapper_Base { + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef ComplexD scalar_type; typedef vComplexD vector_type; typedef vComplexD vector_typeD; @@ -180,7 +182,7 @@ namespace Grid { typedef vRealD Realified; typedef vComplexD DoublePrecision; }; - template<> struct GridTypeMapper : public GridTypeMapper_Base { + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef Integer scalar_type; typedef vInteger vector_type; typedef vInteger vector_typeD; @@ -192,46 +194,49 @@ namespace Grid { }; #define GridTypeMapper_RepeatedTypes \ - typedef typename ObjectTraits::scalar_type scalar_type; \ - typedef typename ObjectTraits::vector_type vector_type; \ - typedef typename ObjectTraits::vector_typeD vector_typeD; \ - typedef typename ObjectTraits::tensor_reduced tensor_reduced; \ - typedef typename ObjectTraits::scalar_object scalar_object; \ - 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 + using BaseTraits = GridTypeMapper; \ + using scalar_type = typename BaseTraits::scalar_type; \ + using vector_type = typename BaseTraits::vector_type; \ + using vector_typeD = typename BaseTraits::vector_typeD; \ + static constexpr int TensorLevel = BaseTraits::TensorLevel + 1 template struct GridTypeMapper> { - using ObjectTraits = iScalar; - using BaseTraits = GridTypeMapper; - 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; + using tensor_reduced = iScalar; + using scalar_object = iScalar; + using Complexified = iScalar; + using Realified = iScalar; + using DoublePrecision = iScalar; + 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 struct GridTypeMapper> { - using ObjectTraits = iVector; - using BaseTraits = GridTypeMapper; - 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; + using tensor_reduced = iScalar; + using scalar_object = iVector; + using Complexified = iVector; + using Realified = iVector; + using DoublePrecision = iVector; + 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 struct GridTypeMapper> { - using ObjectTraits = iMatrix; - using BaseTraits = GridTypeMapper; - 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; + using tensor_reduced = iScalar; + using scalar_object = iMatrix; + using Complexified = iMatrix; + using Realified = iMatrix; + using DoublePrecision = iMatrix; + 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 diff --git a/Grid/util/Eigen.h b/Grid/util/Eigen.h index 7f5fa915..9af510fe 100644 --- a/Grid/util/Eigen.h +++ b/Grid/util/Eigen.h @@ -35,7 +35,7 @@ namespace Grid { template typename std::enable_if::value, void>::type for_all_do_lambda( Lambda lambda, typename ETensor::Scalar &scalar, typename ETensor::Index &Seq, - std::array::Rank> &MyIndex) + std::array::Rank> &MyIndex) { lambda( scalar, Seq++, MyIndex ); } @@ -44,9 +44,9 @@ namespace Grid { template typename std::enable_if::value, void>::type for_all_do_lambda( Lambda lambda, typename ETensor::Scalar &container, typename ETensor::Index &Seq, - std::array::Rank> &MyIndex) + std::array::Rank> &MyIndex) { - using Traits = GridTypeMapper; + using Traits = EigenIO::Traits; const auto rank{ETensor::NumIndices}; const auto InnerRank = Traits::Rank; for( typename Traits::scalar_type &Source : container ) { @@ -65,11 +65,12 @@ namespace Grid { for_all( ETensor &ET, Lambda lambda ) { using Scalar = typename ETensor::Scalar; // This could be a Container - we'll check later + using Traits = EigenIO::Traits; const std::size_t NumScalars = ET.size(); assert( NumScalars > 0 ); using Index = typename ETensor::Index; Index ScalarElementCount{1}; - const auto InnerRank = GridTypeMapper::Rank; + const auto InnerRank = Traits::Rank; const auto rank{ETensor::NumIndices}; std::array Dims; 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 size_t InnerScalarCount{1}; for(auto i = 0; i < InnerRank; i++ ) { - auto dim = GridTypeMapper::Dimension(i); + auto dim = Traits::Dimension(i); assert( dim > 0 ); Dims[rank + i] = static_cast(dim); assert( Dims[rank + i] == dim ); // check we didn't lose anything in the conversion InnerScalarCount *= dim; } - assert(GridTypeMapper::count == InnerScalarCount); - assert(GridTypeMapper::size == sizeof( Scalar )); + assert(Traits::count == InnerScalarCount); std::array MyIndex; for( auto &idx : MyIndex ) idx = 0; Index Seq = 0; @@ -119,11 +119,10 @@ namespace Grid { // Sequential initialisation of tensors // Would have preferred to define template variables for this, but that's c++ 17 template - typename std::enable_if::value && !is_complex::scalar_type>::value, void>::type - SequentialInit( ETensor &ET, typename GridTypeMapper::scalar_type Inc = 1, - unsigned short Precision = 0 ) + typename std::enable_if::value && !EigenIO::Traits::is_complex>::type + SequentialInit( ETensor &ET, typename EigenIO::Traits::scalar_type Inc = 1, unsigned short Precision = 0 ) { - using Traits = GridTypeMapper; + using Traits = EigenIO::Traits; using scalar_type = typename Traits::scalar_type; for_all( ET, [&](scalar_type &c, typename ETensor::Index n, const std::array &Dims ) { scalar_type x = Inc * static_cast(n); @@ -137,11 +136,10 @@ namespace Grid { } template - typename std::enable_if::value && is_complex::scalar_type>::value, void>::type - SequentialInit( ETensor &ET, typename GridTypeMapper::scalar_type Inc={1,-1}, - unsigned short Precision = 0 ) + typename std::enable_if::value && EigenIO::Traits::is_complex>::type + SequentialInit( ETensor &ET, typename EigenIO::Traits::scalar_type Inc={1,-1}, unsigned short Precision = 0 ) { - using Traits = GridTypeMapper; + using Traits = EigenIO::Traits; using scalar_type = typename Traits::scalar_type; for_all( ET, [&](scalar_type &c, typename ETensor::Index n, const std::array &Dims ) { auto re = Inc.real(); @@ -167,7 +165,7 @@ namespace Grid { typename std::enable_if::value, void>::type dump_tensor_func(T &t, const char * pName = nullptr) { - using Traits = GridTypeMapper; + using Traits = EigenIO::Traits; const auto rank{T::NumIndices}; const auto &dims = t.dimensions(); std::cout << "Dumping rank " << rank << ((T::Options & Eigen::RowMajor) ? ", row" : ", column") << "-major tensor "; diff --git a/tests/IO/Test_serialisation.cc b/tests/IO/Test_serialisation.cc index 2ba16361..56cdcb4b 100644 --- a/tests/IO/Test_serialisation.cc +++ b/tests/IO/Test_serialisation.cc @@ -110,8 +110,8 @@ void ioTest(const std::string &filename, const O &object, const std::string &nam } typedef ComplexD TestScalar; -typedef Eigen::TensorFixedSize> TensorRank5UShort; -typedef Eigen::TensorFixedSize, Eigen::StorageOptions::RowMajor> TensorRank5UShortAlt; +typedef Eigen::TensorFixedSize> TensorRank5UShort; +typedef Eigen::TensorFixedSize, Eigen::StorageOptions::RowMajor> TensorRank5UShortAlt; typedef Eigen::Tensor TensorRank3; typedef Eigen::TensorFixedSize, Eigen::StorageOptions::RowMajor> Tensor_9_4_2; typedef std::vector aTensor_9_4_2; @@ -157,11 +157,11 @@ public: #define TEST_PARAMS( T ) #T, Flag, Precision, filename, pszExtension, TestNum template -void EigenTensorTestSingle(const char * MyTypeName, typename GridTypeMapper::scalar_type Flag, +void EigenTensorTestSingle(const char * MyTypeName, typename EigenIO::Traits::scalar_type Flag, unsigned short Precision, std::string &filename, const char * pszExtension, unsigned int &TestNum, IndexTypes... otherDims) { - using Traits = GridTypeMapper; + using Traits = EigenIO::Traits; using scalar_type = typename Traits::scalar_type; std::unique_ptr pTensor{new T(otherDims...)}; SequentialInit( * pTensor, Flag, Precision );