Commit 8c7d3860 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Fixed several very small problems in parallel code.

parent 30349874
......@@ -181,6 +181,7 @@ if(ENABLE_PARALLEL_DOMAIN)
${SOURCE_DIR}/parallel/ParallelDebug.cc
${SOURCE_DIR}/parallel/MpiHelper.cc
${SOURCE_DIR}/parallel/ElementObjectData.cc
${SOURCE_DIR}/parallel/ParallelProblemStatBase.cc
${SOURCE_DIR}/parallel/PetscSolver.cc)
SET(COMPILEFLAGS "${COMPILEFLAGS} -DHAVE_PARALLEL_DOMAIN_AMDIS=1")
endif(ENABLE_PARALLEL_DOMAIN)
......
......@@ -21,6 +21,7 @@ if USE_PARALLEL_DOMAIN_AMDIS
$(SOURCE_DIR)/parallel/MeshManipulation.h $(SOURCE_DIR)/parallel/MeshManipulation.cc \
$(SOURCE_DIR)/parallel/ParallelDebug.h $(SOURCE_DIR)/parallel/ParallelDebug.cc \
$(SOURCE_DIR)/parallel/ParallelProblemStatBase.h \
$(SOURCE_DIR)/parallel/ParallelProblemStatBase.cc \
$(SOURCE_DIR)/parallel/PetscSolver.h $(SOURCE_DIR)/parallel/PetscSolver.cc \
$(SOURCE_DIR)/parallel/MpiHelper.h $(SOURCE_DIR)/parallel/MpiHelper.cc \
$(SOURCE_DIR)/parallel/ElementObjectData.h $(SOURCE_DIR)/parallel/ElementObjectData.cc
......
......@@ -43,6 +43,7 @@ host_triplet = @host@
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/MeshManipulation.h $(SOURCE_DIR)/parallel/MeshManipulation.cc \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/ParallelDebug.h $(SOURCE_DIR)/parallel/ParallelDebug.cc \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/ParallelProblemStatBase.h \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/ParallelProblemStatBase.cc \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/PetscSolver.h $(SOURCE_DIR)/parallel/PetscSolver.cc \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/MpiHelper.h $(SOURCE_DIR)/parallel/MpiHelper.cc \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/ElementObjectData.h $(SOURCE_DIR)/parallel/ElementObjectData.cc
......@@ -89,6 +90,7 @@ am__libamdis_la_SOURCES_DIST = $(SOURCE_DIR)/parallel/StdMpi.h \
$(SOURCE_DIR)/parallel/ParallelDebug.h \
$(SOURCE_DIR)/parallel/ParallelDebug.cc \
$(SOURCE_DIR)/parallel/ParallelProblemStatBase.h \
$(SOURCE_DIR)/parallel/ParallelProblemStatBase.cc \
$(SOURCE_DIR)/parallel/PetscSolver.h \
$(SOURCE_DIR)/parallel/PetscSolver.cc \
$(SOURCE_DIR)/parallel/MpiHelper.h \
......@@ -252,6 +254,7 @@ am__libamdis_la_SOURCES_DIST = $(SOURCE_DIR)/parallel/StdMpi.h \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-MeshDistributor.lo \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-MeshManipulation.lo \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-ParallelDebug.lo \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-ParallelProblemStatBase.lo \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-PetscSolver.lo \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-MpiHelper.lo \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-ElementObjectData.lo
......@@ -803,6 +806,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-OperatorTerm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParMetisPartitioner.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParallelDebug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParallelProblemStatBase.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Parameters.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Parametric.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PeriodicBC.Plo@am__quote@
......@@ -916,6 +920,13 @@ libamdis_la-ParallelDebug.lo: $(SOURCE_DIR)/parallel/ParallelDebug.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ParallelDebug.lo `test -f '$(SOURCE_DIR)/parallel/ParallelDebug.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/parallel/ParallelDebug.cc
libamdis_la-ParallelProblemStatBase.lo: $(SOURCE_DIR)/parallel/ParallelProblemStatBase.cc
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ParallelProblemStatBase.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ParallelProblemStatBase.Tpo" -c -o libamdis_la-ParallelProblemStatBase.lo `test -f '$(SOURCE_DIR)/parallel/ParallelProblemStatBase.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/parallel/ParallelProblemStatBase.cc; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ParallelProblemStatBase.Tpo" "$(DEPDIR)/libamdis_la-ParallelProblemStatBase.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ParallelProblemStatBase.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/parallel/ParallelProblemStatBase.cc' object='libamdis_la-ParallelProblemStatBase.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ParallelProblemStatBase.lo `test -f '$(SOURCE_DIR)/parallel/ParallelProblemStatBase.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/parallel/ParallelProblemStatBase.cc
libamdis_la-PetscSolver.lo: $(SOURCE_DIR)/parallel/PetscSolver.cc
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-PetscSolver.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-PetscSolver.Tpo" -c -o libamdis_la-PetscSolver.lo `test -f '$(SOURCE_DIR)/parallel/PetscSolver.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/parallel/PetscSolver.cc; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-PetscSolver.Tpo" "$(DEPDIR)/libamdis_la-PetscSolver.Plo"; else rm -f "$(DEPDIR)/libamdis_la-PetscSolver.Tpo"; exit 1; fi
......
......@@ -44,7 +44,7 @@ available_tags=" CXX F77"
# ### BEGIN LIBTOOL CONFIG
# Libtool was configured on host deimos101:
# Libtool was configured on host deimos102:
# 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 deimos101:
# Libtool was configured on host deimos102:
# 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 deimos101:
# Libtool was configured on host deimos102:
# Shell to use when invoking shell scripts.
SHELL="/bin/sh"
......
......@@ -215,6 +215,10 @@ namespace AMDiS {
///
virtual DofFace getFace(int localFaceIndex) const = 0;
/// Returns either vertex, edge or face of the element.
template<typename T>
T getObject(int index);
/// Returns the number of parts of type i in this element
virtual int getGeo(GeoIndex i) const = 0;
......
......@@ -86,6 +86,7 @@ namespace AMDiS {
/// Defines a tzpe for global face identiication via its DOFs.
typedef boost::tuple<DegreeOfFreedom, DegreeOfFreedom, DegreeOfFreedom> DofFace;
/// returns the GeoIndex of d for dimension dim.
#define INDEX_OF_DIM(d, dim) (static_cast<GeoIndex>((d == dim) ? CENTER : d + 1))
......
......@@ -654,7 +654,7 @@ namespace AMDiS {
{
FUNCNAME("Mesh::createNewElInfo()");
switch(dim) {
switch (dim) {
case 1:
return new ElInfo1d(this);
break;
......@@ -1176,24 +1176,13 @@ namespace AMDiS {
GET_PARAMETER(0, name + "->preserve coarse dofs", "%d", &preserveCoarseDOFs);
if (macroFilename.length()) {
// In parallel computations, check if a finer macro mesh is required.
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
if (checkParallelMacroFile(macroFilename, periodicFilename, check)) {
std::string newPeriodicFilename = "";
if (periodicFilename != "")
newPeriodicFilename = periodicFilename + ".tmp";
macroFileInfo =
MacroReader::readMacro(macroFilename + ".tmp", this,
newPeriodicFilename, check);
} else {
macroFileInfo =
MacroReader::readMacro(macroFilename, this, periodicFilename, check);
}
#else
// In sequentiel computations just read the macro file to the mesh.
checkParallelMacroFile(macroFilename, periodicFilename, check);
#endif
macroFileInfo =
MacroReader::readMacro(macroFilename, this, periodicFilename, check);
#endif
if (!valueFilename.length())
clearMacroFileInfo();
......@@ -1204,8 +1193,8 @@ namespace AMDiS {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
bool Mesh::checkParallelMacroFile(std::string macroFilename,
std::string periodicFilename,
void Mesh::checkParallelMacroFile(std::string &macroFilename,
std::string &periodicFilename,
int check)
{
FUNCNAME("Mesh::checkParallelMacroFile()");
......@@ -1293,7 +1282,7 @@ namespace AMDiS {
// === If we do not need to refine the mesh, return back. ===
if (nrRefine == 0)
return false;
return;
// === If macro weights are explicitly given, we cannot change the mesh. ===
......@@ -1305,6 +1294,24 @@ namespace AMDiS {
}
// === Create unique file names. ===
int filenameRandomNumber = 0;
if (MPI::COMM_WORLD.Get_rank() == 0) {
srand(time(NULL));
filenameRandomNumber = rand() % 1000000;
}
MPI::COMM_WORLD.Bcast(&filenameRandomNumber, 1, MPI_INT, 0);
std::stringstream newMacroFilename;
newMacroFilename << macroFilename << "." << filenameRandomNumber << ".tmp";
std::stringstream newPeriodicFilename;
newPeriodicFilename << periodicFilename << "." << filenameRandomNumber << ".tmp";
// === Rank 0 creates a new mesh file. ===
if (MPI::COMM_WORLD.Get_rank() == 0) {
......@@ -1322,10 +1329,10 @@ namespace AMDiS {
FiniteElemSpace::provideFeSpace(localAdmin, basFcts, &testMesh, "tmp");
DataCollector dc(feSpace);
MacroWriter::writeMacro(&dc, (macroFilename + ".tmp").c_str());
MacroWriter::writeMacro(&dc, newMacroFilename.str().c_str());
if (periodicFilename != "")
MacroWriter::writePeriodicFile(&dc, (periodicFilename + ".tmp").c_str());
MacroWriter::writePeriodicFile(&dc, newPeriodicFilename.str().c_str());
}
......@@ -1353,10 +1360,11 @@ namespace AMDiS {
// === Print a note to the screen that another mesh file will be used. ===
MSG("The macro mesh file \"%s\" was refined %d times and stored to file \"%s\".\n",
macroFilename.c_str(), nrRefine, (macroFilename + ".tmp").c_str());
macroFilename.c_str(), nrRefine, newMacroFilename.str().c_str());
return true;
macroFilename = newMacroFilename.str();
if (periodicFilename != "")
periodicFilename = newPeriodicFilename.str();
}
#endif
......
......@@ -688,21 +688,19 @@ namespace AMDiS {
* If this is not the case, that macro mesh is globally refined in an
* apropriate way and is written to a new macro file.
*
* The function returns true, if a new macro and parallel file were created for
* the current parallel usage. In this case, a new macro file with the same name
* plus ".tmp", and if required, a new periodic file with the same name plus
* ".tmp" are created.
* The function overwrittes the macro and periodic filenames, if a new macro
* fule was created for the current parallel usage.
*
* \param[in] macroFilename Name of the macro mesh file.
* \param[in] periodicFilename If periodic boundaries are used, name of the
* periodicity file. Otherwise, the string must
* be empty.
* \param[in] check If the mesh should be checked to be a correct
* AMDiS macro mesh, the value must be 1 and 0
* otherwise.
* \param[in/out] macroFilename Name of the macro mesh file.
* \param[in/out] periodicFilename If periodic boundaries are used, name of the
* periodicity file. Otherwise, the string must
* be empty.
* \param[in] check If the mesh should be checked to be a correct
* AMDiS macro mesh, the value must be 1 and 0
* otherwise.
*/
bool checkParallelMacroFile(std::string macroFilename,
std::string periodicFilename,
void checkParallelMacroFile(std::string &macroFilename,
std::string &periodicFilename,
int check);
#endif
......
......@@ -90,7 +90,7 @@ namespace AMDiS {
void addVertex(Element *el, int ith, BoundaryType bound = INTERIOR)
{
DegreeOfFreedom vertex = el->getDof(ith, 0);
DegreeOfFreedom vertex = el->getObject<DegreeOfFreedom>(ith);
int elIndex = el->getIndex();
ElementObjectData elObj(elIndex, ith, bound);
......@@ -101,7 +101,7 @@ namespace AMDiS {
void addEdge(Element *el, int ith, BoundaryType bound = INTERIOR)
{
DofEdge edge = el->getEdge(ith);
DofEdge edge = el->getObject<DofEdge>(ith);
int elIndex = el->getIndex();
ElementObjectData elObj(elIndex, ith, bound);
......@@ -112,7 +112,7 @@ namespace AMDiS {
void addFace(Element *el, int ith, BoundaryType bound = INTERIOR)
{
DofFace face = el->getFace(ith);
DofFace face = el->getObject<DofFace>(ith);
int elIndex = el->getIndex();
ElementObjectData elObj(elIndex, ith, bound);
......
......@@ -146,7 +146,7 @@ namespace AMDiS {
// and now partition the mesh
partitioner->fillCoarsePartitionVec(&oldPartitionVec);
partitioner->partition(&elemWeights, INITIAL);
partitioner->partition(elemWeights, INITIAL);
partitioner->fillCoarsePartitionVec(&partitionVec);
......@@ -1029,10 +1029,9 @@ namespace AMDiS {
elInfo = stack.traverseNext(elInfo);
}
partitioner->useLocalGlobalDofMap(&mapLocalGlobalDofs);
oldPartitionVec = partitionVec;
partitioner->partition(&elemWeights, ADAPTIVE_REPART, 1000.0);
partitioner->partition(elemWeights, ADAPTIVE_REPART, 1000.0);
// === Create map that maps macro element indices to pointers to the ===
......
......@@ -207,7 +207,7 @@ namespace AMDiS {
}
void ParMetisPartitioner::partition(std::map<int, double> *elemWeights,
void ParMetisPartitioner::partition(std::map<int, double> &elemWeights,
PartitionMode mode,
float itr)
{
......@@ -226,10 +226,10 @@ namespace AMDiS {
int nElements = parMetisMesh->getNumElements();
// === create weight array ===
int *wgts = elemWeights ? new int[nElements] : NULL;
float *floatWgts = elemWeights ? new float[nElements] : NULL;
std::vector<int> wgts(nElements);
std::vector<float> floatWgts(nElements);
unsigned int floatWgtsPos = 0;
float maxWgt = 0.0;
float *ptr_floatWgts = floatWgts;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, 0, Mesh::CALL_EL_LEVEL);
......@@ -238,16 +238,18 @@ namespace AMDiS {
if (elementInRank[index]) {
// get weight
float wgt = static_cast<float>((*elemWeights)[index]);
float wgt = static_cast<float>(elemWeights[index]);
maxWgt = max(wgt, maxWgt);
// write float weight
*ptr_floatWgts = wgt;
ptr_floatWgts++;
TEST_EXIT_DBG(floatWgtsPos < floatWgts.size())("Should not happen!\n");
floatWgts[floatWgtsPos++] = wgt;
}
elInfo = stack.traverseNext(elInfo);
}
TEST_EXIT_DBG(floatWgtsPos == floatWgts.size())("Should not happen!\n");
float tmp;
mpiComm->Allreduce(&maxWgt, &tmp, 1, MPI_FLOAT, MPI_MAX);
maxWgt = tmp;
......@@ -256,27 +258,25 @@ namespace AMDiS {
ParMetisGraph parMetisGraph(parMetisMesh, mpiComm);
// === partitioning of dual graph ===
int wgtflag = elemWeights ? 2 : 0; // weights at vertices only!
int wgtflag = 2; // weights at vertices only!
int numflag = 0; // c numbering style!
int ncon = elemWeights ? 1 : 0; // one weight at each vertex!
int ncon = 1; // one weight at each vertex!
int nparts = mpiSize; // number of partitions
float *tpwgts = elemWeights ? new float[mpiSize] : NULL;
std::vector<float> tpwgts(mpiSize);
float ubvec = 1.05;
int options[3] = {0, 0, 0}; // default options
int options[4] = {0, 0, 15, 1}; // default options
int edgecut = -1;
int *part = new int[nElements];
if (elemWeights) {
// set tpwgts
for (int i = 0; i < mpiSize; i++)
tpwgts[i] = 1.0 / nparts;
std::vector<int> part(nElements);
float scale = 10000.0 / maxWgt;
// scale wgts
for (int i = 0; i < nElements; i++)
wgts[i] = static_cast<int>(floatWgts[i] * scale);
}
// set tpwgts
for (int i = 0; i < mpiSize; i++)
tpwgts[i] = 1.0 / nparts;
float scale = 10000.0 / maxWgt;
// scale wgts
for (int i = 0; i < nElements; i++)
wgts[i] = static_cast<int>(floatWgts[i] * scale);
MPI_Comm tmpComm = MPI_Comm(*mpiComm);
......@@ -285,60 +285,59 @@ namespace AMDiS {
ParMETIS_V3_PartKway(parMetisMesh->getElementDist(),
parMetisGraph.getXAdj(),
parMetisGraph.getAdjncy(),
wgts,
&(wgts[0]),
NULL,
&wgtflag,
&numflag,
&ncon,
&nparts,
tpwgts,
&(tpwgts[0]),
&ubvec,
options,
&edgecut,
part,
&(part[0]),
&tmpComm);
break;
case ADAPTIVE_REPART:
{
int *vsize = new int[nElements];
std::vector<int> vsize(nElements);
for (int i = 0; i < nElements; i++)
vsize[i] = 1;
vsize[i] = static_cast<int>(floatWgts[i]);
ParMETIS_V3_AdaptiveRepart(parMetisMesh->getElementDist(),
parMetisGraph.getXAdj(),
parMetisGraph.getAdjncy(),
wgts,
&(wgts[0]),
NULL,
vsize,
&(vsize[0]),
&wgtflag,
&numflag,
&ncon,
&nparts,
tpwgts,
&(tpwgts[0]),
&ubvec,
&itr,
options,
&edgecut,
part,
&(part[0]),
&tmpComm);
delete [] vsize;
}
break;
case REFINE_PART:
ParMETIS_V3_RefineKway(parMetisMesh->getElementDist(),
parMetisGraph.getXAdj(),
parMetisGraph.getAdjncy(),
wgts,
&(wgts[0]),
NULL,
&wgtflag,
&numflag,
&ncon,
&nparts,
tpwgts,
&(tpwgts[0]),
&ubvec,
options,
&edgecut,
part,
&(part[0]),
&tmpComm);
break;
......@@ -347,16 +346,7 @@ namespace AMDiS {
}
// === distribute new partition data ===
distributePartitioning(part);
if (floatWgts)
delete [] floatWgts;
if (wgts)
delete [] wgts;
if (tpwgts)
delete [] tpwgts;
delete [] part;
distributePartitioning(&(part[0]));
}
......
......@@ -177,7 +177,7 @@ namespace AMDiS {
mapLocalGlobal(NULL)
{}
void partition(std::map<int, double> *elemWeights,
void partition(std::map<int, double> &elemWeights,
PartitionMode mode = INITIAL,
float itr = 1000000.0);
......
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.
#include "parallel/ParallelProblemStatBase.h"
#include "parallel/MeshDistributor.h"
#include "parallel/MpiHelper.h"
namespace AMDiS {
void ParallelProblemStatBase::buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag,
bool assembleMatrix,
bool assembleVector)
{
FUNCNAME("ParallelProblemStatBase::buildAfterCoarsen()");
meshDistributor->checkMeshChange();
ProblemVec::buildAfterCoarsen(adaptInfo, flag, assembleMatrix, assembleVector);
double vm, rss;
processMemUsage(vm, rss);
MSG("My memory usage is VM = %f RSS = %f\n", vm, rss);
mpi::globalAdd(vm);
mpi::globalAdd(rss);
MSG("Overall memory usage is VM = %f RSS = %f\n", vm, rss);
}
void ParallelProblemStatBase::addToMeshDistributor(MeshDistributor& m)
{
meshDistributor = &m;
m.addProblemStat(this);
}
void ParallelProblemStatBase::processMemUsage(double& vm_usage,
double& resident_set)
{
using std::ios_base;
using std::ifstream;
using std::string;
vm_usage = 0.0;
resident_set = 0.0;
// 'file' stat seems to give the most reliable results
ifstream stat_stream("/proc/self/stat",ios_base::in);
// dummy vars for leading entries in stat that we don't care about
string pid, comm, state, ppid, pgrp, session, tty_nr;
string tpgid, flags, minflt, cminflt, majflt, cmajflt;
string utime, stime, cutime, cstime, priority, nice;
string O, itrealvalue, starttime;
// the two fields we want
unsigned long vsize;
long rss;
stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
>> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
>> utime >> stime >> cutime >> cstime >> priority >> nice
>> O >> itrealvalue >> starttime >> vsize >> rss;
// in case x86-64 is configured to use 2MB pages
long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024;
vm_usage = vsize / 1024.0;
resident_set = rss * page_size_kb;
}
}
......@@ -23,6 +23,7 @@
#ifndef AMDIS_PARALLEL_PROBLEM_STAT_BASE_H
#define AMDIS_PARALLEL_PROBLEM_STAT_BASE_H
#include "parallel/MeshDistributor.h"
#include "ProblemVec.h"
namespace AMDiS {
......@@ -39,18 +40,12 @@ namespace AMDiS {
void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag,
bool assembleMatrix,
bool assembleVector)
{
meshDistributor->checkMeshChange();
ProblemVec::buildAfterCoarsen(adaptInfo, flag, assembleMatrix, assembleVector);
}
void addToMeshDistributor(MeshDistributor& m)
{
meshDistributor = &m;
m.addProblemStat(this);
}
bool assembleVector);
void addToMeshDistributor(MeshDistributor& m);
protected:
void processMemUsage(double& vm_usage, double& resident_set);
protected:
MeshDistributor *meshDistributor;
......