ATLAS Offline Software
Loading...
Searching...
No Matches
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.
virtual StatusCode finalize ()
 Standard finalize method.
virtual void onCreate (const IAlgTool *)
 Called after each tool has been created.
 FPEControlSvc (const std::string &name, ISvcLocator *svcloc)
 Constructor.
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const

Private Member Functions

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

Private Attributes

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

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),
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}
ServiceHandle< IToolSvc > m_toolSvc
Tool service.
int m_disabled
Mask of disabled exceptions.
bool m_haveEnv
Flag that we've retrieved the environment.
std::string m_feSetRounding
flag to decide on rounding mode (for stability tests)
void prophand(Gaudi::Details::PropertyBase &prop)
Property change handler.
bool m_removeInFinalize
boolean to decide to (not) remove the observer in finalize
StringArrayProperty m_exceptions
Property specifying the desired exception mask.
int m_enabled
Mask of enabled exceptions.
fenv_t m_env
The FP environment before we initialize.

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}
#define REPORT_MESSAGE(LVL)
Report a message.
#define CHECK(...)
Evaluate an expression and check for errors.

◆ msg()

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

Definition at line 24 of file AthCommonMsg.h.

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

◆ 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}
void setFPU()
Set the FPU exception masks from m_enabled and m_disabled.

◆ 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}
Declarations of feenableexcept()/fedisableexcept() functions for MacOSX.

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: