Tpetra parallel linear algebra Version of the Day
Loading...
Searching...
No Matches
Tpetra_Details_Behavior.cpp
1/*
2// @HEADER
3// ***********************************************************************
4//
5// Tpetra: Templated Linear Algebra Services Package
6// Copyright (2008) Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// ************************************************************************
39// @HEADER
40*/
42#include "TpetraCore_config.h"
43#include <algorithm> // std::transform
44#include <cstdlib> // std::getenv
45#include <cctype> // std::toupper
46#include <string>
47#include <map>
48#include <vector>
49#include <functional>
50#include "Teuchos_TestForException.hpp"
51#include "Teuchos_OrdinalTraits.hpp"
52#include <stdexcept>
53
54namespace Tpetra {
55namespace Details {
56
57namespace BehaviorDetails {
58std::map<std::string, std::map<std::string, bool> > namedVariableMap_;
59bool verboseDisabled_ = false;
60bool timingDisabled_ = false;
61}
62
63namespace { // (anonymous)
64
65 enum EnvironmentVariableState
66 {
67 EnvironmentVariableIsSet_ON,
68 EnvironmentVariableIsSet_OFF,
69 EnvironmentVariableIsSet,
70 EnvironmentVariableIsNotSet
71 };
72
73 // See example here:
74 //
75 // http://en.cppreference.com/w/cpp/string/byte/toupper
76 std::string stringToUpper (std::string s)
77 {
78 std::transform (s.begin (), s.end (), s.begin (),
79 [] (unsigned char c) { return std::toupper (c); });
80 return s;
81 }
82
83 void
84 split(const std::string& s,
85 std::function<void(const std::string&)> f,
86 const char sep=',')
87 {
88 typedef std::string::size_type size_type;
89 size_type cur_pos, last_pos=0, length=s.length();
90 while(last_pos < length + 1)
91 {
92 cur_pos = s.find_first_of(sep, last_pos);
93 if(cur_pos == std::string::npos)
94 {
95 cur_pos = length;
96 }
97 if(cur_pos!=last_pos) {
98 auto token = std::string(s.data()+last_pos, (size_type)cur_pos-last_pos);
99 f(token);
100 }
101 last_pos = cur_pos + 1;
102 }
103 return;
104 }
105
106 EnvironmentVariableState
107 environmentVariableState(const std::string& environmentVariableValue)
108 {
109 std::string v = stringToUpper(environmentVariableValue);
110 if (v == "1" || v == "YES" || v == "TRUE" || v == "ON")
111 // Environment variable is "ON"
112 return EnvironmentVariableIsSet_ON;
113 else if (v == "0" || v == "NO" || v == "FALSE" || v == "OFF")
114 // Environment variable is "OFF"
115 return EnvironmentVariableIsSet_OFF;
116 // Environment has some other non-boolean value
117 return EnvironmentVariableIsSet;
118 }
119
120 void
121 setEnvironmentVariableMap (const char environmentVariableName[],
122 std::map<std::string,std::map<std::string, bool> >& valsMap,
123 const bool defaultValue)
124 {
125 using std::map;
126 using std::getenv;
127 using std::string;
128 using std::vector;
129
130 // Set the default value for this variable
131 valsMap[environmentVariableName] = map<string,bool>{{"DEFAULT", defaultValue}};
132
133 const char* varVal = getenv (environmentVariableName);
134 if (varVal == nullptr) {
135 // Environment variable is not set, use the default value for any named
136 // variants
137 return;
138 }
139
140 // Variable is not empty.
141 const string varStr(varVal);
142 vector<string> names;
143 split(varStr, [&](const string& x){names.push_back(x);});
144 for (auto const& name: names) {
145 auto state = environmentVariableState(name);
146 if (state == EnvironmentVariableIsSet_ON) {
147 // Environment variable was set as ENVAR_NAME=[1,YES,TRUE,ON]
148 // Global value takes precedence
149 valsMap[environmentVariableName]["DEFAULT"] = true;
150 }
151 else if (state == EnvironmentVariableIsSet_OFF) {
152 // Environment variable was set as ENVAR_NAME=[0,NO,FALSE,OFF]
153 // Global value takes precedence
154 valsMap[environmentVariableName]["DEFAULT"] = false;
155 }
156 else {
157 // Environment variable was set as ENVAR_NAME=...:name:...
158 // So we set the mapping true for this named variant
159 valsMap[environmentVariableName][name] = true;
160 }
161 }
162 return;
163 }
164
165 bool
166 getEnvironmentVariableAsBool (const char environmentVariableName[],
167 const bool defaultValue)
168 {
169 const char* varVal = std::getenv (environmentVariableName);
170
171 bool retVal = defaultValue;
172 if (varVal != nullptr) {
173 auto state = environmentVariableState(std::string(varVal));
174 if (state == EnvironmentVariableIsSet_ON) retVal = true;
175 else if (state == EnvironmentVariableIsSet_OFF) retVal = false;
176 }
177 return retVal;
178 }
179
180 size_t
181 getEnvironmentVariableAsSize(const char environmentVariableName[],
182 const size_t defaultValue)
183 {
184 const char prefix[] = "Tpetra::Details::Behavior: ";
185
186 const char* varVal = std::getenv(environmentVariableName);
187 if (varVal == nullptr) {
188 return defaultValue;
189 }
190 else {
191 // This could throw invalid_argument or out_of_range.
192 // Go ahead and let it do so.
193 long long val = std::stoll(stringToUpper(varVal));
194 if (val < static_cast<long long>(0)) {
195 // If negative - user has requested threshold be lifted
196 return std::numeric_limits<size_t>::max();
197 }
198// TEUCHOS_TEST_FOR_EXCEPTION
199// (val < static_cast<long long>(0), std::out_of_range,
200// prefix << "Environment variable \""
201// << environmentVariableName << "\" is supposed to be a size, "
202// "but it has a negative integer value " << val << ".");
203 if (sizeof(long long) > sizeof(size_t)) {
204 // It's hard to test this code, but I want to try writing it
205 // at least, in case we ever have to run on 32-bit machines or
206 // machines with sizeof(long long)=16 and sizeof(size_t)=8.
207 constexpr long long maxSizeT =
208 static_cast<long long>(std::numeric_limits<size_t>::max());
209 TEUCHOS_TEST_FOR_EXCEPTION
210 (val > maxSizeT, std::out_of_range, prefix << "Environment "
211 "variable \"" << environmentVariableName << "\" has a "
212 "value " << val << " larger than the largest size_t value "
213 << maxSizeT << ".");
214 }
215 return static_cast<size_t>(val);
216 }
217 }
218
219 bool
220 idempotentlyGetEnvironmentVariableAsBool (bool& value,
221 bool& initialized,
222 const char environmentVariableName[],
223 const bool defaultValue)
224 {
225 if (! initialized) {
226 value = getEnvironmentVariableAsBool (environmentVariableName,
227 defaultValue);
228 initialized = true;
229 }
230 return value;
231 }
232
233 bool
234 idempotentlyGetNamedEnvironmentVariableAsBool (const char name[],
235 bool& initialized,
236 const char environmentVariableName[],
237 const bool defaultValue)
238 {
239 using BehaviorDetails::namedVariableMap_;
240 if (! initialized) {
241 setEnvironmentVariableMap (environmentVariableName,
242 namedVariableMap_,
243 defaultValue);
244 initialized = true;
245 }
246 auto thisEnvironmentVariableMap = namedVariableMap_[environmentVariableName];
247 auto thisEnvironmentVariable = thisEnvironmentVariableMap.find(name);
248 if (thisEnvironmentVariable != thisEnvironmentVariableMap.end())
249 return thisEnvironmentVariable->second;
250 return thisEnvironmentVariableMap["DEFAULT"];
251 }
252
253 size_t
254 idempotentlyGetEnvironmentVariableAsSize
255 (size_t& value,
256 bool& initialized,
257 const char environmentVariableName[],
258 const size_t defaultValue)
259 {
260 if (! initialized) {
261 value = getEnvironmentVariableAsSize(environmentVariableName,
262 defaultValue);
263 initialized = true;
264 }
265 return value;
266 }
267
268 constexpr bool debugDefault () {
269#ifdef HAVE_TPETRA_DEBUG
270 return true;
271#else
272 return false;
273#endif // HAVE_TPETRA_DEBUG
274 }
275
276 constexpr bool verboseDefault () {
277 return false;
278 }
279
280 constexpr bool timingDefault () {
281 return false;
282 }
283
284 constexpr bool assumeMpiIsGPUAwareDefault () {
285#ifdef TPETRA_ASSUME_GPU_AWARE_MPI
286 return true;
287#else
288 return false;
289#endif // TPETRA_ASSUME_GPU_AWARE_MPI
290 }
291
292 constexpr bool cudaLaunchBlockingDefault () {
293 return false;
294 }
295
296 constexpr bool hierarchicalUnpackDefault () {
297 return true;
298 }
299
300} // namespace (anonymous)
301
303{
304 constexpr char envVarName[] = "TPETRA_DEBUG";
305 constexpr bool defaultValue = debugDefault ();
306
307 static bool value_ = defaultValue;
308 static bool initialized_ = false;
309 return idempotentlyGetEnvironmentVariableAsBool (value_,
310 initialized_,
311 envVarName,
312 defaultValue);
313}
314
316{
317 if (BehaviorDetails::verboseDisabled_) return false;
318
319 constexpr char envVarName[] = "TPETRA_VERBOSE";
320 constexpr bool defaultValue = verboseDefault ();
321
322 static bool value_ = defaultValue;
323 static bool initialized_ = false;
324 return idempotentlyGetEnvironmentVariableAsBool (value_,
325 initialized_,
326 envVarName,
327 defaultValue);
328}
329
331{
332 if (BehaviorDetails::timingDisabled_) return false;
333
334 constexpr char envVarName[] = "TPETRA_TIMING";
335 constexpr bool defaultValue = timingDefault ();
336
337 static bool value_ = defaultValue;
338 static bool initialized_ = false;
339 return idempotentlyGetEnvironmentVariableAsBool (value_,
340 initialized_,
341 envVarName,
342 defaultValue);
343}
344
346{
347 constexpr char envVarName[] = "TPETRA_ASSUME_GPU_AWARE_MPI";
348 constexpr bool defaultValue = assumeMpiIsGPUAwareDefault ();
349
350 static bool value_ = defaultValue;
351 static bool initialized_ = false;
352 return idempotentlyGetEnvironmentVariableAsBool (value_,
353 initialized_,
354 envVarName,
355 defaultValue);
356}
357
359{
360 constexpr char envVarName[] = "CUDA_LAUNCH_BLOCKING";
361 constexpr bool defaultValue = cudaLaunchBlockingDefault ();
362
363 static bool value_ = defaultValue;
364 static bool initialized_ = false;
365 return idempotentlyGetEnvironmentVariableAsBool (value_,
366 initialized_,
367 envVarName,
368 defaultValue);
369}
370
372{
373 // only call getenv once, save the value.
374 static int savedval=-1;
375 if(savedval!=-1) return savedval;
376 const char* varVal = std::getenv ("MM_TAFC_OptimizationCoreCount");
377 if (varVal == nullptr) {
378 savedval = 3000;
379 return savedval;
380 }
381 savedval = std::stoi(std::string(varVal));
382 return savedval;
383}
384
386{
387 constexpr char envVarName[] = "TPETRA_VERBOSE_PRINT_COUNT_THRESHOLD";
388 constexpr size_t defaultValue (200);
389
390 static size_t value_ = defaultValue;
391 static bool initialized_ = false;
392 return idempotentlyGetEnvironmentVariableAsSize
393 (value_, initialized_, envVarName, defaultValue);
394}
395
397{
398 constexpr char envVarName[] = "TPETRA_ROW_IMBALANCE_THRESHOLD";
399 constexpr size_t defaultValue (256);
400
401 static size_t value_ = defaultValue;
402 static bool initialized_ = false;
403 return idempotentlyGetEnvironmentVariableAsSize
404 (value_, initialized_, envVarName, defaultValue);
405}
406
408{
409 constexpr char envVarName[] = "TPETRA_MULTIVECTOR_USE_MERGE_PATH";
410 constexpr bool defaultValue = false;
411
412 static bool value_ = defaultValue;
413 static bool initialized_ = false;
414 return idempotentlyGetEnvironmentVariableAsBool
415 (value_, initialized_, envVarName, defaultValue);
416}
417
419{
420 constexpr char envVarName[] = "TPETRA_VECTOR_DEVICE_THRESHOLD";
421 constexpr size_t defaultValue (22000);
422
423 static size_t value_ = defaultValue;
424 static bool initialized_ = false;
425 return idempotentlyGetEnvironmentVariableAsSize
426 (value_, initialized_, envVarName, defaultValue);
427}
428
430{
431 constexpr char envVarName[] = "TPETRA_HIERARCHICAL_UNPACK_BATCH_SIZE";
432
433#ifdef HAVE_TPETRA_INST_CUDA
434 constexpr size_t defaultValue (16);
435#else
436 constexpr size_t defaultValue (256);
437#endif
438
439 static size_t value_ = defaultValue;
440 static bool initialized_ = false;
441 return idempotentlyGetEnvironmentVariableAsSize
442 (value_, initialized_, envVarName, defaultValue);
443}
444
446{
447 constexpr char envVarName[] = "TPETRA_HIERARCHICAL_UNPACK_TEAM_SIZE";
448#ifdef HAVE_TPETRA_INST_CUDA
449 const size_t defaultValue (16);
450#else
451 const size_t defaultValue (Teuchos::OrdinalTraits<size_t>::invalid ());
452#endif
453
454 static size_t value_ = defaultValue;
455 static bool initialized_ = false;
456 return idempotentlyGetEnvironmentVariableAsSize
457 (value_, initialized_, envVarName, defaultValue);
458}
459
461{
462 constexpr char envVarName[] = "TPETRA_USE_TEUCHOS_TIMERS";
463 constexpr bool defaultValue(false);
464
465 static bool value_ = defaultValue;
466 static bool initialized_ = false;
467 return idempotentlyGetEnvironmentVariableAsBool
468 (value_, initialized_, envVarName, defaultValue);
469}
470
472{
473 constexpr char envVarName[] = "TPETRA_USE_KOKKOS_PROFILING";
474 constexpr bool defaultValue(false);
475
476 static bool value_ = defaultValue;
477 static bool initialized_ = false;
478 return idempotentlyGetEnvironmentVariableAsBool
479 (value_, initialized_, envVarName, defaultValue);
480}
481
482
483bool Behavior::debug (const char name[])
484{
485 constexpr char envVarName[] = "TPETRA_DEBUG";
486 constexpr bool defaultValue = false;
487
488 static bool initialized_ = false;
489 return idempotentlyGetNamedEnvironmentVariableAsBool (name,
490 initialized_,
491 envVarName,
492 defaultValue);
493}
494
495bool Behavior::verbose (const char name[])
496{
497 if (BehaviorDetails::verboseDisabled_) return false;
498
499 constexpr char envVarName[] = "TPETRA_VERBOSE";
500 constexpr bool defaultValue = false;
501
502 static bool initialized_ = false;
503 return idempotentlyGetNamedEnvironmentVariableAsBool (name,
504 initialized_,
505 envVarName,
506 defaultValue);
507}
508
510 BehaviorDetails::verboseDisabled_ = false;
511}
512
514 BehaviorDetails::verboseDisabled_ = true;
515}
516
517bool Behavior::timing (const char name[])
518{
519 if (BehaviorDetails::timingDisabled_) return false;
520
521 constexpr char envVarName[] = "TPETRA_TIMING";
522 constexpr bool defaultValue = false;
523
524 static bool initialized_ = false;
525 return idempotentlyGetNamedEnvironmentVariableAsBool (name,
526 initialized_,
527 envVarName,
528 defaultValue);
529}
530
532 BehaviorDetails::timingDisabled_ = false;
533}
534
536 BehaviorDetails::timingDisabled_ = true;
537}
538
540{
541 constexpr char envVarName[] = "TPETRA_HIERARCHICAL_UNPACK";
542 constexpr bool defaultValue = hierarchicalUnpackDefault();
543
544 static bool value_ = defaultValue;
545 static bool initialized_ = false;
546 return idempotentlyGetEnvironmentVariableAsBool (value_,
547 initialized_,
548 envVarName,
549 defaultValue);
550}
551
553{
554 constexpr char envVarName[] = "TPETRA_SKIP_COPY_AND_PERMUTE";
555 constexpr bool defaultValue(false);
556
557 static bool value_ = defaultValue;
558 static bool initialized_ = false;
559 return idempotentlyGetEnvironmentVariableAsBool
560 (value_, initialized_, envVarName, defaultValue);
561}
562
564{
565 constexpr char envVarName[] = "TPETRA_OVERLAP";
566 constexpr bool defaultValue(false);
567
568 static bool value_ = defaultValue;
569 static bool initialized_ = false;
570 return idempotentlyGetEnvironmentVariableAsBool
571 (value_, initialized_, envVarName, defaultValue);
572}
573
574
575} // namespace Details
576} // namespace Tpetra
577
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
static bool timing()
Whether Tpetra is in timing mode.
static void enable_verbose_behavior()
Enable verbose mode, programatically.
static void disable_timing()
Disable timing, programatically.
static bool cudaLaunchBlocking()
Whether the CUDA_LAUNCH_BLOCKING environment variable has been set.
static bool hierarchicalUnpack()
Unpack rows of a matrix using hierarchical unpacking.
static bool assumeMpiIsGPUAware()
Whether to assume that MPI is CUDA aware.
static bool debug()
Whether Tpetra is in debug mode.
static int TAFC_OptimizationCoreCount()
MPI process count above which Tpetra::CrsMatrix::transferAndFillComplete will attempt to do advanced ...
static bool overlapCommunicationAndComputation()
Overlap communication and computation.
static void enable_timing()
Enable timing, programatically.
static bool profilingRegionUseTeuchosTimers()
Use Teuchos::Timer in Tpetra::ProfilingRegion.
static bool profilingRegionUseKokkosProfiling()
Use Kokkos::Profiling in Tpetra::ProfilingRegion.
static bool verbose()
Whether Tpetra is in verbose mode.
static bool useMergePathMultiVector()
Whether to use the cuSPARSE merge path algorithm to perform sparse matrix-multivector products,...
static size_t multivectorKernelLocationThreshold()
the threshold for transitioning from device to host
static size_t verbosePrintCountThreshold()
Number of entries below which arrays, lists, etc. will be printed in debug mode.
static size_t hierarchicalUnpackBatchSize()
Size of batch for hierarchical unpacking.
static void disable_verbose_behavior()
Disable verbose mode, programatically.
static size_t rowImbalanceThreshold()
Threshold for deciding if a local matrix is "imbalanced" in the number of entries per row....
static bool skipCopyAndPermuteIfPossible()
Skip copyAndPermute if possible.
static size_t hierarchicalUnpackTeamSize()
Size of team for hierarchical unpacking.
Implementation details of Tpetra.
Namespace Tpetra contains the class and methods constituting the Tpetra library.