CMS 3D CMS Logo

Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes

edm::service::EnableFloatingPointExceptions Class Reference

#include <EnableFloatingPointExceptions.h>

List of all members.

Public Types

typedef int fpu_flags_type

Public Member Functions

 EnableFloatingPointExceptions (ParameterSet const &pset, ActivityRegistry &registry)
void postEndJob ()
void postModule (ModuleDescription const &description)
void postModuleBeginJob (ModuleDescription const &description)
void postModuleBeginLumi (ModuleDescription const &description)
void postModuleBeginRun (ModuleDescription const &description)
void postModuleEndJob (ModuleDescription const &description)
void postModuleEndLumi (ModuleDescription const &description)
void postModuleEndRun (ModuleDescription const &description)
void preModule (ModuleDescription const &description)
void preModuleBeginJob (ModuleDescription const &description)
void preModuleBeginLumi (ModuleDescription const &description)
void preModuleBeginRun (ModuleDescription const &description)
void preModuleEndJob (ModuleDescription const &description)
void preModuleEndLumi (ModuleDescription const &description)
void preModuleEndRun (ModuleDescription const &description)

Static Public Member Functions

static void fillDescriptions (edm::ConfigurationDescriptions &descriptions)

Private Member Functions

void echoState () const
void enableAndDisableExcept (fpu_flags_type target)
void establishModuleEnvironments (ParameterSet const &pset)
void postActions (ModuleDescription const &description, char const *debugInfo)
void preActions (ModuleDescription const &description, char const *debugInfo)
void setPrecision (bool precisionDouble)

Private Attributes

fpu_flags_type defaultState_
fpu_flags_type fpuState_
bool reportSettings_
std::map< std::string,
fpu_flags_type
stateMap_
std::stack< fpu_flags_typestateStack_

Detailed Description

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.


Member Typedef Documentation

Definition at line 100 of file EnableFloatingPointExceptions.h.


Constructor & Destructor Documentation

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);
    }

Member Function Documentation

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
    }

Member Data Documentation

Definition at line 144 of file EnableFloatingPointExceptions.h.

Referenced by establishModuleEnvironments(), and preActions().