#include <EnableFloatingPointExceptions.h>
Description: This service gives cmsRun users the ability to configure the behavior of the Floating Point (FP) environment. There are two separate aspects of the FP environment this service can control:
1. floating-point exceptions (on a module by module basis if desired) 2. precision control on x87 FP processors.
If you do not use the service at all, floating point exceptions will not be trapped anywhere (FP exceptions will not cause a crash). Add something like the following to the configuration file to enable to the exceptions:
process.EnableFloatingPointExceptions = cms.Service("EnableFloatingPointExceptions", moduleNames = cms.untracked.vstring( 'default', 'sendMessages1', 'sendMessages2' ), default = cms.untracked.PSet( enableOverFlowEx = cms.untracked.bool(False), enableDivByZeroEx = cms.untracked.bool(False), enableInvalidEx = cms.untracked.bool(False), enableUnderFlowEx = cms.untracked.bool(False) ), sendMessages1 = cms.untracked.PSet( enableOverFlowEx = cms.untracked.bool(False), enableDivByZeroEx = cms.untracked.bool(True), enableInvalidEx = cms.untracked.bool(False), enableUnderFlowEx = cms.untracked.bool(False) ), sendMessages2 = cms.untracked.PSet( enableOverFlowEx = cms.untracked.bool(False), enableDivByZeroEx = cms.untracked.bool(False), enableInvalidEx = cms.untracked.bool(True), enableUnderFlowEx = cms.untracked.bool(False) ) )
In this example, the "Divide By Zero" exception is enabled only for the module with label "sendMessages1", the "Invalid" exception is enabled only for the module with label sendMessages2 and no floating point exceptions are otherwise enabled.
The defaults for these options are currently all false. (in an earlier version DivByZero, Invalid, and Overflow defaulted to true, we hope to return to those defaults someday when the frequency of such exceptions has decreased)
Enabling exceptions is very useful if you are trying to track down where a floating point value of 'nan' or 'inf' is being generated and is even better if the goal is to eliminate them.
One can also control the precision of floating point operations in x87 FP processors as follows:
process.EnableFloatingPointExceptions = cms.Service("EnableFloatingPointExceptions", setPrecisionDouble = cms.untracked.bool(True) )
If set true (the default if the service is used), the floating precision in the x87 math processor will be set to round results of addition, subtraction, multiplication, division, and square root to 64 bits after each operation instead of the x87 default, which is 80 bits for values in registers (this is the default you get if this service is not used at all).
The precision control only affects Intel and AMD 32 bit CPUs under LINUX. We have not implemented precision control in the service for other CPUs yet (some other CPUs round to 64 bits by default and some other CPUs do not allow control of the precision of floating point calculations, the behavior of other CPUs may need more study in the future).
Definition at line 98 of file EnableFloatingPointExceptions.h.
Definition at line 100 of file EnableFloatingPointExceptions.h.
edm::service::EnableFloatingPointExceptions::EnableFloatingPointExceptions | ( | ParameterSet const & | pset, |
ActivityRegistry & | registry | ||
) |
Definition at line 80 of file EnableFloatingPointExceptions.cc.
References defaultState_, echoState(), enableAndDisableExcept(), establishModuleEnvironments(), fpuState_, edm::ParameterSet::getUntrackedParameter(), postEndJob(), postModule(), postModuleBeginJob(), postModuleBeginLumi(), postModuleBeginRun(), postModuleEndJob(), postModuleEndLumi(), postModuleEndRun(), preModule(), preModuleBeginJob(), preModuleBeginLumi(), preModuleBeginRun(), preModuleEndJob(), preModuleEndLumi(), preModuleEndRun(), reportSettings_, setPrecision(), stateStack_, edm::ActivityRegistry::watchPostEndJob(), edm::ActivityRegistry::watchPostModule(), edm::ActivityRegistry::watchPostModuleBeginJob(), edm::ActivityRegistry::watchPostModuleBeginLumi(), edm::ActivityRegistry::watchPostModuleBeginRun(), edm::ActivityRegistry::watchPostModuleEndJob(), edm::ActivityRegistry::watchPostModuleEndLumi(), edm::ActivityRegistry::watchPostModuleEndRun(), edm::ActivityRegistry::watchPreModule(), edm::ActivityRegistry::watchPreModuleBeginJob(), edm::ActivityRegistry::watchPreModuleBeginLumi(), edm::ActivityRegistry::watchPreModuleBeginRun(), edm::ActivityRegistry::watchPreModuleEndJob(), edm::ActivityRegistry::watchPreModuleEndLumi(), and edm::ActivityRegistry::watchPreModuleEndRun().
: fpuState_(0), defaultState_(0), stateMap_(), stateStack_(), reportSettings_(false) { reportSettings_ = pset.getUntrackedParameter<bool>("reportSettings", false); bool precisionDouble = pset.getUntrackedParameter<bool>("setPrecisionDouble", true); if (reportSettings_) { edm::LogVerbatim("FPE_Enable") << "\nSettings in EnableFloatingPointExceptions constructor"; echoState(); } establishModuleEnvironments(pset); stateStack_.push(defaultState_); fpuState_ = defaultState_; enableAndDisableExcept(defaultState_); setPrecision(precisionDouble); // Note that we must watch all of the transitions even if there are no module specific settings. // This is because the floating point environment may be modified by code outside of this service. registry.watchPostEndJob(this,&EnableFloatingPointExceptions::postEndJob); registry.watchPreModuleBeginJob(this, &EnableFloatingPointExceptions::preModuleBeginJob); registry.watchPostModuleBeginJob(this, &EnableFloatingPointExceptions::postModuleBeginJob); registry.watchPreModuleEndJob(this, &EnableFloatingPointExceptions::preModuleEndJob); registry.watchPostModuleEndJob(this, &EnableFloatingPointExceptions::postModuleEndJob); registry.watchPreModuleBeginRun(this, &EnableFloatingPointExceptions::preModuleBeginRun); registry.watchPostModuleBeginRun(this, &EnableFloatingPointExceptions::postModuleBeginRun); registry.watchPreModuleEndRun(this, &EnableFloatingPointExceptions::preModuleEndRun); registry.watchPostModuleEndRun(this, &EnableFloatingPointExceptions::postModuleEndRun); registry.watchPreModuleBeginLumi(this, &EnableFloatingPointExceptions::preModuleBeginLumi); registry.watchPostModuleBeginLumi(this, &EnableFloatingPointExceptions::postModuleBeginLumi); registry.watchPreModuleEndLumi(this, &EnableFloatingPointExceptions::preModuleEndLumi); registry.watchPostModuleEndLumi(this, &EnableFloatingPointExceptions::postModuleEndLumi); registry.watchPreModule(this, &EnableFloatingPointExceptions::preModule); registry.watchPostModule(this, &EnableFloatingPointExceptions::postModule); }
void edm::service::EnableFloatingPointExceptions::echoState | ( | ) | const [private] |
Definition at line 410 of file EnableFloatingPointExceptions.cc.
Referenced by EnableFloatingPointExceptions(), establishModuleEnvironments(), postActions(), postEndJob(), and preActions().
{ feclearexcept(FE_ALL_EXCEPT); fpu_flags_type femask = fegetexcept(); edm::LogVerbatim("FPE_Enable") << "Floating point exception mask is " << std::showbase << std::hex << femask; if (femask & FE_DIVBYZERO) edm::LogVerbatim("FPE_Enable") << "\tDivByZero exception is on"; else edm::LogVerbatim("FPE_Enable") << "\tDivByZero exception is off"; if (femask & FE_INVALID) edm::LogVerbatim("FPE_Enable") << "\tInvalid exception is on"; else edm::LogVerbatim("FPE_Enable") << "\tInvalid exception is off"; if (femask & FE_OVERFLOW) edm::LogVerbatim("FPE_Enable") << "\tOverFlow exception is on"; else edm::LogVerbatim("FPE_Enable") << "\tOverflow exception is off"; if (femask & FE_UNDERFLOW) edm::LogVerbatim("FPE_Enable") << "\tUnderFlow exception is on"; else edm::LogVerbatim("FPE_Enable") << "\tUnderFlow exception is off"; }
void edm::service::EnableFloatingPointExceptions::enableAndDisableExcept | ( | fpu_flags_type | target | ) | [private] |
Definition at line 362 of file EnableFloatingPointExceptions.cc.
References cond::rpcobimon::current, and filterCSVwithJSON::target.
Referenced by EnableFloatingPointExceptions(), establishModuleEnvironments(), postActions(), and preActions().
{ feclearexcept(FE_ALL_EXCEPT); fpu_flags_type current = fegetexcept(); fpu_flags_type exceptionsToModify = current ^ target; fpu_flags_type exceptionsToEnable = 0; fpu_flags_type exceptionsToDisable = 0; if (exceptionsToModify & FE_DIVBYZERO) { if (target & FE_DIVBYZERO) { exceptionsToEnable |= FE_DIVBYZERO; } else { exceptionsToDisable |= FE_DIVBYZERO; } } if (exceptionsToModify & FE_INVALID) { if (target & FE_INVALID) { exceptionsToEnable |= FE_INVALID; } else { exceptionsToDisable |= FE_INVALID; } } if (exceptionsToModify & FE_OVERFLOW) { if (target & FE_OVERFLOW) { exceptionsToEnable |= FE_OVERFLOW; } else { exceptionsToDisable |= FE_OVERFLOW; } } if (exceptionsToModify & FE_UNDERFLOW) { if (target & FE_UNDERFLOW) { exceptionsToEnable |= FE_UNDERFLOW; } else { exceptionsToDisable |= FE_UNDERFLOW; } } if (exceptionsToEnable != 0) { feenableexcept(exceptionsToEnable); } if (exceptionsToDisable != 0) { fedisableexcept(exceptionsToDisable); } }
void edm::service::EnableFloatingPointExceptions::establishModuleEnvironments | ( | ParameterSet const & | pset | ) | [private] |
Definition at line 129 of file EnableFloatingPointExceptions.cc.
References def, defaultState_, echoState(), enableAndDisableExcept(), flags, fpuState_, edm::ParameterSet::getUntrackedParameter(), edm::ParameterSet::getUntrackedParameterSet(), reportSettings_, and stateMap_.
Referenced by EnableFloatingPointExceptions().
{ // Scan the module name list and set per-module values. Be careful to treat // any user-specified default first. If there is one, use it to override our default. // Then remove it from the list so we don't see it again while handling everything else. typedef std::vector<std::string> VString; std::string const def("default"); ParameterSet const empty_PSet; VString const empty_VString; VString moduleNames = pset.getUntrackedParameter<VString>("moduleNames", empty_VString); for (VString::const_iterator it(moduleNames.begin()), itEnd = moduleNames.end(); it != itEnd; ++it) { ParameterSet const& modulePSet = pset.getUntrackedParameterSet(*it, empty_PSet); bool enableDivByZeroEx = modulePSet.getUntrackedParameter<bool>("enableDivByZeroEx", false); bool enableInvalidEx = modulePSet.getUntrackedParameter<bool>("enableInvalidEx", false); bool enableOverFlowEx = modulePSet.getUntrackedParameter<bool>("enableOverFlowEx", false); bool enableUnderFlowEx = modulePSet.getUntrackedParameter<bool>("enableUnderFlowEx", false); fpu_flags_type flags = 0; if (enableDivByZeroEx) flags |= FE_DIVBYZERO; if (enableInvalidEx) flags |= FE_INVALID; if (enableOverFlowEx) flags |= FE_OVERFLOW; if (enableUnderFlowEx) flags |= FE_UNDERFLOW; enableAndDisableExcept(flags); fpuState_ = fegetexcept(); assert(flags == fpuState_); if (reportSettings_) { edm::LogVerbatim("FPE_Enable") << "\nSettings for module " << *it; echoState(); } if (*it == def) { defaultState_ = fpuState_; } else { stateMap_[*it] = fpuState_; } } }
void edm::service::EnableFloatingPointExceptions::fillDescriptions | ( | edm::ConfigurationDescriptions & | descriptions | ) | [static] |
Definition at line 267 of file EnableFloatingPointExceptions.cc.
References edm::ConfigurationDescriptions::add(), edm::ParameterSetDescription::addNode(), edm::ParameterSetDescription::addUntracked(), python::Node::node, edm::ParameterDescriptionNode::setComment(), edm::ParameterSetDescription::setComment(), and edm::ConfigurationDescriptions::setComment().
{ edm::ParameterSetDescription desc; desc.addUntracked<bool>("reportSettings", false)->setComment( "Log FPE settings at different phases of the job." ); desc.addUntracked<bool>("setPrecisionDouble", true)->setComment( "Set the FPU to use double precision"); edm::ParameterSetDescription validator; validator.setComment("FPU exceptions to enable/disable for the requested module"); validator.addUntracked<bool>("enableDivByZeroEx", false)->setComment( "Enable/disable exception for 'divide by zero'"); validator.addUntracked<bool>("enableInvalidEx", false)->setComment( "Enable/disable exception for 'invalid' math operations (e.g. sqrt(-1))"); validator.addUntracked<bool>("enableOverFlowEx", false)->setComment( "Enable/disable exception for numeric 'overflow' (value to big for type)"); validator.addUntracked<bool>("enableUnderFlowEx", false)->setComment( "Enable/disable exception for numeric 'underflow' (value to small to be represented accurately)"); edm::AllowedLabelsDescription<edm::ParameterSetDescription> node("moduleNames", validator, false); node.setComment("Contains the names for PSets where the PSet name matches the label of a module for which you want to modify the FPE"); desc.addNode(node); descriptions.add("EnableFloatingPointExceptions", desc); descriptions.setComment("This service allows you to control the FPU and its exceptions on a per module basis."); }
void edm::service::EnableFloatingPointExceptions::postActions | ( | ModuleDescription const & | description, |
char const * | debugInfo | ||
) | [private] |
Definition at line 329 of file EnableFloatingPointExceptions.cc.
References echoState(), enableAndDisableExcept(), fpuState_, edm::ModuleDescription::moduleLabel(), reportSettings_, and stateStack_.
Referenced by postModule(), postModuleBeginJob(), postModuleBeginLumi(), postModuleBeginRun(), postModuleEndJob(), postModuleEndLumi(), and postModuleEndRun().
{ // On exit from a module, set the state of the fpu back to what // it was before entry stateStack_.pop(); fpuState_ = stateStack_.top(); enableAndDisableExcept(fpuState_); if (reportSettings_) { edm::LogVerbatim("FPE_Enable") << "\nSettings for module label \"" << description.moduleLabel() << "\" after " << debugInfo; echoState(); } }
void edm::service::EnableFloatingPointExceptions::postEndJob | ( | ) |
Definition at line 173 of file EnableFloatingPointExceptions.cc.
References echoState(), and reportSettings_.
Referenced by EnableFloatingPointExceptions().
{ if (reportSettings_) { edm::LogVerbatim("FPE_Enable") << "\nSettings after endJob "; echoState(); } }
void edm::service::EnableFloatingPointExceptions::postModule | ( | ModuleDescription const & | description | ) |
Definition at line 261 of file EnableFloatingPointExceptions.cc.
References postActions().
Referenced by EnableFloatingPointExceptions().
{ postActions(description, "event"); }
void edm::service::EnableFloatingPointExceptions::postModuleBeginJob | ( | ModuleDescription const & | description | ) |
Definition at line 189 of file EnableFloatingPointExceptions.cc.
References postActions().
Referenced by EnableFloatingPointExceptions().
{ postActions(description, "beginJob"); }
void edm::service::EnableFloatingPointExceptions::postModuleBeginLumi | ( | ModuleDescription const & | description | ) |
Definition at line 237 of file EnableFloatingPointExceptions.cc.
References postActions().
Referenced by EnableFloatingPointExceptions().
{ postActions(description, "beginLumi"); }
void edm::service::EnableFloatingPointExceptions::postModuleBeginRun | ( | ModuleDescription const & | description | ) |
Definition at line 213 of file EnableFloatingPointExceptions.cc.
References postActions().
Referenced by EnableFloatingPointExceptions().
{ postActions(description, "beginRun"); }
void edm::service::EnableFloatingPointExceptions::postModuleEndJob | ( | ModuleDescription const & | description | ) |
Definition at line 201 of file EnableFloatingPointExceptions.cc.
References postActions().
Referenced by EnableFloatingPointExceptions().
{ postActions(description, "endJob"); }
void edm::service::EnableFloatingPointExceptions::postModuleEndLumi | ( | ModuleDescription const & | description | ) |
Definition at line 249 of file EnableFloatingPointExceptions.cc.
References postActions().
Referenced by EnableFloatingPointExceptions().
{ postActions(description, "endLumi"); }
void edm::service::EnableFloatingPointExceptions::postModuleEndRun | ( | ModuleDescription const & | description | ) |
Definition at line 225 of file EnableFloatingPointExceptions.cc.
References postActions().
Referenced by EnableFloatingPointExceptions().
{ postActions(description, "endRun"); }
void edm::service::EnableFloatingPointExceptions::preActions | ( | ModuleDescription const & | description, |
char const * | debugInfo | ||
) | [private] |
Definition at line 298 of file EnableFloatingPointExceptions.cc.
References defaultState_, echoState(), enableAndDisableExcept(), fpuState_, moduleLabel(), edm::ModuleDescription::moduleLabel(), reportSettings_, stateMap_, and stateStack_.
Referenced by preModule(), preModuleBeginJob(), preModuleBeginLumi(), preModuleBeginRun(), preModuleEndJob(), preModuleEndLumi(), and preModuleEndRun().
{ // On entry to a module, find the desired state of the fpu and set it // accordingly. Note that any module whose label does not appear in // our list gets the default settings. std::string const& moduleLabel = description.moduleLabel(); std::map<std::string, fpu_flags_type>::const_iterator iModule = stateMap_.find(moduleLabel); if (iModule == stateMap_.end()) { fpuState_ = defaultState_; } else { fpuState_ = iModule->second; } enableAndDisableExcept(fpuState_); stateStack_.push(fpuState_); if (reportSettings_) { edm::LogVerbatim("FPE_Enable") << "\nSettings for module label \"" << moduleLabel << "\" before " << debugInfo; echoState(); } }
void edm::service::EnableFloatingPointExceptions::preModule | ( | ModuleDescription const & | description | ) |
Definition at line 255 of file EnableFloatingPointExceptions.cc.
References preActions().
Referenced by EnableFloatingPointExceptions().
{ preActions(description, "event"); }
void edm::service::EnableFloatingPointExceptions::preModuleBeginJob | ( | ModuleDescription const & | description | ) |
Definition at line 183 of file EnableFloatingPointExceptions.cc.
References preActions().
Referenced by EnableFloatingPointExceptions().
{ preActions(description, "beginJob"); }
void edm::service::EnableFloatingPointExceptions::preModuleBeginLumi | ( | ModuleDescription const & | description | ) |
Definition at line 231 of file EnableFloatingPointExceptions.cc.
References preActions().
Referenced by EnableFloatingPointExceptions().
{ preActions(description, "beginLumi"); }
void edm::service::EnableFloatingPointExceptions::preModuleBeginRun | ( | ModuleDescription const & | description | ) |
Definition at line 207 of file EnableFloatingPointExceptions.cc.
References preActions().
Referenced by EnableFloatingPointExceptions().
{ preActions(description, "beginRun"); }
void edm::service::EnableFloatingPointExceptions::preModuleEndJob | ( | ModuleDescription const & | description | ) |
Definition at line 195 of file EnableFloatingPointExceptions.cc.
References preActions().
Referenced by EnableFloatingPointExceptions().
{ preActions(description, "endJob"); }
void edm::service::EnableFloatingPointExceptions::preModuleEndLumi | ( | ModuleDescription const & | description | ) |
Definition at line 243 of file EnableFloatingPointExceptions.cc.
References preActions().
Referenced by EnableFloatingPointExceptions().
{ preActions(description, "endLumi"); }
void edm::service::EnableFloatingPointExceptions::preModuleEndRun | ( | ModuleDescription const & | description | ) |
Definition at line 219 of file EnableFloatingPointExceptions.cc.
References preActions().
Referenced by EnableFloatingPointExceptions().
{ preActions(description, "endRun"); }
void edm::service::EnableFloatingPointExceptions::setPrecision | ( | bool | precisionDouble | ) | [private] |
Definition at line 347 of file EnableFloatingPointExceptions.cc.
Referenced by EnableFloatingPointExceptions().
{ #ifdef __linux__ #ifdef __i386__ if (precisionDouble) { fpu_control_t cw; _FPU_GETCW(cw); cw = (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(cw); } #endif #endif }
Definition at line 143 of file EnableFloatingPointExceptions.h.
Referenced by EnableFloatingPointExceptions(), establishModuleEnvironments(), and preActions().
Definition at line 142 of file EnableFloatingPointExceptions.h.
Referenced by EnableFloatingPointExceptions(), establishModuleEnvironments(), postActions(), and preActions().
bool edm::service::EnableFloatingPointExceptions::reportSettings_ [private] |
Definition at line 146 of file EnableFloatingPointExceptions.h.
Referenced by EnableFloatingPointExceptions(), establishModuleEnvironments(), postActions(), postEndJob(), and preActions().
std::map<std::string, fpu_flags_type> edm::service::EnableFloatingPointExceptions::stateMap_ [private] |
Definition at line 144 of file EnableFloatingPointExceptions.h.
Referenced by establishModuleEnvironments(), and preActions().
std::stack<fpu_flags_type> edm::service::EnableFloatingPointExceptions::stateStack_ [private] |
Definition at line 145 of file EnableFloatingPointExceptions.h.
Referenced by EnableFloatingPointExceptions(), postActions(), and preActions().