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  }
320 
322 
323  // Set up for debugging/status output.
324  // By default: if no output stream is specified, then node zero
325  // outputs BASIC_STATUS to std::cout.
326 
327 #ifndef Z2_OMIT_ALL_STATUS_MESSAGES
328  int &level = params_.get<int>("debug_level", NUM_STATUS_OUTPUT_LEVELS);
329  std::string &fname = params_.get<std::string>("debug_output_file", Z2_UNSET_STRING);
330  int &os = params_.get<int>("debug_output_stream", NUM_OUTPUT_STREAMS);
331 
332  if (fname==Z2_UNSET_STRING && os==NUM_OUTPUT_STREAMS)
333  os = COUT_STREAM; // default output target
334  if (level == NUM_STATUS_OUTPUT_LEVELS)
335  level = BASIC_STATUS; // default level of verbosity
336 
337  bool iPrint = (myRank_ == 0); // default reporter
338 
339  const Array<int> *reporters =
340  params_.getPtr<Array<int> >("debug_procs");
341  if (reporters)
342  iPrint = IsInRangeList(myRank_, *reporters);
343 
344  try{
345  makeDebugManager(myRank_, iPrint, level, fname, os, debugOut_);
346  }
347  catch (std::exception &e){
348  std::ostringstream oss;
349  oss << myRank_ << ": unable to create debug output manager";
350  oss << " (" << e.what() << ")";
351  throw std::runtime_error(oss.str());
352  }
353 #endif
354 
355  // Set up for memory usage output.
356 
357 #ifndef Z2_OMIT_ALL_PROFILING
358  std::string &f2 =
359  params_.get<std::string>("memory_output_file", Z2_UNSET_STRING);
360  int &os2 =
361  params_.get<int>("memory_output_stream", NUM_OUTPUT_STREAMS);
362 
363  const Array<int> *reporters2 =
364  params_.getPtr<Array<int> >("memory_procs");
365 
366  bool doMemory = true;
367 
368  if (f2 != Z2_UNSET_STRING || os2 != NUM_OUTPUT_STREAMS || reporters2 != NULL){
369  // user indicated they want memory usage information
370  long numKbytes = 0;
371  if (myRank_ == 0)
372  numKbytes = getProcessKilobytes();
373 
374  Teuchos::broadcast<int, long>(*comm_, 0, 1, &numKbytes);
375 
376  if (numKbytes == 0){
377  // This is not a Linux system with proc/pid/statm.
378  f2 = Z2_UNSET_STRING;
379  os2 = NUM_OUTPUT_STREAMS;
380  reporters2 = NULL;
381  this->debug(BASIC_STATUS,
382  std::string("Warning: memory profiling requested but not available."));
383  doMemory = false; // can't do it
384  }
385  }
386  else{
387  doMemory = false; // not requested
388  }
389 
390  if (doMemory){
391  iPrint = (myRank_ == 0); // default
392  if (reporters2)
393  iPrint = IsInRangeList(myRank_, *reporters2);
394 
395  try{
396  makeMetricOutputManager<long>(myRank_, iPrint, f2, os2, memoryOut_,
397  std::string("KB"), 10, memoryOutputFile_);
398  }
399  catch (std::exception &e){
400  std::ostringstream oss;
401  oss << myRank_ << ": unable to create memory profiling output manager";
402  oss << " (" << e.what() << ")";
403  throw std::runtime_error(oss.str());
404  }
405 
406  memoryOn_ = true;
407  }
408 #endif
409 
410 #ifdef Z2_OMIT_ALL_ERROR_CHECKING
412 #else
413  errorCheckLevel_ = static_cast<AssertionLevel>(
414  params_.get<int>("error_check_level", BASIC_ASSERTION));
415 #endif
416 }
417 
418 } //namespace Zoltan2
419 
420 #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: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