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
575{
576 constexpr char envVarName[] = "TPETRA_SPACES_ID_WARN_LIMT";
577 constexpr size_t defaultValue(16);
578
579 static size_t value_ = defaultValue;
580 static bool initialized_ = false;
581 return idempotentlyGetEnvironmentVariableAsSize
582 (value_, initialized_, envVarName, defaultValue);
583}
584
586{
587 constexpr char envVarName[] = "TPETRA_TIME_KOKKOS_DEEP_COPY";
588 constexpr bool defaultValue(false);
589
590 static bool value_ = defaultValue;
591 static bool initialized_ = false;
592 return idempotentlyGetEnvironmentVariableAsBool
593 (value_, initialized_, envVarName, defaultValue);
594
595}
596
597
598} // namespace Details
599} // namespace Tpetra
600
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 timeKokkosDeepCopy()
Add Teuchos timers for all host calls to Kokkos::deep_copy(). This is especially useful for identifyi...
static bool hierarchicalUnpack()
Unpack rows of a matrix using hierarchical unpacking.
static size_t spacesIdWarnLimit()
Warn if more than this many Kokkos spaces are accessed.
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.
Nonmember function that computes a residual Computes R = B - A * X.
Namespace Tpetra contains the class and methods constituting the Tpetra library.