change LinAlgInit to a refcounted singleton.

we need control over the destruction order since several destructors
do MPI calls. The LinAlgInit destructor calls MPI_Finalize() through
PetscFinalize() and thus programs may crash on exit.

git-svn-id: http://svn.sintef.no/trondheim/IFEM/trunk@883 e10b68d5-8a6e-419e-a041-bce267b0401d
This commit is contained in:
akva 2011-03-31 07:37:53 +00:00 committed by Knut Morten Okstad
parent eaafe088a0
commit 6d6ae100c5
6 changed files with 59 additions and 3 deletions

View File

@ -77,7 +77,7 @@ int main (int argc, char** argv)
bool twoD = false;
char* infile = 0;
LinAlgInit linalg(argc,argv);
LinAlgInit& linalg = LinAlgInit::Init(argc,argv);
for (int i = 1; i < argc; i++)
if (!strcmp(argv[i],"-dense"))

View File

@ -16,6 +16,8 @@
#include "ASMbase.h"
#include "MPC.h"
#include "LinAlgInit.h"
SAMpatchPara::SAMpatchPara(const IntVec& l2gn_mp)
{
@ -25,6 +27,7 @@ SAMpatchPara::SAMpatchPara(const IntVec& l2gn_mp)
#else
nProc = 1;
#endif
LinAlgInit::increfs();
}
@ -34,6 +37,7 @@ SAMpatchPara::~SAMpatchPara ()
ISDestroy(iglob);
ISDestroy(iloc);
#endif
LinAlgInit::decrefs();
}

View File

@ -19,6 +19,30 @@
#include "slepceps.h"
#endif
LinAlgInit* LinAlgInit::instance;
int LinAlgInit::refs;
LinAlgInit& LinAlgInit::Init(int argc, char** argv)
{
if (!instance)
instance = new LinAlgInit(argc,argv);
return *instance;
}
void LinAlgInit::increfs()
{
refs++;
}
void LinAlgInit::decrefs()
{
refs--;
if (!refs)
delete instance;
}
LinAlgInit::LinAlgInit (int argc, char** argv)
{

View File

@ -22,12 +22,26 @@
class LinAlgInit
{
public:
//! \brief The constructor uses the command-line arguments to set up things.
LinAlgInit(int argc, char** argv);
//! \brief This class is a ref-counted singleton. We need control over
// the destruction order since the destructor calls PetscFinalize()
// which shuts down MPI. Thus this object must be destroyed after
// objects that do MPI calls in their destructor.
// This we cannot guarantee without the ref-counting since this
// class is instanced as a local variable in the main() scope of
// applications.
static LinAlgInit& Init(int argc, char** argv);
//! \brief The destructor finalizes the linear algebra packages.
~LinAlgInit();
int myPid; //!< Processor ID in parallel simulations
static void increfs();
static void decrefs();
private:
static int refs;
//! \brief The constructor uses the command-line arguments to set up things.
LinAlgInit(int argc, char** argv);
static LinAlgInit* instance;
};
#endif

View File

@ -19,11 +19,14 @@
#include "slepceps.h"
#endif
#include "LinAlgInit.h"
PETScVector::PETScVector()
{
VecCreate(PETSC_COMM_WORLD,&x);
VecSetFromOptions(x);
LinAlgInit::increfs();
}
@ -32,6 +35,7 @@ PETScVector::PETScVector(size_t n)
VecCreate(PETSC_COMM_WORLD,&x);
VecSetSizes(x,n,PETSC_DECIDE);
VecSetFromOptions(x);
LinAlgInit::increfs();
}
@ -45,6 +49,7 @@ PETScVector::PETScVector(const real* values, size_t n)
VecGetArray(x,&x_array);
*x_array = *values;
VecRestoreArray(x,&x_array);
LinAlgInit::increfs();
}
@ -52,6 +57,7 @@ PETScVector::PETScVector(const PETScVector& vec)
{
VecDuplicate(vec.x,&x);
VecCopy(vec.x,x);
LinAlgInit::increfs();
}
@ -59,6 +65,7 @@ PETScVector::~PETScVector()
{
// Deallocation of vector
VecDestroy(x);
LinAlgInit::decrefs();
}
@ -165,6 +172,7 @@ PETScMatrix::PETScMatrix(const LinSolParams& spar) : solParams(spar)
MatNullSpaceCreate(PETSC_COMM_WORLD,PETSC_TRUE,0,0,&nsp);
KSPSetNullSpace(ksp,nsp);
}
LinAlgInit::increfs();
}
@ -182,6 +190,7 @@ PETScMatrix::PETScMatrix (const PETScMatrix& B) : solParams(B.solParams)
MatNullSpaceCreate(PETSC_COMM_WORLD,PETSC_TRUE,0,0,&nsp);
KSPSetNullSpace(ksp,nsp);
}
LinAlgInit::increfs();
}
@ -196,6 +205,7 @@ PETScMatrix::~PETScMatrix ()
// Deallocation of matrix object.
MatDestroy(A);
LinAlgInit::decrefs();
}

View File

@ -17,6 +17,8 @@
#endif
#include <sys/time.h>
#include "LinAlgInit.h"
Profiler* utl::profiler = 0;
@ -30,6 +32,7 @@ Profiler::Profiler (const std::string& name) : myName(name), nRunners(0)
// Update pointer to current profiler (it should only be one at any time)
if (utl::profiler) delete utl::profiler;
utl::profiler = this;
LinAlgInit::increfs();
}
@ -37,6 +40,7 @@ Profiler::~Profiler ()
{
this->stop("Total");
this->report(std::cout);
LinAlgInit::decrefs();
}