LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
FloatingPointControl_service.cc
Go to the documentation of this file.
2 #include "cetlib/ProvideFilePathMacro.h"
3 #include "cetlib/container_algorithms.h"
5 
6 using namespace art::fp_detail;
7 
8 // ======================================================================
9 
11  ActivityRegistry& reg)
12  : enableDivByZeroEx_{c().enableDivByZeroEx()}
13  , enableInvalidEx_{c().enableInvalidEx()}
14  , enableOverFlowEx_{c().enableOverFlowEx()}
15  , enableUnderFlowEx_{c().enableUnderFlowEx()}
16  , setPrecisionDouble_{c().setPrecisionDouble()}
17  , reportSettings_{c().reportSettings()}
19 {
20  reg.sPostEndJob.watch(this, &FloatingPointControl::postEndJob);
21 
22  if (reportSettings_) {
23  mf::LogVerbatim("FPE_Enable") << "\nOS's FP settings";
24  echoState();
25  }
26 
27  // Update the state according to the user's configuration
28  controlFpe();
29  if (reportSettings_) {
30  mf::LogVerbatim("FPE_Enable")
31  << "\nUpdated FP settings per user's configuration";
32  echoState();
33  }
34 }
35 
36 auto
38 {
39  return static_cast<precision_t>(getFPCW() & fpControl_ALL_PREC);
40 }
41 
42 auto
44 {
45  return static_cast<mask_t>(getFPCW() & FE_ALL_EXCEPT);
46 }
47 
48 void
50 {
51  (void)setFPControl(OSdefault_);
52  if (reportSettings_) {
53  mf::LogVerbatim("FPE_Enable") << "\nRestored to OS's FPE settings";
54  echoState();
55  }
56 }
57 
58 // ----------------------------------------------------------------------
59 
60 void
62 {
63  // NB: We do not let users configure signaling of denormalized operand
64  // (fpControl_DENORMALOPERAND) or inexact (FE_INEXACT), both of which
65  // are suppressed.
66  unsigned short int enable_except{};
67  unsigned short int enable_sse{};
68 
69  if (enableDivByZeroEx_) {
70  enable_except |= FE_DIVBYZERO;
71  enable_sse |= fpControl_ZM_MASK;
72  }
73 
74  if (enableInvalidEx_) {
75  enable_except |= FE_INVALID;
76  enable_sse |= fpControl_IM_MASK;
77  }
78 
79  if (enableOverFlowEx_) {
80  enable_except |= FE_OVERFLOW;
81  enable_sse |= fpControl_OM_MASK;
82  }
83 
84  if (enableUnderFlowEx_) {
85  enable_except |= FE_UNDERFLOW;
86  enable_sse |= fpControl_UM_MASK;
87  }
88 
89  auto fpControl = getFPControl();
90 
91  // Reset exception mask before clearing the bits we care about.
92  fpControl.fpcw = (fpControl.fpcw | FE_ALL_EXCEPT) & (~enable_except);
93 
94  if (setPrecisionDouble_) {
95  // Clear precision bits before setting only the ones we care about.
96  fpControl.fpcw =
97  (fpControl.fpcw & (~fpControl_ALL_PREC)) | fpControl_DOUBLE_PREC;
98  }
99 
100 #ifdef fpControl_HAVE_MXCSR
101  // Reset exception mask before clearing the bits we care about.
102  fpControl.mxcsr =
103  (fpControl.mxcsr | fpControl_ALL_SSE_EXCEPT) & (~enable_sse);
104 #endif
105 
106  // Write back.
107  (void)setFPControl(fpControl);
108 }
109 
110 // ----------------------------------------------------------------------
111 
112 void
114 {
115  if (reportSettings_) {
116  auto const femask{getFPCW()};
117  mf::LogVerbatim("FPE_Enable")
118  << "Floating point exception mask is " << std::showbase << std::hex
119  << femask << "\tDivByZero exception is"
120  << on_or_off(femask & FE_DIVBYZERO) << "\tInvalid exception is"
121  << on_or_off(femask & FE_INVALID) << "\tOverFlow exception is"
122  << on_or_off(femask & FE_OVERFLOW) << "\tUnderFlow exception is"
123  << on_or_off(femask & FE_UNDERFLOW);
124  }
125 }
126 
127 // ======================================================================
128 CET_PROVIDE_FILE_PATH()
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
fp_detail::fp_control_t OSdefault_
FloatingPointControl(FloatingPointControl const &)=delete
char const * on_or_off(bool const b)
Definition: fpControl.h:154
#define FHICL_PROVIDE_ALLOWED_CONFIGURATION(klass)
fpcw_t getFPCW()
Definition: fpControl.cc:28
fp_control_t getFPControl()
Definition: fpControl.h:130
fp_control_t setFPControl(fp_control_t const &fpControl)
Definition: fpControl.h:142