Tpetra parallel linear algebra  Version of the Day
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 
248 {
249  // only call getenv once, save the value.
250  static int savedval=-1;
251  if(savedval!=-1) return static_cast<size_t>(savedval);
252  const char* varVal = std::getenv ("TPETRA_VERBOSE_PRINT_COUNT_THRESHOLD");
253  if (varVal == nullptr) {
254  savedval = 200;
255  return static_cast<size_t>(savedval);
256  }
257  savedval = std::stoi(std::string(varVal));
258  return static_cast<size_t>(savedval);
259 }
260 
261 bool Behavior::debug (const char name[])
262 {
263  constexpr char envVarName[] = "TPETRA_DEBUG";
264  constexpr bool defaultValue = false;
265 
266  static bool initialized_ = false;
267  return idempotentlyGetNamedEnvironmentVariableAsBool (name,
268  initialized_,
269  envVarName,
270  defaultValue);
271 }
272 
273 bool Behavior::verbose (const char name[])
274 {
275  if (BehaviorDetails::verboseDisabled_) return false;
276 
277  constexpr char envVarName[] = "TPETRA_VERBOSE";
278  constexpr bool defaultValue = false;
279 
280  static bool initialized_ = false;
281  return idempotentlyGetNamedEnvironmentVariableAsBool (name,
282  initialized_,
283  envVarName,
284  defaultValue);
285 }
286 
288  BehaviorDetails::verboseDisabled_ = false;
289 }
290 
292  BehaviorDetails::verboseDisabled_ = true;
293 }
294 
295 } // namespace Details
296 } // namespace Tpetra
297 
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
static void enable_verbose_behavior()
Enable verbose mode, programatically.
static bool assumeMpiIsCudaAware()
Whether to assume that MPI is CUDA aware.
static bool debug()
Whether Tpetra is in debug mode.
static int TAFC_OptimizationCoreCount()
The core count above which Tpetra::CrsMatrix::transferAndFillComplete will attempt to do advanced nei...
static bool verbose()
Whether Tpetra is in verbose mode.
static size_t verbosePrintCountThreshold()
Threshold, below which arrays, lists, etc. will be printed in debug mode.
static void disable_verbose_behavior()
Disable verbose mode, programatically.
Implementation details of Tpetra.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void transform(const char kernelLabel[], ExecutionSpace execSpace, GlobalDataStructure &input, GlobalDataStructure &output, UnaryFunctionType f)
For each local entry input_i of input, assign f(input_i) to the corresponding local entry output_i of...