Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_Environment.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Zoltan2: A package of combinatorial algorithms for scientific computing
4 //
5 // Copyright 2012 NTESS and the Zoltan2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
14 #ifndef _ZOLTAN2_ENVIRONMENT_CPP_
15 #define _ZOLTAN2_ENVIRONMENT_CPP_
16 
17 #include <Zoltan2_Environment.hpp>
19 #include <Zoltan2_Util.hpp>
20 
21 #include <Teuchos_StandardParameterEntryValidators.hpp>
22 #include <Teuchos_RCP.hpp>
23 
24 #include <sstream>
25 #include <ostream>
26 
27 namespace Zoltan2 {
28 
30 // Namespace definitions used by this class.
31 
42 void makeDebugManager(int rank, bool iPrint,
43  int level, std::string fname, int ost,
44  Teuchos::RCP<DebugManager> &mgr)
45 {
46  MessageOutputLevel lvl = static_cast<MessageOutputLevel>(level);
47 
48  if (fname != Z2_UNSET_STRING){
49  std::ofstream *dbgFile = new std::ofstream;
50  if (iPrint){
51  std::string newFname;
52  addNumberToFileName(rank, fname, newFname);
53  try{
54  dbgFile->open(newFname.c_str(), std::ios::out|std::ios::trunc);
55  }
56  catch(std::exception &e){
57  throw std::runtime_error(e.what());
58  }
59  }
60  mgr = Teuchos::rcp(new DebugManager(rank, iPrint, *dbgFile, lvl));
61  return;
62  }
63 
64  OSType os = static_cast<OSType>(ost);
65 
66  if (os == COUT_STREAM)
67  mgr = Teuchos::rcp(new DebugManager(rank, iPrint, std::cout, lvl));
68  else if (os == CERR_STREAM)
69  mgr = Teuchos::rcp(new DebugManager(rank, iPrint, std::cerr, lvl));
70  else if (os == NULL_STREAM)
71  mgr = Teuchos::rcp(new DebugManager(rank, false, std::cout, lvl));
72 }
73 
75 // Environment definitions
76 
77 Environment::Environment( Teuchos::ParameterList &problemParams,
78  const Teuchos::RCP<const Teuchos::Comm<int> > &comm):
79  myRank_(comm->getRank()), numProcs_(comm->getSize()), comm_(comm),
80  errorCheckLevel_(BASIC_ASSERTION),
81  unvalidatedParams_(problemParams), params_(problemParams),
82  debugOut_(), timerOut_(), timingOn_(false), memoryOut_(), memoryOn_(false),
83  memoryOutputFile_()
84 {
85  try{
86  commitParameters();
87  }
89 }
90 
91 Environment::Environment(const Teuchos::RCP<const Teuchos::Comm<int> > &comm):
92  myRank_(comm->getRank()), numProcs_(comm->getSize()), comm_(comm),
93  errorCheckLevel_(BASIC_ASSERTION),
94  unvalidatedParams_("emptyList"), params_("emptyList"),
95  debugOut_(), timerOut_(), timingOn_(false), memoryOut_(), memoryOn_(false),
96  memoryOutputFile_()
97 {
98  try{
99  commitParameters();
100  }
102 }
103 
105 {
106  if (!memoryOutputFile_.is_null())
107  memoryOutputFile_->close();
108 }
109 
110 void Environment::resetParameters(Teuchos::ParameterList &problemParams)
111 {
112  params_ = problemParams;
113  commitParameters();
114 }
115 
116 RCP<Teuchos::BoolParameterEntryValidator> Environment::getBoolValidator()
117 {
118  return Teuchos::rcp( new Teuchos::BoolParameterEntryValidator() );
119 }
120 
121 // provides a generic any double validator to avoid clutter
122 RCP<Teuchos::AnyNumberParameterEntryValidator>
124 {
125  Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes allTypes;
126  RCP<Teuchos::AnyNumberParameterEntryValidator> any_number_validator =
127  Teuchos::rcp( new Teuchos::AnyNumberParameterEntryValidator(
128  Teuchos::AnyNumberParameterEntryValidator::PREFER_DOUBLE, allTypes) );
129  return any_number_validator;
130 }
131 
132 // provides a generic any number validator to avoid clutter
133 RCP<Teuchos::AnyNumberParameterEntryValidator>
135 {
136  Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes typesNoDoubles;
137  typesNoDoubles.allowDouble(false);
138  RCP<Teuchos::AnyNumberParameterEntryValidator> int_string_validator =
139  Teuchos::rcp( new Teuchos::AnyNumberParameterEntryValidator(
140  Teuchos::AnyNumberParameterEntryValidator::PREFER_INT, typesNoDoubles) );
141  return int_string_validator;
142 }
143 
144 void Environment::getValidParameters(ParameterList & pl)
145 {
146  // these parameters are generic to all environments - timers, debugging, etc
147 
148  // we set the name here because this always happens
149  pl.setName("zoltan2ValidatingParameters");
150 
151  // error_check_level
152  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
153  error_check_level_Validator = Teuchos::rcp(
154  new Teuchos::StringToIntegralParameterEntryValidator<int>(
155  Teuchos::tuple<std::string>( "no_assertions", "basic_assertions",
156  "complex_assertions", "debug_mode_assertions" ),
157  Teuchos::tuple<std::string>( "no assertions will be performed",
158  "typical checks of argument validity",
159  "additional checks, i.e. is input graph a valid graph)",
160  "check for everything including logic errors (slowest)" ),
161  Teuchos::tuple<int>( 0, 1, 2, 3 ), "error_check_level") );
162  pl.set("error_check_level", "basic_assertions", "the amount of error checking"
163  " performed (If the compile flag Z2_OMIT_ALL_ERROR_CHECKING was set, then "
164  "error checking code is not executed at runtime.)",
165  error_check_level_Validator);
166 
167  // basic_status
168  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
169  debug_level_Validator = Teuchos::rcp(
170  new Teuchos::StringToIntegralParameterEntryValidator<int>(
171  Teuchos::tuple<std::string>( "no_status", "basic_status",
172  "detailed_status", "verbose_detailed_status" ),
173  Teuchos::tuple<std::string>( "library outputs no status information",
174  "library outputs basic status information",
175  "library outputs detailed information",
176  "library outputs very detailed information" ),
177  Teuchos::tuple<int>( 0, 1, 2, 3 ),
178  "basic_status") );
179  pl.set("debug_level", "basic_status", "the amount of status/debugging/warning"
180  " information to print",
181  debug_level_Validator);
182 
183  // timer_type
184  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
185  timer_type_Validator = Teuchos::rcp( new
186  Teuchos::StringToIntegralParameterEntryValidator<int>(
187  Teuchos::tuple<std::string>( "no_timers", "macro_timers",
188  "micro_timers", "both_timers", "test_timers" ),
189  Teuchos::tuple<std::string>( "No timing data will be collected ",
190  "Time an algorithm (or other entity) as a whole.",
191  "Time the substeps of an entity.", "Run both MACRO and MICRO timers.",
192  "Run timers added to code for testing, removed later" ),
193  Teuchos::tuple<int>( 0, 1, 2, 3, 4 ),
194  "no_timers") );
195  pl.set("timer_type", "no_timers", " the type of timing information to "
196  "collect (If the compile flag Z2_OMIT_ALL_PROFILING was set, then the "
197  "timing code is not executed at runtime.)",
198  timer_type_Validator);
199 
200  // debug_output_stream
201  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
202  output_stream_Validator = Teuchos::rcp(
203  new Teuchos::StringToIntegralParameterEntryValidator<int>(
204  Teuchos::tuple<std::string>( "std::cout", "cout", "stdout",
205  "std::cerr", "cerr", "stderr", "/dev/null", "null" ),
206  // original did not have this documented - left blank
207  Teuchos::tuple<std::string>( "", "", "", "", "", "", "", "" ),
208  Teuchos::tuple<int>( 0, 0, 0, 1, 1, 1, 2, 2 ),
209  "cout") );
210 
211  pl.set("debug_output_stream", "cout",
212  "output stream for debug/status/warning messages",
213  output_stream_Validator);
214 
215  pl.set("timer_output_stream", "cout",
216  "output stream for timing report",
217  output_stream_Validator);
218 
219  pl.set("memory_output_stream", "cout",
220  "output stream for memory usage messages",
221  output_stream_Validator);
222 
223  // validator for file does not have to exist
224  RCP<Teuchos::FileNameValidator> file_not_required_validator =
225  Teuchos::rcp( new Teuchos::FileNameValidator(false) );
226 
227  // debug_output_file
228  pl.set("memory_output_file", "/dev/null",
229  "name of file to which memory profiling information should "
230  "be written (process rank will be included in file name)",
231  file_not_required_validator);
232 
233  // timer_output_file
234  pl.set("timer_output_file", "/dev/null", "name of file to which "
235  "timing information should be written (process rank will be "
236  "included in file name)", file_not_required_validator);
237 
238  // debug_output_file
239  pl.set("debug_output_file", "/dev/null", "name of file to which debug/status"
240  " messages should be written (process rank will be included in file name)",
241  file_not_required_validator);
242 
243  const bool bUnsortedFalse = false; // defined this to clarify the meaning
244  RCP<Zoltan2::IntegerRangeListValidator<int>> procs_Validator =
245  Teuchos::rcp( new Zoltan2::IntegerRangeListValidator<int>(bUnsortedFalse) );
246 
247  // debug_procs
248  pl.set("debug_procs", "0", "list of ranks that output debugging/status "
249  "messages", procs_Validator);
250 
251  // memory_procs
252  pl.set("memory_procs", "0", "list of ranks that do memory profiling "
253  "information", procs_Validator);
254 }
255 
256 void Environment::commitParameters()
257 {
258  using Teuchos::Array;
259  using Teuchos::ParameterList;
260 
261  bool emptyList = (params_.begin() == params_.end());
262 
263  if (!emptyList){
264 
265  ParameterList validParams;
266 
267  try{
268  createValidatorList(params_, validParams);
269  }
271 
272  // Note that since validParams only contains parameters that
273  // appear in params_, there are no defaults being set. We
274  // call ParameterList::validateParametersAndSetDefaults() instead of
275  // ParameterList::validateParameters() because we want the
276  // the validators' validateAndModify() to be called instead
277  // of validate(). validateAndModify() "fixes" some of the
278  // parameters for us.
279  // Note: depth==0 --> do not validate sublists,
280  // since they are for TPL parameters
281 
282  params_.validateParametersAndSetDefaults(validParams, 0);
283 
284  }
285 
287 
288  // Set up for debugging/status output.
289  // By default: if no output stream is specified, then node zero
290  // outputs BASIC_STATUS to std::cout.
291 
292 #ifndef Z2_OMIT_ALL_STATUS_MESSAGES
293  int &level = params_.get<int>("debug_level", NUM_STATUS_OUTPUT_LEVELS);
294  std::string &fname = params_.get<std::string>("debug_output_file", Z2_UNSET_STRING);
295  int &os = params_.get<int>("debug_output_stream", NUM_OUTPUT_STREAMS);
296 
297  if (fname==Z2_UNSET_STRING && os==NUM_OUTPUT_STREAMS)
298  os = COUT_STREAM; // default output target
299  if (level == NUM_STATUS_OUTPUT_LEVELS)
300  level = BASIC_STATUS; // default level of verbosity
301 
302  bool iPrint = (myRank_ == 0); // default reporter
303 
304  const Array<int> *reporters =
305  params_.getPtr<Array<int> >("debug_procs");
306  if (reporters)
307  iPrint = IsInRangeList(myRank_, *reporters);
308 
309  try{
310  makeDebugManager(myRank_, iPrint, level, fname, os, debugOut_);
311  }
312  catch (std::exception &e){
313  std::ostringstream oss;
314  oss << myRank_ << ": unable to create debug output manager";
315  oss << " (" << e.what() << ")";
316  throw std::runtime_error(oss.str());
317  }
318 #endif
319 
320  // Set up for memory usage output.
321 
322 #ifndef Z2_OMIT_ALL_PROFILING
323  std::string &f2 =
324  params_.get<std::string>("memory_output_file", Z2_UNSET_STRING);
325  int &os2 =
326  params_.get<int>("memory_output_stream", NUM_OUTPUT_STREAMS);
327 
328  const Array<int> *reporters2 =
329  params_.getPtr<Array<int> >("memory_procs");
330 
331  bool doMemory = true;
332 
333  if (f2 != Z2_UNSET_STRING || os2 != NUM_OUTPUT_STREAMS || reporters2 != NULL){
334  // user indicated they want memory usage information
335  long numKbytes = 0;
336  if (myRank_ == 0)
337  numKbytes = getProcessKilobytes();
338 
339  Teuchos::broadcast<int, long>(*comm_, 0, 1, &numKbytes);
340 
341  if (numKbytes == 0){
342  // This is not a Linux system with proc/pid/statm.
343  f2 = Z2_UNSET_STRING;
344  os2 = NUM_OUTPUT_STREAMS;
345  reporters2 = NULL;
346  this->debug(BASIC_STATUS,
347  std::string("Warning: memory profiling requested but not available."));
348  doMemory = false; // can't do it
349  }
350  }
351  else{
352  doMemory = false; // not requested
353  }
354 
355  if (doMemory){
356  iPrint = (myRank_ == 0); // default
357  if (reporters2)
358  iPrint = IsInRangeList(myRank_, *reporters2);
359 
360  try{
361  makeMetricOutputManager<long>(myRank_, iPrint, f2, os2, memoryOut_,
362  std::string("KB"), 10, memoryOutputFile_);
363  }
364  catch (std::exception &e){
365  std::ostringstream oss;
366  oss << myRank_ << ": unable to create memory profiling output manager";
367  oss << " (" << e.what() << ")";
368  throw std::runtime_error(oss.str());
369  }
370 
371  memoryOn_ = true;
372  }
373 #endif
374 
375 #ifdef Z2_OMIT_ALL_ERROR_CHECKING
377 #else
378  errorCheckLevel_ = static_cast<AssertionLevel>(
379  params_.get<int>("error_check_level", BASIC_ASSERTION));
380 #endif
381 }
382 
383 } //namespace Zoltan2
384 
385 #endif
fast typical checks for valid arguments
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
MessageOutputLevel
The amount of debugging or status output to print.
static RCP< Teuchos::BoolParameterEntryValidator > getBoolValidator()
Exists to make setting up validators less cluttered.
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.
Environment(Teuchos::ParameterList &problemParams, const Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Constructor.
void createValidatorList(const Teuchos::ParameterList &plIn, Teuchos::ParameterList &plOut)
Create a list by adding validators to the users parameter list.
/dev/null: do actions but don&#39;t output results
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyDoubleValidator()
Exists to make setting up validators less cluttered.
long getProcessKilobytes()
AssertionLevel
Level of error checking or assertions desired.
A ParameterList validator for integer range lists.
list fname
Begin.
Definition: validXML.py:19
void debug(MessageOutputLevel level, const char *msg) const
Send a message to the debug output manager.
no assertion checks will be done
int myRank_
mpi rank (relative to comm_)
OSType
Output stream types.
Comm_t comm_
communicator for environment
static void getValidParameters(ParameterList &pl)
Collect the paramaters specific to Environment.
void addNumberToFileName(int number, std::string fname, std::string &newf)
Helper method to add number to a file name.
Definition: Zoltan2_IO.cpp:20
#define Z2_UNSET_STRING
A value to indicate a string parameter that was not set by the user.
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.
void resetParameters(Teuchos::ParameterList &problemParams)
resetParameters and validate them - preserve the comm
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyIntValidator()
Exists to make setting up validators less cluttered.
the status at each high level step
Define IntegerRangeList validator.
DebugManager contains the methods that perform output of debug and status messages.
Defines the Environment class.
A gathering of useful namespace methods.
AssertionLevel errorCheckLevel_
level of error checking to do