Zoltan2
Zoltan2_Environment.cpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Zoltan2: A package of combinatorial algorithms for scientific computing
6 // Copyright 2012 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 // Questions? Contact Karen Devine (kddevin@sandia.gov)
39 // Erik Boman (egboman@sandia.gov)
40 // Siva Rajamanickam (srajama@sandia.gov)
41 //
42 // ***********************************************************************
43 //
44 // @HEADER
49 #ifndef _ZOLTAN2_ENVIRONMENT_CPP_
50 #define _ZOLTAN2_ENVIRONMENT_CPP_
51 
52 #include <Zoltan2_Environment.hpp>
54 #include <Zoltan2_Util.hpp>
55 
56 #include <Teuchos_StandardParameterEntryValidators.hpp>
57 #include <Teuchos_RCP.hpp>
58 
59 #include <sstream>
60 #include <ostream>
61 
62 namespace Zoltan2 {
63 
65 // Namespace definitions used by this class.
66 
77 void makeDebugManager(int rank, bool iPrint,
78  int level, std::string fname, int ost,
79  Teuchos::RCP<DebugManager> &mgr)
80 {
81  MessageOutputLevel lvl = static_cast<MessageOutputLevel>(level);
82 
83  if (fname != Z2_UNSET_STRING){
84  std::ofstream *dbgFile = new std::ofstream;
85  if (iPrint){
86  std::string newFname;
87  addNumberToFileName(rank, fname, newFname);
88  try{
89  dbgFile->open(newFname.c_str(), std::ios::out|std::ios::trunc);
90  }
91  catch(std::exception &e){
92  throw std::runtime_error(e.what());
93  }
94  }
95  mgr = Teuchos::rcp(new DebugManager(rank, iPrint, *dbgFile, lvl));
96  return;
97  }
98 
99  OSType os = static_cast<OSType>(ost);
100 
101  if (os == COUT_STREAM)
102  mgr = Teuchos::rcp(new DebugManager(rank, iPrint, std::cout, lvl));
103  else if (os == CERR_STREAM)
104  mgr = Teuchos::rcp(new DebugManager(rank, iPrint, std::cerr, lvl));
105  else if (os == NULL_STREAM)
106  mgr = Teuchos::rcp(new DebugManager(rank, false, std::cout, lvl));
107 }
108 
110 // Environment definitions
111 
112 Environment::Environment( Teuchos::ParameterList &problemParams,
113  const Teuchos::RCP<const Teuchos::Comm<int> > &comm):
114  myRank_(comm->getRank()), numProcs_(comm->getSize()), comm_(comm),
115  errorCheckLevel_(BASIC_ASSERTION),
116  unvalidatedParams_(problemParams), params_(problemParams),
117  debugOut_(), timerOut_(), timingOn_(false), memoryOut_(), memoryOn_(false),
118  memoryOutputFile_()
119 {
120  try{
121  commitParameters();
122  }
124 }
125 
126 Environment::Environment(const Teuchos::RCP<const Teuchos::Comm<int> > &comm):
127  myRank_(comm->getRank()), numProcs_(comm->getSize()), comm_(comm),
128  errorCheckLevel_(BASIC_ASSERTION),
129  unvalidatedParams_("emptyList"), params_("emptyList"),
130  debugOut_(), timerOut_(), timingOn_(false), memoryOut_(), memoryOn_(false),
131  memoryOutputFile_()
132 {
133  try{
134  commitParameters();
135  }
137 }
138 
140 {
141  if (!memoryOutputFile_.is_null())
142  memoryOutputFile_->close();
143 }
144 
145 void Environment::resetParameters(Teuchos::ParameterList &problemParams)
146 {
147  params_ = problemParams;
148  commitParameters();
149 }
150 
151 RCP<Teuchos::BoolParameterEntryValidator> Environment::getBoolValidator()
152 {
153  return Teuchos::rcp( new Teuchos::BoolParameterEntryValidator() );
154 }
155 
156 // provides a generic any double validator to avoid clutter
157 RCP<Teuchos::AnyNumberParameterEntryValidator>
159 {
160  Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes allTypes;
161  RCP<Teuchos::AnyNumberParameterEntryValidator> any_number_validator =
162  Teuchos::rcp( new Teuchos::AnyNumberParameterEntryValidator(
163  Teuchos::AnyNumberParameterEntryValidator::PREFER_DOUBLE, allTypes) );
164  return any_number_validator;
165 }
166 
167 // provides a generic any number validator to avoid clutter
168 RCP<Teuchos::AnyNumberParameterEntryValidator>
170 {
171  Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes typesNoDoubles;
172  typesNoDoubles.allowDouble(false);
173  RCP<Teuchos::AnyNumberParameterEntryValidator> int_string_validator =
174  Teuchos::rcp( new Teuchos::AnyNumberParameterEntryValidator(
175  Teuchos::AnyNumberParameterEntryValidator::PREFER_INT, typesNoDoubles) );
176  return int_string_validator;
177 }
178 
179 void Environment::getValidParameters(ParameterList & pl)
180 {
181  // these parameters are generic to all environments - timers, debugging, etc
182 
183  // we set the name here because this always happens
184  pl.setName("zoltan2ValidatingParameters");
185 
186  // error_check_level
187  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
188  error_check_level_Validator = Teuchos::rcp(
189  new Teuchos::StringToIntegralParameterEntryValidator<int>(
190  Teuchos::tuple<std::string>( "no_assertions", "basic_assertions",
191  "complex_assertions", "debug_mode_assertions" ),
192  Teuchos::tuple<std::string>( "no assertions will be performed",
193  "typical checks of argument validity",
194  "additional checks, i.e. is input graph a valid graph)",
195  "check for everything including logic errors (slowest)" ),
196  Teuchos::tuple<int>( 0, 1, 2, 3 ), "error_check_level") );
197  pl.set("error_check_level", "basic_assertions", "the amount of error checking"
198  " performed (If the compile flag Z2_OMIT_ALL_ERROR_CHECKING was set, then "
199  "error checking code is not executed at runtime.)",
200  error_check_level_Validator);
201 
202  // basic_status
203  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
204  debug_level_Validator = Teuchos::rcp(
205  new Teuchos::StringToIntegralParameterEntryValidator<int>(
206  Teuchos::tuple<std::string>( "no_status", "basic_status",
207  "detailed_status", "verbose_detailed_status" ),
208  Teuchos::tuple<std::string>( "library outputs no status information",
209  "library outputs basic status information",
210  "library outputs detailed information",
211  "library outputs very detailed information" ),
212  Teuchos::tuple<int>( 0, 1, 2, 3 ),
213  "basic_status") );
214  pl.set("debug_level", "basic_status", "the amount of status/debugging/warning"
215  " information to print",
216  debug_level_Validator);
217 
218  // timer_type
219  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
220  timer_type_Validator = Teuchos::rcp( new
221  Teuchos::StringToIntegralParameterEntryValidator<int>(
222  Teuchos::tuple<std::string>( "no_timers", "macro_timers",
223  "micro_timers", "both_timers", "test_timers" ),
224  Teuchos::tuple<std::string>( "No timing data will be collected ",
225  "Time an algorithm (or other entity) as a whole.",
226  "Time the substeps of an entity.", "Run both MACRO and MICRO timers.",
227  "Run timers added to code for testing, removed later" ),
228  Teuchos::tuple<int>( 0, 1, 2, 3, 4 ),
229  "no_timers") );
230  pl.set("timer_type", "no_timers", " the type of timing information to "
231  "collect (If the compile flag Z2_OMIT_ALL_PROFILING was set, then the "
232  "timing code is not executed at runtime.)",
233  timer_type_Validator);
234 
235  // debug_output_stream
236  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
237  output_stream_Validator = Teuchos::rcp(
238  new Teuchos::StringToIntegralParameterEntryValidator<int>(
239  Teuchos::tuple<std::string>( "std::cout", "cout", "stdout",
240  "std::cerr", "cerr", "stderr", "/dev/null", "null" ),
241  // original did not have this documented - left blank
242  Teuchos::tuple<std::string>( "", "", "", "", "", "", "", "" ),
243  Teuchos::tuple<int>( 0, 0, 0, 1, 1, 1, 2, 2 ),
244  "cout") );
245 
246  pl.set("debug_output_stream", "cout",
247  "output stream for debug/status/warning messages",
248  output_stream_Validator);
249 
250  pl.set("timer_output_stream", "cout",
251  "output stream for timing report",
252  output_stream_Validator);
253 
254  pl.set("memory_output_stream", "cout",
255  "output stream for memory usage messages",
256  output_stream_Validator);
257 
258  // validator for file does not have to exist
259  RCP<Teuchos::FileNameValidator> file_not_required_validator =
260  Teuchos::rcp( new Teuchos::FileNameValidator(false) );
261 
262  // debug_output_file
263  pl.set("memory_output_file", "/dev/null",
264  "name of file to which memory profiling information should "
265  "be written (process rank will be included in file name)",
266  file_not_required_validator);
267 
268  // timer_output_file
269  pl.set("timer_output_file", "/dev/null", "name of file to which "
270  "timing information should be written (process rank will be "
271  "included in file name)", file_not_required_validator);
272 
273  // debug_output_file
274  pl.set("debug_output_file", "/dev/null", "name of file to which debug/status"
275  " messages should be written (process rank will be included in file name)",
276  file_not_required_validator);
277 
278  const bool bUnsortedFalse = false; // defined this to clarify the meaning
279  RCP<Zoltan2::IntegerRangeListValidator<int>> procs_Validator =
280  Teuchos::rcp( new Zoltan2::IntegerRangeListValidator<int>(bUnsortedFalse) );
281 
282  // debug_procs
283  pl.set("debug_procs", "0", "list of ranks that output debugging/status "
284  "messages", procs_Validator);
285 
286  // memory_procs
287  pl.set("memory_procs", "0", "list of ranks that do memory profiling "
288  "information", procs_Validator);
289 }
290 
291 void Environment::commitParameters()
292 {
293  using Teuchos::Array;
294  using Teuchos::ParameterList;
295 
296  bool emptyList = (params_.begin() == params_.end());
297 
298  if (!emptyList){
299 
300  ParameterList validParams;
301 
302  try{
303  createValidatorList(params_, validParams);
304  }
306 
307  // Note that since validParams only contains parameters that
308  // appear in params_, there are no defaults being set. We
309  // call ParameterList::validateParametersAndSetDefaults() instead of
310  // ParameterList::validateParameters() because we want the
311  // the validators' validateAndModify() to be called instead
312  // of validate(). validateAndModify() "fixes" some of the
313  // parameters for us.
314  // Note: depth==0 --> do not validate sublists,
315  // since they are for TPL parameters
316 
317  params_.validateParametersAndSetDefaults(validParams, 0);
318 
319  // For all of the string to integer parameters, convert
320  // them to the integer. I would have
321  // expected validateAndModify() to do this.
322 
323  convertStringToInt(params_);
324  }
325 
327 
328  // Set up for debugging/status output.
329  // By default: if no output stream is specified, then node zero
330  // outputs BASIC_STATUS to std::cout.
331 
332 #ifndef Z2_OMIT_ALL_STATUS_MESSAGES
333  int &level = params_.get<int>("debug_level", NUM_STATUS_OUTPUT_LEVELS);
334  std::string &fname = params_.get<std::string>("debug_output_file", Z2_UNSET_STRING);
335  int &os = params_.get<int>("debug_output_stream", NUM_OUTPUT_STREAMS);
336 
338  os = COUT_STREAM; // default output target
339  if (level == NUM_STATUS_OUTPUT_LEVELS)
340  level = BASIC_STATUS; // default level of verbosity
341 
342  bool iPrint = (myRank_ == 0); // default reporter
343 
344  const Array<int> *reporters =
345  params_.getPtr<Array<int> >("debug_procs");
346  if (reporters)
347  iPrint = IsInRangeList(myRank_, *reporters);
348 
349  try{
350  makeDebugManager(myRank_, iPrint, level, fname, os, debugOut_);
351  }
352  catch (std::exception &e){
353  std::ostringstream oss;
354  oss << myRank_ << ": unable to create debug output manager";
355  oss << " (" << e.what() << ")";
356  throw std::runtime_error(oss.str());
357  }
358 #endif
359 
360  // Set up for memory usage output.
361 
362 #ifndef Z2_OMIT_ALL_PROFILING
363  std::string &f2 =
364  params_.get<std::string>("memory_output_file", Z2_UNSET_STRING);
365  int &os2 =
366  params_.get<int>("memory_output_stream", NUM_OUTPUT_STREAMS);
367 
368  const Array<int> *reporters2 =
369  params_.getPtr<Array<int> >("memory_procs");
370 
371  bool doMemory = true;
372 
373  if (f2 != Z2_UNSET_STRING || os2 != NUM_OUTPUT_STREAMS || reporters2 != NULL){
374  // user indicated they want memory usage information
375  long numKbytes = 0;
376  if (myRank_ == 0)
377  numKbytes = getProcessKilobytes();
378 
379  Teuchos::broadcast<int, long>(*comm_, 0, 1, &numKbytes);
380 
381  if (numKbytes == 0){
382  // This is not a Linux system with proc/pid/statm.
383  f2 = Z2_UNSET_STRING;
384  os2 = NUM_OUTPUT_STREAMS;
385  reporters2 = NULL;
386  this->debug(BASIC_STATUS,
387  std::string("Warning: memory profiling requested but not available."));
388  doMemory = false; // can't do it
389  }
390  }
391  else{
392  doMemory = false; // not requested
393  }
394 
395  if (doMemory){
396  iPrint = (myRank_ == 0); // default
397  if (reporters2)
398  iPrint = IsInRangeList(myRank_, *reporters2);
399 
400  try{
401  makeMetricOutputManager<long>(myRank_, iPrint, f2, os2, memoryOut_,
402  std::string("KB"), 10, memoryOutputFile_);
403  }
404  catch (std::exception &e){
405  std::ostringstream oss;
406  oss << myRank_ << ": unable to create memory profiling output manager";
407  oss << " (" << e.what() << ")";
408  throw std::runtime_error(oss.str());
409  }
410 
411  memoryOn_ = true;
412  }
413 #endif
414 
415 #ifdef Z2_OMIT_ALL_ERROR_CHECKING
417 #else
418  errorCheckLevel_ = static_cast<AssertionLevel>(
419  params_.get<int>("error_check_level", BASIC_ASSERTION));
420 #endif
421 }
422 
423 void Environment::convertStringToInt(Teuchos::ParameterList &params)
424 {
425  using Teuchos::ParameterList;
426  using Teuchos::ParameterEntry;
427  using Teuchos::RCP;
428  using Teuchos::rcp_dynamic_cast;
429  ParameterList::ConstIterator next = params.begin();
430 
431  // Data type of these parameters will now change from string to int
432 
433  std::string validatorNameInt("StringIntegralValidator(int)");
434  std::string validatorNameBool("StringIntegralValidator(bool)");
435  typedef Teuchos::StringToIntegralParameterEntryValidator<int> s2int_t;
436 
437  while (next != params.end()){
438 
439  const std::string &name = next->first;
440  ParameterEntry &entry = params.getEntry(name);
441 
442  if (entry.isList()){
443  ParameterList *dummy = NULL;
444  ParameterList &pl = entry.getValue<ParameterList>(dummy);
445  convertStringToInt(pl);
446  }
447  else{
448  if ((entry.validator()).get()){
449  if (entry.validator()->getXMLTypeName() == validatorNameInt){
450  std::string dummy("");
451  std::string &entryValue = entry.getValue<std::string>(&dummy);
452  RCP<const s2int_t> s2int =
453  Teuchos::rcp_dynamic_cast<const s2int_t>(entry.validator(), true);
454  int val = s2int->getIntegralValue(entryValue);
455  entry.setValue<int>(val);
456  }
457  }
458  }
459  ++next;
460  }
461 }
462 
463 } //namespace Zoltan2
464 
465 #endif
Defines the Environment class.
#define Z2_UNSET_STRING
A value to indicate a string parameter that was not set by the user.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
Define IntegerRangeList validator.
A gathering of useful namespace methods.
DebugManager contains the methods that perform output of debug and status messages.
int myRank_
mpi rank (relative to comm_)
static void convertStringToInt(Teuchos::ParameterList &params)
Convert parameters of type Teuchos::StringToIntegralParameterEntryValidator<int> to integer.
static RCP< Teuchos::BoolParameterEntryValidator > getBoolValidator()
Exists to make setting up validators less cluttered.
Environment(Teuchos::ParameterList &problemParams, const Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Constructor.
void debug(MessageOutputLevel level, const char *msg) const
Send a message to the debug output manager.
Comm_t comm_
communicator for environment
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyDoubleValidator()
Exists to make setting up validators less cluttered.
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyIntValidator()
Exists to make setting up validators less cluttered.
static void getValidParameters(ParameterList &pl)
Collect the paramaters specific to Environment.
void resetParameters(Teuchos::ParameterList &problemParams)
resetParameters and validate them - preserve the comm
AssertionLevel errorCheckLevel_
level of error checking to do
A ParameterList validator for integer range lists.
Created by mbenlioglu on Aug 31, 2020.
void addNumberToFileName(int number, std::string fname, std::string &newf)
Helper method to add number to a file name.
Definition: Zoltan2_IO.cpp:56
void makeDebugManager(int rank, bool iPrint, int level, std::string fname, int ost, Teuchos::RCP< DebugManager > &mgr)
Create an output manager for debugging or status information.
bool IsInRangeList(const Integral val, const Teuchos::Array< Integral > &valList, bool sorted=true)
A helper function that determines if a value is in the list.
MessageOutputLevel
The amount of debugging or status output to print.
@ BASIC_STATUS
the status at each high level step
OSType
Output stream types.
@ CERR_STREAM
std::cerr
@ NULL_STREAM
/dev/null: do actions but don't output results
@ COUT_STREAM
std::cout
AssertionLevel
Level of error checking or assertions desired.
@ BASIC_ASSERTION
fast typical checks for valid arguments
@ NO_ASSERTIONS
no assertion checks will be done
long getProcessKilobytes()
void createValidatorList(const Teuchos::ParameterList &plIn, Teuchos::ParameterList &plOut)
Create a list by adding validators to the users parameter list.
fname
Begin.
Definition: validXML.py:19