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 
127  myRank_(0), numProcs_(1), comm_(), errorCheckLevel_(BASIC_ASSERTION),
128  unvalidatedParams_("emptyList"), params_("emptyList"),
129  debugOut_(), timerOut_(), timingOn_(false), memoryOut_(), memoryOn_(false),
130  memoryOutputFile_()
131 {
132  comm_ = Teuchos::DefaultComm<int>::getComm();
133  myRank_ = comm_->getRank();
134  numProcs_ = comm_->getSize();
135 
136  try{
137  commitParameters();
138  }
140 }
141 
143 {
144  if (!memoryOutputFile_.is_null())
145  memoryOutputFile_->close();
146 }
147 
148 RCP<Teuchos::BoolParameterEntryValidator> Environment::getBoolValidator()
149 {
150  return Teuchos::rcp( new Teuchos::BoolParameterEntryValidator() );
151 }
152 
153 // provides a generic any double validator to avoid clutter
154 RCP<Teuchos::AnyNumberParameterEntryValidator>
156 {
157  Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes allTypes;
158  RCP<Teuchos::AnyNumberParameterEntryValidator> any_number_validator =
159  Teuchos::rcp( new Teuchos::AnyNumberParameterEntryValidator(
160  Teuchos::AnyNumberParameterEntryValidator::PREFER_DOUBLE, allTypes) );
161  return any_number_validator;
162 }
163 
164 // provides a generic any number validator to avoid clutter
165 RCP<Teuchos::AnyNumberParameterEntryValidator>
167 {
168  Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes typesNoDoubles;
169  typesNoDoubles.allowDouble(false);
170  RCP<Teuchos::AnyNumberParameterEntryValidator> int_string_validator =
171  Teuchos::rcp( new Teuchos::AnyNumberParameterEntryValidator(
172  Teuchos::AnyNumberParameterEntryValidator::PREFER_INT, typesNoDoubles) );
173  return int_string_validator;
174 }
175 
176 void Environment::getValidParameters(ParameterList & pl)
177 {
178  // these parameters are generic to all environments - timers, debugging, etc
179 
180  // we set the name here because this always happens
181  pl.setName("zoltan2ValidatingParameters");
182 
183  // error_check_level
184  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
185  error_check_level_Validator = Teuchos::rcp(
186  new Teuchos::StringToIntegralParameterEntryValidator<int>(
187  Teuchos::tuple<std::string>( "no_assertions", "basic_assertions",
188  "complex_assertions", "debug_mode_assertions" ),
189  Teuchos::tuple<std::string>( "no assertions will be performed",
190  "typical checks of argument validity",
191  "additional checks, i.e. is input graph a valid graph)",
192  "check for everything including logic errors (slowest)" ),
193  Teuchos::tuple<int>( 0, 1, 2, 3 ), "error_check_level") );
194  pl.set("error_check_level", "basic_assertions", "the amount of error checking"
195  " performed (If the compile flag Z2_OMIT_ALL_ERROR_CHECKING was set, then "
196  "error checking code is not executed at runtime.)",
197  error_check_level_Validator);
198 
199  // basic_status
200  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
201  debug_level_Validator = Teuchos::rcp(
202  new Teuchos::StringToIntegralParameterEntryValidator<int>(
203  Teuchos::tuple<std::string>( "no_status", "basic_status",
204  "detailed_status", "verbose_detailed_status" ),
205  Teuchos::tuple<std::string>( "library outputs no status information",
206  "library outputs basic status information",
207  "library outputs detailed information",
208  "library outputs very detailed information" ),
209  Teuchos::tuple<int>( 0, 1, 2, 3 ),
210  "basic_status") );
211  pl.set("debug_level", "basic_status", "the amount of status/debugging/warning"
212  " information to print",
213  debug_level_Validator);
214 
215  // timer_type
216  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
217  timer_type_Validator = Teuchos::rcp( new
218  Teuchos::StringToIntegralParameterEntryValidator<int>(
219  Teuchos::tuple<std::string>( "no_timers", "macro_timers",
220  "micro_timers", "both_timers", "test_timers" ),
221  Teuchos::tuple<std::string>( "No timing data will be collected ",
222  "Time an algorithm (or other entity) as a whole.",
223  "Time the substeps of an entity.", "Run both MACRO and MICRO timers.",
224  "Run timers added to code for testing, removed later" ),
225  Teuchos::tuple<int>( 0, 1, 2, 3, 4 ),
226  "no_timers") );
227  pl.set("timer_type", "no_timers", " the type of timing information to "
228  "collect (If the compile flag Z2_OMIT_ALL_PROFILING was set, then the "
229  "timing code is not executed at runtime.)",
230  timer_type_Validator);
231 
232  // debug_output_stream
233  RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
234  output_stream_Validator = Teuchos::rcp(
235  new Teuchos::StringToIntegralParameterEntryValidator<int>(
236  Teuchos::tuple<std::string>( "std::cout", "cout", "stdout",
237  "std::cerr", "cerr", "stderr", "/dev/null", "null" ),
238  // original did not have this documented - left blank
239  Teuchos::tuple<std::string>( "", "", "", "", "", "", "", "" ),
240  Teuchos::tuple<int>( 0, 0, 0, 1, 1, 1, 2, 2 ),
241  "cout") );
242 
243  pl.set("debug_output_stream", "cout",
244  "output stream for debug/status/warning messages",
245  output_stream_Validator);
246 
247  pl.set("timer_output_stream", "cout",
248  "output stream for timing report",
249  output_stream_Validator);
250 
251  pl.set("memory_output_stream", "cout",
252  "output stream for memory usage messages",
253  output_stream_Validator);
254 
255  // validator for file does not have to exist
256  RCP<Teuchos::FileNameValidator> file_not_required_validator =
257  Teuchos::rcp( new Teuchos::FileNameValidator(false) );
258 
259  // debug_output_file
260  pl.set("memory_output_file", "/dev/null",
261  "name of file to which memory profiling information should "
262  "be written (process rank will be included in file name)",
263  file_not_required_validator);
264 
265  // timer_output_file
266  pl.set("timer_output_file", "/dev/null", "name of file to which "
267  "timing information should be written (process rank will be "
268  "included in file name)", file_not_required_validator);
269 
270  // debug_output_file
271  pl.set("debug_output_file", "/dev/null", "name of file to which debug/status"
272  " messages should be written (process rank will be included in file name)",
273  file_not_required_validator);
274 
275  const bool bUnsortedFalse = false; // defined this to clarify the meaning
276  RCP<Zoltan2::IntegerRangeListValidator<int>> procs_Validator =
277  Teuchos::rcp( new Zoltan2::IntegerRangeListValidator<int>(bUnsortedFalse) );
278 
279  // debug_procs
280  pl.set("debug_procs", "0", "list of ranks that output debugging/status "
281  "messages", procs_Validator);
282 
283  // memory_procs
284  pl.set("memory_procs", "0", "list of ranks that do memory profiling "
285  "information", procs_Validator);
286 }
287 
288 void Environment::commitParameters()
289 {
290  using Teuchos::Array;
291  using Teuchos::ParameterList;
292 
293  bool emptyList = (params_.begin() == params_.end());
294 
295  if (!emptyList){
296 
297  ParameterList validParams;
298 
299  try{
300  createValidatorList(params_, validParams);
301  }
303 
304  // Note that since validParams only contains parameters that
305  // appear in params_, there are no defaults being set. We
306  // call ParameterList::validateParametersAndSetDefaults() instead of
307  // ParameterList::validateParameters() because we want the
308  // the validators' validateAndModify() to be called instead
309  // of validate(). validateAndModify() "fixes" some of the
310  // parameters for us.
311  // Note: depth==0 --> do not validate sublists,
312  // since they are for TPL parameters
313 
314  params_.validateParametersAndSetDefaults(validParams, 0);
315 
316  // For all of the string to integer parameters, convert
317  // them to the integer. I would have
318  // expected validateAndModify() to do this.
319 
320  convertStringToInt(params_);
321  }
322 
324 
325  // Set up for debugging/status output.
326  // By default: if no output stream is specified, then node zero
327  // outputs BASIC_STATUS to std::cout.
328 
329 #ifndef Z2_OMIT_ALL_STATUS_MESSAGES
330  int &level = params_.get<int>("debug_level", NUM_STATUS_OUTPUT_LEVELS);
331  std::string &fname = params_.get<std::string>("debug_output_file", Z2_UNSET_STRING);
332  int &os = params_.get<int>("debug_output_stream", NUM_OUTPUT_STREAMS);
333 
334  if (fname==Z2_UNSET_STRING && os==NUM_OUTPUT_STREAMS)
335  os = COUT_STREAM; // default output target
336  if (level == NUM_STATUS_OUTPUT_LEVELS)
337  level = BASIC_STATUS; // default level of verbosity
338 
339  bool iPrint = (myRank_ == 0); // default reporter
340 
341  const Array<int> *reporters =
342  params_.getPtr<Array<int> >("debug_procs");
343  if (reporters)
344  iPrint = IsInRangeList(myRank_, *reporters);
345 
346  try{
347  makeDebugManager(myRank_, iPrint, level, fname, os, debugOut_);
348  }
349  catch (std::exception &e){
350  std::ostringstream oss;
351  oss << myRank_ << ": unable to create debug output manager";
352  oss << " (" << e.what() << ")";
353  throw std::runtime_error(oss.str());
354  }
355 #endif
356 
357  // Set up for memory usage output.
358 
359 #ifndef Z2_OMIT_ALL_PROFILING
360  std::string &f2 =
361  params_.get<std::string>("memory_output_file", Z2_UNSET_STRING);
362  int &os2 =
363  params_.get<int>("memory_output_stream", NUM_OUTPUT_STREAMS);
364 
365  const Array<int> *reporters2 =
366  params_.getPtr<Array<int> >("memory_procs");
367 
368  bool doMemory = true;
369 
370  if (f2 != Z2_UNSET_STRING || os2 != NUM_OUTPUT_STREAMS || reporters2 != NULL){
371  // user indicated they want memory usage information
372  long numKbytes = 0;
373  if (myRank_ == 0)
374  numKbytes = getProcessKilobytes();
375 
376  Teuchos::broadcast<int, long>(*comm_, 0, 1, &numKbytes);
377 
378  if (numKbytes == 0){
379  // This is not a Linux system with proc/pid/statm.
380  f2 = Z2_UNSET_STRING;
381  os2 = NUM_OUTPUT_STREAMS;
382  reporters2 = NULL;
383  this->debug(BASIC_STATUS,
384  std::string("Warning: memory profiling requested but not available."));
385  doMemory = false; // can't do it
386  }
387  }
388  else{
389  doMemory = false; // not requested
390  }
391 
392  if (doMemory){
393  iPrint = (myRank_ == 0); // default
394  if (reporters2)
395  iPrint = IsInRangeList(myRank_, *reporters2);
396 
397  try{
398  makeMetricOutputManager<long>(myRank_, iPrint, f2, os2, memoryOut_,
399  std::string("KB"), 10, memoryOutputFile_);
400  }
401  catch (std::exception &e){
402  std::ostringstream oss;
403  oss << myRank_ << ": unable to create memory profiling output manager";
404  oss << " (" << e.what() << ")";
405  throw std::runtime_error(oss.str());
406  }
407 
408  memoryOn_ = true;
409  }
410 #endif
411 
412 #ifdef Z2_OMIT_ALL_ERROR_CHECKING
414 #else
415  errorCheckLevel_ = static_cast<AssertionLevel>(
416  params_.get<int>("error_check_level", BASIC_ASSERTION));
417 #endif
418 }
419 
420 void Environment::convertStringToInt(Teuchos::ParameterList &params)
421 {
422  using Teuchos::ParameterList;
423  using Teuchos::ParameterEntry;
424  using Teuchos::RCP;
425  using Teuchos::rcp_dynamic_cast;
426  ParameterList::ConstIterator next = params.begin();
427 
428  // Data type of these parameters will now change from string to int
429 
430  std::string validatorNameInt("StringIntegralValidator(int)");
431  std::string validatorNameBool("StringIntegralValidator(bool)");
432  typedef Teuchos::StringToIntegralParameterEntryValidator<int> s2int_t;
433 
434  while (next != params.end()){
435 
436  const std::string &name = next->first;
437  ParameterEntry &entry = params.getEntry(name);
438 
439  if (entry.isList()){
440  ParameterList *dummy = NULL;
441  ParameterList &pl = entry.getValue<ParameterList>(dummy);
442  convertStringToInt(pl);
443  }
444  else{
445  if ((entry.validator()).get()){
446  if (entry.validator()->getXMLTypeName() == validatorNameInt){
447  std::string dummy("");
448  std::string &entryValue = entry.getValue<std::string>(&dummy);
449  RCP<const s2int_t> s2int =
450  Teuchos::rcp_dynamic_cast<const s2int_t>(entry.validator(), true);
451  int val = s2int->getIntegralValue(entryValue);
452  entry.setValue<int>(val);
453  }
454  }
455  }
456  ++next;
457  }
458 }
459 
460 } //namespace Zoltan2
461 
462 #endif
Environment()
Default Constructor.
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.
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<int> to integer...
/dev/null: do actions but don&#39;t output results
void debug(MessageOutputLevel level, const char *msg) const
Send a message to the debug output manager.
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.
int numProcs_
number of processes (relative to comm_)
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.
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