From e6b9aa90761abc65e56ce13bb1e361119ba3797b Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 27 Oct 2015 10:47:07 +0000 Subject: [PATCH 1/4] Config.h removed form repository --- .gitignore | 1 + lib/Config.h | 172 --------------------------------------------------- 2 files changed, 1 insertion(+), 172 deletions(-) delete mode 100644 lib/Config.h diff --git a/.gitignore b/.gitignore index fb988e6b..12bb4c5b 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ ######################################## Makefile.in Makefile +Config.h config.log config.status .deps diff --git a/lib/Config.h b/lib/Config.h deleted file mode 100644 index 3507e6b7..00000000 --- a/lib/Config.h +++ /dev/null @@ -1,172 +0,0 @@ -/* lib/Config.h. Generated from Config.h.in by configure. */ -/* lib/Config.h.in. Generated from configure.ac by autoheader. */ - -/* AVX Intrinsics */ -/* #undef AVX1 */ - -/* AVX2 Intrinsics */ -/* #undef AVX2 */ - -/* AVX512 Intrinsics for Knights Corner */ -/* #undef AVX512 */ - -/* EMPTY_SIMD only for DEBUGGING */ -/* #undef EMPTY_SIMD */ - -/* GRID_COMMS_MPI */ -/* #undef GRID_COMMS_MPI */ - -/* GRID_COMMS_NONE */ -#define GRID_COMMS_NONE 1 - -/* GRID_DEFAULT_PRECISION is DOUBLE */ -/* #undef GRID_DEFAULT_PRECISION_DOUBLE */ - -/* GRID_DEFAULT_PRECISION is SINGLE */ -#define GRID_DEFAULT_PRECISION_SINGLE 1 - -/* Support Altivec instructions */ -/* #undef HAVE_ALTIVEC */ - -/* Support AVX (Advanced Vector Extensions) instructions */ -/* #undef HAVE_AVX */ - -/* Support AVX2 (Advanced Vector Extensions 2) instructions */ -/* #undef HAVE_AVX2 */ - -/* Define to 1 if you have the declaration of `be64toh', and to 0 if you - don't. */ -#define HAVE_DECL_BE64TOH 1 - -/* Define to 1 if you have the declaration of `ntohll', and to 0 if you don't. - */ -#define HAVE_DECL_NTOHLL 0 - -/* Define to 1 if you have the header file. */ -#define HAVE_ENDIAN_H 1 - -/* Support FMA3 (Fused Multiply-Add) instructions */ -/* #undef HAVE_FMA */ - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_GMP_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `gmp' library (-lgmp). */ -#define HAVE_LIBGMP 1 - -/* Define to 1 if you have the `mpfr' library (-lmpfr). */ -#define HAVE_LIBMPFR 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MALLOC_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_MALLOC_MALLOC_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Support mmx instructions */ -#define HAVE_MMX /**/ - -/* Define to 1 if you have the header file. */ -#define HAVE_MM_MALLOC_H 1 - -/* Support SSE (Streaming SIMD Extensions) instructions */ -#define HAVE_SSE /**/ - -/* Support SSE2 (Streaming SIMD Extensions 2) instructions */ -#define HAVE_SSE2 /**/ - -/* Support SSE3 (Streaming SIMD Extensions 3) instructions */ -#define HAVE_SSE3 /**/ - -/* Support SSSE4.1 (Streaming SIMD Extensions 4.1) instructions */ -#define HAVE_SSE4_1 /**/ - -/* Support SSSE4.2 (Streaming SIMD Extensions 4.2) instructions */ -#define HAVE_SSE4_2 /**/ - -/* Support SSSE3 (Supplemental Streaming SIMD Extensions 3) instructions */ -#define HAVE_SSSE3 /**/ - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* NEON ARMv8 Experimental support */ -/* #undef NEONv8 */ - -/* Name of package */ -#define PACKAGE "grid" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "paboyle@ph.ed.ac.uk" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "Grid" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "Grid 1.0" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "grid" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "1.0" - -/* SSE4 Intrinsics */ -#define SSE4 1 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "1.0" - -/* Define for Solaris 2.5.1 so the uint32_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT32_T */ - -/* Define for Solaris 2.5.1 so the uint64_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT64_T */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* Define to the type of an unsigned integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint32_t */ - -/* Define to the type of an unsigned integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint64_t */ From 1b22ce5720cd32a01b1374fdfb4bbc7a779af87d Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 27 Oct 2015 10:47:52 +0000 Subject: [PATCH 2/4] tests Make.inc fix --- tests/Make.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Make.inc b/tests/Make.inc index 3c0d84fe..51913724 100644 --- a/tests/Make.inc +++ b/tests/Make.inc @@ -98,8 +98,8 @@ Test_gamma_LDADD=-lGrid #Test_gparity_LDADD=-lGrid -Test_gpwilson_even_odd_SOURCES=Test_gpwilson_even_odd.cc -Test_gpwilson_even_odd_LDADD=-lGrid +#Test_gpwilson_even_odd_SOURCES=Test_gpwilson_even_odd.cc +#Test_gpwilson_even_odd_LDADD=-lGrid Test_hmc_EODWFRatio_SOURCES=Test_hmc_EODWFRatio.cc From 8709117aea51addcf6b8e9397b8ed04f14b68bbf Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 27 Oct 2015 17:31:13 +0000 Subject: [PATCH 3/4] Log: generalised Logger class to allow separate logs in Grid-based applications --- lib/Log.cc | 4 ++-- lib/Log.h | 54 +++++++++++++++++++++++++++++++----------------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/lib/Log.cc b/lib/Log.cc index 468d9116..8aa0b809 100644 --- a/lib/Log.cc +++ b/lib/Log.cc @@ -2,8 +2,8 @@ namespace Grid { -GridStopWatch GridLogger::StopWatch; -std::ostream GridLogger::devnull(0); +GridStopWatch Logger::StopWatch; +std::ostream Logger::devnull(0); GridLogger GridLogError (1,"Error"); GridLogger GridLogWarning (1,"Warning"); diff --git a/lib/Log.h b/lib/Log.h index 4cf094bc..eaadfd81 100644 --- a/lib/Log.h +++ b/lib/Log.h @@ -6,31 +6,39 @@ namespace Grid { std::ostream& operator<< (std::ostream& stream, const GridTime& time); -class GridLogger { - int active; - std::string name; +class Logger { +protected: + int active; + std::string name, topName; public: - - static GridStopWatch StopWatch; - static std::ostream devnull; - - GridLogger(int on, std::string nm): active(on), name(nm) { - }; - - void Active(int on) {active = on;}; - - friend std::ostream& operator<< (std::ostream& stream, const GridLogger& log){ - if ( log.active ) { - StopWatch.Stop(); - GridTime now = StopWatch.Elapsed(); - StopWatch.Start(); - stream << "Grid : "< &logstreams); From af19118113bb25d3e116512ddef8fed3783acd01 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 16 Nov 2015 18:14:37 +0000 Subject: [PATCH 4/4] new I/O interface --- lib/Make.inc | 2 +- lib/serialisation/BaseIO.h | 244 +++++++++++++++++++++++++----- lib/serialisation/BinaryIO.cc | 36 +++++ lib/serialisation/BinaryIO.h | 153 ++++++++----------- lib/serialisation/MacroMagic.h | 10 +- lib/serialisation/Serialisation.h | 83 +--------- lib/serialisation/TextIO.cc | 66 ++++++++ lib/serialisation/TextIO.h | 198 +++++++++--------------- lib/serialisation/XmlIO.cc | 59 ++++++++ lib/serialisation/XmlIO.h | 201 ++++++++++-------------- tests/Test_serialisation.cc | 108 +++++++------ 11 files changed, 650 insertions(+), 510 deletions(-) create mode 100644 lib/serialisation/BinaryIO.cc create mode 100644 lib/serialisation/TextIO.cc create mode 100644 lib/serialisation/XmlIO.cc diff --git a/lib/Make.inc b/lib/Make.inc index 9196ee52..a13d8f27 100644 --- a/lib/Make.inc +++ b/lib/Make.inc @@ -1,4 +1,4 @@ HFILES=./algorithms/approx/bigfloat.h ./algorithms/approx/bigfloat_double.h ./algorithms/approx/Chebyshev.h ./algorithms/approx/MultiShiftFunction.h ./algorithms/approx/Remez.h ./algorithms/approx/Zolotarev.h ./algorithms/CoarsenedMatrix.h ./algorithms/iterative/AdefGeneric.h ./algorithms/iterative/ConjugateGradient.h ./algorithms/iterative/ConjugateGradientMultiShift.h ./algorithms/iterative/ConjugateResidual.h ./algorithms/iterative/ImplicitlyRestartedLanczos.h ./algorithms/iterative/MatrixUtils.h ./algorithms/iterative/NormalEquations.h ./algorithms/iterative/PrecConjugateResidual.h ./algorithms/iterative/PrecGeneralisedConjugateResidual.h ./algorithms/iterative/SchurRedBlack.h ./algorithms/LinearOperator.h ./algorithms/Preconditioner.h ./algorithms/SparseMatrix.h ./Algorithms.h ./AlignedAllocator.h ./cartesian/Cartesian_base.h ./cartesian/Cartesian_full.h ./cartesian/Cartesian_red_black.h ./Cartesian.h ./communicator/Communicator_base.h ./Communicator.h ./Config.h ./cshift/Cshift_common.h ./cshift/Cshift_mpi.h ./cshift/Cshift_none.h ./Cshift.h ./Grid.h ./Init.h ./lattice/Lattice_arith.h ./lattice/Lattice_base.h ./lattice/Lattice_comparison.h ./lattice/Lattice_comparison_utils.h ./lattice/Lattice_conformable.h ./lattice/Lattice_coordinate.h ./lattice/Lattice_ET.h ./lattice/Lattice_local.h ./lattice/Lattice_overload.h ./lattice/Lattice_peekpoke.h ./lattice/Lattice_reality.h ./lattice/Lattice_reduction.h ./lattice/Lattice_rng.h ./lattice/Lattice_trace.h ./lattice/Lattice_transfer.h ./lattice/Lattice_transpose.h ./lattice/Lattice_unary.h ./lattice/Lattice_where.h ./Lattice.h ./Log.h ./Old/Tensor_peek.h ./Old/Tensor_poke.h ./parallelIO/BinaryIO.h ./parallelIO/NerscIO.h ./pugixml/pugixml.h ./qcd/action/ActionBase.h ./qcd/action/ActionParams.h ./qcd/action/Actions.h ./qcd/action/fermion/CayleyFermion5D.h ./qcd/action/fermion/ContinuedFractionFermion5D.h ./qcd/action/fermion/DomainWallFermion.h ./qcd/action/fermion/FermionOperator.h ./qcd/action/fermion/FermionOperatorImpl.h ./qcd/action/fermion/g5HermitianLinop.h ./qcd/action/fermion/MobiusFermion.h ./qcd/action/fermion/MobiusZolotarevFermion.h ./qcd/action/fermion/OverlapWilsonCayleyTanhFermion.h ./qcd/action/fermion/OverlapWilsonCayleyZolotarevFermion.h ./qcd/action/fermion/OverlapWilsonContfracTanhFermion.h ./qcd/action/fermion/OverlapWilsonContfracZolotarevFermion.h ./qcd/action/fermion/OverlapWilsonPartialFractionTanhFermion.h ./qcd/action/fermion/OverlapWilsonPartialFractionZolotarevFermion.h ./qcd/action/fermion/PartialFractionFermion5D.h ./qcd/action/fermion/ScaledShamirFermion.h ./qcd/action/fermion/ShamirZolotarevFermion.h ./qcd/action/fermion/WilsonCompressor.h ./qcd/action/fermion/WilsonFermion.h ./qcd/action/fermion/WilsonFermion5D.h ./qcd/action/fermion/WilsonKernels.h ./qcd/action/gauge/WilsonGaugeAction.h ./qcd/action/pseudofermion/EvenOddSchurDifferentiable.h ./qcd/action/pseudofermion/OneFlavourEvenOddRational.h ./qcd/action/pseudofermion/OneFlavourEvenOddRationalRatio.h ./qcd/action/pseudofermion/OneFlavourRational.h ./qcd/action/pseudofermion/OneFlavourRationalRatio.h ./qcd/action/pseudofermion/TwoFlavour.h ./qcd/action/pseudofermion/TwoFlavourEvenOdd.h ./qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h ./qcd/action/pseudofermion/TwoFlavourRatio.h ./qcd/hmc/HMC.h ./qcd/hmc/integrators/Integrator.h ./qcd/hmc/integrators/Integrator_algorithm.h ./qcd/QCD.h ./qcd/spin/Dirac.h ./qcd/spin/TwoSpinor.h ./qcd/utils/CovariantCshift.h ./qcd/utils/LinalgUtils.h ./qcd/utils/SpaceTimeGrid.h ./qcd/utils/SUn.h ./qcd/utils/WilsonLoops.h ./serialisation/BaseIO.h ./serialisation/BinaryIO.h ./serialisation/MacroMagic.h ./serialisation/Serialisation.h ./serialisation/TextIO.h ./serialisation/XmlIO.h ./simd/Grid_avx.h ./simd/Grid_avx512.h ./simd/Grid_empty.h ./simd/Grid_imci.h ./simd/Grid_neon.h ./simd/Grid_qpx.h ./simd/Grid_sse4.h ./simd/Grid_vector_types.h ./simd/Grid_vector_unops.h ./Simd.h ./stencil/Lebesgue.h ./Stencil.h ./tensors/Tensor_arith.h ./tensors/Tensor_arith_add.h ./tensors/Tensor_arith_mac.h ./tensors/Tensor_arith_mul.h ./tensors/Tensor_arith_scalar.h ./tensors/Tensor_arith_sub.h ./tensors/Tensor_class.h ./tensors/Tensor_determinant.h ./tensors/Tensor_exp.h ./tensors/Tensor_extract_merge.h ./tensors/Tensor_index.h ./tensors/Tensor_inner.h ./tensors/Tensor_logical.h ./tensors/Tensor_outer.h ./tensors/Tensor_reality.h ./tensors/Tensor_Ta.h ./tensors/Tensor_trace.h ./tensors/Tensor_traits.h ./tensors/Tensor_transpose.h ./tensors/Tensor_unary.h ./Tensors.h ./Threads.h ./Timer.h -CCFILES=./algorithms/approx/MultiShiftFunction.cc ./algorithms/approx/Remez.cc ./algorithms/approx/Zolotarev.cc ./Init.cc ./Log.cc ./pugixml/pugixml.cc ./qcd/action/fermion/CayleyFermion5D.cc ./qcd/action/fermion/ContinuedFractionFermion5D.cc ./qcd/action/fermion/PartialFractionFermion5D.cc ./qcd/action/fermion/WilsonFermion.cc ./qcd/action/fermion/WilsonFermion5D.cc ./qcd/action/fermion/WilsonKernels.cc ./qcd/action/fermion/WilsonKernelsHand.cc ./qcd/hmc/HMC.cc ./qcd/spin/Dirac.cc ./qcd/utils/SpaceTimeGrid.cc ./stencil/Lebesgue.cc ./stencil/Stencil_common.cc +CCFILES=./algorithms/approx/MultiShiftFunction.cc ./algorithms/approx/Remez.cc ./algorithms/approx/Zolotarev.cc ./Init.cc ./Log.cc ./pugixml/pugixml.cc ./qcd/action/fermion/CayleyFermion5D.cc ./qcd/action/fermion/ContinuedFractionFermion5D.cc ./qcd/action/fermion/PartialFractionFermion5D.cc ./qcd/action/fermion/WilsonFermion.cc ./qcd/action/fermion/WilsonFermion5D.cc ./qcd/action/fermion/WilsonKernels.cc ./qcd/action/fermion/WilsonKernelsHand.cc ./qcd/hmc/HMC.cc ./qcd/spin/Dirac.cc ./qcd/utils/SpaceTimeGrid.cc ./serialisation/BinaryIO.cc ./serialisation/TextIO.cc ./serialisation/XmlIO.cc ./stencil/Lebesgue.cc ./stencil/Stencil_common.cc diff --git a/lib/serialisation/BaseIO.h b/lib/serialisation/BaseIO.h index b572cc46..200b8ee3 100644 --- a/lib/serialisation/BaseIO.h +++ b/lib/serialisation/BaseIO.h @@ -1,49 +1,211 @@ #ifndef GRID_SERIALISATION_ABSTRACT_READER_H #define GRID_SERIALISATION_ABSTRACT_READER_H +#include + namespace Grid { - class Writer { -public: - - virtual ~Writer() {}; - - virtual void push(const std::string &s) = 0; - virtual void pop(void) =0; - virtual void write( const std::string& s,const std::string &output ) =0; - virtual void write( const std::string& s,const int16_t output ) =0; - virtual void write( const std::string& s,const uint16_t output ) =0; - virtual void write( const std::string& s,const int32_t output ) =0; - virtual void write( const std::string& s,const uint32_t output ) =0; - virtual void write( const std::string& s,const int64_t output ) =0; - virtual void write( const std::string& s,const uint64_t output ) =0; - virtual void write( const std::string& s,const float output ) =0; - virtual void write( const std::string& s,const double output ) =0; - virtual void write( const std::string& s,const bool output ) =0; -}; - -class Reader { -public: - - - - virtual ~Reader() {}; - - virtual void read( const std::string& s,std::string &output ) =0; - virtual void push(const std::string &s) =0; - virtual void pop(void) = 0; - - virtual void read( const std::string& s, int16_t &output ) =0; - virtual void read( const std::string& s, uint16_t &output ) =0; - virtual void read( const std::string& s, int32_t &output ) =0; - virtual void read( const std::string& s, uint32_t &output ) =0; - virtual void read( const std::string& s, int64_t &output ) =0; - virtual void read( const std::string& s, uint64_t &output ) =0; - virtual void read( const std::string& s, float &output ) =0; - virtual void read( const std::string& s, double &output ) =0; - virtual void read( const std::string& s, bool &output ) =0; + class Serializable {}; + + // static polymorphism implemented using CRTP idiom + + // Static abstract writer + template + class Writer + { + public: + Writer(void); + virtual ~Writer(void) = default; + void push(const std::string &s); + void pop(void); + template + typename std::enable_if::value, void>::type + write(const std::string& s, const U &output); + template + typename std::enable_if::value, void>::type + write(const std::string& s, const U &output); + private: + T *upcast; + }; + + // Static abstract reader + template + class Reader + { + public: + Reader(void); + virtual ~Reader(void) = default; + void push(const std::string &s); + void pop(void); + template + typename std::enable_if::value, void>::type + read(const std::string& s, U &output); + template + typename std::enable_if::value, void>::type + read(const std::string& s, U &output); + protected: + template + void fromString(U &output, const std::string &s); + private: + T *upcast; + }; + + // 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 void push(Reader &r, const std::string &s) + { + r.push(s); + } + + template + inline void push(Reader &r, const char *s) + { + 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); + } + + 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; + } + + // Writer template implementation //////////////////////////////////////////// + template + Writer::Writer(void) + { + upcast = static_cast(this); + } + + template + void Writer::push(const std::string &s) + { + upcast->push(s); + } + + template + void Writer::pop(void) + { + upcast->pop(); + } + + template + template + typename std::enable_if::value, void>::type + Writer::write(const std::string &s, const U &output) + { + U::write(*this, s, output); + } + + template + template + typename std::enable_if::value, void>::type + Writer::write(const std::string &s, const U &output) + { + upcast->writeDefault(s, output); + } + + // Reader template implementation //////////////////////////////////////////// + template + Reader::Reader(void) + { + upcast = static_cast(this); + } + + template + void Reader::push(const std::string &s) + { + upcast->push(s); + } + + template + void Reader::pop(void) + { + upcast->pop(); + } + + template + template + typename std::enable_if::value, void>::type + Reader::read(const std::string &s, U &output) + { + U::read(*this, s, output); + } + + template + template + typename std::enable_if::value, void>::type + Reader::read(const std::string &s, U &output) + { + upcast->readDefault(s, output); + } + + template + template + void Reader::fromString(U &output, const std::string &s) + { + std::istringstream is(s); + + is.exceptions(std::ios::failbit); + try + { + is >> std::boolalpha >> output; + } + catch(std::istringstream::failure &e) + { + std::cerr << "numerical conversion failure on '" << s << "' "; + std::cerr << "(typeid: " << typeid(U).name() << ")" << std::endl; + abort(); + } + } -}; - } + #endif diff --git a/lib/serialisation/BinaryIO.cc b/lib/serialisation/BinaryIO.cc new file mode 100644 index 00000000..eb3f9833 --- /dev/null +++ b/lib/serialisation/BinaryIO.cc @@ -0,0 +1,36 @@ +#include + +using namespace Grid; +using namespace std; + +// Writer implementation /////////////////////////////////////////////////////// +BinaryWriter::BinaryWriter(const string &fileName) +: file_(fileName, ios::binary|ios::out) +{} + +template <> +void BinaryWriter::writeDefault(const string &s, const string &output) +{ + uint64_t sz = output.size(); + + write("", sz); + for (uint64_t i = 0; i < sz; ++i) + { + write("", output[i]); + } +} + +// Reader implementation /////////////////////////////////////////////////////// +BinaryReader::BinaryReader(const string &fileName) +: file_(fileName, ios::binary|ios::in) +{} + +template <> +void BinaryReader::readDefault(const string &s, string &output) +{ + uint64_t sz; + + read("", sz); + output.reserve(sz); + file_.read((char *)output.data(), sz); +} diff --git a/lib/serialisation/BinaryIO.h b/lib/serialisation/BinaryIO.h index 74edbe4e..004ab9a8 100644 --- a/lib/serialisation/BinaryIO.h +++ b/lib/serialisation/BinaryIO.h @@ -9,101 +9,76 @@ #include #include - namespace Grid { - -class BinaryWriter : public Writer { -private: - std::ofstream file; - -public: - - BinaryWriter(const std::string &_file) : file(_file,std::ios::binary|std::ios::out) {} - - ~BinaryWriter() {} - - // Binary is scopeless - void push(const std::string &s) {} - void pop(void) {} - - void write(const std::string& s,const std::string &output) { - uint32_t sz = output.size(); - write(s,sz); - const char * cstr = output.c_str(); - for(int c=0;c + { + public: + BinaryWriter(const std::string &fileName); + virtual ~BinaryWriter(void) = default; + void push(const std::string &s) {}; + void pop(void) {}; + template + void writeDefault(const std::string &s, const U &x); + template + void writeDefault(const std::string &s, const std::vector &x); + private: + std::ofstream file_; }; - void write( const std::string& s,const char output ) { writeInternal(s,output); }; - void write( const std::string& s,const int16_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const uint16_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const int32_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const uint32_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const int64_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const uint64_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const float output ) { writeInternal(s,output); }; - void write( const std::string& s,const double output ) { writeInternal(s,output); }; - void write( const std::string& s,const bool output ) { writeInternal(s,output); }; - -private: - template void writeInternal( const std::string& s,const T output ){ - // FIXME --- htons, htonl, htno64 etc.. - file.write((char *)&output,sizeof(T)); + + class BinaryReader: public Reader + { + public: + BinaryReader(const std::string &fileName); + virtual ~BinaryReader(void) = default; + void push(const std::string &s) {}; + void pop(void) {}; + template + void readDefault(const std::string &s, U &output); + template + void readDefault(const std::string &s, std::vector &output); + private: + std::ifstream file_; + }; + + // Writer template implementation //////////////////////////////////////////// + template + void BinaryWriter::writeDefault(const std::string &s, const U &x) + { + file_.write((char *)&x, sizeof(U)); } -}; - - -class BinaryReader : public Reader{ -private: - - std::ifstream file; - -public: - - - BinaryReader(const std::string &_file) : file(_file,std::ios::binary|std::ios::in) {} - - ~BinaryReader() {} - - // Binary is scopeless - void push(const std::string &s) { } - void pop(void) { } - - void read( const std::string& s,std::string &output ) { - - output.clear(); - - uint32_t sz; - file.read((char *)&sz,sizeof(sz)); - - for(int c=0;c + void BinaryWriter::writeDefault(const std::string &s, const std::vector &x) + { + uint64_t sz = x.size(); + + write("", sz); + for (uint64_t i = 0; i < sz; ++i) + { + write("", x[i]); + } + } + + // Reader template implementation //////////////////////////////////////////// + template + void BinaryReader::readDefault(const std::string &s, U &output) + { + file_.read((char *)&output, sizeof(U)); + } + + template + void BinaryReader::readDefault(const std::string &s, std::vector &output) + { + uint64_t sz; + + read("", sz); + output.resize(sz); + for (uint64_t i = 0; i < sz; ++i) + { + read("", output[i]); } - - }; - - void read( const std::string& s, int16_t &output ) { readInternal(s,output); }; - void read( const std::string& s, uint16_t &output ) { readInternal(s,output); }; - void read( const std::string& s, int32_t &output ) { readInternal(s,output); }; - void read( const std::string& s, uint32_t &output ) { readInternal(s,output); }; - void read( const std::string& s, int64_t &output ) { readInternal(s,output); }; - void read( const std::string& s, uint64_t &output ) { readInternal(s,output); }; - void read( const std::string& s, float &output ) { readInternal(s,output); }; - void read( const std::string& s, double &output ) { readInternal(s,output); }; - void read( const std::string& s, bool &output ) { readInternal(s,output); }; - - -private: - - template void readInternal( const std::string& path, T &output ){ - file.read((char *)&output,sizeof(output)); // byte order?? } - -}; - } + #endif diff --git a/lib/serialisation/MacroMagic.h b/lib/serialisation/MacroMagic.h index 05743160..ee497ce4 100644 --- a/lib/serialisation/MacroMagic.h +++ b/lib/serialisation/MacroMagic.h @@ -111,8 +111,8 @@ THE SOFTWARE. #define GRID_MACRO_MEMBER(A,B) A B; #define GRID_MACRO_OS_WRITE_MEMBER(A,B) os<< #A <<" "#B <<" = "<< obj. B <<" ; " <\ + static void write(Writer &WR,const std::string &s, const cname &obj){ \ push(WR,s);\ GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_WRITE_MEMBER,__VA_ARGS__)) \ pop(WR);\ } \ \ \ - friend void read(Reader &RD,const std::string &s, cname &obj){ \ + template \ + static void read(Reader &RD,const std::string &s, cname &obj){ \ push(RD,s);\ GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_READ_MEMBER,__VA_ARGS__)) \ pop(RD);\ diff --git a/lib/serialisation/Serialisation.h b/lib/serialisation/Serialisation.h index c1191504..31e71779 100644 --- a/lib/serialisation/Serialisation.h +++ b/lib/serialisation/Serialisation.h @@ -5,85 +5,6 @@ #include #include -namespace Grid { - - - // Generic reader writer interface - inline void push(Writer & WR,const std::string &s) { WR.push(s);} - inline void push(Writer & WR,const char *s) { WR.push(std::string(s));} - inline void pop (Writer & WR) { WR.pop();} - - // inline void write(Writer& wr, const std::string& s,const char * output ) { wr.write(s,std::string(output)); }; - inline void write(Writer& wr, const std::string& s,const std::string &output) { wr.write(s,output); }; - inline void write(Writer& wr, const std::string& s,const int16_t output ) { wr.write(s,output); }; - inline void write(Writer& wr, const std::string& s,const uint16_t output ) { wr.write(s,output); }; - inline void write(Writer& wr, const std::string& s,const int32_t output ) { wr.write(s,output); }; - inline void write(Writer& wr, const std::string& s,const uint32_t output ) { wr.write(s,output); }; - inline void write(Writer& wr, const std::string& s,const int64_t output ) { wr.write(s,output); }; - inline void write(Writer& wr, const std::string& s,const uint64_t output ) { wr.write(s,output); }; - inline void write(Writer& wr, const std::string& s,const float output ) { wr.write(s,output); }; - inline void write(Writer& wr, const std::string& s,const double output ) { wr.write(s,output); }; - inline void write(Writer& wr, const std::string& s,const bool output ) { wr.write(s,output); }; - - inline void push(Reader & WR,const std::string &s) { WR.push(s);} - inline void push(Reader & WR,const char *s) { WR.push(std::string(s));} - inline void pop (Reader & WR) { WR.pop();} - - inline void read(Reader& rd, const std::string& s,std::string &output) { rd.read(s,output); }; - inline void read(Reader& rd, const std::string& s, int16_t &output ) { rd.read(s,output); }; - inline void read(Reader& rd, const std::string& s, uint16_t &output ) { rd.read(s,output); }; - inline void read(Reader& rd, const std::string& s, int32_t &output ) { rd.read(s,output); }; - inline void read(Reader& rd, const std::string& s, uint32_t &output ) { rd.read(s,output); }; - inline void read(Reader& rd, const std::string& s, int64_t &output ) { rd.read(s,output); }; - inline void read(Reader& rd, const std::string& s, uint64_t &output ) { rd.read(s,output); }; - inline void read(Reader& rd, const std::string& s, float &output ) { rd.read(s,output); }; - inline void read(Reader& rd, const std::string& s, double &output ) { rd.read(s,output); }; - inline void read(Reader& rd, const std::string& s, bool &output ) { rd.read(s,output); }; - - - template void write(Writer& wr, const std::string& s,const std::vector output ) { - push(wr,s); - uint64_t sz =output.size(); - write(wr,"N",sz); - for(int i=0;i - void read(Reader& rd, const std::string& s,std::vector &output ) { - - push(rd,s); - - uint64_t sz; read(rd,"N",sz); - // skip the vector length - T tmp; - output.resize(0); - for(int i=0;i - inline std::ostream& operator << (std::ostream& os, const std::vector& v) - { - os << "["; - for (typename std::vector::const_iterator ii = v.begin(); ii != v.end(); ++ii) - { - os << " " << *ii; - } - os << " ]"; - return os; - } -} - ////////////////////////////////////////// // Todo: ////////////////////////////////////////// @@ -97,7 +18,7 @@ namespace Grid { // Select the default serialiser use ifdef's ////////////////////////////////////////// namespace Grid { - typedef XMLReader DefaultReader; - typedef XMLWriter DefaultWriter; + typedef XmlReader DefaultReader; + typedef XmlWriter DefaultWriter; } #endif diff --git a/lib/serialisation/TextIO.cc b/lib/serialisation/TextIO.cc new file mode 100644 index 00000000..9d88b26a --- /dev/null +++ b/lib/serialisation/TextIO.cc @@ -0,0 +1,66 @@ +#include + +using namespace Grid; +using namespace std; + +// Writer implementation /////////////////////////////////////////////////////// +TextWriter::TextWriter(const string &fileName) +: file_(fileName, ios::out) +{} + +void TextWriter::push(const string &s) +{ + level_++; +}; + +void TextWriter::pop(void) +{ + level_--; +}; + +void TextWriter::indent(void) +{ + for (int i = 0; i < level_; ++i) + { + file_ << '\t'; + } +}; + +// Reader implementation /////////////////////////////////////////////////////// +TextReader::TextReader(const string &fileName) +: file_(fileName, ios::in) +{} + +void TextReader::push(const string &s) +{ + level_++; +}; + +void TextReader::pop(void) +{ + level_--; +}; + +void TextReader::checkIndent(void) +{ + char c; + + for (int i = 0; i < level_; ++i) + { + file_.get(c); + if (c != '\t') + { + cerr << "mismatch on tab " << c << " level " << level_; + cerr << " i "<< i < +void TextReader::readDefault(const string &s, string &output) +{ + checkIndent(); + output.clear(); + getline(file_, output); +} diff --git a/lib/serialisation/TextIO.h b/lib/serialisation/TextIO.h index 727d18dc..9b69b188 100644 --- a/lib/serialisation/TextIO.h +++ b/lib/serialisation/TextIO.h @@ -9,140 +9,88 @@ #include #include -namespace Grid { - -class TextWriter : public Writer { -private: - - std::ofstream file; - int level; - void indent(void) { - for(int i=0;i { - // std::string tmp = s; - // write(s,tmp); - level++; - } - void pop(void) { - level--; - } - - void write( const std::string& s,const std::string &output ) { - indent(); - file< + void writeDefault(const std::string &s, const U &output); + template + void writeDefault(const std::string &s, const std::vector &output); + private: + void indent(void); + private: + std::ofstream file_; + int level_{0}; }; - void write( const std::string& s,const int16_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const uint16_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const int32_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const uint32_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const int64_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const uint64_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const float output ) { writeInternal(s,output); }; - void write( const std::string& s,const double output ) { writeInternal(s,output); }; - void write( const std::string& s,const bool output ) { writeInternal(s,output); }; - -private: - - template void writeInternal( const std::string& s,const T output ){ + + class TextReader: public Reader + { + public: + TextReader(const std::string &fileName); + virtual ~TextReader(void) = default; + void push(const std::string &s); + void pop(void); + template + void readDefault(const std::string &s, U &output); + template + void readDefault(const std::string &s, std::vector &output); + private: + void checkIndent(void); + private: + std::ifstream file_; + int level_{0}; + }; + + // Writer template implementation //////////////////////////////////////////// + template + void TextWriter::writeDefault(const std::string &s, const U &output) + { indent(); - file << std::boolalpha << output< - void read( const std::string& s, std::vector &output ) { + template + void TextWriter::writeDefault(const std::string &s, const std::vector &output) + { + uint64_t sz = output.size(); - push(s); - - uint64_t n; read("N",n); - - // skip the vector length - T tmp; - output.resize(0); - for(int i=0;i void readInternal( const std::string& path, T &output ){ - std::string asString; - read(path,asString); - convert(asString,output); - } - - template void convert(const std::string &asString,T &output) - { - std::istringstream is(asString); is.exceptions(std::ios::failbit); - try { - is >> std::boolalpha >> output; - } catch(std::istringstream::failure e) { - std::cerr << "XML read failure on "<<" "< + void TextReader::readDefault(const std::string &s, U &output) + { + std::string buf; + + readDefault(s, buf); + fromString(output, buf); + } + + template + void TextReader::readDefault(const std::string &s, std::vector &output) + { + uint64_t sz; + + read("", sz); + output.resize(sz); + for (uint64_t i = 0; i < sz; ++i) + { + read("", output[i]); + } + } } + #endif diff --git a/lib/serialisation/XmlIO.cc b/lib/serialisation/XmlIO.cc new file mode 100644 index 00000000..8dd93de7 --- /dev/null +++ b/lib/serialisation/XmlIO.cc @@ -0,0 +1,59 @@ +#include + +using namespace Grid; +using namespace std; + +// Writer implementation /////////////////////////////////////////////////////// +XmlWriter::XmlWriter(const string &fileName) +: fileName_(fileName) +{ + node_ = doc_.append_child(); + node_.set_name("grid"); +} + +XmlWriter::~XmlWriter(void) +{ + doc_.save_file(fileName_.c_str(), " "); +} + +void XmlWriter::push(const string &s) +{ + node_ = node_.append_child(s.c_str()); +} + +void XmlWriter::pop(void) +{ + node_ = node_.parent(); +} + +// Reader implementation /////////////////////////////////////////////////////// +XmlReader::XmlReader(const string &fileName) +: fileName_(fileName) +{ + pugi::xml_parse_result result = doc_.load_file(fileName_.c_str()); + + if ( !result ) + { + cerr << "XML error description: " << result.description() << "\n"; + cerr << "XML error offset : " << result.offset << "\n"; + abort(); + } + + node_ = doc_.child("grid"); +} + +void XmlReader::push(const string &s) +{ + node_ = node_.child(s.c_str()); +} + +void XmlReader::pop(void) +{ + node_ = node_.parent(); +} + +template <> +void XmlReader::readDefault(const string &s, string &output) +{ + output = node_.child(s.c_str()).first_child().value(); +} diff --git a/lib/serialisation/XmlIO.h b/lib/serialisation/XmlIO.h index 6f36dd0c..ba8af167 100644 --- a/lib/serialisation/XmlIO.h +++ b/lib/serialisation/XmlIO.h @@ -11,136 +11,93 @@ #include "pugixml/pugixml.h" - -namespace Grid { - -class XMLWriter : public Writer { -private: - - pugi::xml_document doc; - pugi::xml_node node; - std::string file; - -public: - - XMLWriter(const std::string &_file) : file(_file) +namespace Grid +{ + + class XmlWriter: public Writer { - node=doc.append_child(); - node.set_name("document"); - } - - ~XMLWriter() - { - // simple_walker walker; - // doc.traverse(walker); - - doc.save_file(file.c_str()," "); - } - - void push(const std::string &s) - { - node = node.append_child(s.c_str()); - } - void pop(void) { - node = node.parent(); - } - - void write( const std::string& s,const std::string &output ) { - pugi::xml_node leaf=node.append_child(s.c_str()); - leaf.append_child(pugi::node_pcdata).set_value(output.c_str()); + + public: + XmlWriter(const std::string &fileName); + virtual ~XmlWriter(void); + void push(const std::string &s); + void pop(void); + template + void writeDefault(const std::string &s, const U &x); + template + void writeDefault(const std::string &s, const std::vector &x); + private: + pugi::xml_document doc_; + pugi::xml_node node_; + std::string fileName_; }; - - void write( const std::string& s,const int16_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const uint16_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const int32_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const uint32_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const int64_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const uint64_t output ) { writeInternal(s,output); }; - void write( const std::string& s,const float output ) { writeInternal(s,output); }; - void write( const std::string& s,const double output ) { writeInternal(s,output); }; - void write( const std::string& s,const bool output ) { writeInternal(s,output); }; - -private: - - template void writeInternal( const std::string& s,const T output ){ + + class XmlReader: public Reader + { + public: + XmlReader(const std::string &fileName); + virtual ~XmlReader(void) = default; + void push(const std::string &s); + void pop(void); + template + void readDefault(const std::string &s, U &output); + template + void readDefault(const std::string &s, std::vector &output); + private: + pugi::xml_document doc_; + pugi::xml_node node_; + std::string fileName_; + }; + + // Writer template implementation //////////////////////////////////////////// + template + void XmlWriter::writeDefault(const std::string &s, const U &x) + { std::ostringstream os; - os << std::boolalpha << output; - write(s,os.str()); + + os << std::boolalpha << x; + pugi::xml_node leaf = node_.append_child(s.c_str()); + leaf.append_child(pugi::node_pcdata).set_value(os.str().c_str()); } -}; - - -class XMLReader : public Reader { -private: - - pugi::xml_document doc; - pugi::xml_node node; - -public: - - - XMLReader(const std::string &_file) + template + void XmlWriter::writeDefault(const std::string &s, const std::vector &x) { - pugi::xml_parse_result result = doc.load_file(_file.c_str()); - - if ( !result ) { - std::cout << "XML error description: " << result.description() << "\n"; - std::cout << "XML error offset: " << result.offset << "\n"; + push(s); + for (auto &x_i: x) + { + write("elem", x_i); } - - assert(result); - - // simple_walker walker; - // doc.traverse(walker); - - node= doc.child("document"); - } - - ~XMLReader() { } - - void read( const std::string& s,std::string &output ) { - output=node.child(s.c_str()).first_child().value(); - }; - void push(const std::string &s) - { - node = node.child(s.c_str()); - } - void pop(void) { - node = node.parent(); - } - - void read( const std::string& s, int16_t &output ) { readInternal(s,output); }; - void read( const std::string& s, uint16_t &output ) { readInternal(s,output); }; - void read( const std::string& s, int32_t &output ) { readInternal(s,output); }; - void read( const std::string& s, uint32_t &output ) { readInternal(s,output); }; - void read( const std::string& s, int64_t &output ) { readInternal(s,output); }; - void read( const std::string& s, uint64_t &output ) { readInternal(s,output); }; - void read( const std::string& s, float &output ) { readInternal(s,output); }; - void read( const std::string& s, double &output ) { readInternal(s,output); }; - void read( const std::string& s, bool &output ) { readInternal(s,output); }; - - -private: - - template void readInternal( const std::string& path, T &output ){ - std::string asString; - read(path,asString); - convert(asString,output); - } - - template void convert(const std::string &asString,T &output) - { - std::istringstream is(asString); is.exceptions(std::ios::failbit); - try { - is >> std::boolalpha >> output; - } catch(std::istringstream::failure e) { - std::cerr << "XML read failure on "<<" "< + void XmlReader::readDefault(const std::string &s, U &output) + { + std::string buf; + + readDefault(s, buf); + fromString(output, buf); + } + + template + void XmlReader::readDefault(const std::string &s, std::vector &output) + { + pugi::xml_node nodeCpy; + std::string buf; + unsigned int i = 0; + + push(s); + while (node_.child("elem")) + { + output.resize(i + 1); + read("elem", output[i]); + node_.child("elem").set_name("elem-done"); + i++; + } + pop(); } -}; - } #endif diff --git a/tests/Test_serialisation.cc b/tests/Test_serialisation.cc index 9c669b40..cfb4b8e7 100644 --- a/tests/Test_serialisation.cc +++ b/tests/Test_serialisation.cc @@ -1,36 +1,35 @@ #include namespace Grid { - -class myclass { -public: - - GRID_DECL_CLASS_MEMBERS(myclass, - int, x, - double, y, - bool , b, - std::string, name, - std::vector, array, - std::vector >, twodimarray, - ); - - myclass(){} - myclass(int i) : array(4,5.1), twodimarray(3,std::vector(2,1.23456)) { - x=i; - y=2*i; - b=true; - name="bother said pooh"; - } - -}; - + class myclass: Serializable { + public: + + GRID_DECL_CLASS_MEMBERS(myclass, + int, x, + double, y, + bool , b, + std::string, name, + std::vector, array, + std::vector>, twodimarray, + ); + + myclass() {} + myclass(int i) + : array(4,5.1), twodimarray(3,std::vector(2,1.23456)) + { + x=i; + y=2*i; + b=true; + name="bother said pooh"; + } + }; } - int16_t i16 = 1; +int16_t i16 = 1; uint16_t u16 = 2; - int32_t i32 = 3; +int32_t i32 = 3; uint32_t u32 = 4; - int64_t i64 = 5; +int64_t i64 = 5; uint64_t u64 = 6; float f = M_PI; double d = 2*M_PI; @@ -41,8 +40,9 @@ using namespace Grid; int main(int argc,char **argv) { { - XMLWriter WR("bother.xml"); - + XmlWriter WR("bother.xml"); + + // test basic type writing push(WR,"BasicTypes"); write(WR,std::string("i16"),i16); write(WR,"u16",u16); @@ -54,40 +54,54 @@ int main(int argc,char **argv) write(WR,"d",d); write(WR,"b",b); pop(WR); - + + // test serializable class writing myclass obj(1234); // non-trivial constructor write(WR,"obj",obj); - + WR.write("obj2", obj); + + std::vector vec; + vec.push_back(myclass(1234)); + vec.push_back(myclass(5678)); + vec.push_back(myclass(3838)); + write(WR, "objvec", vec); }; - - XMLReader RD("bother.xml"); - - myclass copy1; - myclass copy2; - myclass copy3; - - read(RD,"obj",copy1); - std::cout << "Loaded " << copy1< veccopy1, veccopy2, veccopy3; + //// XML + { + XmlReader RD("bother.xml"); + read(RD,"obj",copy1); + read(RD,"objvec", veccopy1); + std::cout << "Loaded (XML) -----------------" << std::endl; + std::cout << copy1 << std::endl << veccopy1 << std::endl; + } + //// binary { BinaryWriter BWR("bother.bin"); write(BWR,"discard",copy1 ); + write(BWR,"discard",veccopy1 ); } - { + { BinaryReader BRD("bother.bin"); read (BRD,"discard",copy2 ); - std::cout<