From 0382ae631476b828398855cea556b14c16a120a5 Mon Sep 17 00:00:00 2001 From: Thomas Witkowski Date: Mon, 28 Sep 2009 11:10:54 +0000 Subject: [PATCH] Work on serialization and deserialization of parallel problems. --- AMDiS/src/InteriorBoundary.cc | 47 +++++++++++++++- AMDiS/src/InteriorBoundary.h | 6 +- AMDiS/src/ParallelDomainBase.cc | 99 ++++++++++++++++++++++++++++++++- AMDiS/src/ParallelDomainBase.h | 16 ++++++ AMDiS/src/Serializer.h | 44 +++++++++++++++ 5 files changed, 207 insertions(+), 5 deletions(-) diff --git a/AMDiS/src/InteriorBoundary.cc b/AMDiS/src/InteriorBoundary.cc index 2594017e..47411208 100644 --- a/AMDiS/src/InteriorBoundary.cc +++ b/AMDiS/src/InteriorBoundary.cc @@ -1,4 +1,5 @@ #include "InteriorBoundary.h" +#include "Serializer.h" namespace AMDiS { @@ -10,9 +11,53 @@ namespace AMDiS { void InteriorBoundary::serialize(std::ostream &out) { + int mSize = boundary.size(); + SerUtil::serialize(out, &mSize); + for (RankToBoundMap::iterator it = boundary.begin(); it != boundary.end(); ++it) { + int rank = it->first; + int boundSize = it->second.size(); + SerUtil::serialize(out, &rank); + SerUtil::serialize(out, &boundSize); + for (int i = 0; i < boundSize; i++) { + AtomicBoundary &bound = (it->second)[i]; + + SerUtil::serialize(out, &(bound.rankObject.elIndex)); + SerUtil::serialize(out, &(bound.rankObject.subObjAtBoundary)); + SerUtil::serialize(out, &(bound.rankObject.ithObjAtBoundary)); + + SerUtil::serialize(out, &(bound.neighbourObject.elIndex)); + SerUtil::serialize(out, &(bound.neighbourObject.subObjAtBoundary)); + SerUtil::serialize(out, &(bound.neighbourObject.ithObjAtBoundary)); + } + } } - void InteriorBoundary::deserialize(std::istream &in) + void InteriorBoundary::deserialize(std::istream &in, + std::map &elIndexMap) { + int mSize = 0; + SerUtil::deserialize(in, &mSize); + for (int i = 0; i < mSize; i++) { + int rank = 0; + int boundSize = 0; + SerUtil::deserialize(in, &rank); + SerUtil::deserialize(in, &boundSize); + + boundary[rank].resize(boundSize); + for (int i = 0; i < boundSize; i++) { + AtomicBoundary &bound = boundary[rank][i]; + + SerUtil::deserialize(in, &(bound.rankObject.elIndex)); + SerUtil::deserialize(in, &(bound.rankObject.subObjAtBoundary)); + SerUtil::deserialize(in, &(bound.rankObject.ithObjAtBoundary)); + + SerUtil::deserialize(in, &(bound.neighbourObject.elIndex)); + SerUtil::deserialize(in, &(bound.neighbourObject.subObjAtBoundary)); + SerUtil::deserialize(in, &(bound.neighbourObject.ithObjAtBoundary)); + + bound.rankObject.el = elIndexMap[bound.rankObject.elIndex]; + bound.neighbourObject.el = NULL; + } + } } } diff --git a/AMDiS/src/InteriorBoundary.h b/AMDiS/src/InteriorBoundary.h index 74e9eef9..a595db4a 100644 --- a/AMDiS/src/InteriorBoundary.h +++ b/AMDiS/src/InteriorBoundary.h @@ -26,6 +26,7 @@ #include #include "MacroElement.h" +#include "AMDiS_fwd.h" namespace AMDiS { @@ -81,14 +82,15 @@ namespace AMDiS { AtomicBoundary& getNewAtomicBoundary(int rank); + /// Writes this object to a file. void serialize(std::ostream &out); - void deserialize(std::istream &in); + /// Reads the state of an interior boundary from a file. + void deserialize(std::istream &in, std::map &elIndexMap); public: RankToBoundMap boundary; }; - } #endif // AMDIS_INTERIORBOUNDARY_H diff --git a/AMDiS/src/ParallelDomainBase.cc b/AMDiS/src/ParallelDomainBase.cc index fd75308e..bb0f6930 100644 --- a/AMDiS/src/ParallelDomainBase.cc +++ b/AMDiS/src/ParallelDomainBase.cc @@ -696,6 +696,62 @@ namespace AMDiS { delete [] sendBuffers[i]; } + + void ParallelDomainBase::serialize(std::ostream &out, DofContainer &data) + { + int vecSize = data.size(); + SerUtil::serialize(out, &vecSize); + for (int i = 0; i < vecSize; i++) { + int dofIndex = (*data[i]); + SerUtil::serialize(out, &dofIndex); + } + } + + + void ParallelDomainBase::deserialize(std::istream &in, DofContainer &data, + std::map &dofMap) + { + FUNCNAME("ParallelDomainBase::deserialize()"); + + int vecSize = 0; + SerUtil::deserialize(in, &vecSize); + data.resize(vecSize); + for (int i = 0; i < vecSize; i++) { + int dofIndex = 0; + SerUtil::deserialize(in, &dofIndex); + + TEST_EXIT_DBG(dofMap.count(dofIndex) != 0) + ("Dof index could not be deserialized correctly!\n"); + + data[i] = dofMap[dofIndex]; + } + } + + + void ParallelDomainBase::serialize(std::ostream &out, RankToDofContainer &data) + { + int mapSize = data.size(); + SerUtil::serialize(out, &mapSize); + for (RankToDofContainer::iterator it = data.begin(); it != data.end(); ++it) { + int rank = it->first; + SerUtil::serialize(out, &rank); + serialize(out, it->second); + } + } + + + void ParallelDomainBase::deserialize(std::istream &in, RankToDofContainer &data, + std::map &dofMap) + { + int mapSize = 0; + SerUtil::deserialize(in, &mapSize); + for (int i = 0; i < mapSize; i++) { + int rank = 0; + SerUtil::deserialize(in, &rank); + deserialize(in, data[rank], dofMap); + } + } + double ParallelDomainBase::setElemWeights(AdaptInfo *adaptInfo) { @@ -1542,8 +1598,8 @@ namespace AMDiS { myIntBoundary.serialize(out); otherIntBoundary.serialize(out); - // SerUtil::serialize(out, sendDofs); - // SerUtil::serialize(out, recvDofs); + serialize(out, sendDofs); + serialize(out, recvDofs); SerUtil::serialize(out, mapLocalGlobalDOFs); SerUtil::serialize(out, mapLocalToDofIndex); @@ -1559,6 +1615,45 @@ namespace AMDiS { void ParallelDomainBase::deserialize(std::istream &in) { + SerUtil::deserialize(in, elemWeights); + SerUtil::deserialize(in, &initialPartitionMesh); + SerUtil::deserialize(in, partitionVec); + SerUtil::deserialize(in, oldPartitionVec); + SerUtil::deserialize(in, &nRankDofs); + + // Create two maps: one from from element indices to the corresponding element + // pointers, and one map from Dof indices to the corresponding dof pointers. + std::map elIndexMap; + std::map dofMap; + ElementDofIterator elDofIter(feSpace); + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); + while (elInfo) { + Element *el = elInfo->getElement(); + elIndexMap[el->getIndex()] = el; + elInfo = stack.traverseNext(elInfo); + + elDofIter.reset(el); + do { + dofMap[elDofIter.getDof()] = elDofIter.getDofPtr(); + } while(elDofIter.next()); + } + + myIntBoundary.deserialize(in, elIndexMap); + otherIntBoundary.deserialize(in, elIndexMap); + + deserialize(in, sendDofs, dofMap); + deserialize(in, recvDofs, dofMap); + + SerUtil::deserialize(in, mapLocalGlobalDOFs); + SerUtil::deserialize(in, mapLocalToDofIndex); + SerUtil::deserialize(in, isRankDof); + + // SerUtil::deserialize(in, vertexDof); + + SerUtil::deserialize(in, &rstart); + SerUtil::deserialize(in, &nRankRows); + SerUtil::deserialize(in, &nOverallRows); } diff --git a/AMDiS/src/ParallelDomainBase.h b/AMDiS/src/ParallelDomainBase.h index 36538590..7cd8acc9 100644 --- a/AMDiS/src/ParallelDomainBase.h +++ b/AMDiS/src/ParallelDomainBase.h @@ -181,8 +181,10 @@ namespace AMDiS { return NULL; } + // Writes all data of this object to an output stream. virtual void serialize(std::ostream &out); + // Reads the object data from an input stream. virtual void deserialize(std::istream &in); protected: @@ -290,6 +292,20 @@ namespace AMDiS { */ void synchVectors(SystemVector &vec); + /// Writes a vector of dof pointers to an output stream. + void serialize(std::ostream &out, DofContainer &data); + + /// Reads a vector of dof pointers from an input stream. + void deserialize(std::istream &in, DofContainer &data, + std::map &dofMap); + + /// Writes a \ref RankToDofContainer to an output stream. + void serialize(std::ostream &out, RankToDofContainer &data); + + /// Reads a \ref RankToDofContainer from an input stream. + void deserialize(std::istream &in, RankToDofContainer &data, + std::map &dofMap); + inline void orderDOFs(const DegreeOfFreedom* dof1, const DegreeOfFreedom* dof2, const DegreeOfFreedom* dof3, diff --git a/AMDiS/src/Serializer.h b/AMDiS/src/Serializer.h index 06c47986..10fdc45d 100644 --- a/AMDiS/src/Serializer.h +++ b/AMDiS/src/Serializer.h @@ -101,6 +101,34 @@ namespace AMDiS { in.read(reinterpret_cast(data), sizeof(T)); } + + template + void serialize(std::ostream &out, std::vector &data) + { + int vecSize = data.size(); + serialize(out, &vecSize); + for (typename std::vector::iterator it = data.begin(); + it != data.end(); ++it) { + T v = *it; + serialize(out, &v); + } + } + + template + void deserialize(std::istream &in, std::vector &data) + { + int vecSize = 0; + deserialize(in, &vecSize); + data.resize(vecSize); + + for (int i = 0; i < vecSize; i++) { + T v; + deserialize(in, &v); + data[i] = v; + } + } + + template void serialize(std::ostream &out, std::map &data) { @@ -115,6 +143,22 @@ namespace AMDiS { serialize(out, &v2); } } + + template + void deserialize(std::istream &in, std::map &data) + { + int mapSize = 0; + deserialize(in, &mapSize); + + for (int i = 0; i < mapSize; i++) { + T1 v1; + T2 v2; + deserialize(in, &v1); + deserialize(in, &v2); + data[v1] = v2; + } + } + } } -- GitLab