ENH: add trapFpe and setNaN optimisationSwitch (issue #517)

- allows configuration without an environment variable.
  For compatibility still respect FOAM_SIGFPE and FOAM_SETNAN
  env-variables

- The env-variables are now treated as true/false switch values.
  Previously there was just a check for env exists or not, but this
  can be fairly fragile for a user's environment.
This commit is contained in:
Mark Olesen
2017-07-05 17:49:37 +02:00
parent e54a930dcc
commit c50368ecc6
14 changed files with 139 additions and 83 deletions

View File

@ -59,6 +59,7 @@ Usage
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "sigFpe.H"
#include "Time.H"
#include "fvMesh.H"
#include "fvMeshTools.H"
@ -2277,7 +2278,7 @@ int main(int argc, char *argv[])
bool newTimes = args.optionFound("newTimes");
if (env("FOAM_SIGFPE"))
if (Foam::sigFpe::requested())
{
WarningInFunction
<< "Detected floating point exception trapping (FOAM_SIGFPE)."
@ -2287,7 +2288,6 @@ int main(int argc, char *argv[])
}
const HashSet<word> selectedFields(0);
const HashSet<word> selectedLagrangianFields(0);

View File

@ -39,8 +39,9 @@ usage: ${0##*/}
-foamVersion ver specify project version (eg, 1612)
-projectName name specify project directory name (eg, openfoam1612)
-archOption 32|64 specify 'WM_ARCH_OPTION' architecture option
-SP | -float32 specify 'WM_PRECISION_OPTION'
-DP | -float64 specify 'WM_PRECISION_OPTION'
-int32 | -int64 specify 'WM_LABEL_SIZE'
-SP | -DP specify 'WM_PRECISION_OPTION'
-system name specify 'system' compiler to be used
-third name specify 'ThirdParty' compiler to be used
-boost ver specify 'boost_version'
@ -63,7 +64,7 @@ usage: ${0##*/}
-scotch-path dir specify 'SCOTCH_ARCH_PATH' (eg, /opt/OpenFOAM-scotch_6.0.4)
-vtk ver specify 'vtk_version' (eg, VTK-7.1.0)
-mesa ver specify 'mesa_version' (eg, mesa-13.0.1)
-sigfpe | -no-sigfpe activate/deactivate FOAM_SIGFPE handling
-sigfpe | -no-sigfpe [defunct - now under etc/controlDict]
gmp-VERSION for ThirdParty gcc (gmp-system for system library)
mpfr-VERSION for ThirdParty gcc (mpfr-system for system library)
mpc-VERSION for ThirdParty gcc (mpc-system for system library)
@ -251,6 +252,18 @@ do
shift
;;
-SP | -float32)
# Replace WM_PRECISION_OPTION=...
replace etc/bashrc WM_PRECISION_OPTION "SP"
adjusted=true
;;
-DP | -float64)
# Replace WM_PRECISION_OPTION=...
replace etc/bashrc WM_PRECISION_OPTION "DP"
adjusted=true
;;
-int32 | -int64)
# Replace WM_LABEL_SIZE=...
optionValue="${1#-int}"
@ -258,13 +271,6 @@ do
adjusted=true
;;
-SP | -DP)
# Replace WM_PRECISION_OPTION=...
optionValue="${1#-}"
replace etc/bashrc WM_PRECISION_OPTION "$optionValue"
adjusted=true
;;
-system)
# Replace WM_COMPILER_TYPE=... and WM_COMPILER=...
[ "$#" -ge 2 ] || die "'$1' option requires an argument"
@ -471,20 +477,8 @@ do
adjusted=true
;;
-sigfpe)
# Enable FOAM_SIGFPE handling
_inlineSed etc/bashrc \
"[a-z][a-z]* FOAM_SIGFPE.*" \
"export FOAM_SIGFPE=" \
"Activate FOAM_SIGFPE handling"
;;
-no-sigfpe)
# Disable FOAM_SIGFPE handling
_inlineSed etc/bashrc \
"[a-z][a-z]* FOAM_SIGFPE.*" \
"unset FOAM_SIGFPE" \
"Deactivate FOAM_SIGFPE handling"
-sigfpe | -no-sigfpe)
echo "Enable/disable FOAM_SIGFPE now via controlDict" 1>&2
;;
*)

