OpenLB 1.7
Loading...
Searching...
No Matches
serializer.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2016 Mathias J. Krause, Benjamin Förster
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24
25#ifndef SERIALIZER_H
26#define SERIALIZER_H
27
28#include <iostream>
29#include <vector>
30#include <map>
31#include <utility>
32
33namespace olb {
34
35class Serializable;
36
38
42
43private:
45 Serializable& _serializable;
47 std::size_t _iBlock;
49 std::size_t _size;
51 std::string _fileName;
52
53public:
55
58 Serializer(Serializable& serializable, std::string fileName = "");
59
61 void resetCounter();
62
64 std::size_t getSize() const;
65
67 bool* getNextBlock(std::size_t& sizeBlock, const bool loadingMode);
68
70 template<bool includeLogOutputDir=true>
71 bool load(std::string fileName = "", const bool enforceUint=false);
73 template<bool includeLogOutputDir=true>
74 bool save(std::string fileName = "", const bool enforceUint=false);
75
77 bool load(const std::uint8_t* buffer);
79 bool save(std::uint8_t* buffer);
80
82 void computeSize(const bool enforceRecompute=false);
83
84private:
86 void validateFileName(std::string &fileName);
88 template<bool includeLogOutputDir=true>
89 const std::string getFullFileName(const std::string& fileName);
90};
91
92
94
146public:
147 virtual ~Serializable() = default;
148
150
164 virtual bool* getBlock(const std::size_t iBlock, std::size_t& sizeBlock,
165 const bool loadingMode = false) = 0;
166
168
171 virtual std::size_t getNblock() const = 0;
172
174
177 virtual std::size_t getSerializableSize() const = 0;
178
180 template<bool includeLogOutputDir=true>
181 bool save(std::string fileName = "", const bool enforceUint=false);
183 template<bool includeLogOutputDir=true>
184 bool load(std::string fileName = "", const bool enforceUint=false);
185
187 bool save(std::uint8_t* buffer);
189 bool load(const std::uint8_t* buffer);
190
191 virtual void postLoad() { };
192
193protected:
195
211 template<typename DataType>
212 void registerVar(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, bool *&dataPtr,
213 const DataType &data, const size_t arrayLength = 1) const
214 {
215 if (iBlock == currentBlock) {
216 sizeBlock = sizeof(DataType) * arrayLength;
217 dataPtr = (bool *) (&data);
218 }
219 currentBlock++;
220 }
221
222
224
238 template<typename DataType>
239 void registerSerializableOfConstSize(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock,
240 bool *&dataPtr, DataType &data, const bool loadingMode=false)
241 {
242 if (iBlock >= currentBlock && iBlock < currentBlock + data.getNblock()) {
243 dataPtr = data.getBlock(iBlock - currentBlock, sizeBlock, loadingMode);
244 }
245 currentBlock += data.getNblock();
246 }
247
249
260 template<typename DataType>
261 void registerSerializablesOfConstSize(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock,
262 bool *&dataPtr, DataType* data, const size_t arrayLength,
263 const bool loadingMode=false)
264 {
265 static_assert(std::is_base_of<Serializable, DataType>::value, "DataType must be a Serializable.");
266
267 if ( arrayLength > 0 ) {
268 if (iBlock >= currentBlock && iBlock < currentBlock + arrayLength * data[0].getNblock()) {
269 size_t local_iBlock = iBlock - currentBlock;
270 size_t dataBlockCount = data[0].getNblock();
271 dataPtr = data[local_iBlock / dataBlockCount].getBlock(local_iBlock % dataBlockCount, sizeBlock, loadingMode);
272 }
273 currentBlock += arrayLength * data[0].getNblock();
274 }
275 }
276};
277
278
280
300protected:
302
307 mutable std::vector<bool*> _dataBuffer;
309
313 mutable std::vector<size_t> _sizeBuffer;
314
315
317
328 template<typename DataType>
329 void registerSerializable(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock,
330 size_t &sizeBufferIndex, bool *&dataPtr, DataType &data,
331 const bool loadingMode=false)
332 {
333 static_assert(std::is_base_of<Serializable, DataType>::value, "DataType must be a Serializable.");
334
335 size_t dataBlockCount = 0;
336
337 // hold getNblock() in sizeBuffer
338 if (loadingMode) { // loading -> set to 0 and wait for reading next util::round
339 dataBlockCount = addSizeToBuffer(iBlock, sizeBlock, currentBlock, sizeBufferIndex, dataPtr, 0);
340 }
341 else { // saving -> save getNblock from data object
342 dataBlockCount = addSizeToBuffer(iBlock, sizeBlock, currentBlock, sizeBufferIndex, dataPtr, data.getNblock());
343 }
344
345 if (iBlock >= currentBlock) {
346 if (iBlock < currentBlock + dataBlockCount) {
347 dataPtr = data.getBlock(iBlock - currentBlock, sizeBlock, loadingMode);
348 }
349 }
350 }
351
353
370 template<typename DataType>
371 void registerStdVectorOfVars(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock,
372 size_t &sizeBufferIndex, bool *&dataPtr, std::vector<DataType> &data,
373 const bool loadingMode = false)
374 {
375 if (iBlock >= currentBlock) {
376 // process length of data vector
377 size_t sizeOfVector = addSizeToBuffer(iBlock, sizeBlock, currentBlock, sizeBufferIndex, dataPtr, data.size());
378
379 // resize data vector from buffer (only for loading)
380 if (iBlock == currentBlock && loadingMode) {
381 data.resize(_sizeBuffer[sizeBufferIndex - 1]);
382 }
383
384 if (iBlock >= currentBlock && iBlock < currentBlock + sizeOfVector) {
385 sizeBlock = sizeof(DataType);
386 dataPtr = (bool *) (&data[iBlock - currentBlock]);
387 }
388 currentBlock += sizeOfVector;
389 }
390 }
391
392
394
417 template<typename DataType>
418 void registerStdVectorOfSerializablesOfConstSize(const std::size_t iBlock, std::size_t &sizeBlock,
419 std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr,
420 std::vector<DataType> &data, const bool loadingMode = false)
421 {
422 static_assert(std::is_base_of<Serializable, DataType>::value, "DataType must be a Serializable.");
423
424 if (iBlock >= currentBlock) {
425 // process length of data vector
426 size_t sizeOfVector = addSizeToBuffer(iBlock, sizeBlock, currentBlock, sizeBufferIndex, dataPtr, data.size());
427
428 // resize data vector from buffer (only for loading)
429 if (iBlock == currentBlock && loadingMode) {
430 data.resize(_sizeBuffer[sizeBufferIndex - 1]);
431 }
432
433
434 // process Serializables
435 if (iBlock >= currentBlock && sizeOfVector > 0) {
436 for ( DataType& dataValue : data ) {
437 registerSerializableOfConstSize(iBlock, sizeBlock, currentBlock, dataPtr, dataValue, loadingMode);
438 }
439 }
440 }
441 }
442
443
444
446
470 template<typename DataType>
471 void registerStdVectorOfSerializables(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock,
472 size_t &sizeBufferIndex, bool *&dataPtr, std::vector<DataType> &data,
473 const bool loadingMode = false)
474 {
475 static_assert(std::is_base_of<Serializable, DataType>::value, "DataType must be a Serializable.");
476
477 if (iBlock >= currentBlock) {
478 // process length of data vector
479 size_t sizeOfVector = addSizeToBuffer(iBlock, sizeBlock, currentBlock, sizeBufferIndex, dataPtr, data.size());
480
481 // resize data vector from buffer (only for loading)
482 if (iBlock == currentBlock && loadingMode) {
483 data.resize(_sizeBuffer[sizeBufferIndex - 1]);
484 }
485
486 // process Serializables
487 if (iBlock >= currentBlock && sizeOfVector > 0) {
488 for ( DataType& dataValue : data ) {
489 registerSerializable(iBlock, sizeBlock, currentBlock, sizeBufferIndex, dataPtr, dataValue, loadingMode);
490 }
491 }
492 }
493 }
494
495
496
498
521 template<typename DataTypeKey, typename DataTypeValue>
522 void registerMap(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex,
523 bool *&dataPtr, std::map<DataTypeKey, DataTypeValue> &data, const bool loadingMode = false)
524 {
525 if (iBlock >= currentBlock) {
526 // process length of data map
527 size_t sizeOfMap = addSizeToBuffer(iBlock, sizeBlock, currentBlock, sizeBufferIndex, dataPtr, data.size());
528
529 if (iBlock >= currentBlock && iBlock < currentBlock + sizeOfMap + 1) {
530 // determine size of pair
531 sizeBlock = sizeof(std::pair<DataTypeKey, DataTypeValue>);
532
533 // LOADING MODE
534 if (loadingMode) {
535 // If pair in dataBuffer => insert into data and delete
536 if (iBlock > currentBlock) {
537 std::pair<DataTypeKey, DataTypeValue> *pairPtr = (std::pair<DataTypeKey, DataTypeValue> *) _dataBuffer.back();
538 data.insert(*pairPtr); // copy pair into map
539 delete pairPtr; // delete pair object that was created (with new!) in the buffer
540 _dataBuffer.pop_back(); // remove pointer to deleted pair from buffer vector
541 }
542
543 // push new pair into buffer and return pointer
544 if (iBlock < currentBlock + sizeOfMap) {
545 _dataBuffer.push_back((bool *) new std::pair<DataTypeKey, DataTypeValue>);
546 dataPtr = _dataBuffer.back();
547 }
548 }
549
550 // SAVING MODE
551 else {
552 if (iBlock < currentBlock + sizeOfMap) {
553 // advance through iterator to n-th element and return pointer to pair
554 auto map_it = data.begin();
555 std::advance(map_it, iBlock - currentBlock);
556 dataPtr = (bool *) (&(*map_it));
557 }
558 }
559 }
560 currentBlock += sizeOfMap;
561 }
562 }
563
564
566
571 size_t addSizeToBuffer(const std::size_t iBlock, std::size_t& sizeBlock, std::size_t&currentBlock,
572 size_t& sizeBufferIndex, bool*& dataPtr, const size_t data) const
573 {
574 size_t returnSize = 0;
575
576 if (iBlock == currentBlock) {
577 // write size into _sizeBuffer vector
578 _sizeBuffer.push_back(*new size_t(data));
579 }
580
581 if (iBlock >= currentBlock) {
582 returnSize = _sizeBuffer[sizeBufferIndex];
583 }
584
585 // register size as var
586 registerVar(iBlock, sizeBlock, currentBlock, dataPtr, _sizeBuffer[sizeBufferIndex]);
587 sizeBufferIndex++;
588
589 return returnSize;
590 }
591};
592
593} // namespace olb
594
595#endif
Base class for serializable objects of dynamic size
Definition serializer.h:299
void registerStdVectorOfVars(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, std::vector< DataType > &data, const bool loadingMode=false)
Method for registering a std::vector<DataType> of primitive DataType (int, double,...
Definition serializer.h:371
std::vector< size_t > _sizeBuffer
std::vector of integer buffers (e.g. for std::vector size) to be buffered for the whole iteration pro...
Definition serializer.h:313
void registerMap(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, std::map< DataTypeKey, DataTypeValue > &data, const bool loadingMode=false)
Method for registering a std::map<DataTypeKey, DataTypeValue> of fixed-sized types (i....
Definition serializer.h:522
void registerStdVectorOfSerializablesOfConstSize(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, std::vector< DataType > &data, const bool loadingMode=false)
Method for registering a std::vector<DataType> of constant-sized Serializable
Definition serializer.h:418
std::vector< bool * > _dataBuffer
Data buffer for data that has to be buffered between two getBlock() iterations.
Definition serializer.h:307
void registerStdVectorOfSerializables(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, std::vector< DataType > &data, const bool loadingMode=false)
Method for registering a std::vector<DataType> of dynamic-sized DataType
Definition serializer.h:471
void registerSerializable(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, DataType &data, const bool loadingMode=false)
Register Serializable object of dynamic size.
Definition serializer.h:329
size_t addSizeToBuffer(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, const size_t data) const
Add a size_t to the sizeBuffer in the n-th util::round and return that size_t in all successive round...
Definition serializer.h:571
Base class for serializable objects of constant size. For dynamic size use BufferSerializable.
Definition serializer.h:145
virtual std::size_t getNblock() const =0
Returns the number of blocks.
virtual bool * getBlock(const std::size_t iBlock, std::size_t &sizeBlock, const bool loadingMode=false)=0
Returns the address of the i-th block and its size.
void registerVar(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, bool *&dataPtr, const DataType &data, const size_t arrayLength=1) const
Register primitive data types (int, double, ...) or arrays of those.
Definition serializer.h:212
void registerSerializablesOfConstSize(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, bool *&dataPtr, DataType *data, const size_t arrayLength, const bool loadingMode=false)
Register an array of Serializable objects of constant size.
Definition serializer.h:261
virtual ~Serializable()=default
virtual std::size_t getSerializableSize() const =0
Returns the binary size of the data to be saved.
bool save(std::string fileName="", const bool enforceUint=false)
Save Serializable into file fileName
bool load(std::string fileName="", const bool enforceUint=false)
Load Serializable from file fileName
void registerSerializableOfConstSize(const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, bool *&dataPtr, DataType &data, const bool loadingMode=false)
Register Serializable object of constant size.
Definition serializer.h:239
virtual void postLoad()
Definition serializer.h:191
Class for writing, reading, sending and receiving Serializable objects.
Definition serializer.h:41
void resetCounter()
Resets the _iBlock counter.
Definition serializer.hh:49
std::size_t getSize() const
Returns the total memory size in bits.
Definition serializer.hh:54
bool load(std::string fileName="", const bool enforceUint=false)
Loads a file and pushes the data into the serialized class. Always in parallel, i....
Definition serializer.hh:65
bool save(std::string fileName="", const bool enforceUint=false)
Save _serializable into file filename. Always in parallel, i.e. one file per rank.
Definition serializer.hh:81
void computeSize(const bool enforceRecompute=false)
computes _size based on the individual definition of getBlock()
Serializer(Serializable &serializable, std::string fileName="")
Constructor.
Definition serializer.hh:44
bool * getNextBlock(std::size_t &sizeBlock, const bool loadingMode)
Returns pointer to the memory of the current block and increments iBlock
Definition serializer.hh:59
Top level namespace for all of OpenLB.