From 13579ff884b71401b57df5441b437bd59595f55c Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Tue, 29 Sep 2009 13:35:25 +0000 Subject: [PATCH] Serialization and deserialization of parallel domain problems should now work correctly. --- AMDiS/libtool | 6 +- AMDiS/src/AdaptInfo.cc | 179 ++++++++++++++----------------- AMDiS/src/CreatorMap.cc | 6 +- AMDiS/src/DOFAdmin.cc | 55 +++------- AMDiS/src/DOFMatrix.cc | 62 ++++++++++- AMDiS/src/DOFMatrix.h | 76 +------------ AMDiS/src/Element.cc | 35 +++--- AMDiS/src/ElementFileWriter.cc | 4 +- AMDiS/src/FileWriter.cc | 18 ++-- AMDiS/src/InteriorBoundary.cc | 36 +++---- AMDiS/src/Lagrange.cc | 17 ++- AMDiS/src/MacroElement.cc | 98 ++++++++--------- AMDiS/src/MacroElement.h | 10 +- AMDiS/src/Mesh.cc | 137 +++++++++-------------- AMDiS/src/ParallelDomainBase.cc | 49 +++++---- AMDiS/src/ParallelDomainBase.h | 20 ++-- AMDiS/src/ParallelDomainVec.cc | 15 +++ AMDiS/src/ParallelDomainVec.h | 3 + AMDiS/src/ParallelProblem.cc | 15 ++- AMDiS/src/PartitionElementData.h | 13 +-- AMDiS/src/ProblemVec.cc | 66 +++++------- AMDiS/src/ProblemVec.h | 5 +- AMDiS/src/Serializer.h | 41 +++---- 23 files changed, 451 insertions(+), 515 deletions(-) diff --git a/AMDiS/libtool b/AMDiS/libtool index 5984c8db..486eabd3 100755 --- a/AMDiS/libtool +++ b/AMDiS/libtool @@ -44,7 +44,7 @@ available_tags=" CXX F77" # ### BEGIN LIBTOOL CONFIG -# Libtool was configured on host p2d125: +# Libtool was configured on host deimos103: # Shell to use when invoking shell scripts. SHELL="/bin/sh" @@ -6760,7 +6760,7 @@ build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` # End: # ### BEGIN LIBTOOL TAG CONFIG: CXX -# Libtool was configured on host p2d125: +# Libtool was configured on host deimos103: # Shell to use when invoking shell scripts. SHELL="/bin/sh" @@ -7065,7 +7065,7 @@ include_expsyms="" # ### BEGIN LIBTOOL TAG CONFIG: F77 -# Libtool was configured on host p2d125: +# Libtool was configured on host deimos103: # Shell to use when invoking shell scripts. SHELL="/bin/sh" diff --git a/AMDiS/src/AdaptInfo.cc b/AMDiS/src/AdaptInfo.cc index 4829f3f7..262ae05b 100644 --- a/AMDiS/src/AdaptInfo.cc +++ b/AMDiS/src/AdaptInfo.cc @@ -1,122 +1,105 @@ -#include <AdaptInfo.h> +#include "boost/lexical_cast.hpp" +#include "AdaptInfo.h" +#include "Serializer.h" namespace AMDiS { - void AdaptInfo::setScalContents(int newSize) { + using boost::lexical_cast; + + void AdaptInfo::setScalContents(int newSize) + { int oldSize = scalContents.getSize(); if (newSize > oldSize) { scalContents.resize(newSize); - char number[5]; - for (int i = oldSize; i < newSize; i++) { - sprintf(number, "[%d]", i); - scalContents[i] = new ScalContent(name + std::string(number)); - } + for (int i = oldSize; i < newSize; i++) + scalContents[i] = + new ScalContent(name + "[" + lexical_cast<std::string>(i) + "]"); } } - void AdaptInfo::serialize(std::ostream& out) { + void AdaptInfo::serialize(std::ostream& out) + { out << name << "\n"; - out.write(reinterpret_cast<const char*>(&maxSpaceIteration), sizeof(int)); - out.write(reinterpret_cast<const char*>(&spaceIteration), sizeof(int)); - out.write(reinterpret_cast<const char*>(×tepIteration), sizeof(int)); - out.write(reinterpret_cast<const char*>(&maxTimestepIteration), sizeof(int)); - out.write(reinterpret_cast<const char*>(&timeIteration), sizeof(int)); - out.write(reinterpret_cast<const char*>(&maxTimeIteration), sizeof(int)); - out.write(reinterpret_cast<const char*>(&time), sizeof(double)); - out.write(reinterpret_cast<const char*>(&startTime), sizeof(double)); - out.write(reinterpret_cast<const char*>(&endTime), sizeof(double)); - out.write(reinterpret_cast<const char*>(×tep), sizeof(double)); - out.write(reinterpret_cast<const char*>(&minTimestep), sizeof(double)); - out.write(reinterpret_cast<const char*>(&maxTimestep), sizeof(double)); - out.write(reinterpret_cast<const char*>(×tepNumber), sizeof(int)); - out.write(reinterpret_cast<const char*>(&nTimesteps), sizeof(int)); - out.write(reinterpret_cast<const char*>(&solverIterations), sizeof(int)); - out.write(reinterpret_cast<const char*>(&maxSolverIterations), sizeof(int)); - out.write(reinterpret_cast<const char*>(&solverTolerance), sizeof(double)); - out.write(reinterpret_cast<const char*>(&solverResidual), sizeof(double)); + + SerUtil::serialize(out, maxSpaceIteration); + SerUtil::serialize(out, spaceIteration); + SerUtil::serialize(out, timestepIteration); + SerUtil::serialize(out, maxTimestepIteration); + SerUtil::serialize(out, timeIteration); + SerUtil::serialize(out, maxTimeIteration); + SerUtil::serialize(out, time); + SerUtil::serialize(out, startTime); + SerUtil::serialize(out, endTime); + SerUtil::serialize(out, timestep); + SerUtil::serialize(out, minTimestep); + SerUtil::serialize(out, maxTimestep); + SerUtil::serialize(out, timestepNumber); + SerUtil::serialize(out, nTimesteps); + SerUtil::serialize(out, solverIterations); + SerUtil::serialize(out, maxSolverIterations); + SerUtil::serialize(out, solverTolerance); + SerUtil::serialize(out, solverResidual); + int size = scalContents.getSize(); - out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + SerUtil::serialize(out, size); for (int i = 0; i < size; i++) { - out.write(reinterpret_cast<const char*>(&(scalContents[i]->est_sum)), - sizeof(double)); - out.write(reinterpret_cast<const char*>(&(scalContents[i]->est_t_sum)), - sizeof(double)); - out.write(reinterpret_cast<const char*>(&(scalContents[i]->est_max)), - sizeof(double)); - out.write(reinterpret_cast<const char*>(&(scalContents[i]->est_t_max)), - sizeof(double)); - out.write(reinterpret_cast<const char*>(&(scalContents[i]->spaceTolerance)), - sizeof(double)); - out.write(reinterpret_cast<const char*>(&(scalContents[i]->timeTolerance)), - sizeof(double)); - out.write(reinterpret_cast<const char*>(&(scalContents[i]->timeErrLow)), - sizeof(double)); - out.write(reinterpret_cast<const char*>(&(scalContents[i]->coarsenAllowed)), - sizeof(int)); - out.write(reinterpret_cast<const char*>(&(scalContents[i]->refinementAllowed)), - sizeof(int)); - out.write(reinterpret_cast<const char*>(&(scalContents[i]->refineBisections)), - sizeof(int)); - out.write(reinterpret_cast<const char*>(&(scalContents[i]->coarseBisections)), - sizeof(int)); + SerUtil::serialize(out, scalContents[i]->est_sum); + SerUtil::serialize(out, scalContents[i]->est_t_sum); + SerUtil::serialize(out, scalContents[i]->est_max); + SerUtil::serialize(out, scalContents[i]->est_t_max); + SerUtil::serialize(out, scalContents[i]->spaceTolerance); + SerUtil::serialize(out, scalContents[i]->timeTolerance); + SerUtil::serialize(out, scalContents[i]->timeErrLow); + SerUtil::serialize(out, scalContents[i]->coarsenAllowed); + SerUtil::serialize(out, scalContents[i]->refinementAllowed); + SerUtil::serialize(out, scalContents[i]->refineBisections); + SerUtil::serialize(out, scalContents[i]->coarseBisections); } } - void AdaptInfo::deserialize(std::istream& in) { + void AdaptInfo::deserialize(std::istream& in) + { in >> name; - in.get(); // because of std::endl in serialization + in.get(); - in.read(reinterpret_cast<char*>(&maxSpaceIteration), sizeof(int)); - in.read(reinterpret_cast<char*>(&spaceIteration), sizeof(int)); - in.read(reinterpret_cast<char*>(×tepIteration), sizeof(int)); - in.read(reinterpret_cast<char*>(&maxTimestepIteration), sizeof(int)); - in.read(reinterpret_cast<char*>(&timeIteration), sizeof(int)); - in.read(reinterpret_cast<char*>(&maxTimeIteration), sizeof(int)); - in.read(reinterpret_cast<char*>(&time), sizeof(double)); - in.read(reinterpret_cast<char*>(&startTime), sizeof(double)); - in.read(reinterpret_cast<char*>(&endTime), sizeof(double)); - in.read(reinterpret_cast<char*>(×tep), sizeof(double)); - in.read(reinterpret_cast<char*>(&minTimestep), sizeof(double)); - in.read(reinterpret_cast<char*>(&maxTimestep), sizeof(double)); - in.read(reinterpret_cast<char*>(×tepNumber), sizeof(int)); - in.read(reinterpret_cast<char*>(&nTimesteps), sizeof(int)); - in.read(reinterpret_cast<char*>(&solverIterations), sizeof(int)); - in.read(reinterpret_cast<char*>(&maxSolverIterations), sizeof(int)); - in.read(reinterpret_cast<char*>(&solverTolerance), sizeof(double)); - in.read(reinterpret_cast<char*>(&solverResidual), sizeof(double)); - int size; - in.read(reinterpret_cast<char*>(&size), sizeof(int)); + SerUtil::deserialize(in, maxSpaceIteration); + SerUtil::deserialize(in, spaceIteration); + SerUtil::deserialize(in, timestepIteration); + SerUtil::deserialize(in, maxTimestepIteration); + SerUtil::deserialize(in, timeIteration); + SerUtil::deserialize(in, maxTimeIteration); + SerUtil::deserialize(in, time); + SerUtil::deserialize(in, startTime); + SerUtil::deserialize(in, endTime); + SerUtil::deserialize(in, timestep); + SerUtil::deserialize(in, minTimestep); + SerUtil::deserialize(in, maxTimestep); + SerUtil::deserialize(in, timestepNumber); + SerUtil::deserialize(in, nTimesteps); + SerUtil::deserialize(in, solverIterations); + SerUtil::deserialize(in, maxSolverIterations); + SerUtil::deserialize(in, solverTolerance); + SerUtil::deserialize(in, solverResidual); + int size = 0; + SerUtil::deserialize(in, size); scalContents.resize(size); for (int i = 0; i < size; i++) { - // if (!scalContents[i]) { - char number[5]; - sprintf(number, "[%d]", i); - scalContents[i] = new ScalContent(name + std::string(number)); - // } - in.read(reinterpret_cast<char*>(&(scalContents[i]->est_sum)), - sizeof(double)); - in.read(reinterpret_cast<char*>(&(scalContents[i]->est_t_sum)), - sizeof(double)); - in.read(reinterpret_cast<char*>(&(scalContents[i]->est_max)), - sizeof(double)); - in.read(reinterpret_cast<char*>(&(scalContents[i]->est_t_max)), - sizeof(double)); - in.read(reinterpret_cast<char*>(&(scalContents[i]->spaceTolerance)), - sizeof(double)); - in.read(reinterpret_cast<char*>(&(scalContents[i]->timeTolerance)), - sizeof(double)); - in.read(reinterpret_cast<char*>(&(scalContents[i]->timeErrLow)), - sizeof(double)); - in.read(reinterpret_cast<char*>(&(scalContents[i]->coarsenAllowed)), - sizeof(int)); - in.read(reinterpret_cast<char*>(&(scalContents[i]->refinementAllowed)), - sizeof(int)); - in.read(reinterpret_cast<char*>(&(scalContents[i]->refineBisections)), - sizeof(int)); - in.read(reinterpret_cast<char*>(&(scalContents[i]->coarseBisections)), - sizeof(int)); + scalContents[i] = + new ScalContent(name + "[" + lexical_cast<std::string>(i) + "]"); + + SerUtil::deserialize(in, scalContents[i]->est_sum); + SerUtil::deserialize(in, scalContents[i]->est_t_sum); + SerUtil::deserialize(in, scalContents[i]->est_max); + SerUtil::deserialize(in, scalContents[i]->est_t_max); + SerUtil::deserialize(in, scalContents[i]->spaceTolerance); + SerUtil::deserialize(in, scalContents[i]->timeTolerance); + SerUtil::deserialize(in, scalContents[i]->timeErrLow); + SerUtil::deserialize(in, scalContents[i]->coarsenAllowed); + SerUtil::deserialize(in, scalContents[i]->refinementAllowed); + SerUtil::deserialize(in, scalContents[i]->refineBisections); + SerUtil::deserialize(in, scalContents[i]->coarseBisections); } } diff --git a/AMDiS/src/CreatorMap.cc b/AMDiS/src/CreatorMap.cc index ccda871a..6fbc46bc 100644 --- a/AMDiS/src/CreatorMap.cc +++ b/AMDiS/src/CreatorMap.cc @@ -10,8 +10,9 @@ #include "ResidualEstimator.h" #include "LeafData.h" #include "SurfaceRegion_ED.h" -#include "DOFMatrix.h" #include "ElementRegion_ED.h" +#include "PartitionElementData.h" +#include "DOFMatrix.h" #include "UmfPackSolver.h" namespace AMDiS { @@ -141,6 +142,9 @@ namespace AMDiS { creator = new ElementRegion_ED::Creator; addCreator("ElementRegion_ED", creator); + + creator = new PartitionElementData::Creator; + addCreator("PartitionElementData", creator); } } diff --git a/AMDiS/src/DOFAdmin.cc b/AMDiS/src/DOFAdmin.cc index 4aad64e9..128530f0 100755 --- a/AMDiS/src/DOFAdmin.cc +++ b/AMDiS/src/DOFAdmin.cc @@ -10,6 +10,7 @@ #include "Mesh.h" #include "DOFVector.h" #include "DOFIterator.h" +#include "Serializer.h" namespace AMDiS { @@ -331,31 +332,19 @@ namespace AMDiS { // write dofFree int s = static_cast<int>(dofFree.size()); - out.write(reinterpret_cast<const char*>(&s), sizeof(int)); + SerUtil::serialize(out, s); for (int i = 0; i < s; i++) { - bool free = dofFree[i]; - out.write(reinterpret_cast<const char*>(&free), sizeof(bool)); + bool free = dofFree[i]; + SerUtil::serialize(out, free); } - // write firstHole - out.write(reinterpret_cast<const char*>(&firstHole), sizeof(unsigned int)); + SerUtil::serialize(out, firstHole); + SerUtil::serialize(out, size); + SerUtil::serialize(out, usedCount); + SerUtil::serialize(out, holeCount); + SerUtil::serialize(out, sizeUsed); - // write size - out.write(reinterpret_cast<const char*>(&size), sizeof(int)); - - // write usedCount - out.write(reinterpret_cast<const char*>(&usedCount), sizeof(int)); - - // write holeCount - out.write(reinterpret_cast<const char*>(&holeCount), sizeof(int)); - - // write sizeUsed - out.write(reinterpret_cast<const char*>(&sizeUsed), sizeof(int)); - - // write nrDOF nrDOF.serialize(out); - - // write nr0DOF nr0DOF.serialize(out); } @@ -367,33 +356,21 @@ namespace AMDiS { // read dofFree int s; - in.read(reinterpret_cast<char*>(&s), sizeof(int)); + SerUtil::deserialize(in, s); dofFree.resize(s); for (int i = 0; i < s; i++) { bool free; - in.read(reinterpret_cast<char*>(&free), sizeof(bool)); + SerUtil::deserialize(in, free); dofFree[i] = free; } - // read firstHole - in.read(reinterpret_cast<char*>(&firstHole), sizeof(unsigned int)); + SerUtil::deserialize(in, firstHole); + SerUtil::deserialize(in, size); + SerUtil::deserialize(in, usedCount); + SerUtil::deserialize(in, holeCount); + SerUtil::deserialize(in, sizeUsed); - // read size - in.read(reinterpret_cast<char*>(&size), sizeof(int)); - - // read usedCount - in.read(reinterpret_cast<char*>(&usedCount), sizeof(int)); - - // read holeCount - in.read(reinterpret_cast<char*>(&holeCount), sizeof(int)); - - // read sizeUsed - in.read(reinterpret_cast<char*>(&sizeUsed), sizeof(int)); - - // read nrDOF nrDOF.deserialize(in); - - // read nr0DOF nr0DOF.deserialize(in); std::list<DOFIndexedBase*>::iterator di; diff --git a/AMDiS/src/DOFMatrix.cc b/AMDiS/src/DOFMatrix.cc index d8686419..f99efee1 100644 --- a/AMDiS/src/DOFMatrix.cc +++ b/AMDiS/src/DOFMatrix.cc @@ -14,7 +14,7 @@ #include "BoundaryCondition.h" #include "BoundaryManager.h" #include "Assembler.h" - +#include "Serializer.h" namespace AMDiS { @@ -376,9 +376,67 @@ namespace AMDiS { operatorEstFactor.push_back(estFactor); } + void DOFMatrix::serialize(std::ostream &out) + { + using namespace mtl; + + typedef traits::range_generator<tag::major, base_matrix_type>::type c_type; + typedef traits::range_generator<tag::nz, c_type>::type ic_type; + + typedef Collection<base_matrix_type>::size_type size_type; + typedef Collection<base_matrix_type>::value_type value_type; + + traits::row<base_matrix_type>::type row(matrix); + traits::col<base_matrix_type>::type col(matrix); + traits::const_value<base_matrix_type>::type value(matrix); + + size_type rows= num_rows(matrix), cols= num_cols(matrix), total= matrix.nnz(); + SerUtil::serialize(out, rows); + SerUtil::serialize(out, cols); + SerUtil::serialize(out, total); + + for (c_type cursor(mtl::begin<tag::major>(matrix)), + cend(mtl::end<tag::major>(matrix)); cursor != cend; ++cursor) + for (ic_type icursor(mtl::begin<tag::nz>(cursor)), + icend(mtl::end<tag::nz>(cursor)); icursor != icend; ++icursor) { + size_type my_row= row(*icursor), my_col= col(*icursor); + value_type my_value= value(*icursor); + SerUtil::serialize(out, my_row); + SerUtil::serialize(out, my_col); + SerUtil::serialize(out, my_value); + } + } + + void DOFMatrix::deserialize(std::istream &in) + { + using namespace mtl; + + typedef Collection<base_matrix_type>::size_type size_type; + typedef Collection<base_matrix_type>::value_type value_type; + + size_type rows, cols, total; + SerUtil::deserialize(in, rows); + SerUtil::deserialize(in, cols); + SerUtil::deserialize(in, total); + + // Prepare matrix insertion + clear(); + // matrix.change_dim(rows, cols) // do we want this? + inserter_type ins(matrix); + + for (size_type i = 0; i < total; ++i) { + size_type my_row, my_col; + value_type my_value; + SerUtil::deserialize(in, my_row); + SerUtil::deserialize(in, my_col); + SerUtil::deserialize(in, my_value); + ins(my_row, my_col) << my_value; + } + } + void DOFMatrix::copy(const DOFMatrix& rhs) { - matrix= rhs.matrix; + matrix = rhs.matrix; } void DOFMatrix::removeRowsWithDBC(std::set<int> *rows) diff --git a/AMDiS/src/DOFMatrix.h b/AMDiS/src/DOFMatrix.h index 2838cb17..6e427391 100644 --- a/AMDiS/src/DOFMatrix.h +++ b/AMDiS/src/DOFMatrix.h @@ -399,79 +399,11 @@ namespace AMDiS { return nnzPerRow; } - private: - template <typename T> - void s_write(::std::ostream &out, const T& value) - { - out.write(reinterpret_cast<const char*>(&value), sizeof value); - } - - public: - void serialize(::std::ostream &out) - { - using namespace mtl; - - typedef traits::range_generator<tag::major, base_matrix_type>::type c_type; - typedef traits::range_generator<tag::nz, c_type>::type ic_type; - - typedef Collection<base_matrix_type>::size_type size_type; - typedef Collection<base_matrix_type>::value_type value_type; - - traits::row<base_matrix_type>::type row(matrix); - traits::col<base_matrix_type>::type col(matrix); - traits::const_value<base_matrix_type>::type value(matrix); - - size_type rows= num_rows(matrix), cols= num_cols(matrix), total= matrix.nnz(); - s_write(out, rows); - s_write(out, cols); - s_write(out, total); - - for (c_type cursor(mtl::begin<tag::major>(matrix)), cend(mtl::end<tag::major>(matrix)); - cursor != cend; ++cursor) - for (ic_type icursor(mtl::begin<tag::nz>(cursor)), icend(mtl::end<tag::nz>(cursor)); - icursor != icend; ++icursor) { - size_type my_row= row(*icursor), my_col= col(*icursor); - value_type my_value= value(*icursor); - s_write(out, my_row); - s_write(out, my_col); - s_write(out, my_value); - } - } + /// Writes the matrix to an output stream. + void serialize(std::ostream &out); - private: - template <typename T> - void s_read(::std::istream &in, T& value) - { - in.read(reinterpret_cast<char*>(&value), sizeof value); - } - - public: - void deserialize(::std::istream &in) - { - using namespace mtl; - - typedef Collection<base_matrix_type>::size_type size_type; - typedef Collection<base_matrix_type>::value_type value_type; - - size_type rows, cols, total; - s_read(in, rows); - s_read(in, cols); - s_read(in, total); - - // Prepare matrix insertion - clear(); - // matrix.change_dim(rows, cols) // do we want this? - inserter_type ins(matrix); - - for (size_type i= 0; i < total; ++i) { - size_type my_row, my_col; - value_type my_value; - s_read(in, my_row); - s_read(in, my_col); - s_read(in, my_value); - ins(my_row, my_col) << my_value; - } - } + /// Reads a matrix from an input stream. + void deserialize(::std::istream &in); /// int memsize(); diff --git a/AMDiS/src/Element.cc b/AMDiS/src/Element.cc index 97c66eb7..94b987ff 100644 --- a/AMDiS/src/Element.cc +++ b/AMDiS/src/Element.cc @@ -4,6 +4,7 @@ #include "CoarseningManager.h" #include "FixVec.h" #include "ElementRegion_ED.h" +#include "Serializer.h" namespace AMDiS { @@ -382,7 +383,7 @@ namespace AMDiS { int dim = mesh->getDim(); int nodes = mesh->getNumberOfNodes(); int j = 0; - out.write(reinterpret_cast<const char*>(&nodes), sizeof(int)); + SerUtil::serialize(out, nodes); for (int pos = 0; pos <= dim; pos++) { GeoIndex position = INDEX_OF_DIM(pos, dim); @@ -399,21 +400,21 @@ namespace AMDiS { if (Mesh::serializedDOFs[idx] == NULL) { Mesh::serializedDOFs[idx] = dof[j]; - out.write(reinterpret_cast<const char*>(&ndof), sizeof(int)); - out.write(reinterpret_cast<const char*>(&pos), sizeof(int)); + SerUtil::serialize(out, ndof); + SerUtil::serialize(out, pos); out.write(reinterpret_cast<const char*>(dof[j]), ndof * sizeof(DegreeOfFreedom)); } else { int minusOne = -1; - out.write(reinterpret_cast<const char*>(&minusOne), sizeof(int)); - out.write(reinterpret_cast<const char*>(&pos), sizeof(int)); + SerUtil::serialize(out, minusOne); + SerUtil::serialize(out, pos); out.write(reinterpret_cast<const char*>(&(dof[j][0])), sizeof(DegreeOfFreedom)); } } else { int zero = 0; - out.write(reinterpret_cast<const char*>(&zero), sizeof(int)); - out.write(reinterpret_cast<const char*>(&pos), sizeof(int)); + SerUtil::serialize(out, zero); + SerUtil::serialize(out, pos); } j++; } @@ -421,10 +422,10 @@ namespace AMDiS { } // write index - out.write(reinterpret_cast<const char*>(&index), sizeof(int)); + SerUtil::serialize(out, index); // write mark - out.write(reinterpret_cast<const char*>(&mark), sizeof(signed char)); + SerUtil::serialize(out, mark); // write newCoord if (newCoord) { @@ -447,7 +448,7 @@ namespace AMDiS { { FUNCNAME("Element::deserialize()"); - std::string typeName; + std::string typeName = ""; // read children in >> typeName; @@ -475,14 +476,14 @@ namespace AMDiS { // read dofs int nodes; - in.read(reinterpret_cast<char*>(&nodes), sizeof(int)); + SerUtil::deserialize(in, nodes); dof = new DegreeOfFreedom*[nodes]; for (int i = 0; i < nodes; i++) { int nDofs, pos; - in.read(reinterpret_cast<char*>(&nDofs), sizeof(int)); - in.read(reinterpret_cast<char*>(&pos), sizeof(int)); + SerUtil::deserialize(in, nDofs); + SerUtil::deserialize(in, pos); if (nDofs) { if (nDofs != -1) { @@ -502,8 +503,8 @@ namespace AMDiS { } else { DegreeOfFreedom index; - in.read(reinterpret_cast<char*>(&index), sizeof(DegreeOfFreedom)); - + SerUtil::deserialize(in, index); + std::pair<DegreeOfFreedom, int> idx = std::make_pair(index, pos); TEST_EXIT(Mesh::serializedDOFs.find(idx) != Mesh::serializedDOFs.end()) ("This should never happen!\n"); @@ -515,10 +516,10 @@ namespace AMDiS { } // read index - in.read(reinterpret_cast<char*>(&index), sizeof(int)); + SerUtil::deserialize(in, index); // read mark - in.read(reinterpret_cast<char*>(&mark), sizeof(signed char)); + SerUtil::deserialize(in, mark); // read newCoord in >> typeName; diff --git a/AMDiS/src/ElementFileWriter.cc b/AMDiS/src/ElementFileWriter.cc index 8710c719..0ba5dd56 100644 --- a/AMDiS/src/ElementFileWriter.cc +++ b/AMDiS/src/ElementFileWriter.cc @@ -48,7 +48,7 @@ namespace AMDiS { timestepNumber++; timestepNumber %= tsModulo; - if ((timestepNumber != 0) && !force) + if (timestepNumber != 0 && !force) return; std::string fn = filename; @@ -59,11 +59,9 @@ namespace AMDiS { TEST_EXIT(indexDecimals < indexLength)("index length <= index decimals\n"); char formatStr[9]; - sprintf(formatStr, "%%0%d.%df", indexLength, indexDecimals); char timeStr[20]; - sprintf(timeStr, formatStr, adaptInfo ? adaptInfo->getTime() : 0.0); fn += timeStr; diff --git a/AMDiS/src/FileWriter.cc b/AMDiS/src/FileWriter.cc index 12f21ce8..26af7361 100644 --- a/AMDiS/src/FileWriter.cc +++ b/AMDiS/src/FileWriter.cc @@ -1,3 +1,4 @@ +#include "boost/lexical_cast.hpp" #include "FileWriter.h" #include "SystemVector.h" #include "Parameters.h" @@ -19,6 +20,8 @@ namespace AMDiS { + using boost::lexical_cast; + FileWriter::FileWriter(std::string str, Mesh *m, DOFVector<double> *vec) : name(str), mesh(m) @@ -141,9 +144,9 @@ namespace AMDiS { std::string compressionStr = ""; GET_PARAMETER(0, name + "->compression", &compressionStr); - if ((compressionStr == "gzip") || (compressionStr == "gz")) { + if (compressionStr == "gzip" || compressionStr == "gz") { compression = GZIP; - } else if ((compressionStr == "bzip2") || (compressionStr == "bz2")) { + } else if (compressionStr == "bzip2" || compressionStr == "bz2") { compression = BZIP2; } } @@ -178,10 +181,8 @@ namespace AMDiS { #if HAVE_PARALLEL_DOMAIN_AMDIS std::string paraFilename = fn; + fn += "-p" + lexical_cast<std::string>(MPI::COMM_WORLD.Get_rank()) + "-"; std::string postfix = ""; - char f[15]; - sprintf(f, "-p%d-", MPI::COMM_WORLD.Get_rank()); - fn += f; #endif if (appendIndex) { @@ -198,8 +199,7 @@ namespace AMDiS { fn += timeStr; #if HAVE_PARALLEL_DOMAIN_AMDIS paraFilename += timeStr; - postfix += timeStr; - postfix += paraviewFileExt; + postfix += timeStr + paraviewFileExt; #endif } @@ -211,14 +211,11 @@ namespace AMDiS { } if (writeAMDiSFormat) { - TEST_EXIT(mesh)("no mesh\n"); - MacroWriter::writeMacro(dataCollectors[0], const_cast<char*>((fn + amdisMeshExt).c_str()), adaptInfo ? adaptInfo->getTime() : 0.0); MSG("macro file written to %s\n", (fn + amdisMeshExt).c_str()); - ValueWriter::writeValues(dataCollectors[0], (fn + amdisDataExt).c_str(), adaptInfo ? adaptInfo->getTime() : 0.0); @@ -270,7 +267,6 @@ namespace AMDiS { MSG("PNG image file written to %s\n", (fn + ".png").c_str()); } - for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++) delete dataCollectors[i]; } diff --git a/AMDiS/src/InteriorBoundary.cc b/AMDiS/src/InteriorBoundary.cc index 47411208..3d219649 100644 --- a/AMDiS/src/InteriorBoundary.cc +++ b/AMDiS/src/InteriorBoundary.cc @@ -12,22 +12,22 @@ namespace AMDiS { void InteriorBoundary::serialize(std::ostream &out) { int mSize = boundary.size(); - SerUtil::serialize(out, &mSize); + 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); + 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.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)); + SerUtil::serialize(out, bound.neighbourObject.elIndex); + SerUtil::serialize(out, bound.neighbourObject.subObjAtBoundary); + SerUtil::serialize(out, bound.neighbourObject.ithObjAtBoundary); } } } @@ -36,24 +36,24 @@ namespace AMDiS { std::map<int, Element*> &elIndexMap) { int mSize = 0; - SerUtil::deserialize(in, &mSize); + 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); + 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.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)); + 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/Lagrange.cc b/AMDiS/src/Lagrange.cc index 4a9857d9..fa06efd6 100644 --- a/AMDiS/src/Lagrange.cc +++ b/AMDiS/src/Lagrange.cc @@ -1,3 +1,7 @@ +#include <stdio.h> +#include <algorithm> +#include <list> +#include "boost/lexical_cast.hpp" #include "Mesh.h" #include "Element.h" #include "Lagrange.h" @@ -10,12 +14,10 @@ #include "Tetrahedron.h" #include "Parametric.h" -#include <stdio.h> -#include <algorithm> -#include <list> - namespace AMDiS { + using boost::lexical_cast; + std::vector<DimVec<double>* > Lagrange::baryDimDegree[MAX_DIM + 1][MAX_DEGREE + 1]; DimVec<int>* Lagrange::ndofDimDegree[MAX_DIM + 1][MAX_DEGREE + 1]; int Lagrange::nBasFctsDimDegree[MAX_DIM + 1][MAX_DEGREE + 1]; @@ -29,12 +31,7 @@ namespace AMDiS { : BasisFunction(std::string("Lagrange"), dim, degree) { // set name - char dummy[3]; - sprintf(dummy, "%d", dim); - name.append(dummy); - name.append(" "); - sprintf(dummy, "%d", degree); - name.append(dummy); + name += lexical_cast<std::string>(dim) + " " + lexical_cast<std::string>(degree); // set nDOF setNDOF(); diff --git a/AMDiS/src/MacroElement.cc b/AMDiS/src/MacroElement.cc index 94044be0..507002ad 100644 --- a/AMDiS/src/MacroElement.cc +++ b/AMDiS/src/MacroElement.cc @@ -1,11 +1,12 @@ +#include <string> +#include <map> #include "MacroElement.h" #include "Boundary.h" #include "FiniteElemSpace.h" #include "Mesh.h" -#include <string> #include "FixVec.h" #include "FixVecConvert.h" -#include <map> +#include "Serializer.h" namespace AMDiS { @@ -18,7 +19,7 @@ namespace AMDiS { oppVertex(dim, NO_INIT), index(-1), elType(0), - deserializedNeighbourIndices_(NULL) + deserializedNeighbourIndices(NULL) { neighbour.set(NULL); projection.set(NULL); @@ -55,7 +56,8 @@ namespace AMDiS { // write coords int size = coord.getSize(); - out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + SerUtil::serialize(out, size); + for (int i = 0; i < size; i++) coord[i].serialize(out); @@ -64,33 +66,36 @@ namespace AMDiS { // write projection size = projection.getSize(); - out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + SerUtil::serialize(out, size); for (int i = 0; i < size; i++) { int id = projection[i] ? projection[i]->getID() : -1; - out.write(reinterpret_cast<const char*>(&id), sizeof(int)); + SerUtil::serialize(out, id); } // write neighbour size = neighbour.getSize(); - out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + SerUtil::serialize(out, size); for (int i = 0; i < size; i++) { int index = neighbour[i] ? neighbour[i]->getIndex() : -1; - out.write(reinterpret_cast<const char*>(&index), sizeof(int)); + SerUtil::serialize(out, index); } // write oppVertex oppVertex.serialize(out); // write index - out.write(reinterpret_cast<const char*>(&index), sizeof(int)); + SerUtil::serialize(out, index); // write elType - out.write(reinterpret_cast<const char*>(&elType), sizeof(unsigned char)); + SerUtil::serialize(out, elType); } void MacroElement::deserialize(std::istream &in) { - // read element-tree + FUNCNAME("MacroElement::deserialize()"); + + // === Read element-tree. === + std::string typeName; in >> typeName; in.get(); @@ -108,73 +113,60 @@ namespace AMDiS { element->deserialize(in); - // read coords + // === Read coords. === + int size; - in.read(reinterpret_cast<char*>(&size), sizeof(int)); - if (coord.getSize()) { + SerUtil::deserialize(in, size); + + if (coord.getSize()) TEST_EXIT(coord.getSize() == size)("invalid size\n"); - } else { + else coord.initSize(size); - } - for (int i = 0; i < size; i++) { + + for (int i = 0; i < size; i++) coord[i].deserialize(in); - } - // read boundary boundary.deserialize(in); - // read projection - in.read(reinterpret_cast<char*>(&size), sizeof(int)); + // === Read projections. === - if (projection.getSize()) { + SerUtil::deserialize(in, size); + + if (projection.getSize()) TEST_EXIT(projection.getSize() == size)("invalid size\n"); - } else { + else projection.initSize(size); - } - + for (int i = 0; i < size; i++) { int id; - in.read(reinterpret_cast<char*>(&id), sizeof(int)); + SerUtil::deserialize(in, id); projection[i] = (id != -1) ? Projection::getProjection(id) : NULL; } - // read neighbour indices - in.read(reinterpret_cast<char*>(&size), sizeof(int)); + // === Read neighbour indices. === + + SerUtil::deserialize(in, size); - TEST_EXIT(deserializedNeighbourIndices_) - ("neighbour indices for deserializing not set\n"); + TEST_EXIT(deserializedNeighbourIndices) + ("Neighbour indices for deserializing not set!\n"); - deserializedNeighbourIndices_->resize(size); + deserializedNeighbourIndices->resize(size); - if(neighbour.getSize()) { + if (neighbour.getSize()) TEST_EXIT(neighbour.getSize() == size)("invalid size\n"); - } else { + else neighbour.initSize(size); - } - - for (int i = 0; i < size; i++) { - int index; - in.read(reinterpret_cast<char*>(&index), sizeof(int)); - - // neighbour[i] = reinterpret_cast<MacroElement*>(index); - // // attention: the neighbour INDEX is stored in the neighbour vector. - // // After all macro elements are read in, the indices must be replaced - // // by the corresponding pointers. - - (*deserializedNeighbourIndices_)[i] = index; - } + + for (int i = 0; i < size; i++) + SerUtil::deserialize(in, (*deserializedNeighbourIndices)[i]); - deserializedNeighbourIndices_ = NULL; + deserializedNeighbourIndices = NULL; // read oppVertex oppVertex.deserialize(in); - // write index - in.read(reinterpret_cast<char*>(&index), sizeof(int)); - - - // write elType - in.read(reinterpret_cast<char*>(&elType), sizeof(unsigned char)); + SerUtil::deserialize(in, index); + SerUtil::deserialize(in, elType); } int MacroElement::calcMemoryUsage() diff --git a/AMDiS/src/MacroElement.h b/AMDiS/src/MacroElement.h index 53fe9baf..269d97f4 100644 --- a/AMDiS/src/MacroElement.h +++ b/AMDiS/src/MacroElement.h @@ -122,12 +122,12 @@ namespace AMDiS { } /// Sets \ref element if not yet set. - inline void setElement(Element* element_) + inline void setElement(Element* el) { if (!element) { - element = element_; + element = el; } else { - if (element != element_) + if (element != el) ERROR("Trying to change element in MacroElement\n"); } } @@ -180,7 +180,7 @@ namespace AMDiS { /// inline void writeNeighboursTo(std::vector<int> *indices) { - deserializedNeighbourIndices_ = indices; + deserializedNeighbourIndices = indices; } /// @@ -212,7 +212,7 @@ namespace AMDiS { unsigned char elType; /// - std::vector<int> *deserializedNeighbourIndices_; + std::vector<int> *deserializedNeighbourIndices; friend class MacroInfo; diff --git a/AMDiS/src/Mesh.cc b/AMDiS/src/Mesh.cc index c3ddaf60..560430b3 100644 --- a/AMDiS/src/Mesh.cc +++ b/AMDiS/src/Mesh.cc @@ -23,6 +23,7 @@ #include "PeriodicMap.h" #include "Projection.h" #include "ElInfoStack.h" +#include "Serializer.h" namespace AMDiS { @@ -952,125 +953,84 @@ namespace AMDiS { { serializedDOFs.clear(); - // write name out << name << "\n"; - // write dim - out.write(reinterpret_cast<const char*>(&dim), sizeof(int)); + SerUtil::serialize(out, dim); + SerUtil::serialize(out, nVertices); + SerUtil::serialize(out, nEdges); + SerUtil::serialize(out, nLeaves); + SerUtil::serialize(out, nElements); + SerUtil::serialize(out, nFaces); + SerUtil::serialize(out, maxEdgeNeigh); - // write nVertices - out.write(reinterpret_cast<const char*>(&nVertices), sizeof(int)); - - // write nEdges - out.write(reinterpret_cast<const char*>(&nEdges), sizeof(int)); - - // write nLeaves - out.write(reinterpret_cast<const char*>(&nLeaves), sizeof(int)); - - // write nElements - out.write(reinterpret_cast<const char*>(&nElements), sizeof(int)); - - // write nFaces - out.write(reinterpret_cast<const char*>(&nFaces), sizeof(int)); - - // write maxEdgeNeigh - out.write(reinterpret_cast<const char*>(&maxEdgeNeigh), sizeof(int)); - - // write diam diam.serialize(out); - // write preserveCoarseDOFs - out.write(reinterpret_cast<const char*>(&preserveCoarseDOFs), sizeof(bool)); + SerUtil::serialize(out, preserveCoarseDOFs); + SerUtil::serialize(out, nDOFEl); - // write nDOFEl - out.write(reinterpret_cast<const char*>(&nDOFEl), sizeof(int)); - - // write nDOF nDOF.serialize(out); - // write nNodeEl - out.write(reinterpret_cast<const char*>(&nNodeEl), sizeof(int)); + SerUtil::serialize(out, nNodeEl); - // write node node.serialize(out); // write admins int size = static_cast<int>(admin.size()); - out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + SerUtil::serialize(out, size); for (int i = 0; i < size; i++) admin[i]->serialize(out); // write macroElements size = static_cast<int>(macroElements.size()); - out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + SerUtil::serialize(out, size); for (int i = 0; i < size; i++) macroElements[i]->serialize(out); - // write elementIndex - out.write(reinterpret_cast<const char*>(&elementIndex), sizeof(int)); - - // write initialized - out.write(reinterpret_cast<const char*>(&initialized), sizeof(bool)); + SerUtil::serialize(out, elementIndex); + SerUtil::serialize(out, initialized); serializedDOFs.clear(); } void Mesh::deserialize(std::istream &in) { + FUNCNAME("Mesh::deserialize()"); + serializedDOFs.clear(); - // read name in >> name; in.get(); - // read dim int oldVal = dim; - in.read(reinterpret_cast<char*>(&dim), sizeof(int)); - TEST_EXIT_DBG((oldVal == 0) || (dim == oldVal))("invalid dimension\n"); - - // read nVertices - in.read(reinterpret_cast<char*>(&nVertices), sizeof(int)); - - // read nEdges - in.read(reinterpret_cast<char*>(&nEdges), sizeof(int)); - - // read nLeaves - in.read(reinterpret_cast<char*>(&nLeaves), sizeof(int)); + SerUtil::deserialize(in, dim); + TEST_EXIT_DBG(oldVal == 0 || dim == oldVal)("Invalid dimension!\n"); - // read nElements - in.read(reinterpret_cast<char*>(&nElements), sizeof(int)); + SerUtil::deserialize(in, nVertices); + SerUtil::deserialize(in, nEdges); + SerUtil::deserialize(in, nLeaves); + SerUtil::deserialize(in, nElements); + SerUtil::deserialize(in, nFaces); + SerUtil::deserialize(in, maxEdgeNeigh); - // read nFaces - in.read(reinterpret_cast<char*>(&nFaces), sizeof(int)); - - // read maxEdgeNeigh - in.read(reinterpret_cast<char*>(&maxEdgeNeigh), sizeof(int)); - - // diam diam.deserialize(in); - // read preserveCoarseDOFs - in.read(reinterpret_cast<char*>(&preserveCoarseDOFs), sizeof(bool)); + SerUtil::deserialize(in, preserveCoarseDOFs); - // read nDOFEl oldVal = nDOFEl; - in.read(reinterpret_cast<char*>(&nDOFEl), sizeof(int)); - TEST_EXIT_DBG((oldVal == 0) || (nDOFEl == oldVal))("invalid nDOFEl\n"); + SerUtil::deserialize(in, nDOFEl); + TEST_EXIT_DBG(oldVal == 0 || nDOFEl == oldVal)("Invalid nDOFEl!\n"); - // read nDOF nDOF.deserialize(in); - // read nNodeEl oldVal = nNodeEl; - in.read(reinterpret_cast<char*>(&nNodeEl), sizeof(int)); - TEST_EXIT_DBG((oldVal == 0) || (nNodeEl == oldVal))("invalid nNodeEl\n"); + SerUtil::deserialize(in, nNodeEl); + TEST_EXIT_DBG(oldVal == 0 || nNodeEl == oldVal)("Invalid nNodeEl!\n"); - // read node node.deserialize(in); // read admins int size; - in.read(reinterpret_cast<char*>(&size), sizeof(int)); + SerUtil::deserialize(in, size); admin.resize(size, NULL); for (int i = 0; i < size; i++) { if (!admin[i]) @@ -1079,35 +1039,44 @@ namespace AMDiS { admin[i]->deserialize(in); } - // read macroElements - in.read(reinterpret_cast<char*>(&size), sizeof(int)); - + SerUtil::deserialize(in, size); std::vector< std::vector<int> > neighbourIndices(size); - for (int i = 0; i < static_cast<int>(macroElements.size()); i++) { + for (int i = 0; i < static_cast<int>(macroElements.size()); i++) if (macroElements[i]) delete macroElements[i]; - } + + // All macro elements are stored in the list \ref macroElements with continous + // index from 0 to n - 1. But the macro element index may be different and may + // contain holes (for example when macro elements were removed because of domain + // decomposition based parallelization. Therefore we create a temporary map + // from macro element indices to the continous index of \ref macroElements. This + // will be used later to find the correct neighbours of the macro elements. + std::map<int, int> elIndexVecIndex; macroElements.resize(size); for (int i = 0; i < size; i++) { macroElements[i] = new MacroElement(dim); macroElements[i]->writeNeighboursTo(&(neighbourIndices[i])); macroElements[i]->deserialize(in); + elIndexVecIndex[macroElements[i]->getIndex()] = i; } - // read elementIndex - in.read(reinterpret_cast<char*>(&elementIndex), sizeof(int)); - - // read initialized - in.read(reinterpret_cast<char*>(&initialized), sizeof(bool)); + SerUtil::deserialize(in, elementIndex); + SerUtil::deserialize(in, initialized); // set neighbour pointer in macro elements - int neighs = getGeo(NEIGH); + int nNeighbour = getGeo(NEIGH); for (int i = 0; i < static_cast<int>(macroElements.size()); i++) { - for (int j = 0; j < neighs; j++) { + for (int j = 0; j < nNeighbour; j++) { int index = neighbourIndices[i][j]; - if(index != -1) { + + if (index != -1) { + TEST_EXIT_DBG(elIndexVecIndex.count(index) == 1) + ("Cannot find correct index from neighbouring macro element!\n"); + + index = elIndexVecIndex[index]; + macroElements[i]->setNeighbour(j, macroElements[index]); } else { macroElements[i]->setNeighbour(j, NULL); diff --git a/AMDiS/src/ParallelDomainBase.cc b/AMDiS/src/ParallelDomainBase.cc index b7964d6e..80d50b48 100644 --- a/AMDiS/src/ParallelDomainBase.cc +++ b/AMDiS/src/ParallelDomainBase.cc @@ -47,7 +47,8 @@ namespace AMDiS { initialPartitionMesh(true), nRankDofs(0), rstart(0), - nComponents(1) + nComponents(1), + deserialized(false) { FUNCNAME("ParallelDomainBase::ParalleDomainBase()"); @@ -64,7 +65,13 @@ namespace AMDiS { void ParallelDomainBase::initParallelization(AdaptInfo *adaptInfo) { - if (mpiSize <= 1) + FUNCNAME("ParallelDomainBase::initParallelization()"); + + TEST_EXIT(mpiSize > 1) + ("Parallelization does not work with only one process!\n"); + + // If the problem has been already read from a file, we do not need to do anything. + if (deserialized) return; // Test, if the mesh is the macro mesh only! Paritioning of the mesh is supported @@ -699,10 +706,10 @@ namespace AMDiS { void ParallelDomainBase::serialize(std::ostream &out, DofContainer &data) { int vecSize = data.size(); - SerUtil::serialize(out, &vecSize); + SerUtil::serialize(out, vecSize); for (int i = 0; i < vecSize; i++) { int dofIndex = (*data[i]); - SerUtil::serialize(out, &dofIndex); + SerUtil::serialize(out, dofIndex); } } @@ -713,11 +720,11 @@ namespace AMDiS { FUNCNAME("ParallelDomainBase::deserialize()"); int vecSize = 0; - SerUtil::deserialize(in, &vecSize); + SerUtil::deserialize(in, vecSize); data.resize(vecSize); for (int i = 0; i < vecSize; i++) { int dofIndex = 0; - SerUtil::deserialize(in, &dofIndex); + SerUtil::deserialize(in, dofIndex); TEST_EXIT_DBG(dofMap.count(dofIndex) != 0) ("Dof index could not be deserialized correctly!\n"); @@ -730,10 +737,10 @@ namespace AMDiS { void ParallelDomainBase::serialize(std::ostream &out, RankToDofContainer &data) { int mapSize = data.size(); - SerUtil::serialize(out, &mapSize); + SerUtil::serialize(out, mapSize); for (RankToDofContainer::iterator it = data.begin(); it != data.end(); ++it) { int rank = it->first; - SerUtil::serialize(out, &rank); + SerUtil::serialize(out, rank); serialize(out, it->second); } } @@ -743,10 +750,10 @@ namespace AMDiS { std::map<int, const DegreeOfFreedom*> &dofMap) { int mapSize = 0; - SerUtil::deserialize(in, &mapSize); + SerUtil::deserialize(in, mapSize); for (int i = 0; i < mapSize; i++) { int rank = 0; - SerUtil::deserialize(in, &rank); + SerUtil::deserialize(in, rank); deserialize(in, data[rank], dofMap); } } @@ -1589,10 +1596,10 @@ namespace AMDiS { void ParallelDomainBase::serialize(std::ostream &out) { SerUtil::serialize(out, elemWeights); - SerUtil::serialize(out, &initialPartitionMesh); + SerUtil::serialize(out, initialPartitionMesh); SerUtil::serialize(out, partitionVec); SerUtil::serialize(out, oldPartitionVec); - SerUtil::serialize(out, &nRankDofs); + SerUtil::serialize(out, nRankDofs); myIntBoundary.serialize(out); otherIntBoundary.serialize(out); @@ -1606,19 +1613,19 @@ namespace AMDiS { serialize(out, vertexDof); - SerUtil::serialize(out, &rstart); - SerUtil::serialize(out, &nRankRows); - SerUtil::serialize(out, &nOverallRows); + SerUtil::serialize(out, rstart); + SerUtil::serialize(out, nRankRows); + SerUtil::serialize(out, nOverallRows); } void ParallelDomainBase::deserialize(std::istream &in) { SerUtil::deserialize(in, elemWeights); - SerUtil::deserialize(in, &initialPartitionMesh); + SerUtil::deserialize(in, initialPartitionMesh); SerUtil::deserialize(in, partitionVec); SerUtil::deserialize(in, oldPartitionVec); - SerUtil::deserialize(in, &nRankDofs); + 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. @@ -1650,9 +1657,11 @@ namespace AMDiS { deserialize(in, vertexDof, dofMap); - SerUtil::deserialize(in, &rstart); - SerUtil::deserialize(in, &nRankRows); - SerUtil::deserialize(in, &nOverallRows); + SerUtil::deserialize(in, rstart); + SerUtil::deserialize(in, nRankRows); + SerUtil::deserialize(in, nOverallRows); + + deserialized = true; } diff --git a/AMDiS/src/ParallelDomainBase.h b/AMDiS/src/ParallelDomainBase.h index 88ea2565..f7ecd5a9 100644 --- a/AMDiS/src/ParallelDomainBase.h +++ b/AMDiS/src/ParallelDomainBase.h @@ -311,13 +311,13 @@ namespace AMDiS { void serialize(std::ostream &out, std::map<const DegreeOfFreedom*, T> &data) { int mapSize = data.size(); - SerUtil::serialize(out, &mapSize); + SerUtil::serialize(out, mapSize); for (typename std::map<const DegreeOfFreedom*, T>::iterator it = data.begin(); it != data.end(); ++it) { int v1 = (*(it->first)); T v2 = it->second; - SerUtil::serialize(out, &v1); - SerUtil::serialize(out, &v2); + SerUtil::serialize(out, v1); + SerUtil::serialize(out, v2); } } @@ -327,12 +327,12 @@ namespace AMDiS { std::map<int, const DegreeOfFreedom*> &dofMap) { int mapSize = 0; - SerUtil::deserialize(in, &mapSize); + SerUtil::deserialize(in, mapSize); for (int i = 0; i < mapSize; i++) { int v1 = 0; T v2; - SerUtil::deserialize(in, &v1); - SerUtil::deserialize(in, &v2); + SerUtil::deserialize(in, v1); + SerUtil::deserialize(in, v2); data[dofMap[v1]] = v2; } } @@ -491,6 +491,14 @@ namespace AMDiS { /// Overall number of the rows in the lineary system. int nOverallRows; + + /** \brief + * If the problem definition has been read from a serialization file, this + * variable is true, otherwise it is false. This variable is used to stop the + * initialization function, if the problem definition has already been read from + * a serialization file. + */ + bool deserialized; }; } diff --git a/AMDiS/src/ParallelDomainVec.cc b/AMDiS/src/ParallelDomainVec.cc index e4c2e818..12edf33b 100644 --- a/AMDiS/src/ParallelDomainVec.cc +++ b/AMDiS/src/ParallelDomainVec.cc @@ -1,3 +1,4 @@ +#include "boost/lexical_cast.hpp" #include "ParallelDomainVec.h" #include "ProblemVec.h" #include "ProblemInstat.h" @@ -6,6 +7,8 @@ namespace AMDiS { + using boost::lexical_cast; + ParallelDomainVec::ParallelDomainVec(ProblemVec *problem, ProblemInstatVec *problemInstat) : ParallelDomainBase(problem, @@ -31,6 +34,18 @@ namespace AMDiS { GET_PARAMETER(0, name + "->output->write serialization", "%d", &writeSerialization); if (writeSerialization) problem->getFileWriterList().push_back(new Serializer<ParallelDomainVec>(this)); + + int readSerialization = 0; + GET_PARAMETER(0, name + "->input->read serialization", "%d", &readSerialization); + if (readSerialization) { + std::string filename = ""; + GET_PARAMETER(0, name + "->input->serialization filename", &filename); + filename += ".p" + lexical_cast<std::string>(mpiRank); + MSG("Start serialization with %s\n", filename.c_str()); + std::ifstream in(filename.c_str()); + deserialize(in); + in.close(); + } } diff --git a/AMDiS/src/ParallelDomainVec.h b/AMDiS/src/ParallelDomainVec.h index 4d6a7f4f..4d694d36 100644 --- a/AMDiS/src/ParallelDomainVec.h +++ b/AMDiS/src/ParallelDomainVec.h @@ -52,8 +52,11 @@ namespace AMDiS { // Reads the object data from an input stream. virtual void deserialize(std::istream &in) { + MSG("DESER 1\n"); probVec->deserialize(in); + MSG("DESER 2\n"); ParallelDomainBase::deserialize(in); + MSG("DESER 3\n"); } protected: diff --git a/AMDiS/src/ParallelProblem.cc b/AMDiS/src/ParallelProblem.cc index b8eda6c9..9fc1678c 100644 --- a/AMDiS/src/ParallelProblem.cc +++ b/AMDiS/src/ParallelProblem.cc @@ -1,3 +1,6 @@ +#include <queue> +#include <time.h> +#include "boost/lexical_cast.hpp" #include "ParallelProblem.h" #include "ProblemScal.h" #include "ProblemVec.h" @@ -26,11 +29,11 @@ #include "SystemVector.h" #include "VtkWriter.h" #include "mpi.h" -#include <queue> -#include <time.h> namespace AMDiS { + using boost::lexical_cast; + bool elementInPartition(ElInfo *elInfo) { PartitionElementData *elementData = dynamic_cast<PartitionElementData*> @@ -1407,15 +1410,13 @@ namespace AMDiS { } // modify file writers - char number[10]; - sprintf(number, "%d", mpiRank); std::vector<FileWriterInterface*> fileWriters = problem->getFileWriterList(); std::vector<FileWriterInterface*>::iterator fwIt, fwBegin, fwEnd; fwBegin = fileWriters.begin(); fwEnd = fileWriters.end(); for (fwIt = fwBegin; fwIt != fwEnd; ++fwIt) { (*fwIt)->setFilename((*fwIt)->getFilename() + "_proc" + - std::string(number) + "_"); + lexical_cast<std::string>(mpiRank) + "_"); (*fwIt)->setTraverseProperties(-1, 0, elementInPartition); } } @@ -1588,15 +1589,13 @@ namespace AMDiS { } // modify file writers - char number[10]; - sprintf(number, "%d", mpiComm.Get_rank()); std::vector<FileWriterInterface*> fileWriters = problem->getFileWriterList(); std::vector<FileWriterInterface*>::iterator fwIt, fwBegin, fwEnd; fwBegin = fileWriters.begin(); fwEnd = fileWriters.end(); for (fwIt = fwBegin; fwIt != fwEnd; ++fwIt) { (*fwIt)->setFilename((*fwIt)->getFilename() + "_proc" + - std::string(number) + "_"); + lexical_cast<std::string>(mpiComm.Get_rank()) + "_"); (*fwIt)->setTraverseProperties(-1, 0, elementInPartition); } } diff --git a/AMDiS/src/PartitionElementData.h b/AMDiS/src/PartitionElementData.h index a3a85956..8caf7c9d 100644 --- a/AMDiS/src/PartitionElementData.h +++ b/AMDiS/src/PartitionElementData.h @@ -25,6 +25,7 @@ #include "Element.h" #include "ElementData.h" #include "FixVec.h" +#include "Serializer.h" namespace AMDiS { @@ -105,20 +106,20 @@ namespace AMDiS { void serialize(std::ostream& out) { ElementData::serialize(out); - out.write(reinterpret_cast<const char*>(&status), sizeof(PartitionStatus)); - out.write(reinterpret_cast<const char*>(&level), sizeof(int)); + SerUtil::serialize(out, status); + SerUtil::serialize(out, level); } void deserialize(std::istream& in) { ElementData::deserialize(in); - in.read(reinterpret_cast<char*>(&status), sizeof(PartitionStatus)); - in.read(reinterpret_cast<char*>(&level), sizeof(int)); + SerUtil::deserialize(in, status); + SerUtil::deserialize(in, level); } - inline void setPartitionStatus(PartitionStatus status_) + inline void setPartitionStatus(PartitionStatus s) { - status = status_; + status = s; } inline PartitionStatus getPartitionStatus() diff --git a/AMDiS/src/ProblemVec.cc b/AMDiS/src/ProblemVec.cc index 3cee67a6..f249683c 100644 --- a/AMDiS/src/ProblemVec.cc +++ b/AMDiS/src/ProblemVec.cc @@ -1,4 +1,5 @@ #include <sstream> +#include "boost/lexical_cast.hpp" #include "ProblemVec.h" #include "RecoveryEstimator.h" #include "Serializer.h" @@ -27,6 +28,8 @@ namespace AMDiS { + using boost::lexical_cast; + void ProblemVec::initialize(Flag initFlag, ProblemVec *adoptProblem, Flag adoptFlag) @@ -157,8 +160,7 @@ namespace AMDiS { if (!serializationFilename.compare("")) { int readSerializationWithAdaptInfo = 0; - GET_PARAMETER(0, name + "->input->read serialization", "%d", - &readSerialization); + GET_PARAMETER(0, name + "->input->read serialization", "%d", &readSerialization); GET_PARAMETER(0, name + "->input->serialization with adaptinfo", "%d", &readSerializationWithAdaptInfo); @@ -171,10 +173,15 @@ namespace AMDiS { &serializationFilename); TEST_EXIT(serializationFilename != "")("no serialization file\n"); - MSG("Deserialization from file: %s\n", serializationFilename.c_str()); + // We AMDiS is compiled for parallel computations, the deserialization is + // controlled by the parallel problem definition object. +#ifndef HAVE_PARALLEL_DOMAIN_AMDIS std::ifstream in(serializationFilename.c_str()); deserialize(in); in.close(); + + MSG("Deserialization from file: %s\n", serializationFilename.c_str()); +#endif } else { int globalRefinements = 0; GET_PARAMETER(0, meshes[0]->getName() + "->global refinements", "%d", @@ -216,7 +223,6 @@ namespace AMDiS { componentMeshes.resize(nComponents); std::map<int, Mesh*> meshForRefinementSet; - char number[3]; std::string meshName(""); GET_PARAMETER(0, name + "->mesh", &meshName); @@ -226,9 +232,9 @@ namespace AMDiS { TEST_EXIT(dim)("no problem dimension specified!\n"); for (int i = 0; i < nComponents; i++) { - sprintf(number, "%d", i); int refSet = -1; - GET_PARAMETER(0, name + "->refinement set[" + number + "]", "%d", &refSet); + GET_PARAMETER(0, name + "->refinement set[" + + lexical_cast<std::string>(i) + "]", "%d", &refSet); if (refSet < 0) refSet = 0; @@ -262,7 +268,7 @@ namespace AMDiS { { FUNCNAME("ProblemVec::createFESpace()"); - std::map< std::pair<Mesh*, int>, FiniteElemSpace*> feSpaceMap; + std::map<std::pair<Mesh*, int>, FiniteElemSpace*> feSpaceMap; int dim = -1; GET_PARAMETER(0, name + "->dim", "%d", &dim); TEST_EXIT(dim != -1)("no problem dimension specified!\n"); @@ -271,10 +277,9 @@ namespace AMDiS { traverseInfo.resize(nComponents); for (int i = 0; i < nComponents; i++) { - char number[3]; - sprintf(number, "%d", i); int degree = 1; - GET_PARAMETER(0, name + "->polynomial degree[" + number + "]","%d", °ree); + GET_PARAMETER(0, name + "->polynomial degree[" + + boost::lexical_cast<std::string>(i) + "]","%d", °ree); TEST_EXIT(componentSpaces[i] == NULL)("feSpace already created\n"); @@ -319,17 +324,14 @@ namespace AMDiS { rhs = new SystemVector("rhs", componentSpaces, nComponents); solution = new SystemVector("solution", componentSpaces, nComponents); - char number[10] = ""; - std::string numberedName = ""; for (int i = 0; i < nComponents; i++) { (*systemMatrix)[i][i] = new DOFMatrix(componentSpaces[i], componentSpaces[i], "A_ii"); (*systemMatrix)[i][i]->setCoupleMatrix(false); - sprintf(number, "[%d]", i); - numberedName = "rhs" + std::string(number); + std::string numberedName = "rhs[" + boost::lexical_cast<std::string>(i) + "]"; rhs->setDOFVector(i, new DOFVector<double>(componentSpaces[i], numberedName)); - numberedName = name + std::string(number); + numberedName = name + boost::lexical_cast<std::string>(i); solution->setDOFVector(i, new DOFVector<double>(componentSpaces[i], numberedName)); solution->getDOFVector(i)->setCoarsenOperation(COARSE_INTERPOL); @@ -357,18 +359,14 @@ namespace AMDiS { FUNCNAME("ProblemVec::createEstimator()"); // create and set leaf data prototype - for (int i = 0; i < static_cast<int>(meshes.size()); i++) { + for (int i = 0; i < static_cast<int>(meshes.size()); i++) meshes[i]->setElementDataPrototype (new LeafDataEstimatableVec(new LeafDataCoarsenableVec)); - } - - char number[3]; - std::string estName; for (int i = 0; i < nComponents; i++) { TEST_EXIT(estimator[i] == NULL)("estimator already created\n"); - sprintf(number, "%d", i); - estName = name + "->estimator[" + std::string(number) + "]"; + std::string estName = + name + "->estimator[" + boost::lexical_cast<std::string>(i) + "]"; // === create estimator === std::string estimatorType("0"); @@ -387,11 +385,10 @@ namespace AMDiS { if (estimator[i]) { - for (int j = 0; j < nComponents; j++) { + for (int j = 0; j < nComponents; j++) estimator[i]->addSystem((*systemMatrix)[i][j], solution->getDOFVector(j), rhs->getDOFVector(j)); - } } } } @@ -400,20 +397,18 @@ namespace AMDiS { { FUNCNAME("ProblemVec::createMarker()"); - std::string numberedName; - char number[10]; int nMarkersCreated = 0; for (int i = 0; i < nComponents; i++) { - sprintf(number, "[%d]", i); - numberedName = name + "->marker" + std::string(number); - marker[i] = Marker::createMarker(numberedName, i); + marker[i] = Marker::createMarker + (name + "->marker[" + boost::lexical_cast<std::string>(i) + "]", i); + if (marker[i]) { nMarkersCreated++; // If there is more than one marker, and all components are defined // on the same mesh, the maximum marking has to be enabled. - if ((nMarkersCreated > 1) && (nMeshes == 1)) + if (nMarkersCreated > 1 && nMeshes == 1) marker[i]->setMaximumMarking(true); } } @@ -423,7 +418,6 @@ namespace AMDiS { { FUNCNAME("ProblemVec::createFileWriter()"); - // Create one filewriter for all components of the problem std::string numberedName = name + "->output"; std::string filename = ""; @@ -444,12 +438,9 @@ namespace AMDiS { solutionList)); } - // Create own filewriters for each components of the problem - char number[10]; for (int i = 0; i < nComponents; i++) { - sprintf(number, "[%d]", i); - numberedName = name + "->output" + std::string(number); + numberedName = name + "->output[" + boost::lexical_cast<std::string>(i) + "]"; filename = ""; GET_PARAMETER(0, numberedName + "->filename", &filename); @@ -459,7 +450,6 @@ namespace AMDiS { solution->getDOFVector(i))); } - // Check for serializer int writeSerialization = 0; GET_PARAMETER(0, name + "->write serialization", "%d", &writeSerialization); @@ -1314,7 +1304,7 @@ namespace AMDiS { { FUNCNAME("ProblemVec::serialize()"); - SerUtil::serialize(out, &allowFirstRef); + SerUtil::serialize(out, allowFirstRef); for (int i = 0; i < static_cast<int>(meshes.size()); i++) meshes[i]->serialize(out); @@ -1326,7 +1316,7 @@ namespace AMDiS { { FUNCNAME("ProblemVec::deserialize()"); - SerUtil::deserialize(in, &allowFirstRef); + SerUtil::deserialize(in, allowFirstRef); for (int i = 0; i < static_cast<int>(meshes.size()); i++) meshes[i]->deserialize(in); diff --git a/AMDiS/src/ProblemVec.h b/AMDiS/src/ProblemVec.h index 451d8b11..6bfe04ba 100644 --- a/AMDiS/src/ProblemVec.h +++ b/AMDiS/src/ProblemVec.h @@ -114,7 +114,10 @@ namespace AMDiS { /// Used in \ref initialize(). virtual void createFileWriter(); - /// Used in \ref initialize(). + /** \brief + * Used in \ref initialize(). This function is deprecated and should not be used + * anymore. There is no guarantee that it will work in the future. + */ virtual void doOtherStuff(); /** \brief diff --git a/AMDiS/src/Serializer.h b/AMDiS/src/Serializer.h index ffacbba6..5c54b9af 100644 --- a/AMDiS/src/Serializer.h +++ b/AMDiS/src/Serializer.h @@ -23,6 +23,8 @@ #define AMDIS_SERIALIZER_H #include <map> +#include "boost/lexical_cast.hpp" + #include "FileWriter.h" #include "Parameters.h" #include "AdaptInfo.h" @@ -48,8 +50,7 @@ namespace AMDiS { TEST_EXIT(name != "")("no filename\n"); #if HAVE_PARALLEL_DOMAIN_AMDIS - name += ".p"; - name += MPI::COMM_WORLD.Get_rank(); + name += ".p" + boost::lexical_cast<std::string>(MPI::COMM_WORLD.Get_rank()); #endif } @@ -96,71 +97,71 @@ namespace AMDiS { namespace SerUtil { template<typename T> - void serialize(std::ostream &out, T *data) + void serialize(std::ostream& out, T& data) { - out.write(reinterpret_cast<const char*>(data), sizeof(T)); + out.write(reinterpret_cast<const char*>(&data), sizeof(T)); } template<typename T> - void deserialize(std::istream &in, T *data) + void deserialize(std::istream& in, T& data) { - in.read(reinterpret_cast<char*>(data), sizeof(T)); + in.read(reinterpret_cast<char*>(&data), sizeof(T)); } template<typename T> - void serialize(std::ostream &out, std::vector<T> &data) + void serialize(std::ostream& out, std::vector<T>& data) { int vecSize = data.size(); - serialize(out, &vecSize); + serialize(out, vecSize); for (typename std::vector<T>::iterator it = data.begin(); it != data.end(); ++it) { T v = *it; - serialize(out, &v); + serialize(out, v); } } template<typename T> - void deserialize(std::istream &in, std::vector<T> &data) + void deserialize(std::istream& in, std::vector<T>& data) { int vecSize = 0; - deserialize(in, &vecSize); + deserialize(in, vecSize); data.resize(vecSize); for (int i = 0; i < vecSize; i++) { T v; - deserialize(in, &v); + deserialize(in, v); data[i] = v; } } template<typename T1, typename T2> - void serialize(std::ostream &out, std::map<T1, T2> &data) + void serialize(std::ostream& out, std::map<T1, T2>& data) { int mapSize = data.size(); - serialize(out, &mapSize); + serialize(out, mapSize); for (typename std::map<T1,T2>::iterator it = data.begin(); it != data.end(); ++it) { T1 v1 = it->first; T2 v2 = it->second; - serialize(out, &v1); - serialize(out, &v2); + serialize(out, v1); + serialize(out, v2); } } template<typename T1, typename T2> - void deserialize(std::istream &in, std::map<T1, T2> &data) + void deserialize(std::istream& in, std::map<T1, T2>& data) { int mapSize = 0; - deserialize(in, &mapSize); + deserialize(in, mapSize); for (int i = 0; i < mapSize; i++) { T1 v1; T2 v2; - deserialize(in, &v1); - deserialize(in, &v2); + deserialize(in, v1); + deserialize(in, v2); data[v1] = v2; } } -- GitLab