/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/tensors/Tensor_traits.h Copyright (C) 2015 Author: Azusa Yamaguchi Author: Peter Boyle Author: Christopher Kelly 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 (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ #ifndef GRID_MATH_TRAITS_H #define GRID_MATH_TRAITS_H #include namespace Grid { ////////////////////////////////////////////////////////////////////////////////// // Want to recurse: GridTypeMapper >::scalar_type == ComplexD. // Use of a helper class like this allows us to template specialise and "dress" // other classes such as RealD == double, ComplexD == std::complex with these // traits. // // It is possible that we could do this more elegantly if I introduced a // queryable trait in iScalar, iMatrix and iVector and used the query on vtype in // place of the type mapper? // // Not sure how to do this, but probably could be done with a research effort // 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::tensor_reduced tensor_reduced; typedef typename T::scalar_object scalar_object; typedef typename T::Complexified Complexified; typedef typename T::Realified Realified; enum { TensorLevel = T::TensorLevel }; }; ////////////////////////////////////////////////////////////////////////////////// // Recursion stops with these template specialisations ////////////////////////////////////////////////////////////////////////////////// template<> class GridTypeMapper { public: typedef RealF scalar_type; typedef RealF vector_type; typedef RealF tensor_reduced ; typedef RealF scalar_object; typedef ComplexF Complexified; typedef RealF Realified; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { public: typedef RealD scalar_type; typedef RealD vector_type; typedef RealD tensor_reduced; typedef RealD scalar_object; typedef ComplexD Complexified; typedef RealD Realified; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { public: typedef ComplexF scalar_type; typedef ComplexF vector_type; typedef ComplexF tensor_reduced; typedef ComplexF scalar_object; typedef ComplexF Complexified; typedef RealF Realified; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { public: typedef ComplexD scalar_type; typedef ComplexD vector_type; typedef ComplexD tensor_reduced; typedef ComplexD scalar_object; typedef ComplexD Complexified; typedef RealD Realified; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { public: typedef Integer scalar_type; typedef Integer vector_type; typedef Integer tensor_reduced; typedef Integer scalar_object; typedef void Complexified; typedef void Realified; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { public: typedef RealF scalar_type; typedef vRealF vector_type; typedef vRealF tensor_reduced; typedef RealF scalar_object; typedef vComplexF Complexified; typedef vRealF Realified; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { public: typedef RealD scalar_type; typedef vRealD vector_type; typedef vRealD tensor_reduced; typedef RealD scalar_object; typedef vComplexD Complexified; typedef vRealD Realified; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { public: typedef ComplexF scalar_type; typedef vComplexF vector_type; typedef vComplexF tensor_reduced; typedef ComplexF scalar_object; typedef vComplexF Complexified; typedef vRealF Realified; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { public: typedef ComplexD scalar_type; typedef vComplexD vector_type; typedef vComplexD tensor_reduced; typedef ComplexD scalar_object; typedef vComplexD Complexified; typedef vRealD Realified; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { public: typedef Integer scalar_type; typedef vInteger vector_type; typedef vInteger tensor_reduced; typedef Integer scalar_object; typedef void Complexified; typedef void Realified; enum { TensorLevel = 0 }; }; // First some of my own traits template struct isGridTensor { static const bool value = true; static const bool notvalue = false; }; 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 isGridTensor { static const bool value = false; static const bool notvalue = true; }; // Match the index template struct matchGridTensorIndex { static const bool value = (Level==T::TensorLevel); static const bool notvalue = (Level!=T::TensorLevel); }; // What is the vtype template struct isComplex { static const bool value = false; }; template<> struct isComplex { static const bool value = true; }; template<> struct isComplex { static const bool value = true; }; //Get the SIMD vector type from a Grid tensor or Lattice template struct getVectorType{ 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 *); 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{ typedef typename getVectorType::type vector_obj; //get the vector_obj (i.e. a grid Tensor) if its a Lattice, do nothing otherwise (i.e. if fundamental or grid Tensor) typedef typename GridTypeMapper::scalar_type scalar_type; //get the associated scalar type. Works on fundamental and tensor types typedef typename GridTypeMapper::Realified real_scalar_type; //remove any std::complex wrapper, should get us to the fundamental type public: enum { value = sizeof(real_scalar_type)/sizeof(float) }; }; } #endif