From b7db99967a1cbbe84964caea41606f3d523aa74f Mon Sep 17 00:00:00 2001 From: Michael Marshall Date: Thu, 28 Feb 2019 20:06:59 +0000 Subject: [PATCH 1/2] Recommendations for Traits classes --- Grid/simd/Grid_vector_types.h | 20 ++-- Grid/tensors/Tensor_class.h | 100 +++++++++++++++++- Grid/tensors/Tensor_traits.h | 194 ++++++++++++++++------------------ 3 files changed, 201 insertions(+), 113 deletions(-) diff --git a/Grid/simd/Grid_vector_types.h b/Grid/simd/Grid_vector_types.h index c67e74cb..b34e056d 100644 --- a/Grid/simd/Grid_vector_types.h +++ b/Grid/simd/Grid_vector_types.h @@ -89,17 +89,25 @@ template using NotEnableIf = Invoke struct is_complex : public std::false_type {}; -template <> struct is_complex > : public std::true_type {}; -template <> struct is_complex > : public std::true_type {}; +template <> struct is_complex : public std::true_type {}; +template <> struct is_complex : public std::true_type {}; -template using IfReal = Invoke::value, int> >; +template struct is_real : public std::false_type {}; +template struct is_real::value, + void>::type> : public std::true_type {}; + +template struct is_integer : public std::false_type {}; +template struct is_integer::value, + void>::type> : public std::true_type {}; + +template using IfReal = Invoke::value, int> >; template using IfComplex = Invoke::value, int> >; -template using IfInteger = Invoke::value, int> >; +template using IfInteger = Invoke::value, int> >; template using IfSame = Invoke::value, int> >; -template using IfNotReal = Invoke::value, int> >; +template using IfNotReal = Invoke::value, int> >; template using IfNotComplex = Invoke::value, int> >; -template using IfNotInteger = Invoke::value, int> >; +template using IfNotInteger = Invoke::value, int> >; template using IfNotSame = Invoke::value, int> >; //////////////////////////////////////////////////////// diff --git a/Grid/tensors/Tensor_class.h b/Grid/tensors/Tensor_class.h index c7f868db..c87503c6 100644 --- a/Grid/tensors/Tensor_class.h +++ b/Grid/tensors/Tensor_class.h @@ -62,7 +62,7 @@ class iScalar { // get double precision version typedef iScalar::DoublePrecision> DoublePrecision; - enum { TensorLevel = GridTypeMapper::TensorLevel + 1 }; + static constexpr int TensorLevel = GridTypeMapper::TensorLevel + 1; // Scalar no action // template using tensor_reduce_level = typename @@ -173,7 +173,37 @@ 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); } }; /////////////////////////////////////////////////////////// // Allows to turn scalar>>> back to double. @@ -218,7 +248,7 @@ class iVector { return *this; } - enum { TensorLevel = GridTypeMapper::TensorLevel + 1 }; + static constexpr int TensorLevel = GridTypeMapper::TensorLevel + 1; iVector(const Zero &z) { *this = zero; }; iVector() = default; /* @@ -303,6 +333,38 @@ class iVector { // strong_inline vtype && operator ()(int i) { // 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); } }; template @@ -328,7 +390,7 @@ class iMatrix { typedef iScalar tensor_reduced; typedef iMatrix scalar_object; - enum { TensorLevel = GridTypeMapper::TensorLevel + 1 }; + static constexpr int TensorLevel = GridTypeMapper::TensorLevel + 1; iMatrix(const Zero &z) { *this = zero; }; iMatrix() = default; @@ -458,6 +520,38 @@ class iMatrix { // strong_inline vtype && operator ()(int i,int j) { // 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); } }; template diff --git a/Grid/tensors/Tensor_traits.h b/Grid/tensors/Tensor_traits.h index c1ef397a..d4854768 100644 --- a/Grid/tensors/Tensor_traits.h +++ b/Grid/tensors/Tensor_traits.h @@ -26,6 +26,21 @@ Author: Christopher Kelly namespace Grid { + // Forward declarations + template class iScalar; + template class iVector; + 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; }; + ////////////////////////////////////////////////////////////////////////////////// // Want to recurse: GridTypeMapper >::scalar_type == ComplexD. // Use of a helper class like this allows us to template specialise and "dress" @@ -40,25 +55,31 @@ namespace Grid { // to study C++11's type_traits.h file. (std::enable_if >) // ////////////////////////////////////////////////////////////////////////////////// - - template class GridTypeMapper { - public: - typedef typename T::scalar_type scalar_type; - typedef typename T::vector_type vector_type; - typedef typename T::vector_typeD vector_typeD; - typedef typename T::tensor_reduced tensor_reduced; - typedef typename T::scalar_object scalar_object; - typedef typename T::Complexified Complexified; - typedef typename T::Realified Realified; - typedef typename T::DoublePrecision DoublePrecision; - enum { TensorLevel = T::TensorLevel }; + + // 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 { + 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; } }; ////////////////////////////////////////////////////////////////////////////////// // Recursion stops with these template specialisations ////////////////////////////////////////////////////////////////////////////////// - template<> class GridTypeMapper { - public: + + template struct GridTypeMapper {}; + + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef RealF scalar_type; typedef RealF vector_type; typedef RealD vector_typeD; @@ -67,10 +88,8 @@ namespace Grid { typedef ComplexF Complexified; typedef RealF Realified; typedef RealD DoublePrecision; - enum { TensorLevel = 0 }; }; - template<> class GridTypeMapper { - public: + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef RealD scalar_type; typedef RealD vector_type; typedef RealD vector_typeD; @@ -79,10 +98,8 @@ namespace Grid { typedef ComplexD Complexified; typedef RealD Realified; typedef RealD DoublePrecision; - enum { TensorLevel = 0 }; }; - template<> class GridTypeMapper { - public: + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef ComplexF scalar_type; typedef ComplexF vector_type; typedef ComplexD vector_typeD; @@ -91,10 +108,8 @@ namespace Grid { typedef ComplexF Complexified; typedef RealF Realified; typedef ComplexD DoublePrecision; - enum { TensorLevel = 0 }; }; - template<> class GridTypeMapper { - public: + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef ComplexD scalar_type; typedef ComplexD vector_type; typedef ComplexD vector_typeD; @@ -103,10 +118,8 @@ namespace Grid { typedef ComplexD Complexified; typedef RealD Realified; typedef ComplexD DoublePrecision; - enum { TensorLevel = 0 }; }; - template<> class GridTypeMapper { - public: + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef Integer scalar_type; typedef Integer vector_type; typedef Integer vector_typeD; @@ -115,11 +128,9 @@ namespace Grid { typedef void Complexified; typedef void Realified; typedef void DoublePrecision; - enum { TensorLevel = 0 }; }; - template<> class GridTypeMapper { - public: + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef RealF scalar_type; typedef vRealF vector_type; typedef vRealD vector_typeD; @@ -128,10 +139,8 @@ namespace Grid { typedef vComplexF Complexified; typedef vRealF Realified; typedef vRealD DoublePrecision; - enum { TensorLevel = 0 }; }; - template<> class GridTypeMapper { - public: + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef RealD scalar_type; typedef vRealD vector_type; typedef vRealD vector_typeD; @@ -140,10 +149,8 @@ namespace Grid { typedef vComplexD Complexified; typedef vRealD Realified; typedef vRealD DoublePrecision; - enum { TensorLevel = 0 }; }; - template<> class GridTypeMapper { - public: + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef ComplexF scalar_type; typedef vComplexH vector_type; typedef vComplexD vector_typeD; @@ -152,10 +159,8 @@ namespace Grid { typedef vComplexH Complexified; typedef vRealH Realified; typedef vComplexD DoublePrecision; - enum { TensorLevel = 0 }; }; - template<> class GridTypeMapper { - public: + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef ComplexF scalar_type; typedef vComplexF vector_type; typedef vComplexD vector_typeD; @@ -164,10 +169,8 @@ namespace Grid { typedef vComplexF Complexified; typedef vRealF Realified; typedef vComplexD DoublePrecision; - enum { TensorLevel = 0 }; }; - template<> class GridTypeMapper { - public: + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef ComplexD scalar_type; typedef vComplexD vector_type; typedef vComplexD vector_typeD; @@ -176,10 +179,8 @@ namespace Grid { typedef vComplexD Complexified; typedef vRealD Realified; typedef vComplexD DoublePrecision; - enum { TensorLevel = 0 }; }; - template<> class GridTypeMapper { - public: + template<> struct GridTypeMapper : public GridTypeMapper_Base { typedef Integer scalar_type; typedef vInteger vector_type; typedef vInteger vector_typeD; @@ -188,57 +189,49 @@ namespace Grid { typedef void Complexified; typedef void Realified; typedef void DoublePrecision; - enum { TensorLevel = 0 }; }; - // First some of my own traits - template struct isGridTensor { - static const bool value = true; - static const bool notvalue = false; +#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 + + 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; }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; + + 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; }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; + + 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; }; // Match the index @@ -263,20 +256,13 @@ namespace Grid { typedef T type; }; - //Query if a tensor or Lattice is SIMD vector or scalar - template - class isSIMDvectorized{ - template - static typename std::enable_if< !std::is_same< typename GridTypeMapper::type>::scalar_type, - typename GridTypeMapper::type>::vector_type>::value, char>::type test(void *); + //Query whether a tensor or Lattice is SIMD vector or scalar + template struct isSIMDvectorized : public std::false_type {}; + template struct isSIMDvectorized::type>::scalar_type, + typename GridTypeMapper::type>::vector_type>::value, void>::type> + : public std::true_type {}; - template - static double test(...); - - public: - enum {value = sizeof(test(0)) == sizeof(char) }; - }; - //Get the precision of a Lattice, tensor or scalar type in units of sizeof(float) template class getPrecision{ From 91cffef883a60f83058142404b1166e467a70d56 Mon Sep 17 00:00:00 2001 From: Michael Marshall Date: Thu, 7 Mar 2019 14:30:35 +0000 Subject: [PATCH 2/2] Updates after review with Peter. --- Grid/simd/Grid_vector_types.h | 3 + Grid/tensors/Tensor_class.h | 179 ++++++---------------------------- Grid/tensors/Tensor_traits.h | 115 +++++++++++----------- 3 files changed, 95 insertions(+), 202 deletions(-) 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