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 // ***********************************************************************
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 
337  if (fname==Z2_UNSET_STRING && os==NUM_OUTPUT_STREAMS)
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
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.
static void convertStringToInt(Teuchos::ParameterList &params)
Convert parameters of type Teuchos::StringToIntegralParameterEntryValidator&lt;int&gt; to integer...
/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.
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:56
#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