mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
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:
@ -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,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
|
||||
;;
|
||||
|
||||
*)
|
||||
|
||||
12
etc/bashrc
12
etc/bashrc
@ -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;
|
||||
|
||||
|
||||
12
etc/cshrc
12
etc/cshrc
@ -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.
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user