ATLAS Offline Software
Public Member Functions | Private Member Functions | Private Attributes | List of all members
FPEControlSvc Class Reference

Service to enable or disable floating-point exceptions. More...

#include <FPEControlSvc.h>

Inheritance diagram for FPEControlSvc:
Collaboration diagram for FPEControlSvc:

Public Member Functions

virtual StatusCode initialize ()
 Standard initialize method. More...
 
virtual StatusCode finalize ()
 Standard finalize method. More...
 
virtual void onCreate (const IAlgTool *)
 Called after each tool has been created. More...
 
 FPEControlSvc (const std::string &name, ISvcLocator *svcloc)
 Constructor. More...
 
MsgStream & msg () const
 
MsgStream & msg (const MSG::Level lvl) const
 
bool msgLvl (const MSG::Level lvl) const
 

Private Member Functions

void setFPU ()
 Set the FPU exception masks from m_enabled and m_disabled. More...
 
void prophand (Gaudi::Details::PropertyBase &prop)
 Property change handler. More...
 

Private Attributes

StringArrayProperty m_exceptions
 Property specifying the desired exception mask. More...
 
ServiceHandle< IToolSvc > m_toolSvc
 Tool service. More...
 
fenv_t m_env
 The FP environment before we initialize. More...
 
bool m_haveEnv
 Flag that we've retrieved the environment. More...
 
int m_enabled
 Mask of enabled exceptions. More...
 
int m_disabled
 Mask of disabled exceptions. More...
 
bool m_removeInFinalize
 boolean to decide to (not) remove the observer in finalize More...
 
std::string m_feSetRounding
 flag to decide on rounding mode (for stability tests) More...
 

Detailed Description

Service to enable or disable floating-point exceptions.

When this service initializes, it will set the floating-point exception mask based on the value of the Exceptions property. This is a string array, containing any of the following strings to enable the corresponding exceptions:

inexact divbyzero underflow overflow invalid

In addition, these words can appear with a ! in front to disable them. Later words take precendence over earlier ones.

The default is divbyzero overflow invalid.

The property can be reassigned at any time to change the current exception mask.

Definition at line 50 of file FPEControlSvc.h.

Constructor & Destructor Documentation

◆ FPEControlSvc()

FPEControlSvc::FPEControlSvc ( const std::string &  name,
ISvcLocator *  svc 
)

Constructor.

Parameters
nameThe service name.
svclocThe service locator.

Definition at line 22 of file FPEControlSvc.cxx.

23  : AthService( name, svc ),
24  m_toolSvc ("ToolSvc", name),
25  m_env(),
26  m_haveEnv(false),
27  m_enabled (0),
28  m_disabled (0),
29  m_removeInFinalize(false),
30  m_feSetRounding("")
31 {
32  declareProperty("Exceptions", m_exceptions);
33  declareProperty("ToolSvc", m_toolSvc);
34  declareProperty("FERoundingMode", m_feSetRounding);
35  m_exceptions.declareUpdateHandler (&FPEControlSvc::prophand, this);
36 
37  // Set up the default exceptions.
38  std::vector<std::string> defexc;
39  defexc.push_back ("invalid");
40  defexc.push_back ("divbyzero");
41  defexc.push_back ("overflow");
42  m_exceptions = defexc;
43 }

Member Function Documentation

◆ finalize()

StatusCode FPEControlSvc::finalize ( )
virtual

Standard finalize method.

Definition at line 92 of file FPEControlSvc.cxx.

93 {
94  // remove only if requested
96  {
97  // Restore the FP environment to what is was before we ran.
98  fesetenv (&m_env);
99  }
100 
101  return StatusCode::SUCCESS;
102 }

◆ initialize()

StatusCode FPEControlSvc::initialize ( )
virtual

Standard initialize method.

Definition at line 49 of file FPEControlSvc.cxx.

