Zoltan2
Zoltan2_Environment.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //   Zoltan2: A package of combinatorial algorithms for scientific computing
00006 //                  Copyright 2012 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Karen Devine      (kddevin@sandia.gov)
00039 //                    Erik Boman        (egboman@sandia.gov)
00040 //                    Siva Rajamanickam (srajama@sandia.gov)
00041 //
00042 // ***********************************************************************
00043 //
00044 // @HEADER
00049 #ifndef _ZOLTAN2_ENVIRONMENT_CPP_
00050 #define _ZOLTAN2_ENVIRONMENT_CPP_
00051 
00052 #include <Zoltan2_Environment.hpp>
00053 #include <Zoltan2_IntegerRangeList.hpp>
00054 #include <Zoltan2_Util.hpp>
00055 
00056 #include <Teuchos_StandardParameterEntryValidators.hpp>
00057 #include <Teuchos_RCP.hpp>
00058 
00059 #include <sstream>
00060 #include <ostream>
00061 
00062 namespace Zoltan2 {
00063 
00065 // Namespace definitions used by this class.
00066 
00077 void makeDebugManager(int rank, bool iPrint,
00078   int level, std::string fname, int ost,
00079   Teuchos::RCP<DebugManager> &mgr)
00080 {
00081   MessageOutputLevel lvl = static_cast<MessageOutputLevel>(level);
00082 
00083   if (fname != Z2_UNSET_STRING){
00084     std::ofstream *dbgFile = new std::ofstream;
00085     if (iPrint){
00086       std::string newFname;
00087       addNumberToFileName(rank, fname, newFname);
00088       try{
00089         dbgFile->open(newFname.c_str(), std::ios::out|std::ios::trunc);
00090       }
00091       catch(std::exception &e){
00092         throw std::runtime_error(e.what());
00093       }
00094     }
00095     mgr = Teuchos::rcp(new DebugManager(rank, iPrint, *dbgFile, lvl));
00096     return;
00097   }
00098 
00099   OSType os = static_cast<OSType>(ost);
00100 
00101   if (os == COUT_STREAM)
00102     mgr = Teuchos::rcp(new DebugManager(rank, iPrint, std::cout, lvl));
00103   else if (os == CERR_STREAM)
00104     mgr = Teuchos::rcp(new DebugManager(rank, iPrint, std::cerr, lvl));
00105   else if (os == NULL_STREAM)
00106     mgr = Teuchos::rcp(new DebugManager(rank, false, std::cout, lvl));
00107 }
00108 
00110 // Environment definitions
00111 
00112 Environment::Environment( Teuchos::ParameterList &problemParams,
00113   const Teuchos::RCP<const Teuchos::Comm<int> > &comm):
00114   myRank_(comm->getRank()), numProcs_(comm->getSize()), comm_(comm), 
00115   errorCheckLevel_(BASIC_ASSERTION),
00116   unvalidatedParams_(problemParams), params_(problemParams),
00117   debugOut_(), timerOut_(), timingOn_(false), memoryOut_(), memoryOn_(false),
00118   memoryOutputFile_()
00119 {
00120   try{
00121     commitParameters();
00122   }
00123   Z2_FORWARD_EXCEPTIONS
00124 }
00125 
00126 Environment::Environment():
00127   myRank_(0), numProcs_(1), comm_(), errorCheckLevel_(BASIC_ASSERTION),
00128   unvalidatedParams_("emptyList"), params_("emptyList"), 
00129   debugOut_(), timerOut_(), timingOn_(false), memoryOut_(), memoryOn_(false),
00130   memoryOutputFile_()
00131 {
00132   comm_ = Teuchos::DefaultComm<int>::getComm();
00133   myRank_ = comm_->getRank();
00134   numProcs_ = comm_->getSize();
00135 
00136   try{
00137     commitParameters();
00138   }
00139   Z2_FORWARD_EXCEPTIONS
00140 }
00141 
00142 Environment::~Environment()
00143 {
00144   if (!memoryOutputFile_.is_null())
00145     memoryOutputFile_->close();
00146 }
00147 
00148 void Environment::commitParameters()
00149 {
00150   using std::string;
00151   using Teuchos::Array;
00152   using Teuchos::rcp;
00153   using Teuchos::RCP;
00154   using Teuchos::ParameterList;
00155 
00156   bool emptyList = (params_.begin() == params_.end());
00157 
00158   if (!emptyList){
00159 
00160     ParameterList validParams;
00161 
00162     try{
00163       createValidatorList(params_, validParams);
00164     }
00165     Z2_FORWARD_EXCEPTIONS
00166   
00167     // Note that since validParams only contains parameters that
00168     // appear in params_, there are no defaults being set.  We
00169     // call ParameterList::validateParametersAndSetDefaults() instead of
00170     // ParameterList::validateParameters() because we want the
00171     // the validators' validateAndModify() to be called instead
00172     // of validate().  validateAndModify() "fixes" some of the
00173     // parameters for us.
00174   
00175     params_.validateParametersAndSetDefaults(validParams);
00176 
00177     // For all of the string to integer parameters, convert
00178     // them to the integer.  I would have
00179     // expected validateAndModify() to do this.
00180   
00181     convertStringToInt(params_);
00182   }
00183 
00185 
00186   // Set up for debugging/status output.
00187   //   By default: if no output stream is specified, then node zero
00188   //       outputs BASIC_STATUS to std::cout.
00189 
00190 #ifndef Z2_OMIT_ALL_STATUS_MESSAGES
00191   int &level = params_.get<int>("debug_level", NUM_STATUS_OUTPUT_LEVELS);
00192   string &fname = params_.get<string>("debug_output_file", Z2_UNSET_STRING);
00193   int &os = params_.get<int>("debug_output_stream", NUM_OUTPUT_STREAMS);
00194 
00195   if (fname==Z2_UNSET_STRING && os==NUM_OUTPUT_STREAMS)
00196     os = COUT_STREAM;        // default output target
00197   if (level == NUM_STATUS_OUTPUT_LEVELS)
00198     level = BASIC_STATUS;    // default level of verbosity
00199 
00200   bool iPrint = (myRank_ == 0);   // default reporter
00201 
00202   const Array<int> *reporters = 
00203     params_.getPtr<Array<int> >("debug_procs");
00204   if (reporters)
00205     iPrint = IsInRangeList(myRank_, *reporters);
00206 
00207   try{
00208     makeDebugManager(myRank_, iPrint, level, fname, os, debugOut_);
00209   }
00210   catch (std::exception &e){
00211     std::ostringstream oss;
00212     oss << myRank_ << ": unable to create debug output manager";
00213     oss << " (" << e.what() << ")";
00214     throw std::runtime_error(oss.str());
00215   }
00216 #endif
00217 
00218   // Set up for memory usage output. 
00219   
00220 #ifndef Z2_OMIT_ALL_PROFILING
00221   string &f2 = 
00222     params_.get<string>("memory_output_file", Z2_UNSET_STRING);
00223   int &os2 = 
00224     params_.get<int>("memory_output_stream", NUM_OUTPUT_STREAMS);
00225 
00226   const Array<int> *reporters2 = 
00227     params_.getPtr<Array<int> >("memory_procs");
00228 
00229   bool doMemory = true;
00230 
00231   if (f2 != Z2_UNSET_STRING || os2 != NUM_OUTPUT_STREAMS || reporters2 != NULL){
00232     // user indicated they want memory usage information
00233     long numKbytes = 0;
00234     if (myRank_ == 0)
00235       numKbytes = getProcessKilobytes();
00236 
00237     Teuchos::broadcast<int, long>(*comm_, 0, 1, &numKbytes);
00238 
00239     if (numKbytes == 0){
00240       // This is not a Linux system with proc/pid/statm.
00241       f2 = Z2_UNSET_STRING;
00242       os2 = NUM_OUTPUT_STREAMS;
00243       reporters2 = NULL;
00244       this->debug(BASIC_STATUS, 
00245         string("Warning: memory profiling requested but not available."));
00246       doMemory = false;   // can't do it
00247     }
00248   }
00249   else{
00250     doMemory = false;   // not requested
00251   }
00252 
00253   if (doMemory){
00254     iPrint = (myRank_ == 0);   // default
00255     if (reporters2)
00256       iPrint = IsInRangeList(myRank_, *reporters2);
00257 
00258     try{
00259       makeMetricOutputManager<long>(myRank_, iPrint, f2, os2, memoryOut_,
00260         string("KB"), 10, memoryOutputFile_);
00261     }
00262     catch (std::exception &e){
00263       std::ostringstream oss;
00264       oss << myRank_ << ": unable to create memory profiling output manager";
00265       oss << " (" << e.what() << ")";
00266       throw std::runtime_error(oss.str());
00267     }
00268 
00269     memoryOn_ = true;
00270   }
00271 #endif
00272 
00273 #ifdef Z2_OMIT_ALL_ERROR_CHECKING
00274   errorCheckLevel_ = NO_ASSERTIONS;
00275 #else
00276   errorCheckLevel_ = static_cast<AssertionLevel>( 
00277     params_.get<int>("error_check_level", BASIC_ASSERTION));
00278 #endif
00279 }
00280   
00281 void Environment::convertStringToInt(Teuchos::ParameterList &params)
00282 {
00283   using Teuchos::ParameterList;
00284   using Teuchos::ParameterEntry;
00285   using Teuchos::RCP;
00286   using Teuchos::rcp_dynamic_cast;
00287   using std::string;
00288   ParameterList::ConstIterator next = params.begin();
00289 
00290   // Data type of these parameters will now change from string to int
00291 
00292   string validatorName("StringIntegralValidator(int)");
00293   typedef Teuchos::StringToIntegralParameterEntryValidator<int> s2i_t;
00294 
00295   while (next != params.end()){
00296 
00297     const std::string &name = next->first;
00298     ParameterEntry &entry = params.getEntry(name);
00299 
00300     if (entry.isList()){
00301       ParameterList *dummy = NULL;
00302       ParameterList &pl = entry.getValue<ParameterList>(dummy);
00303       convertStringToInt(pl);
00304     }
00305     else{
00306       if ((entry.validator()).get()){
00307         if (entry.validator()->getXMLTypeName() == validatorName){
00308           string dummy("");
00309           string &entryValue = entry.getValue<string>(&dummy);
00310           RCP<const s2i_t> s2i =
00311             Teuchos::rcp_dynamic_cast<const s2i_t>(entry.validator(), true);
00312           int val = s2i->getIntegralValue(entryValue);
00313           entry.setValue<int>(val);
00314         }
00315       }
00316     }
00317     ++next;
00318   }
00319 }
00320 
00321 }  //namespace Zoltan2
00322 
00323 #endif