View File

@ -96,13 +96,13 @@ export WM_MPLIB=SYSTEMOPENMPI
# WM_OSTYPE = POSIX
#export WM_OSTYPE=POSIX
#- Floating-point signal handling:
# set or unset
export FOAM_SIGFPE=
#- Alternative to 'trapFpe' controlDict entry
# for floating-point exceptions (true|false)
#export FOAM_SIGFPE=true
#- memory initialisation:
# set or unset
#export FOAM_SETNAN=
#- Alternative to 'setNaN' controlDict entry
# for memory initialisation (true|false)
#export FOAM_SETNAN=false
################################################################################

View File

@ -79,6 +79,14 @@ OptimisationSwitches
// global reduction, even if multi-pass is not needed)
maxCommsSize 0;
// Trap floating point exception.
// Can override with FOAM_SIGFPE (true|false)
trapFpe 1;
// Initialization malloced memory to NaN.
// Can override with FOAM_SETNAN (true|false)
setNaN 0;
// Force dumping (at next timestep) upon signal (-1 to disable)
writeNowSignal -1; // 10;

View File

@ -93,13 +93,13 @@ setenv WM_MPLIB SYSTEMOPENMPI
# WM_OSTYPE = POSIX
#setenv WM_OSTYPE POSIX
#- Floating-point signal handling:
# set or unset
setenv FOAM_SIGFPE
#- Alternative to 'trapFpe' controlDict entry
# for floating-point exceptions (true|false)
#setenv FOAM_SIGFPE true
#- memory initialisation:
# set or unset
#setenv FOAM_SETNAN
#- Alternative to 'setNaN' controlDict entry
# for memory initialisation (true|false)
#setenv FOAM_SETNAN false
################################################################################

View File

