|
Zoltan2
|
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 00045 00050 #ifndef _ZOLTAN2_ENVIRONMENT_HPP_ 00051 #define _ZOLTAN2_ENVIRONMENT_HPP_ 00052 00053 #include <Zoltan2_config.h> 00054 #include <Zoltan2_Util.hpp> 00055 #include <Zoltan2_IO.hpp> 00056 #include <Zoltan2_Parameters.hpp> 00057 #include <Zoltan2_DebugManager.hpp> 00058 #include <Zoltan2_TimerManager.hpp> 00059 #include <Zoltan2_MetricOutputManager.hpp> 00060 00061 #include <Teuchos_RCP.hpp> 00062 #include <Teuchos_ParameterList.hpp> 00063 #include <Teuchos_Comm.hpp> 00064 #include <Teuchos_DefaultComm.hpp> 00065 #include <Teuchos_CommHelpers.hpp> 00066 00067 namespace Zoltan2 { 00068 00082 class Environment{ 00083 00084 public: 00085 00086 typedef long memory_t; 00088 typedef Teuchos::RCP<const Teuchos::Comm<int> > Comm_t; 00089 typedef Teuchos::RCP<DebugManager> DebugManager_t; 00090 typedef Teuchos::RCP<MetricOutputManager<memory_t> > MemoryProfilerManager_t; 00091 typedef Teuchos::RCP<TimerManager> Timer_t; 00092 00093 int myRank_; 00095 int numProcs_; 00097 Comm_t comm_; 00099 AssertionLevel errorCheckLevel_; 00109 Environment(Teuchos::ParameterList &problemParams, 00110 const Teuchos::RCP<const Teuchos::Comm<int> > &comm ); 00111 00118 Environment(); 00119 00122 ~Environment(); 00123 00130 void setTimer(RCP<TimerManager> &timer) { timerOut_=timer; timingOn_=true;} 00131 00132 #ifdef Z2_OMIT_ALL_ERROR_CHECKING 00133 00134 void localInputAssertion(const char *file, int lineNum, 00135 const char *msg, bool ok, AssertionLevel level) const {} 00136 00137 void globalInputAssertion(const char *file, int lineNum, 00138 const char *msg, bool ok, AssertionLevel level, 00139 const Comm_t &comm=comm_) const {} 00140 00141 void localBugAssertion(const char *file, int lineNum, 00142 const char *msg, bool ok, AssertionLevel level) const {} 00143 00144 void globalBugAssertion(const char *file, int lineNum, 00145 const char *msg, bool ok, AssertionLevel level, 00146 const Comm_t &comm=comm_) const {} 00147 00148 void localMemoryAssertion(const char *file, int lineNum, 00149 size_t nobj, bool ok) const {} 00150 00151 void globalMemoryAssertion(const char *file, int lineNum, 00152 size_t nobj, bool ok, const Comm_t &comm=comm_) const {} 00153 00154 #else 00155 00169 void localInputAssertion(const char *file, int lineNum, 00170 const char *msg, bool ok, AssertionLevel level) const { 00171 00172 if (level <= errorCheckLevel_ && !ok){ 00173 std::ostringstream emsg; 00174 emsg << myRank_<< ": " << file << "," << lineNum<< std::endl; 00175 if (msg) 00176 emsg << myRank_ << ": error: " << msg << std::endl; 00177 throw std::runtime_error(emsg.str()); 00178 } 00179 } 00196 void globalInputAssertion(const char *file, int lineNum, 00197 const char *msg, bool ok, AssertionLevel level, 00198 const Comm_t &comm) const { 00199 00200 if (level <= errorCheckLevel_){ 00201 int anyFail=0, fail = (!ok ? 1 : 0); 00202 Teuchos::reduceAll<int,int>(*comm, Teuchos::REDUCE_MAX, 1, &fail, 00203 &anyFail); 00204 if (anyFail > 0){ 00205 std::ostringstream emsg; 00206 emsg << myRank_<< ": " << file << "," << lineNum<< std::endl; 00207 if (msg && !ok) 00208 emsg << myRank_ << ": error: " << msg << std::endl; 00209 else 00210 emsg << myRank_ << ": exiting" << std::endl; 00211 00212 throw std::runtime_error(emsg.str()); 00213 } 00214 } 00215 } 00216 00236 void localBugAssertion(const char *file, int lineNum, 00237 const char *msg, bool ok, AssertionLevel level) const { 00238 00239 if (level <= errorCheckLevel_ && !ok){ 00240 std::ostringstream emsg; 00241 emsg << myRank_<< ": " << file << "," << lineNum<< std::endl; 00242 if (msg) 00243 emsg << myRank_ << ": bug: " << msg << std::endl; 00244 throw std::logic_error(emsg.str()); 00245 } 00246 } 00247 00269 void globalBugAssertion(const char *file, int lineNum, 00270 const char *msg, bool ok, AssertionLevel level, 00271 const Comm_t &comm) const { 00272 00273 if (level <= errorCheckLevel_){ 00274 int anyFail=0, fail = (!ok ? 1 : 0); 00275 Teuchos::reduceAll<int,int>(*comm, Teuchos::REDUCE_MAX, 1, &fail, 00276 &anyFail); 00277 if (anyFail > 0){ 00278 00279 std::ostringstream emsg; 00280 emsg << myRank_<< ": " << file << "," << lineNum<< std::endl; 00281 if (msg && !ok) 00282 emsg << myRank_ << ": bug: " << msg << std::endl; 00283 else 00284 emsg << myRank_ << ": exiting" << std::endl; 00285 00286 throw std::logic_error(emsg.str()); 00287 } 00288 } 00289 } 00290 00304 void localMemoryAssertion(const char *file, int lineNum, size_t nobj, 00305 bool ok) const { 00306 00307 if (!ok){ 00308 std::cerr << myRank_ << ": " << file << ", " << lineNum<< std::endl; 00309 std::cerr << myRank_ << ": " << nobj << " objects" << std::endl; 00310 throw std::bad_alloc(); 00311 } 00312 } 00313 00329 void globalMemoryAssertion(const char *file, int lineNum, 00330 size_t nobj, bool ok, const Comm_t &comm) const { 00331 00332 int anyFail=0, fail = (!ok ? 1 : 0); 00333 Teuchos::reduceAll<int,int>(*comm, Teuchos::REDUCE_MAX, 1, &fail, &anyFail); 00334 if (anyFail > 0){ 00335 std::cerr << myRank_ << ": " << file << ", " << lineNum<< std::endl; 00336 if (!ok) 00337 std::cerr << myRank_ << ": " << nobj << " objects" << std::endl; 00338 else 00339 std::cerr << myRank_ << ": exiting" << std::endl; 00340 00341 throw std::bad_alloc(); 00342 } 00343 } 00344 #endif 00345 00346 // For debugging and profiling output, we define "char *" versions 00347 // as well as "string" versions to avoid runtime conversion of "char *" 00348 // to "string". 00349 00361 #ifdef Z2_OMIT_ALL_STATUS_MESSAGES 00362 inline void debug(MessageOutputLevel level, const char *msg) const{ return;} 00363 inline void debug(MessageOutputLevel level, const std::string& msg) const{ 00364 return; 00365 } 00366 inline void debug(int level, const char *msg) const{ return;} 00367 inline void debug(int level, const std::string& msg) const{ return;} 00368 #else 00369 inline void debug(MessageOutputLevel level, const char *msg) const{ 00370 debugOut_->print(level, msg); 00371 } 00372 00373 inline void debug(MessageOutputLevel level, const std::string& msg) const{ 00374 debugOut_->print(level, msg); 00375 } 00376 00377 inline void debug(int level, const char *msg) const{ 00378 MessageOutputLevel msg_enum = static_cast<MessageOutputLevel>(level); 00379 debugOut_->print(msg_enum, msg); 00380 } 00381 00382 inline void debug(int level, const std::string& msg) const{ 00383 MessageOutputLevel msg_enum = static_cast<MessageOutputLevel>(level); 00384 debugOut_->print(msg_enum, msg); 00385 } 00386 #endif 00387 00388 #ifdef Z2_OMIT_ALL_PROFILING 00389 00390 void timerStart(TimerType tt, const char * timerName) const {return;} 00391 void timerStart(TimerType tt, const std::string &timerName) const {return;} 00392 void timerStart(TimerType tt, const char * timerName, int, 00393 int fieldWidth=0) const {return;} 00394 void timerStart(TimerType tt, const std::string &timerName, int, 00395 int fieldWidth=0) const {return;} 00396 00397 void timerStop(TimerType tt, const char * timerName) const {return;} 00398 void timerStop(TimerType tt, const std::string &timerName) const {return;} 00399 void timerStop(TimerType tt, const char * timerName, int, 00400 int fieldWidth=0) const {return;} 00401 void timerStop(TimerType tt, const std::string &timerName, int, 00402 int fieldWidth=0) const {return;} 00403 00404 #else 00405 00408 void timerStart(TimerType tt, const char *timerName) const { 00409 if (timingOn_) timerOut_->start(tt, timerName); } 00410 00411 void timerStart(TimerType tt, const std::string &timerName) const { 00412 if (timingOn_) timerOut_->start(tt, timerName); } 00413 00416 void timerStart(TimerType tt, const char *timerName, int num, 00417 int fieldWidth=0) const { 00418 if (timingOn_){ 00419 std::ostringstream oss; 00420 oss << timerName << " "; 00421 if (fieldWidth > 0){ 00422 oss.width(fieldWidth); 00423 oss.fill('0'); 00424 } 00425 oss << num; 00426 timerOut_->start(tt, oss.str()); 00427 } 00428 } 00429 00430 void timerStart(TimerType tt, const std::string &timerName, int num, 00431 int fieldWidth=0) const { 00432 if (timingOn_){ 00433 std::ostringstream oss; 00434 oss << timerName << " "; 00435 if (fieldWidth > 0){ 00436 oss.width(fieldWidth); 00437 oss.fill('0'); 00438 } 00439 oss << num; 00440 timerOut_->start(tt, oss.str()); 00441 } 00442 } 00443 00447 void timerStop(TimerType tt, const char *timerName) const { 00448 if (timingOn_) timerOut_->stop(tt, timerName); } 00449 00450 void timerStop(TimerType tt, const std::string &timerName) const { 00451 if (timingOn_) timerOut_->stop(tt, timerName); } 00452 00456 void timerStop(TimerType tt, const char *timerName, int num, 00457 int fieldWidth=0) const { 00458 if (timingOn_){ 00459 std::ostringstream oss; 00460 oss << timerName << " "; 00461 if (fieldWidth > 0){ 00462 oss.width(fieldWidth); 00463 oss.fill('0'); 00464 } 00465 oss << num; 00466 timerOut_->stop(tt, oss.str()); 00467 } 00468 } 00469 00470 void timerStop(TimerType tt, const std::string &timerName, int num, 00471 int fieldWidth=0) const { 00472 if (timingOn_){ 00473 std::ostringstream oss; 00474 oss << timerName << " "; 00475 if (fieldWidth > 0){ 00476 oss.width(fieldWidth); 00477 oss.fill('0'); 00478 } 00479 oss << num; 00480 timerOut_->stop(tt, oss.str()); 00481 } 00482 } 00483 00484 #endif 00485 00501 #ifdef Z2_OMIT_ALL_PROFILING 00502 void memory(const char *msg) const {return;} 00503 00504 void memory(const std::string &msg) const {return; } 00505 #else 00506 void memory(const char *msg) const 00507 {if (memoryOn_) 00508 memoryOut_->print(msg, getProcessKilobytes());} 00509 00510 void memory(const std::string &msg) const 00511 {if (memoryOn_) 00512 memoryOut_->print(msg, getProcessKilobytes());} 00513 #endif 00514 00519 const Teuchos::ParameterList &getParameters() const { return params_; } 00520 00525 Teuchos::ParameterList &getParametersNonConst() { return params_; } 00526 00530 bool doTiming() const { return timingOn_; } 00531 00535 #ifdef Z2_OMIT_ALL_STATUS_MESSAGES 00536 inline bool doStatus() const { return false;} 00537 inline MessageOutputLevel getDebugLevel() const {return NO_STATUS;} 00538 inline std::ostream *getDebugOStream() const {return std::cout;} 00539 #else 00540 inline bool doStatus() const { 00541 return (debugOut_->getDebugLevel() > NO_STATUS); 00542 } 00543 inline MessageOutputLevel getDebugLevel() const { 00544 return debugOut_->getDebugLevel(); 00545 } 00546 inline std::ostream *getDebugOStream() const { 00547 return debugOut_->getOStream(); 00548 } 00549 #endif 00550 00554 bool doMemoryProfiling() const { return memoryOn_;} 00555 00567 const Teuchos::ParameterList &getUnvalidatedParameters() const { 00568 return unvalidatedParams_; } 00569 00583 static void convertStringToInt(Teuchos::ParameterList ¶ms); 00584 00585 private: 00586 00589 void commitParameters(); 00590 00595 Teuchos::ParameterList unvalidatedParams_; 00596 00605 Teuchos::ParameterList params_; 00606 00607 DebugManager_t debugOut_; 00609 Timer_t timerOut_; 00610 bool timingOn_; 00611 00612 MemoryProfilerManager_t memoryOut_; 00613 bool memoryOn_; 00614 RCP<std::ofstream> memoryOutputFile_; 00615 }; 00616 00620 #define Z2_UNSET_STRING std::string("notSet") 00621 00623 // Templated namespace definitions used by the class 00624 00637 template<typename metric_t> 00638 void makeMetricOutputManager(int rank, bool iPrint, 00639 std::string fname, int ost, 00640 Teuchos::RCP<MetricOutputManager<metric_t> > &mgr, 00641 std::string units, int fieldWidth, 00642 RCP<std::ofstream> &fptr) 00643 { 00644 typedef MetricOutputManager<metric_t> manager_t; 00645 00646 OSType os = static_cast<OSType>(ost); 00647 00648 bool haveFname = (fname != Z2_UNSET_STRING); 00649 bool haveStreamName = (os != NUM_OUTPUT_STREAMS); 00650 00651 if (!haveFname && !haveStreamName){ 00652 mgr = Teuchos::rcp(new manager_t(rank, iPrint, std::cout, true, 00653 units, fieldWidth)); 00654 return; 00655 } 00656 00657 if (haveFname){ 00658 std::ofstream *oFile = NULL; 00659 if (iPrint){ 00660 oFile = new std::ofstream; 00661 std::string newFname; 00662 addNumberToFileName(rank, fname, newFname); 00663 try{ 00664 oFile->open(newFname.c_str(), std::ios::out|std::ios::trunc); 00665 } 00666 catch(std::exception &e){ 00667 throw std::runtime_error(e.what()); 00668 } 00669 fptr = rcp(oFile); 00670 } 00671 mgr = Teuchos::rcp(new manager_t(rank, iPrint, *oFile, true, 00672 units, fieldWidth)); 00673 return; 00674 } 00675 00676 if (os == COUT_STREAM) 00677 mgr = Teuchos::rcp(new manager_t(rank, iPrint, std::cout, true, 00678 units, fieldWidth)); 00679 else if (os == CERR_STREAM) 00680 mgr = Teuchos::rcp(new manager_t(rank, iPrint, std::cerr, true, 00681 units, fieldWidth)); 00682 else if (os == NULL_STREAM) 00683 mgr = Teuchos::rcp(new manager_t(rank, false, std::cout, true, 00684 units, fieldWidth)); 00685 else 00686 throw std::logic_error("invalid metric output stream was not caught"); 00687 } 00688 00689 } // namespace Zoltan2 00690 00691 #endif
1.7.6.1