50 {
51  // And change the exception mask.
53 
54  // Add ourself as an observer.
55  CHECK( m_toolSvc.retrieve() );
56  m_toolSvc->registerObserver (this);
57 
58  if(m_feSetRounding!="")
59  {
60  REPORT_MESSAGE (MSG::INFO) << "FE Rounding mode " << m_feSetRounding << " requested";
61  if(m_feSetRounding=="FE_TONEAREST")
62  {
63  if ( fesetround(FE_TONEAREST) )
64  REPORT_MESSAGE (MSG::WARNING) << "Couldn't change FE Rounding to mode FE_TONEAREST !";
65  }
66  else if(m_feSetRounding=="FE_UPWARD")
67  {
68  if ( fesetround(FE_UPWARD) )
69  REPORT_MESSAGE (MSG::WARNING) << "Couldn't change FE Rounding to mode FE_UPWARD !";
70  }
71  else if(m_feSetRounding=="FE_DOWNWARD")
72  {
73  if ( fesetround(FE_DOWNWARD) )
74  REPORT_MESSAGE (MSG::WARNING) << "Couldn't change FE Rounding to mode FE_DOWNWARD !";
75  }
76  else if(m_feSetRounding=="FE_TOWARDZERO")
77  {
78  if ( fesetround(FE_TOWARDZERO) )
79  REPORT_MESSAGE (MSG::WARNING) << "Couldn't change FE Rounding to mode FE_TOWARDZERO !";
80  }
81  else
82  REPORT_MESSAGE (MSG::WARNING) << "Don't know FE Rounding to mode " << m_feSetRounding;
83  }
84 
85  return StatusCode::SUCCESS;
86 }

◆ msg() [1/2]

MsgStream& AthCommonMsg< Service >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24  {
25  return this->msgStream();
26  }

◆ msg() [2/2]

MsgStream& AthCommonMsg< Service >::msg ( const MSG::Level  lvl) const
inlineinherited

Definition at line 27 of file AthCommonMsg.h.

27  {
28  return this->msgStream(lvl);
29  }

◆ msgLvl()

