Liebe Gitlab-Nutzer, lieber Gitlab-Nutzer, es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Ein Anmelden über dieses erzeugt ein neues Konto. Das alte Konto ist über den Reiter "Standard" erreichbar. Die Administratoren

Dear Gitlab user, it is now possible to log in to our service using the ZIH login/LDAP. Logging in via this will create a new account. The old account can be accessed via the "Standard" tab. The administrators

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;
......
......@@ -36,22 +36,13 @@ namespace AMDiS {
TEST_EXIT(meshDistributor)("Should not happen!\n");