diff --git a/libsrc/core/archive.hpp b/libsrc/core/archive.hpp index a011b6bf..bddd2533 100644 --- a/libsrc/core/archive.hpp +++ b/libsrc/core/archive.hpp @@ -10,6 +10,7 @@ #include // for shared_ptr #include // for string #include // for declval, enable_if_t, false_type, is_co... +#include // for std::byte #include // for type_info #include // for move, swap, pair #include // for vector @@ -93,6 +94,17 @@ namespace ngcore template constexpr bool is_archivable = detail::is_Archivable_struct::value; + + template + constexpr size_t TotSize () + { + if constexpr (sizeof...(Trest) == 0) + return sizeof(T); + else + return sizeof(T) + TotSize (); + } + + // Base Archive class class NGCORE_API Archive { @@ -206,7 +218,7 @@ namespace ngcore Do(&v[0], size); return (*this); } - + // archive implementation for enums template auto operator & (T& val) -> std::enable_if_t::value, Archive&> @@ -307,6 +319,55 @@ namespace ngcore val.DoArchive(*this); return *this; } + + + + // pack elements to binary + template + Archive & DoPacked (Types & ... args) + { + if (true) // (isbinary) + { + constexpr size_t totsize = TotSize(); // (args...); + std::byte mem[totsize]; + if (is_output) + { + CopyToBin (&mem[0], args...); + Do(&mem[0], totsize); + } + else + { + Do(&mem[0], totsize); + CopyFromBin (&mem[0], args...); + } + } + // else + // cout << "DoPacked of non-binary called --> individual pickling" << endl; + return *this; + } + + + template + constexpr void CopyToBin (std::byte * ptr, T & first, Trest & ...rest) const + { + memcpy (ptr, &first, sizeof(first)); + CopyToBin(ptr+sizeof(first), rest...); + } + constexpr void CopyToBin (std::byte * ptr) const { } + + template + constexpr void CopyFromBin (std::byte * ptr, T & first, Trest & ...rest) const + { + memcpy (&first, ptr, sizeof(first)); + CopyFromBin(ptr+sizeof(first), rest...); + } + constexpr void CopyFromBin (std::byte * ptr) const { } + + + + + + // Archive shared_ptrs ================================================= template Archive& operator & (std::shared_ptr& ptr) @@ -705,6 +766,7 @@ namespace ngcore { return Write(i); } Archive & operator & (bool & b) override { return Write(b); } + Archive & operator & (std::string & str) override { int len = str.length(); @@ -731,6 +793,11 @@ namespace ngcore ptr = 0; } } + Archive & Do (std::byte * d, size_t n) override + { + FlushBuffer(); + stream->write(reinterpret_cast(d), n*sizeof(std::byte)); return *this; + } private: template @@ -808,6 +875,8 @@ namespace ngcore return *this; } + Archive & Do (std::byte * d, size_t n) override + { stream->read(reinterpret_cast(d), n*sizeof(std::byte)); return *this; } // NOLINT Archive & Do (double * d, size_t n) override { stream->read(reinterpret_cast(d), n*sizeof(double)); return *this; } // NOLINT Archive & Do (int * i, size_t n) override diff --git a/libsrc/meshing/meshtype.cpp b/libsrc/meshing/meshtype.cpp index 4a42abd8..9bebaec4 100644 --- a/libsrc/meshing/meshtype.cpp +++ b/libsrc/meshing/meshtype.cpp @@ -1124,26 +1124,6 @@ namespace netgen is_curved = typ != TET; // false; } - void Element :: DoArchive (Archive & ar) - { - short _np, _typ; - bool _curved; - if (ar.Output()) - { _np = np; _typ = typ; _curved = is_curved; } - ar & _np; - - // placement new to init flags - if (ar.Input()) - new (this) Element(_np); - - ar & _typ & index & _curved; - typ = ELEMENT_TYPE(_typ); - is_curved = _curved; - - static_assert(sizeof(int) == sizeof (PointIndex)); - ar.Do( (int*)&pnum[0], np); - } - void Element :: SetOrder (const int aorder) { orderx = aorder; diff --git a/libsrc/meshing/meshtype.hpp b/libsrc/meshing/meshtype.hpp index 21289121..72488d8a 100644 --- a/libsrc/meshing/meshtype.hpp +++ b/libsrc/meshing/meshtype.hpp @@ -378,9 +378,10 @@ namespace netgen void DoArchive (Archive & ar) { // ar & x[0] & x[1] & x[2] & layer & singular; - ar.Do(&x[0], 3); - ar & layer & singular; - ar & (unsigned char&)(type); + // ar.Do(&x[0], 3); + // ar & layer & singular; + // ar & (unsigned char&)(type); + ar.DoPacked (x[0], x[1], x[2], layer, singular, (unsigned char&)(type)); } }; @@ -558,13 +559,18 @@ namespace netgen if (ar.Output()) { _np = np; _typ = typ; _curved = is_curved; _vis = visible; _deleted = deleted; } - ar & _np & _typ & index & _curved & _vis & _deleted; + // ar & _np & _typ & index & _curved & _vis & _deleted; + ar.DoPacked (_np, _typ, index, _curved, _vis, _deleted); // ar & next; don't need if (ar.Input()) { np = _np; typ = ELEMENT_TYPE(_typ); is_curved = _curved; visible = _vis; deleted = _deleted; } + /* for (size_t i = 0; i < np; i++) ar & pnum[i]; + */ + static_assert(sizeof(int) == sizeof (PointIndex)); + ar.Do( (int*)&pnum[0], np); } #ifdef PARALLEL @@ -838,7 +844,35 @@ namespace netgen /// const PointIndex & PNumMod (int i) const { return pnum[(i-1) % np]; } - void DoArchive (Archive & ar); + void DoArchive (Archive & ar) + { + short _np, _typ; + bool _curved; + if (ar.Output()) + { _np = np; _typ = typ; _curved = is_curved; } + // ar & _np & _typ & index & _curved; + ar.DoPacked (_np, _typ, index, _curved); + + if (ar.Input()) + { + np = _np; + typ = ELEMENT_TYPE(_typ); + is_curved = _curved; + flags.marked = 1; + flags.badel = 0; + flags.reverse = 0; + flags.illegal = 0; + flags.illegal_valid = 0; + flags.badness_valid = 0; + flags.refflag = 1; + flags.strongrefflag = false; + flags.deleted = 0; + flags.fixed = 0; + } + + static_assert(sizeof(int) == sizeof (PointIndex)); + ar.Do( (int*)&pnum[0], np); + } #ifdef PARALLEL static MPI_Datatype MyGetMPIType();