diff --git a/.gitignore b/.gitignore index dc59879f..49295fc6 100644 --- a/.gitignore +++ b/.gitignore @@ -123,6 +123,7 @@ make-bin-BUCK.sh ##################### lib/qcd/spin/gamma-gen/*.h lib/qcd/spin/gamma-gen/*.cc +lib/version.h # vs code editor files # ######################## diff --git a/Makefile.am b/Makefile.am index 3a65cf1b..d507bf08 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,6 +5,10 @@ include $(top_srcdir)/doxygen.inc bin_SCRIPTS=grid-config +BUILT_SOURCES = version.h + +version.h: + echo "`git log -n 1 --format=format:"#define GITHASH \\"%H:%d\\"%n" HEAD`" > $(srcdir)/lib/version.h .PHONY: bench check tests doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL) diff --git a/lib/lattice/Lattice_comparison_utils.h b/lib/lattice/Lattice_comparison_utils.h index 14a19383..9580d4d2 100644 --- a/lib/lattice/Lattice_comparison_utils.h +++ b/lib/lattice/Lattice_comparison_utils.h @@ -198,7 +198,7 @@ namespace Grid { typedef typename vsimd::scalar_type scalar;\ return Comparison(functor(),lhs,rhs);\ }\ - template\ + template = 0>\ inline vInteger operator op(const iScalar &lhs,const iScalar &rhs)\ { \ return lhs._internal op rhs._internal; \ diff --git a/lib/serialisation/BaseIO.h b/lib/serialisation/BaseIO.h index 24e1cec7..c9b3fb9e 100644 --- a/lib/serialisation/BaseIO.h +++ b/lib/serialisation/BaseIO.h @@ -31,113 +31,10 @@ Author: Guido Cossu #define GRID_SERIALISATION_ABSTRACT_READER_H #include +#include +#include namespace Grid { - // Vector IO utilities /////////////////////////////////////////////////////// - // helper function to read space-separated values - template - std::vector strToVec(const std::string s) - { - std::istringstream sstr(s); - T buf; - std::vector v; - - while(!sstr.eof()) - { - sstr >> buf; - v.push_back(buf); - } - - return v; - } - - // output to streams for vectors - template < class T > - inline std::ostream & operator<<(std::ostream &os, const std::vector &v) - { - os << "["; - for (auto &x: v) - { - os << x << " "; - } - if (v.size() > 0) - { - os << "\b"; - } - os << "]"; - - return os; - } - - // Vector element trait ////////////////////////////////////////////////////// - template - struct element - { - typedef T type; - static constexpr bool is_number = false; - }; - - template - struct element> - { - typedef typename element::type type; - static constexpr bool is_number = std::is_arithmetic::value - or is_complex::value - or element::is_number; - }; - - // Vector flattening utility class //////////////////////////////////////////// - // Class to flatten a multidimensional std::vector - template - class Flatten - { - public: - typedef typename element::type Element; - public: - explicit Flatten(const V &vector); - const V & getVector(void); - const std::vector & getFlatVector(void); - const std::vector & getDim(void); - private: - void accumulate(const Element &e); - template - void accumulate(const W &v); - void accumulateDim(const Element &e); - template - void accumulateDim(const W &v); - private: - const V &vector_; - std::vector flatVector_; - std::vector dim_; - }; - - // Class to reconstruct a multidimensional std::vector - template - class Reconstruct - { - public: - typedef typename element::type Element; - public: - Reconstruct(const std::vector &flatVector, - const std::vector &dim); - const V & getVector(void); - const std::vector & getFlatVector(void); - const std::vector & getDim(void); - private: - void fill(std::vector &v); - template - void fill(W &v); - void resize(std::vector &v, const unsigned int dim); - template - void resize(W &v, const unsigned int dim); - private: - V vector_; - const std::vector &flatVector_; - std::vector dim_; - size_t ind_{0}; - unsigned int dimInd_{0}; - }; - // Pair IO utilities ///////////////////////////////////////////////////////// // helper function to parse input in the format "" template @@ -151,15 +48,15 @@ namespace Grid { do { is.get(c); - } while (c != '<' && !is.eof()); - if (c == '<') + } while (c != '(' && !is.eof()); + if (c == '(') { int start = is.tellg(); do { is.get(c); - } while (c != '>' && !is.eof()); - if (c == '>') + } while (c != ')' && !is.eof()); + if (c == ')') { int end = is.tellg(); int psize = end - start - 1; @@ -182,7 +79,7 @@ namespace Grid { template inline std::ostream & operator<<(std::ostream &os, const std::pair &p) { - os << "<" << p.first << " " << p.second << ">"; + os << "(" << p.first << " " << p.second << ")"; return os; } @@ -205,6 +102,12 @@ namespace Grid { template typename std::enable_if::value, void>::type write(const std::string& s, const U &output); + template + void write(const std::string &s, const iScalar &output); + template + void write(const std::string &s, const iVector &output); + template + void write(const std::string &s, const iMatrix &output); private: T *upcast; }; @@ -224,6 +127,12 @@ namespace Grid { template typename std::enable_if::value, void>::type read(const std::string& s, U &output); + template + void read(const std::string &s, iScalar &output); + template + void read(const std::string &s, iVector &output); + template + void read(const std::string &s, iMatrix &output); protected: template void fromString(U &output, const std::string &s); @@ -237,203 +146,9 @@ namespace Grid { }; template struct isWriter { static const bool value = false; - }; - - - - // Generic writer interface - // serializable base class - class Serializable - { - public: - template - static inline void write(Writer &WR,const std::string &s, - const Serializable &obj) - {} - - template - static inline void read(Reader &RD,const std::string &s, - Serializable &obj) - {} - - friend inline std::ostream & operator<<(std::ostream &os, - const Serializable &obj) - { - return os; - } }; - - // Flatten class template implementation ///////////////////////////////////// - template - void Flatten::accumulate(const Element &e) - { - flatVector_.push_back(e); - } - - template - template - void Flatten::accumulate(const W &v) - { - for (auto &e: v) - { - accumulate(e); - } - } - - template - void Flatten::accumulateDim(const Element &e) {}; - - template - template - void Flatten::accumulateDim(const W &v) - { - dim_.push_back(v.size()); - accumulateDim(v[0]); - } - - template - Flatten::Flatten(const V &vector) - : vector_(vector) - { - accumulate(vector_); - accumulateDim(vector_); - } - - template - const V & Flatten::getVector(void) - { - return vector_; - } - - template - const std::vector::Element> & - Flatten::getFlatVector(void) - { - return flatVector_; - } - - template - const std::vector & Flatten::getDim(void) - { - return dim_; - } - - // Reconstruct class template implementation ///////////////////////////////// - template - void Reconstruct::fill(std::vector &v) - { - for (auto &e: v) - { - e = flatVector_[ind_++]; - } - } - - template - template - void Reconstruct::fill(W &v) - { - for (auto &e: v) - { - fill(e); - } - } - - template - void Reconstruct::resize(std::vector &v, const unsigned int dim) - { - v.resize(dim_[dim]); - } - - template - template - void Reconstruct::resize(W &v, const unsigned int dim) - { - v.resize(dim_[dim]); - for (auto &e: v) - { - resize(e, dim + 1); - } - } - - template - Reconstruct::Reconstruct(const std::vector &flatVector, - const std::vector &dim) - : flatVector_(flatVector) - , dim_(dim) - { - resize(vector_, 0); - fill(vector_); - } - - template - const V & Reconstruct::getVector(void) - { - return vector_; - } - - template - const std::vector::Element> & - Reconstruct::getFlatVector(void) - { - return flatVector_; - } - - template - const std::vector & Reconstruct::getDim(void) - { - return dim_; - } - - // Generic writer interface ////////////////////////////////////////////////// - template - inline void push(Writer &w, const std::string &s) { - w.push(s); - } - - template - inline void push(Writer &w, const char *s) - { - w.push(std::string(s)); - } - - template - inline void pop(Writer &w) - { - w.pop(); - } - - template - inline void write(Writer &w, const std::string& s, const U &output) - { - w.write(s, output); - } - - // Generic reader interface - template - inline bool push(Reader &r, const std::string &s) - { - return r.push(s); - } - - template - inline bool push(Reader &r, const char *s) - { - return r.push(std::string(s)); - } - - template - inline void pop(Reader &r) - { - r.pop(); - } - - template - inline void read(Reader &r, const std::string &s, U &output) - { - r.read(s, output); - } - - // Writer template implementation //////////////////////////////////////////// + + // Writer template implementation template Writer::Writer(void) { @@ -467,6 +182,27 @@ namespace Grid { { upcast->writeDefault(s, output); } + + template + template + void Writer::write(const std::string &s, const iScalar &output) + { + upcast->writeDefault(s, tensorToVec(output)); + } + + template + template + void Writer::write(const std::string &s, const iVector &output) + { + upcast->writeDefault(s, tensorToVec(output)); + } + + template + template + void Writer::write(const std::string &s, const iMatrix &output) + { + upcast->writeDefault(s, tensorToVec(output)); + } // Reader template implementation template @@ -502,7 +238,37 @@ namespace Grid { { upcast->readDefault(s, output); } + + template + template + void Reader::read(const std::string &s, iScalar &output) + { + typename TensorToVec>::type v; + + upcast->readDefault(s, v); + vecToTensor(output, v); + } + + template + template + void Reader::read(const std::string &s, iVector &output) + { + typename TensorToVec>::type v; + + upcast->readDefault(s, v); + vecToTensor(output, v); + } + template + template + void Reader::read(const std::string &s, iMatrix &output) + { + typename TensorToVec>::type v; + + upcast->readDefault(s, v); + vecToTensor(output, v); + } + template template void Reader::fromString(U &output, const std::string &s) @@ -521,6 +287,76 @@ namespace Grid { abort(); } } + + // serializable base class /////////////////////////////////////////////////// + class Serializable + { + public: + template + static inline void write(Writer &WR,const std::string &s, + const Serializable &obj) + {} + + template + static inline void read(Reader &RD,const std::string &s, + Serializable &obj) + {} + + friend inline std::ostream & operator<<(std::ostream &os, + const Serializable &obj) + { + return os; + } + }; + + // Generic writer interface ////////////////////////////////////////////////// + template + inline void push(Writer &w, const std::string &s) { + w.push(s); + } + + template + inline void push(Writer &w, const char *s) + { + w.push(std::string(s)); + } + + template + inline void pop(Writer &w) + { + w.pop(); + } + + template + inline void write(Writer &w, const std::string& s, const U &output) + { + w.write(s, output); + } + + // Generic reader interface ////////////////////////////////////////////////// + template + inline bool push(Reader &r, const std::string &s) + { + return r.push(s); + } + + template + inline bool push(Reader &r, const char *s) + { + return r.push(std::string(s)); + } + + template + inline void pop(Reader &r) + { + r.pop(); + } + + template + inline void read(Reader &r, const std::string &s, U &output) + { + r.read(s, output); + } } #endif diff --git a/lib/serialisation/Hdf5IO.h b/lib/serialisation/Hdf5IO.h index 94ad9736..12625ab8 100644 --- a/lib/serialisation/Hdf5IO.h +++ b/lib/serialisation/Hdf5IO.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "Hdf5Type.h" #ifndef H5_NO_NAMESPACE diff --git a/lib/serialisation/VectorUtils.h b/lib/serialisation/VectorUtils.h new file mode 100644 index 00000000..f5c76b84 --- /dev/null +++ b/lib/serialisation/VectorUtils.h @@ -0,0 +1,336 @@ +#ifndef GRID_SERIALISATION_VECTORUTILS_H +#define GRID_SERIALISATION_VECTORUTILS_H + +#include +#include + +namespace Grid { + // Grid scalar tensors to nested std::vectors ////////////////////////////////// + template + struct TensorToVec + { + typedef T type; + }; + + template + struct TensorToVec> + { + typedef typename TensorToVec::type type; + }; + + template + struct TensorToVec> + { + typedef typename std::vector::type> type; + }; + + template + struct TensorToVec> + { + typedef typename std::vector::type>> type; + }; + + template + typename TensorToVec::type tensorToVec(const T &t) + { + return t; + } + + template + typename TensorToVec>::type tensorToVec(const iScalar& t) + { + return tensorToVec(t._internal); + } + + template + typename TensorToVec>::type tensorToVec(const iVector& t) + { + typename TensorToVec>::type v; + + v.resize(N); + for (unsigned int i = 0; i < N; i++) + { + v[i] = tensorToVec(t._internal[i]); + } + + return v; + } + + template + typename TensorToVec>::type tensorToVec(const iMatrix& t) + { + typename TensorToVec>::type v; + + v.resize(N); + for (unsigned int i = 0; i < N; i++) + { + v[i].resize(N); + for (unsigned int j = 0; j < N; j++) + { + v[i][j] = tensorToVec(t._internal[i][j]); + } + } + + return v; + } + + template + void vecToTensor(T &t, const typename TensorToVec::type &v) + { + t = v; + } + + + template + void vecToTensor(iScalar &t, const typename TensorToVec>::type &v) + { + vecToTensor(t._internal, v); + } + + template + void vecToTensor(iVector &t, const typename TensorToVec>::type &v) + { + for (unsigned int i = 0; i < N; i++) + { + vecToTensor(t._internal[i], v[i]); + } + } + + template + void vecToTensor(iMatrix &t, const typename TensorToVec>::type &v) + { + for (unsigned int i = 0; i < N; i++) + for (unsigned int j = 0; j < N; j++) + { + vecToTensor(t._internal[i][j], v[i][j]); + } + } + + // Vector element trait ////////////////////////////////////////////////////// + template + struct element + { + typedef T type; + static constexpr bool is_number = false; + }; + + template + struct element> + { + typedef typename element::type type; + static constexpr bool is_number = std::is_arithmetic::value + or is_complex::value + or element::is_number; + }; + + // Vector flattening utility class //////////////////////////////////////////// + // Class to flatten a multidimensional std::vector + template + class Flatten + { + public: + typedef typename element::type Element; + public: + explicit Flatten(const V &vector); + const V & getVector(void); + const std::vector & getFlatVector(void); + const std::vector & getDim(void); + private: + void accumulate(const Element &e); + template + void accumulate(const W &v); + void accumulateDim(const Element &e); + template + void accumulateDim(const W &v); + private: + const V &vector_; + std::vector flatVector_; + std::vector dim_; + }; + + // Class to reconstruct a multidimensional std::vector + template + class Reconstruct + { + public: + typedef typename element::type Element; + public: + Reconstruct(const std::vector &flatVector, + const std::vector &dim); + const V & getVector(void); + const std::vector & getFlatVector(void); + const std::vector & getDim(void); + private: + void fill(std::vector &v); + template + void fill(W &v); + void resize(std::vector &v, const unsigned int dim); + template + void resize(W &v, const unsigned int dim); + private: + V vector_; + const std::vector &flatVector_; + std::vector dim_; + size_t ind_{0}; + unsigned int dimInd_{0}; + }; + + // Flatten class template implementation + template + void Flatten::accumulate(const Element &e) + { + flatVector_.push_back(e); + } + + template + template + void Flatten::accumulate(const W &v) + { + for (auto &e: v) + { + accumulate(e); + } + } + + template + void Flatten::accumulateDim(const Element &e) {}; + + template + template + void Flatten::accumulateDim(const W &v) + { + dim_.push_back(v.size()); + accumulateDim(v[0]); + } + + template + Flatten::Flatten(const V &vector) + : vector_(vector) + { + accumulate(vector_); + accumulateDim(vector_); + } + + template + const V & Flatten::getVector(void) + { + return vector_; + } + + template + const std::vector::Element> & + Flatten::getFlatVector(void) + { + return flatVector_; + } + + template + const std::vector & Flatten::getDim(void) + { + return dim_; + } + + // Reconstruct class template implementation + template + void Reconstruct::fill(std::vector &v) + { + for (auto &e: v) + { + e = flatVector_[ind_++]; + } + } + + template + template + void Reconstruct::fill(W &v) + { + for (auto &e: v) + { + fill(e); + } + } + + template + void Reconstruct::resize(std::vector &v, const unsigned int dim) + { + v.resize(dim_[dim]); + } + + template + template + void Reconstruct::resize(W &v, const unsigned int dim) + { + v.resize(dim_[dim]); + for (auto &e: v) + { + resize(e, dim + 1); + } + } + + template + Reconstruct::Reconstruct(const std::vector &flatVector, + const std::vector &dim) + : flatVector_(flatVector) + , dim_(dim) + { + resize(vector_, 0); + fill(vector_); + } + + template + const V & Reconstruct::getVector(void) + { + return vector_; + } + + template + const std::vector::Element> & + Reconstruct::getFlatVector(void) + { + return flatVector_; + } + + template + const std::vector & Reconstruct::getDim(void) + { + return dim_; + } + + // Vector IO utilities /////////////////////////////////////////////////////// + // helper function to read space-separated values + template + std::vector strToVec(const std::string s) + { + std::istringstream sstr(s); + T buf; + std::vector v; + + while(!sstr.eof()) + { + sstr >> buf; + v.push_back(buf); + } + + return v; + } + + // output to streams for vectors + template < class T > + inline std::ostream & operator<<(std::ostream &os, const std::vector &v) + { + os << "["; + for (auto &x: v) + { + os << x << " "; + } + if (v.size() > 0) + { + os << "\b"; + } + os << "]"; + + return os; + } +} + +#endif \ No newline at end of file diff --git a/lib/tensors/Tensor_logical.h b/lib/tensors/Tensor_logical.h index 7ab3668b..58b2b03b 100644 --- a/lib/tensors/Tensor_logical.h +++ b/lib/tensors/Tensor_logical.h @@ -55,5 +55,38 @@ LOGICAL_BINOP(&); LOGICAL_BINOP(||); LOGICAL_BINOP(&&); +template +strong_inline bool operator==(const iScalar &t1, const iScalar &t2) +{ + return (t1._internal == t2._internal); +} + +template +strong_inline bool operator==(const iVector &t1, const iVector &t2) +{ + bool res = true; + + for (unsigned int i = 0; i < N; ++i) + { + res = (res && (t1._internal[i] == t2._internal[i])); + } + + return res; +} + +template +strong_inline bool operator==(const iMatrix &t1, const iMatrix &t2) +{ + bool res = true; + + for (unsigned int i = 0; i < N; ++i) + for (unsigned int j = 0; j < N; ++j) + { + res = (res && (t1._internal[i][j] == t2._internal[i][j])); + } + + return res; +} + } #endif diff --git a/lib/util/Init.cc b/lib/util/Init.cc index fb3d7a1e..b4ac14b7 100644 --- a/lib/util/Init.cc +++ b/lib/util/Init.cc @@ -49,6 +49,7 @@ Author: paboyle #include #include +#include #include @@ -288,6 +289,12 @@ void Grid_init(int *argc,char ***argv) std::cout << "but WITHOUT ANY WARRANTY; without even the implied warranty of"<, array, std::vector >, twodimarray, - std::vector > >, cmplx3darray + std::vector > >, cmplx3darray, + SpinColourMatrix, scm ); myclass() {} myclass(int i) @@ -59,6 +60,12 @@ public: y=2*i; b=true; name="bother said pooh"; + scm()(0, 1)(2, 1) = 2.356; + scm()(3, 0)(1, 1) = 1.323; + scm()(2, 1)(0, 1) = 5.3336; + scm()(0, 2)(1, 1) = 6.336; + scm()(2, 1)(2, 2) = 7.344; + scm()(1, 1)(2, 0) = 8.3534; } }; @@ -93,8 +100,30 @@ void ioTest(const std::string &filename, const O &object, const std::string &nam if (!good) exit(EXIT_FAILURE); } +template +void tensorConvTestFn(GridSerialRNG &rng, const std::string label) +{ + T t, ft; + Real n; + bool good; + + random(rng, t); + auto tv = tensorToVec(t); + vecToTensor(ft, tv); + n = norm2(t - ft); + good = (n == 0); + std::cout << label << " norm 2 diff: " << n << " -- " + << (good ? "success" : "failure") << std::endl; +} + +#define tensorConvTest(rng, type) tensorConvTestFn(rng, #type) + int main(int argc,char **argv) { + GridSerialRNG rng; + + rng.SeedFixedIntegers(std::vector({42,10,81,9})); + std::cout << "==== basic IO" << std::endl; XmlWriter WR("bother.xml"); @@ -120,7 +149,7 @@ int main(int argc,char **argv) std::cout << "-- serialisable class writing to 'bother.xml'..." << std::endl; write(WR,"obj",obj); WR.write("obj2", obj); - vec.push_back(myclass(1234)); + vec.push_back(obj); vec.push_back(myclass(5678)); vec.push_back(myclass(3838)); pair = std::make_pair(myenum::red, myenum::blue); @@ -131,8 +160,6 @@ int main(int argc,char **argv) std::cout << "-- serialisable class comparison:" << std::endl; std::cout << "vec[0] == obj: " << ((vec[0] == obj) ? "true" : "false") << std::endl; std::cout << "vec[1] == obj: " << ((vec[1] == obj) ? "true" : "false") << std::endl; - - write(WR, "objpair", pair); std::cout << "-- pair writing to std::cout:" << std::endl; std::cout << pair << std::endl; @@ -141,26 +168,20 @@ int main(int argc,char **argv) //// XML ioTest("iotest.xml", obj, "XML (object) "); ioTest("iotest.xml", vec, "XML (vector of objects)"); - ioTest("iotest.xml", pair, "XML (pair of objects)"); //// binary ioTest("iotest.bin", obj, "binary (object) "); ioTest("iotest.bin", vec, "binary (vector of objects)"); - ioTest("iotest.bin", pair, "binary (pair of objects)"); //// text ioTest("iotest.dat", obj, "text (object) "); ioTest("iotest.dat", vec, "text (vector of objects)"); - ioTest("iotest.dat", pair, "text (pair of objects)"); //// text ioTest("iotest.json", obj, "JSON (object) "); ioTest("iotest.json", vec, "JSON (vector of objects)"); - ioTest("iotest.json", pair, "JSON (pair of objects)"); //// HDF5 -#undef HAVE_HDF5 #ifdef HAVE_HDF5 ioTest("iotest.h5", obj, "HDF5 (object) "); ioTest("iotest.h5", vec, "HDF5 (vector of objects)"); - ioTest("iotest.h5", pair, "HDF5 (pair of objects)"); #endif std::cout << "\n==== vector flattening/reconstruction" << std::endl; @@ -197,68 +218,11 @@ int main(int argc,char **argv) std::cout << flatdv.getVector() << std::endl; std::cout << std::endl; - - std::cout << ".:::::: Testing JSON classes "<< std::endl; - - - { - JSONWriter JW("bother.json"); - - // test basic type writing - myenum a = myenum::red; - push(JW,"BasicTypes"); - write(JW,std::string("i16"),i16); - write(JW,"myenum",a); - write(JW,"u16",u16); - write(JW,"i32",i32); - write(JW,"u32",u32); - write(JW,"i64",i64); - write(JW,"u64",u64); - write(JW,"f",f); - write(JW,"d",d); - write(JW,"b",b); - pop(JW); - - - // test serializable class writing - myclass obj(1234); // non-trivial constructor - std::cout << obj << std::endl; - std::cout << "-- serialisable class writing to 'bother.json'..." << std::endl; - write(JW,"obj",obj); - JW.write("obj2", obj); - - - std::vector vec; - vec.push_back(myclass(1234)); - vec.push_back(myclass(5678)); - vec.push_back(myclass(3838)); - write(JW, "objvec", vec); - - } - - - { - JSONReader RD("bother.json"); - myclass jcopy1; - std::vector jveccopy1; - read(RD,"obj",jcopy1); - read(RD,"objvec", jveccopy1); - std::cout << "Loaded (JSON) -----------------" << std::endl; - std::cout << jcopy1 << std::endl << jveccopy1 << std::endl; - } - - -/* - // This is still work in progress - { - // Testing the next element function - JSONReader RD("test.json"); - RD.push("grid"); - RD.push("Observable"); - std::string name; - read(RD,"name", name); - } -*/ - - + std::cout << "==== Grid tensor to vector test" << std::endl; + tensorConvTest(rng, SpinColourMatrix); + tensorConvTest(rng, SpinColourVector); + tensorConvTest(rng, ColourMatrix); + tensorConvTest(rng, ColourVector); + tensorConvTest(rng, SpinMatrix); + tensorConvTest(rng, SpinVector); }