bool AthCommonMsg< Service >::msgLvl ( const MSG::Level  lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30  {
31  return this->msgLevel(lvl);
32  }

◆ onCreate()

void FPEControlSvc::onCreate ( const IAlgTool *  )
virtual

Called after each tool has been created.

Observer callback.

This is called after each tool is created. We make sure that the FPE mask is still set correctly. We do this because some tools have been observed to mask off exceptions. In particular, libgfortran will mask exceptions off when it's first loaded. So, if libgfortran hasn't yet been loaded when we initialize, but then gets loaded later, then exceptions will remain masked off.

Definition at line 115 of file FPEControlSvc.cxx.

116 {
117  setFPU();
118 }

◆ prophand()

void FPEControlSvc::prophand ( Gaudi::Details::PropertyBase &  prop)
private

Property change handler.

Definition at line 153 of file FPEControlSvc.cxx.

154 {
155  if (!m_haveEnv) {
156  // Save the current FP environment.
157  fegetenv (&m_env);
158  m_haveEnv = true;
159  }
160  else {
161  // Reset to the FP environment before we started.
162  fesetenv (&m_env);
163  }
164 
165  // Figure out which exceptions to enable/disable.
166  m_enabled = 0;
167  m_disabled = 0;
168  const std::vector<std::string>& v = m_exceptions.value();
169  for (size_t i = 0; i < v.size(); i++) {
170  bool onoff = true;
171  const char* s = v[i].c_str();
172  if (!s) continue;
173  if (s[0] == '!') {
174  onoff = false;
175  ++s;
176  }
177  int thisexc = 0;
178  if (strcasecmp (s, "inexact") == 0)
179  thisexc = FE_INEXACT;
180  else if (strcasecmp (s, "divbyzero") == 0)
181  thisexc = FE_DIVBYZERO;
182  else if (strcasecmp (s, "underflow") == 0)
183  thisexc = FE_UNDERFLOW;
184  else if (strcasecmp (s, "overflow") == 0)
185  thisexc = FE_OVERFLOW;
186  else if (strcasecmp (s, "invalid") == 0)
187  thisexc = FE_INVALID;
188  else {
189  REPORT_MESSAGE (MSG::INFO)
190  << "Unknown exception name: " << v[i];
191  continue;
192  }
193 
194  if (onoff) {
195  m_enabled |= thisexc;
196  m_disabled &= ~thisexc;
197  }
198  else {
199  m_disabled |= thisexc;
200  m_enabled &= ~thisexc;
201  }
202  }
203 
204  // Say what we're doing, and change the masks.
205  REPORT_MESSAGE (MSG::INFO)
206  << "Enable: " << mask_to_string (m_enabled)
207  << "Disable: " << mask_to_string (m_disabled);
208 
209  setFPU();
210 }

◆ setFPU()

void FPEControlSvc::setFPU ( )
private

Set the FPU exception masks from m_enabled and m_disabled.

Definition at line 216 of file FPEControlSvc.cxx.

217 {
218  feclearexcept (m_enabled);
219 #ifdef __GLIBC__
220  feenableexcept (m_enabled);
221  fedisableexcept (m_disabled);
222 #elif defined __APPLE__
223 #include "CxxUtils/excepts.h"
224  feenableexcept (m_enabled);
225  fedisableexcept (m_disabled);
226 #else
227  // The functions above are gnu-specific.
228  // Without GNU, we do it the harder way.
229  fenv_t newval;
230  fegetenv(&newval);
231 
232  // CSR bit on means that the exception is masked.
233 
234  newval.__control_word &= ~m_enabled;
235  newval.__control_word |= m_disabled;
236 # ifdef __x86_64
237  // SSE floating point uses separate exception masks.
238  newval.__mxcsr &= (~m_enabled) << 7;
239  newval.__mxcsr |= ( m_disabled) << 7;
240 # endif
241  fesetenv(&newval);
242 #endif
243 }

Member Data Documentation

◆ m_disabled

int FPEControlSvc::m_disabled
private

Mask of disabled exceptions.

Definition at line 92 of file FPEControlSvc.h.

◆ m_enabled

int FPEControlSvc::m_enabled
private

Mask of enabled exceptions.

Definition at line 89 of file FPEControlSvc.h.

◆ m_env

fenv_t FPEControlSvc::m_env
private

The FP environment before we initialize.

Definition at line 83 of file FPEControlSvc.h.

◆ m_exceptions

StringArrayProperty FPEControlSvc::m_exceptions
private

Property specifying the desired exception mask.

Definition at line 77 of file FPEControlSvc.h.

◆ m_feSetRounding

std::string FPEControlSvc::m_feSetRounding
private

flag to decide on rounding mode (for stability tests)

Definition at line 98 of file FPEControlSvc.h.

◆ m_haveEnv

bool FPEControlSvc::m_haveEnv
private

Flag that we've retrieved the environment.

Definition at line 86 of file FPEControlSvc.h.

◆ m_removeInFinalize

bool FPEControlSvc::m_removeInFinalize
private

boolean to decide to (not) remove the observer in finalize

Definition at line 95 of file FPEControlSvc.h.

◆ m_toolSvc

ServiceHandle<IToolSvc> FPEControlSvc::m_toolSvc
private

Tool service.

Definition at line 80 of file FPEControlSvc.h.


The documentation for this class was generated from the following files:
AthService::AthService
AthService()
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
FPEControlSvc::m_removeInFinalize
bool m_removeInFinalize
boolean to decide to (not) remove the observer in finalize
Definition: FPEControlSvc.h:95
FPEControlSvc::setFPU
void setFPU()
Set the FPU exception masks from m_enabled and m_disabled.
Definition: FPEControlSvc.cxx:216
FPEControlSvc::m_toolSvc
ServiceHandle< IToolSvc > m_toolSvc
Tool service.
Definition: FPEControlSvc.h:80
FPEControlSvc::m_haveEnv
bool m_haveEnv
Flag that we've retrieved the environment.
Definition: FPEControlSvc.h:86
excepts.h
Declarations of feenableexcept()/fedisableexcept() functions for MacOSX.
FPEControlSvc::m_disabled
int m_disabled
Mask of disabled exceptions.
Definition: FPEControlSvc.h:92
FPEControlSvc::prophand
void prophand(Gaudi::Details::PropertyBase &prop)
Property change handler.
Definition: FPEControlSvc.cxx:153
FPEControlSvc::m_feSetRounding
std::string m_feSetRounding
flag to decide on rounding mode (for stability tests)
Definition: FPEControlSvc.h:98
FPEControlSvc::m_env
fenv_t m_env
The FP environment before we initialize.
Definition: FPEControlSvc.h:83
lumiFormat.i
int i
Definition: lumiFormat.py:85
FPEControlSvc::m_exceptions
StringArrayProperty m_exceptions
Property specifying the desired exception mask.
Definition: FPEControlSvc.h:77
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
Handler::svc
AthROOTErrorHandlerSvc * svc
Definition: AthROOTErrorHandlerSvc.cxx:10
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
FPEControlSvc::m_enabled
int m_enabled
Mask of enabled exceptions.
Definition: FPEControlSvc.h:89
REPORT_MESSAGE
#define REPORT_MESSAGE(LVL)
Report a message.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:365
python.PyAthena.v
v
Definition: PyAthena.py:154