@ -28,6 +28,7 @@ License
#include "JobInfo.H"
#include "OSspecific.H"
#include "IOstreams.H"
#include "Switch.H"
#ifdef LINUX_GNUC
#ifndef __USE_GNU
@ -43,17 +44,41 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
bool Foam::sigFpe::switchFpe_(Foam::debug::optimisationSwitch("trapFpe", 0));
bool Foam::sigFpe::switchNan_(Foam::debug::optimisationSwitch("setNaN", 0));
bool Foam::sigFpe::sigActive_ = false;
bool Foam::sigFpe::mallocNanActive_ = false;
struct sigaction Foam::sigFpe::oldAction_;
bool Foam::sigFpe::sigFpeActive_ = false;
// File-scope function.
// Controlled by env variable containing a bool (true|false|on|off ...)
// or by the specified flag
static bool isTrue(const char* envName, const bool flag)
{
const std::string str = Foam::getEnv(envName);
if (str.size())
{
Foam::Switch sw(str, true); // silently ignore bad input
if (sw.valid())
{
return sw;
}
}
// Env was not set or did not contain a valid bool value
return flag;
}
void Foam::sigFpe::fillNan(UList<scalar>& lst)
{
lst = std::numeric_limits<scalar>::signaling_NaN();
}
bool Foam::sigFpe::mallocNanActive_ = false;
#ifdef LINUX
extern "C"
@ -128,9 +153,15 @@ Foam::sigFpe::~sigFpe()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::sigFpe::requested()
{
return isTrue("FOAM_SIGFPE", switchFpe_);
}
void Foam::sigFpe::set(const bool verbose)
{
if (!sigFpeActive_ && env("FOAM_SIGFPE"))
if (!sigActive_ && requested())
{
bool supported = false;
@ -155,7 +186,7 @@ void Foam::sigFpe::set(const bool verbose)
<< abort(FatalError);
}
sigFpeActive_ = true;
sigActive_ = true;
#elif defined(sgiN32) || defined(sgiN32Gcc)
supported = true;
@ -179,28 +210,28 @@ void Foam::sigFpe::set(const bool verbose)
nullptr
);
sigFpeActive_ = true;
sigActive_ = true;
#endif
if (verbose)
{
Info<< "trapFpe: Floating point exception trapping ";
if (supported)
{
Info<< "sigFpe : Enabling floating point exception trapping"
<< " (FOAM_SIGFPE)." << endl;
Info<< "enabled (FOAM_SIGFPE)." << endl;
}
else
{
Info<< "sigFpe : Floating point exception trapping"
<< " - not supported on this platform" << endl;
Info<< "- not supported on this platform" << endl;
}
}
}
if (env("FOAM_SETNAN"))
if (isTrue("FOAM_SETNAN", switchNan_))
{
#ifdef LINUX
mallocNanActive_ = true;
@ -208,15 +239,15 @@ void Foam::sigFpe::set(const bool verbose)
if (verbose)
{
Info<< "setNaN : Initialise allocated memory to NaN ";
if (mallocNanActive_)
{
Info<< "SetNaN : Initialising allocated memory to NaN"
<< " (FOAM_SETNAN)." << endl;
Info<< "enabled (FOAM_SETNAN)." << endl;
}
else
{
Info<< "SetNaN : Initialise allocated memory to NaN"
<< " - not supported on this platform" << endl;
Info<< " - not supported on this platform" << endl;
}
}
}
@ -227,7 +258,7 @@ void Foam::sigFpe::unset(const bool verbose)
{
#ifdef LINUX_GNUC
// Reset signal
if (sigFpeActive_)
if (sigActive_)
{
if (verbose)
{
@ -256,7 +287,7 @@ void Foam::sigFpe::unset(const bool verbose)
<< "Cannot reset SIGFPE trapping"
<< abort(FatalError);
}
sigFpeActive_ = false;
sigActive_ = false;
}
#endif

View File

@ -27,17 +27,24 @@ Class
Description
Set up trapping for floating point exceptions (signal FPE).
Controlled by two env vars:
- \par FOAM_SIGFPE
Exception trapping
- \par FOAM_SETNAN
Initialization of all malloced memory to NaN. If FOAM_SIGFPE
also set, this will cause usage of uninitialized scalars to trigger
an abort.
Defined by controlDict InfoSwitch entries:
- \par trapFpe
Enable floating point exception trapping.
Can be used either directly through the static member functions or
through the scope of the object (constructor sets trapping; destructor
restores original).
- \par setNaN
Initialization all malloced memory to NaN.
Combined with \c trapFpe, this causes usage of uninitialized scalars
to trigger an abort.
Environment variables:
- \par FOAM_SIGFPE (true|false)
overrides \c trapFpe
- \par FOAM_SETNAN (true|false)
overrides \c setNaN
Note that trapping can be set/removed through the static member functions
or through the scope of the object (constructor sets trapping; destructor
restores original). The class behaves as a singleton.
SourceFiles
sigFpe.C
@ -73,12 +80,20 @@ class sigFpe
{
// Private data
//- Flag that floating point trapping should be used.
// Can override with FOAM_SIGFPE env variable
static bool switchFpe_;
//- Flag that NaN initialisation should be used.
// Can override with FOAM_SETNAN env variable
static bool switchNan_;
//- Flag to indicate floating point trapping is currently active
static bool sigActive_;
//- Saved old signal trapping setting
static struct sigaction oldAction_;
//- Flag to indicate floating point trapping is enabled
static bool sigFpeActive_;
// Static data members
@ -90,6 +105,11 @@ class sigFpe
public:
// Public data
//- Flag to indicate mallocNan is enabled
static bool mallocNanActive_;
// Constructors
@ -103,6 +123,11 @@ public:
// Member functions
//- Check if SIGFPE signals handler is to be enabled.
// This is controlled by the trapFpe entry or the FOAM_SIGFPE
// environment variable
static bool requested();
//- Activate SIGFPE signal handler when FOAM_SIGFPE is %set
// Fill memory with NaN when FOAM_SETNAN is %set
static void set(const bool verbose);
@ -110,16 +135,13 @@ public:
//- Deactivate SIGFPE signal handler and NaN memory initialisation
static void unset(const bool verbose);
//- Flag to indicate mallocNan is enabled
static bool mallocNanActive_;
#ifdef LINUX
//- Malloc function which initializes to NaN
static void* mallocNan(size_t size);
#endif
//- Fill block of data with NaN
static void fillNan(UList<scalar>&);
static void fillNan(UList<scalar>& lst);
};

View File

@ -86,7 +86,7 @@ void Foam::sigQuit::set(const bool verbose)
if (sigaction(SIGQUIT, &newAction, &oldAction_) < 0)
{
FatalErrorInFunction
<< "Cannot call sigQuit::set() more than once"
<< "Cannot call more than once"
<< abort(FatalError);
}
sigActive_ = true;
@ -101,7 +101,7 @@ void Foam::sigQuit::unset(const bool)
if (sigaction(SIGQUIT, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot set SIGQUIT trapping"
<< "Cannot unset SIGQUIT trapping"
<< abort(FatalError);
}
sigActive_ = false;

View File

@ -86,7 +86,7 @@ void Foam::sigSegv::set(const bool)
if (sigaction(SIGSEGV, &newAction, &oldAction_) < 0)
{
FatalErrorInFunction
<< "Cannot call sigSegv::set() more than once"
<< "Cannot call more than once"
<< abort(FatalError);
}
sigActive_ = true;
@ -101,7 +101,7 @@ void Foam::sigSegv::unset(const bool)
if (sigaction(SIGSEGV, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot set SIGSEGV trapping"
<< "Cannot unset SIGSEGV trapping"
<< abort(FatalError);
}
sigActive_ = false;

View File

@ -78,7 +78,6 @@ addstopAtWriteNowSignalToOpt addstopAtWriteNowSignalToOpt_
Foam::Time const* Foam::sigStopAtWriteNow::runTimePtr_ = nullptr;
struct sigaction Foam::sigStopAtWriteNow::oldAction_;
@ -109,7 +108,8 @@ void Foam::sigStopAtWriteNow::sigHandler(int)
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::sigStopAtWriteNow::sigStopAtWriteNow(){}
Foam::sigStopAtWriteNow::sigStopAtWriteNow()
{}
Foam::sigStopAtWriteNow::sigStopAtWriteNow

View File

@ -67,6 +67,7 @@ class sigStopAtWriteNow
// Private Member Functions
//- Handler for caught signals
static void sigHandler(int);

View File

@ -33,13 +33,13 @@ License
namespace Foam
{
// Signal number to catch
int sigWriteNow::signal_
(
debug::optimisationSwitch("writeNowSignal", -1)
);
// Register re-reader
class addwriteNowSignalToOpt
:
@ -75,7 +75,6 @@ addwriteNowSignalToOpt addwriteNowSignalToOpt_("writeNowSignal");
Foam::Time* Foam::sigWriteNow::runTimePtr_ = nullptr;
struct sigaction Foam::sigWriteNow::oldAction_;

View File

@ -66,6 +66,7 @@ class sigWriteNow
// Private Member Functions
//- Handler for caught signals
static void sigHandler(int);

View File

@ -8,8 +8,8 @@ cd ${0%/*} || exit 1 # Run from this directory
runParallel $(getApplication)
unset FOAM_SIGFPE
runParallel -s reconstruct redistributePar -reconstruct
# Disable trapping of floating-point exceptions
FOAM_SIGFPE=false runParallel -s reconstruct redistributePar -reconstruct
# A bit more testing of decomposing
\cp system/controlDict_nextWrite system/controlDict