diff --git a/Grid/serialisation/BaseIO.h b/Grid/serialisation/BaseIO.h index 0c527925..3dd01a63 100644 --- a/Grid/serialisation/BaseIO.h +++ b/Grid/serialisation/BaseIO.h @@ -53,7 +53,8 @@ namespace Grid { typename std::enable_if::value, void>::type write(const std::string& s, const U &output); template - typename std::enable_if::value, void>::type + typename std::enable_if::value + && !std::is_base_of, U>::value, void>::type write(const std::string& s, const U &output); template void write(const std::string &s, const iScalar &output); @@ -61,9 +62,12 @@ namespace Grid { void write(const std::string &s, const iVector &output); template void write(const std::string &s, const iMatrix &output); - template + /*template typename std::enable_if::value || Grid::is_complex::value, void>::type - write(const std::string &s, const Eigen::Tensor &output); + write(const std::string &s, const Eigen::Tensor &output);*/ + template + typename std::enable_if, ETensor>::value && (std::is_arithmetic::value || Grid::is_complex::value), void>::type + write(const std::string &s, const ETensor &output); template void write(const std::string &s, const Eigen::Tensor, NumIndices_, Options_, IndexType_> &output); template @@ -146,7 +150,8 @@ namespace Grid { template template - typename std::enable_if::value, void>::type + typename std::enable_if::value + && !std::is_base_of, U>::value, void>::type Writer::write(const std::string &s, const U &output) { upcast->writeDefault(s, output); @@ -176,51 +181,49 @@ namespace Grid { // Eigen::Tensors of arithmetic/complex base type template - template + /*template typename std::enable_if::value || Grid::is_complex::value, void>::type - Writer::write(const std::string &s, const Eigen::Tensor &output) + Writer::write(const std::string &s, const Eigen::Tensor &output)*/ + template + typename std::enable_if, ETensor>::value && (std::is_arithmetic::value || Grid::is_complex::value), void>::type + Writer::write(const std::string &s, const ETensor &output) { - typedef Eigen::Tensor Tensor; - const typename Tensor::Index NumElements{output.size()}; + //typedef Eigen::Tensor Tensor; + //typedef Eigen::TensorBase Tensor; + const typename ETensor::Index NumElements{output.size()}; assert( NumElements > 0 ); if( NumElements == 1 ) upcast->writeDefault(s, * output.data()); else { // Create a single, flat vector to hold all the data - std::vector flat(NumElements); + std::vector flat(NumElements); // We're not interested in trivial dimensions, i.e. dimensions = 1 - const typename Tensor::Dimensions & DimsOriginal{output.dimensions()}; - assert(DimsOriginal.size() == NumIndices_); unsigned int TrivialDimCount{0}; - for(auto i : DimsOriginal ) { - if( i <= 1 ) { + std::vector ReducedDims; + for(auto i = 0; i < output.NumDimensions; i++ ) { + auto dim = output.dimension(i); + if( dim <= 1 ) { TrivialDimCount++; - assert( i == 1 ); // Not expecting dimension to be <= 0 - } - } - const unsigned int ReducedDimCount{NumIndices_ - TrivialDimCount}; - assert( ReducedDimCount > 0 ); // NB: We've already checked this is not a scalar - // Save a flat vector of the non-trivial dimensions - std::vector ReducedDims(ReducedDimCount); - unsigned int ui = 0; - for(auto i : DimsOriginal ) { - if( i > 1 ) { - ReducedDims[ui] = static_cast(i); - assert( ReducedDims[ui] == i ); // check we didn't lose anything in the conversion - ui++; + assert( dim == 1 ); // Not expecting dimension to be <= 0 + } else { + size_t s = static_cast(dim); + assert( s == dim ); // check we didn't lose anything in the conversion + ReducedDims.push_back(s); } } + const unsigned int ReducedDimCount{output.NumDimensions - TrivialDimCount}; + assert( ReducedDimCount > 0 ); // NB: NumElements > 1 implies this is not a scalar // Now copy all the data to my flat vector // Regardless of the Eigen::Tensor storage order, the copy will be Row Major - std::array MyIndex; - for( int i = 0 ; i < NumIndices_ ; i++ ) MyIndex[i] = 0; - for( typename Tensor::Index n = 0; n < NumElements; n++ ) { + std::array MyIndex; + for( int i = 0 ; i < output.NumDimensions ; i++ ) MyIndex[i] = 0; + for( typename ETensor::Index n = 0; n < NumElements; n++ ) { flat[n] = output( MyIndex ); // Now increment the index - for( int i = NumIndices_ - 1; i >= 0 && ++MyIndex[i] == DimsOriginal[i]; i-- ) + for( int i = output.NumDimensions - 1; i >= 0 && ++MyIndex[i] == output.dimension(i); i-- ) MyIndex[i] = 0; } - upcast->template writeMultiDim(s, ReducedDims, flat); + upcast->template writeMultiDim(s, ReducedDims, flat); } } @@ -380,14 +383,15 @@ namespace Grid { } template - static inline bool CompareMember(const T &lhs, const T &rhs) { + static inline typename std::enable_if, T>::value, bool>::type + CompareMember(const T &lhs, const T &rhs) { return lhs == rhs; } - template - static inline bool CompareMember(const Eigen::Tensor &lhs, - const Eigen::Tensor &rhs) { - Eigen::Tensor bResult = (lhs == rhs).all(); + template + static inline typename std::enable_if, T>::value, bool>::type + CompareMember(const T &lhs, const T &rhs) { + Eigen::Tensor bResult = (lhs == rhs).all(); return bResult(0); } }; diff --git a/tests/hadrons/Test_hadrons_distil.cc b/tests/hadrons/Test_hadrons_distil.cc index 4902072c..db4ae273 100644 --- a/tests/hadrons/Test_hadrons_distil.cc +++ b/tests/hadrons/Test_hadrons_distil.cc @@ -446,16 +446,18 @@ typedef Eigen::Tensor TensorOddBall; //typedef int TestScalar; typedef std::complex TestScalar; typedef Eigen::Tensor TestTensor; +typedef Eigen::TensorFixedSize> TestTensorFixed; // From Test_serialisation.cc class myclass: Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(myclass - , TestTensor, critter + , TestTensor, Critter + , TestTensorFixed, FixedCritter , SpinColourVector, scv , SpinColourMatrix, scm ); - myclass() : critter(7,3,2) {} + myclass() : Critter(7,3,2) {} }; template @@ -503,6 +505,9 @@ eval Eigen::TensorForcedEvalOp constexpr T Inc{1,-1}; +//template <> constexpr std::complex Inc< < std::complex > >{1,1}; + bool DebugIOTest(void) { OddBall critter; ioTest("iotest_oddball.h5", critter, "OddBall"); @@ -512,18 +517,17 @@ bool DebugIOTest(void) { ioTest("iotest_vector.h5", scv, "SpinColourVector"); TestTensor t(3,6,2); - TestScalar Val{1}; - const TestScalar Inc{1}; + TestScalar Val{Inc}; for( int i = 0 ; i < 3 ; i++) for( int j = 0 ; j < 6 ; j++) for( int k = 0 ; k < 2 ; k++) { t(i,j,k) = Val; - Val += Inc; + Val += Inc; } ioTest("iotest_tensor.h5", t, "eigen_tensor_instance_name"); TestTensor t2(t); - t2(1,1,1) += Inc; + t2(1,1,1) += Inc; Eigen::Tensor rResult = (t == t2).all(); if( rResult(0) ) std::cout << "t2 == t" << std::endl; @@ -531,6 +535,18 @@ bool DebugIOTest(void) { std::cout << "t2 != t" << std::endl; //std::cout << "(t == t2) : " << (t == t2).all()(0) << std::endl; + // Now serialise a fixed size tensor + using FixedTensor = Eigen::TensorFixedSize>; + FixedTensor tf; + Val = Inc; + for( int i = 0 ; i < 8 ; i++) + for( int j = 0 ; j < 4 ; j++) + for( int k = 0 ; k < 3 ; k++) { + tf(i,j,k) = Val; + Val += Inc; + } + ioTest("iotest_tensor_fixed.h5", tf, "eigen_tensor_fixed_name"); + myclass o; ioTest("iotest_object.h5", o, "myclass_object_instance_name");