Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tpetra_Details_Behavior.cpp
2 #include "TpetraCore_config.h"
3 #include <algorithm> // std::transform
4 #include <cstdlib> // std::getenv
5 #include <cctype> // std::toupper
6 #include <string>
7 #include <map>
8 #include <vector>
9 #include <functional>
10 
11 namespace Tpetra {
12 namespace Details {
13 
14 namespace BehaviorDetails {
15 std::map<std::string, std::map<std::string, bool> > namedVariableMap_;
16 bool verboseDisabled_ = false;
17 }
18 
19 namespace { // (anonymous)
20 
21  enum EnvironmentVariableState
22  {
23  EnvironmentVariableIsSet_ON,
24  EnvironmentVariableIsSet_OFF,
25  EnvironmentVariableIsSet,
26  EnvironmentVariableIsNotSet
27  };
28 
29  // See example here:
30  //
31  // http://en.cppreference.com/w/cpp/string/byte/toupper
32  std::string stringToUpper (std::string s)
33  {
34  std::transform (s.begin (), s.end (), s.begin (),
35  [] (unsigned char c) { return std::toupper (c); });
36  return s;
37  }
38 
39  void
40  split(const std::string& s,
41  std::function<void(const std::string&)> f,
42  const char sep=',')
43  {
44  typedef std::string::size_type size_type;
45  size_type cur_pos, last_pos=0, length=s.length();
46  while(last_pos < length + 1)
47  {
48  cur_pos = s.find_first_of(sep, last_pos);
49  if(cur_pos == std::string::npos)
50  {
51  cur_pos = length;
52  }
53  if(cur_pos!=last_pos) {
54  auto token = std::string(s.data()+last_pos, (size_type)cur_pos-last_pos);
55  f(token);
56  }
57  last_pos = cur_pos + 1;
58  }
59  return;
60  }
61 
62  EnvironmentVariableState
63  environmentVariableState(const std::string& environmentVariableValue)
64  {
65  std::string v = stringToUpper(environmentVariableValue);
66  if (v == "1" || v == "YES" || v == "TRUE" || v == "ON")
67  // Environment variable is "ON"
68  return EnvironmentVariableIsSet_ON;
69  else if (v == "0" || v == "NO" || v == "FALSE" || v == "OFF")
70  // Environment variable is "OFF"
71  return EnvironmentVariableIsSet_OFF;
72  // Environment has some other non-boolean value
73  return EnvironmentVariableIsSet;
74  }
75 
76  void
77  setEnvironmentVariableMap (const char environmentVariableName[],
78  std::map<std::string,std::map<std::string, bool> >& valsMap,
79  const bool defaultValue)
80  {
81  using std::map;
82  using std::getenv;
83  using std::string;
84  using std::vector;
85 
86  // Set the default value for this variable
87  valsMap[environmentVariableName] = map<string,bool>{{"DEFAULT", defaultValue}};
88 
89  const char* varVal = getenv (environmentVariableName);
90  if (varVal == NULL) {
91  // Environment variable is not set, use the default value for any named
92  // variants
93  return;
94  }
95 
96  // Variable is not empty.
97  const string varStr(varVal);
98  vector<string> names;
99  split(varStr, [&](const string& x){names.push_back(x);});
100  for (auto const& name: names) {
101  auto state = environmentVariableState(name);
102  if (state == EnvironmentVariableIsSet_ON) {
103  // Environment variable was set as ENVAR_NAME=[1,YES,TRUE,ON]
104  // Global value takes precedence
105  valsMap[environmentVariableName]["DEFAULT"] = true;
106  }
107  else if (state == EnvironmentVariableIsSet_OFF) {
108  // Environment variable was set as ENVAR_NAME=[0,NO,FALSE,OFF]
109  // Global value takes precedence
110  valsMap[environmentVariableName]["DEFAULT"] = false;
111  }
112  else {
113  // Environment variable was set as ENVAR_NAME=...:name:...
114  // So we set the mapping true for this named variant
115  valsMap[environmentVariableName][name] = true;
116  }
117  }
118  return;
119  }
120 
121  bool
122  getEnvironmentVariableAsBool (const char environmentVariableName[],
123  const bool defaultValue)
124  {
125  const char* varVal = std::getenv (environmentVariableName);
126 
127  bool retVal = defaultValue;
128  if (varVal != NULL) {
129  auto state = environmentVariableState(std::string(varVal));
130  if (state == EnvironmentVariableIsSet_ON) retVal = true;
131  else if (state == EnvironmentVariableIsSet_OFF) retVal = false;
132  }
133  return retVal;
134  }
135 
136  bool
137  idempotentlyGetEnvironmentVariableAsBool (bool& value,
138  bool& initialized,
139  const char environmentVariableName[],
140  const bool defaultValue)
141  {
142  if (! initialized) {
143  value = getEnvironmentVariableAsBool (environmentVariableName,
144  defaultValue);
145  initialized = true;
146  }
147  return value;
148  }
149 
150  bool
151  idempotentlyGetNamedEnvironmentVariableAsBool (const char name[],
152  bool& initialized,
153  const char environmentVariableName[],
154  const bool defaultValue)
155  {
156  using BehaviorDetails::namedVariableMap_;
157  if (! initialized) {
158  setEnvironmentVariableMap (environmentVariableName,
159  namedVariableMap_,
160  defaultValue);
161  initialized = true;
162  }
163  auto thisEnvironmentVariableMap = namedVariableMap_[environmentVariableName];
164  auto thisEnvironmentVariable = thisEnvironmentVariableMap.find(name);
165  if (thisEnvironmentVariable != thisEnvironmentVariableMap.end())
166  return thisEnvironmentVariable->second;
167  return thisEnvironmentVariableMap["DEFAULT"];
168  }
169 
170  constexpr bool debugDefault () {
171 #ifdef HAVE_TPETRA_DEBUG
172  return true;
173 #else
174  return false;
175 #endif // HAVE_TPETRA_DEBUG
176  }
177 
178  constexpr bool verboseDefault () {
179  return false;
180  }
181 
182  constexpr bool assumeMpiIsCudaAwareDefault () {
183 #ifdef TPETRA_ASSUME_CUDA_AWARE_MPI
184  return true;
185 #else
186  return false;
187 #endif // TPETRA_ASSUME_CUDA_AWARE_MPI
188  }
189 
190 } // namespace (anonymous)
191 
193 {
194  constexpr char envVarName[] = "TPETRA_DEBUG";
195  constexpr bool defaultValue = debugDefault ();
196 
197  static bool value_ = defaultValue;
198  static bool initialized_ = false;
199  return idempotentlyGetEnvironmentVariableAsBool (value_,
200  initialized_,
201  envVarName,
202  defaultValue);
203 }
204 
206 {
207  if (BehaviorDetails::verboseDisabled_) return false;
208 
209  constexpr char envVarName[] = "TPETRA_VERBOSE";
210  constexpr bool defaultValue = verboseDefault ();
211 
212  static bool value_ = defaultValue;
213  static bool initialized_ = false;
214  return idempotentlyGetEnvironmentVariableAsBool (value_,
215  initialized_,
216  envVarName,
217  defaultValue);
218 }
219 
221 {
222  constexpr char envVarName[] = "TPETRA_ASSUME_CUDA_AWARE_MPI";
223  constexpr bool defaultValue = assumeMpiIsCudaAwareDefault ();
224 
225  static bool value_ = defaultValue;
226  static bool initialized_ = false;
227  return idempotentlyGetEnvironmentVariableAsBool (value_,
228  initialized_,
229  envVarName,
230  defaultValue);
231 }
232 
234 {
235  // only call getenv once, save the value.
236  static int savedval=-1;
237  if(savedval!=-1) return savedval;
238  const char* varVal = std::getenv ("MM_TAFC_OptimizationCoreCount");
239  if (varVal == nullptr) {
240  savedval = 3000;
241  return savedval;
242  }
243  savedval = std::stoi(std::string(varVal));
244  return savedval;
245 }
246 
247 
248 bool Behavior::debug (const char name[])
249 {
250  constexpr char envVarName[] = "TPETRA_DEBUG";
251  constexpr bool defaultValue = false;
252 
253  static bool initialized_ = false;
254  return idempotentlyGetNamedEnvironmentVariableAsBool (name,
255  initialized_,
256  envVarName,
257  defaultValue);
258 }
259 
260 bool Behavior::verbose (const char name[])
261 {
262  if (BehaviorDetails::verboseDisabled_) return false;
263 
264  constexpr char envVarName[] = "TPETRA_VERBOSE";
265  constexpr bool defaultValue = false;
266 
267  static bool initialized_ = false;
268  return idempotentlyGetNamedEnvironmentVariableAsBool (name,
269  initialized_,
270  envVarName,
271  defaultValue);
272 }
273 
275  BehaviorDetails::verboseDisabled_ = false;
276 }
277 
279  BehaviorDetails::verboseDisabled_ = true;
280 }
281 
282 } // namespace Details
283 } // namespace Tpetra
284 
static int TAFC_OptimizationCoreCount()
The core count above which Tpetra::CrsMatrix::transferAndFillComplere will attempt to do advanced nei...
static void disable_verbose_behavior()
Disable verbose mode, programatically.
static bool debug()
Whether Tpetra is in debug mode.
static bool assumeMpiIsCudaAware()
Whether to assume that MPI is CUDA aware.
static bool verbose()
Whether Tpetra is in verbose mode.
static void enable_verbose_behavior()
Enable verbose mode, programatically.
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra&#39;s behavior.