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 
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 
static int TAFC_OptimizationCoreCount()
The core count above which Tpetra::CrsMatrix::transferAndFillComplete 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.
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...
static void enable_verbose_behavior()
Enable verbose mode, programatically.
static size_t verbosePrintCountThreshold()
Threshold, below which arrays, lists, etc. will be printed in debug mode.
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra&#39;s behavior.