Commit c50368ec authored by Mark Olesen's avatar Mark Olesen
Browse files

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.
parent e54a930d
......@@ -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);
......
......@@ -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,17 +252,22 @@ do
shift
;;
-int32 | -int64)
# Replace WM_LABEL_SIZE=...
optionValue="${1#-int}"
replace etc/bashrc WM_LABEL_SIZE "$optionValue"
-SP | -float32)
# Replace WM_PRECISION_OPTION=...
replace etc/bashrc WM_PRECISION_OPTION "SP"
adjusted=true
;;
-SP | -DP)
-DP | -float64)
# Replace WM_PRECISION_OPTION=...
optionValue="${1#-}"
replace etc/bashrc WM_PRECISION_OPTION "$optionValue"
replace etc/bashrc WM_PRECISION_OPTION "DP"
adjusted=true
;;
-int32 | -int64)
# Replace WM_LABEL_SIZE=...
optionValue="${1#-int}"
replace etc/bashrc WM_LABEL_SIZE "$optionValue"
adjusted=true
;;
......@@ -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
;;
*)
......
......@@ -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
################################################################################
......
......@@ -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;
......
......@@ -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
################################################################################
......
......@@ -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
......
......@@ -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.
Can be used either directly through the static member functions or
through the scope of the object (constructor sets trapping; destructor
restores original).
Defined by controlDict InfoSwitch entries:
- \par trapFpe
Enable floating point exception trapping.
- \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);
};
......
......@@ -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;
......@@ -100,9 +100,9 @@ void Foam::sigQuit::unset(const bool)
{
if (sigaction(SIGQUIT, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot set SIGQUIT trapping"
<< abort(FatalError);
FatalErrorInFunction
<< "Cannot unset SIGQUIT trapping"
<< abort(FatalError);
}
sigActive_ = false;
}
......
......@@ -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;
......
......@@ -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
......
......@@ -67,6 +67,7 @@ class sigStopAtWriteNow
// Private Member Functions
//- Handler for caught signals
static void sigHandler(int);
......
......@@ -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_;
......
......@@ -66,6 +66,7 @@ class sigWriteNow
// Private Member Functions
//- Handler for caught signals
static void sigHandler(int);
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment