00001 #include "Teuchos_VerboseObject.hpp"
00002 #include "Teuchos_StandardCatchMacros.hpp"
00003 #include "Teuchos_GlobalMPISession.hpp"
00004 #include "Teuchos_CommandLineProcessor.hpp"
00005 #include "Teuchos_ParameterListAcceptor.hpp"
00006 #include "Teuchos_StandardParameterEntryValidators.hpp"
00007 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
00008 #include "Teuchos_dyn_cast.hpp"
00009 #include "Teuchos_Version.hpp"
00010
00011
00012
00013
00014
00015 void someDumbFunction( std::ostream &out, const std::string &indentSpacer )
00016 {
00017 out << "\nEntering someDumbFunction(...)\n";
00018 {
00019 out << std::endl << indentSpacer << "I am \"dumb\" code that knows nothing of FancyOStream and does indenting manually! ...\n";
00020 }
00021 out << "\nLeaving someDumbFunction(...)\n";
00022
00023 }
00024
00025
00026
00027
00028
00029 void someLessDumbFunction( std::ostream &out_arg )
00030 {
00031 using Teuchos::OSTab;
00032
00033 Teuchos::RCP<Teuchos::FancyOStream>
00034 out = Teuchos::getFancyOStream(Teuchos::rcp(&out_arg,false));
00035
00036 OSTab tab(out,1,"LDUMBALGO");
00037 *out << "\nEntering someLessDumbFunction(...)\n";
00038 {
00039 Teuchos::OSTab(out_arg).o()
00040 << std::endl << "I am less \"dumb\" code that knows about FancyOStream but my interface does not support it directly! ...\n";
00041 *Teuchos::tab(out)
00042 << std::endl << "Another print from this less \"dumb\" code ...\n";
00043 }
00044 *out << "\nLeaving someLessDumbFunction(...)\n";
00045 }
00046
00047
00048
00049
00050
00051
00052
00053
00054 class AlgorithmA
00055 : public Teuchos::VerboseObject<AlgorithmA>,
00056 public Teuchos::ParameterListAcceptor
00057 {
00058 public:
00059
00060
00061
00062 AlgorithmA();
00063
00064
00065
00066 void setParameterList(Teuchos::RCP<Teuchos::ParameterList> const& paramList);
00067
00068 Teuchos::RCP<Teuchos::ParameterList> getParameterList();
00069
00070 Teuchos::RCP<Teuchos::ParameterList> unsetParameterList();
00071
00072 Teuchos::RCP<const Teuchos::ParameterList> getParameterList() const;
00073
00074 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const;
00075
00076
00077
00078 void doAlgorithm();
00079
00080 private:
00081
00082 enum EAlgoType { ALGO_BOB, ALGO_JOHN, ALGO_HARRY };
00083
00084 static const std::string toString( AlgorithmA::EAlgoType algoType );
00085
00086 Teuchos::RCP<Teuchos::ParameterList> paramList_;
00087 EAlgoType algoType_;
00088 double algoTol_;
00089
00090 };
00091
00092
00093
00094
00095 namespace {
00096
00097 const std::string AlgoType_name = "Algo Type";
00098 const std::string AlgoType_default = "Bob";
00099
00100 const std::string AlgoTol_name = "Algo Tol";
00101 const double AlgoTol_default = 1e-5;
00102
00103 }
00104
00105 const std::string AlgorithmA::toString( AlgorithmA::EAlgoType algoType )
00106 {
00107 switch(algoType) {
00108 case ALGO_BOB: return "Bob";
00109 case ALGO_JOHN: return "John";
00110 case ALGO_HARRY: return "Harry";
00111 default: TEST_FOR_EXCEPT("Should never get here!");
00112 }
00113 return "";
00114 }
00115
00116
00117 AlgorithmA::AlgorithmA()
00118 : algoType_(ALGO_BOB), algoTol_(AlgoTol_default)
00119 {
00120 this->setLinePrefix("ALGO_A");
00121 }
00122
00123
00124 void AlgorithmA::setParameterList(
00125 Teuchos::RCP<Teuchos::ParameterList> const& paramList
00126 )
00127 {
00128 TEST_FOR_EXCEPT(is_null(paramList));
00129
00130
00131
00132
00133
00134 paramList->validateParametersAndSetDefaults(*this->getValidParameters(),0);
00135 paramList_ = paramList;
00136
00137
00138
00139
00140
00141 algoType_ = Teuchos::getIntegralValue<EAlgoType>(*paramList_,AlgoType_name);
00142
00143
00144
00145
00146 algoTol_ = Teuchos::getParameter<double>(*paramList_,AlgoTol_name);
00147
00148 Teuchos::readVerboseObjectSublist(&*paramList_,this);
00149 #ifdef TEUCHOS_DEBUG
00150 paramList_->validateParameters(*this->getValidParameters());
00151 #endif
00152 }
00153
00154
00155 Teuchos::RCP<Teuchos::ParameterList>
00156 AlgorithmA::getParameterList()
00157 {
00158 return paramList_;
00159 }
00160
00161
00162 Teuchos::RCP<Teuchos::ParameterList>
00163 AlgorithmA::unsetParameterList()
00164 {
00165 Teuchos::RCP<Teuchos::ParameterList> paramList = paramList_;
00166 paramList_ = Teuchos::null;
00167 return paramList;
00168 }
00169
00170
00171 Teuchos::RCP<const Teuchos::ParameterList>
00172 AlgorithmA::getParameterList() const
00173 {
00174 return paramList_;
00175 }
00176
00177
00178 Teuchos::RCP<const Teuchos::ParameterList>
00179 AlgorithmA::getValidParameters() const
00180 {
00181 using Teuchos::RCP; using Teuchos::ParameterList;
00182 using Teuchos::setStringToIntegralParameter;
00183 using Teuchos::tuple;
00184 static RCP<const ParameterList> validParams;
00185 if (is_null(validParams)) {
00186 RCP<ParameterList>
00187 pl = Teuchos::rcp(new ParameterList("AlgorithmA"));
00188 setStringToIntegralParameter(
00189 AlgoType_name, AlgoType_default,
00190 "The algorithm type to use",
00191 tuple<std::string>("Bob", "John", "Harry"),
00192 tuple<EAlgoType>(ALGO_BOB, ALGO_JOHN, ALGO_HARRY),
00193 &*pl
00194 );
00195 Teuchos::setDoubleParameter(
00196 AlgoTol_name, AlgoTol_default,
00197 "The tolerance for the algorithm.",
00198 &*pl
00199 );
00200 Teuchos::setupVerboseObjectSublist(&*pl);
00201 validParams = pl;
00202 }
00203 return validParams;
00204 }
00205
00206
00207 void AlgorithmA::doAlgorithm()
00208 {
00209 using Teuchos::OSTab;
00210
00211 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00212
00213
00214 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
00215
00216
00217
00218 OSTab tab = this->getOSTab();
00219 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
00220 *out << "\nEntering AlgorithmA::doAlgorithm() with verbLevel="<<Teuchos::toString(verbLevel)<<"\n";
00221 {
00222
00223
00224
00225 TEUCHOS_OSTAB;
00226 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
00227 *out
00228 << "\nI am \"smart\" code that knows about FancyOStream and OSTab ...\n"
00229 << "\nDoing algorithm of type \""<<toString(algoType_)<<"\""
00230 << "\nUsing tolerance of " << algoTol_ << "\n";
00231 {
00232
00233 OSTab tab = this->getOSTab(OSTab::DISABLE_TABBING);
00234 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
00235 *out << "\n***\n*** Warning, I am doing something very dangerous so watch out!!!\n***\n";
00236 }
00237 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
00238 *out << "\nHere I am doing some more stuff and printing with indenting turned back on!\n";
00239 {
00240
00241
00242
00243
00244
00245
00246 OSTab tab = this->getOSTab(1,"DUMBALGO");
00247
00248
00249
00250
00251
00252 someDumbFunction(*out,out->getTabIndentStr());
00253 }
00254
00255
00256
00257
00258 someLessDumbFunction(*out);
00259 }
00260 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
00261 *out << "\nLeaving AlgorithmA::doAlgorithm()\n";
00262 }
00263
00264
00265
00266
00267
00268
00269
00270 void doAlgorithmStuff( Teuchos::ParameterList *algoParams = 0 )
00271 {
00272
00273
00274
00275 AlgorithmA algoA;
00276 if(algoParams)
00277 algoA.setParameterList(Teuchos::rcp(algoParams,false));
00278
00279
00280
00281
00282 algoA.doAlgorithm();
00283
00284 *algoA.getOStream() << std::endl;
00285
00286 }
00287
00288
00289
00290
00291
00292 class TestVerboseObjectBaseInitialization {
00293 public:
00294 TestVerboseObjectBaseInitialization()
00295 {
00296
00297 Teuchos::EVerbosityLevel verbLevel = Teuchos::VerboseObject<AlgorithmA>::getDefaultVerbLevel();
00298 TEST_FOR_EXCEPT_PRINT(verbLevel!=Teuchos::VERB_DEFAULT,&std::cerr);
00299
00300
00301 *Teuchos::VerboseObjectBase::getDefaultOStream()
00302 << "\n***\n*** Printing to default OStream before main() even starts!\n***\n\n"
00303 << std::flush;
00304 }
00305 };
00306
00307 static TestVerboseObjectBaseInitialization testVerboseObjectBaseInitialization;
00308
00309
00310
00311
00312
00313 int main(int argc, char* argv[])
00314 {
00315
00316 using Teuchos::RCP;
00317 using Teuchos::rcp;
00318 using Teuchos::FancyOStream;
00319 using Teuchos::VerboseObjectBase;
00320 using Teuchos::OSTab;
00321 using Teuchos::dyn_cast;
00322 using Teuchos::CommandLineProcessor;
00323
00324 bool success = true;
00325
00326 Teuchos::GlobalMPISession mpiSession(&argc,&argv);
00327 const int numProcs = Teuchos::GlobalMPISession::getNProc();
00328
00329 try {
00330
00331
00332 CommandLineProcessor clp;
00333 clp.throwExceptions(false);
00334 clp.addOutputSetupOptions(true);
00335 CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00336 if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
00337
00338
00339 RCP<FancyOStream>
00340 out = VerboseObjectBase::getDefaultOStream();
00341
00342
00343
00344
00345 *out << std::endl << Teuchos::Teuchos_Version() << std::endl << std::endl;
00346
00347
00348
00349
00350
00351
00352 *out << "\n***\n*** Testing VerboseObject base class use\n***\n";
00353
00354 *out << "\n*** Algorithm output with default formatting\n\n";
00355 doAlgorithmStuff();
00356
00357 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00358 *out << "\n*** Algorithm output with no front matter\n\n";
00359 out->setShowAllFrontMatter(false);
00360 doAlgorithmStuff();
00361
00362 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00363 *out << "\n*** Algorithm output with processor ranks\n\n";
00364 out->setShowAllFrontMatter(false).setShowProcRank(true);
00365 doAlgorithmStuff();
00366
00367 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00368 *out << "\n*** Algorithm output with line prefix names\n\n";
00369 out->setShowAllFrontMatter(false).setShowLinePrefix(true);
00370 doAlgorithmStuff();
00371
00372 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00373 *out << "\n*** Algorithm output with tab counts\n\n";
00374 out->setShowAllFrontMatter(false).setShowTabCount(true);
00375 doAlgorithmStuff();
00376
00377 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00378 *out << "\n*** Algorithm output with line prefix names and tab counts\n\n";
00379 out->setShowAllFrontMatter(false).setShowLinePrefix(true).setShowTabCount(true);
00380 doAlgorithmStuff();
00381
00382 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00383 *out << "\n*** Algorithm output with processor ranks and line prefix names\n\n";
00384 out->setShowAllFrontMatter(false).setShowProcRank(true).setShowLinePrefix(true);
00385 doAlgorithmStuff();
00386
00387 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00388 *out << "\n*** Algorithm output with processor ranks and tab counts\n\n";
00389 out->setShowAllFrontMatter(false).setShowProcRank(true).setShowTabCount(true);
00390 doAlgorithmStuff();
00391
00392 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00393 *out << "\n*** Algorithm output with processor ranks, line prefix names, and tab counts\n\n";
00394 out->setShowAllFrontMatter(false).setShowProcRank(true).setShowLinePrefix(true).setShowTabCount(true);
00395 doAlgorithmStuff();
00396
00397 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00398 *out << "\n*** Algorithm output with processor ranks, line prefix names, and tab counts but no output for AlgorithmA\n\n";
00399 Teuchos::VerboseObject<AlgorithmA>::setDefaultVerbLevel(Teuchos::VERB_NONE);
00400 out->setShowAllFrontMatter(false).setShowProcRank(true).setShowLinePrefix(true).setShowTabCount(true);
00401 doAlgorithmStuff();
00402 Teuchos::VerboseObject<AlgorithmA>::setDefaultVerbLevel(Teuchos::VERB_DEFAULT);
00403
00404 *out << "\n*** Running the algorithm by setting parameters in the parameter list ...\n";
00405
00406 Teuchos::ParameterList algoParams("AlgorithmA");
00407
00408 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00409 *out << "\n*** Set AlgorithmA verbosity level to extreme through a parameter list\n\n";
00410 algoParams.sublist("VerboseObject").set("Verbosity Level","extreme");
00411 algoParams.set("Algo Type","Harry");
00412 algoParams.set("Algo Tol",0.3);
00413 doAlgorithmStuff(&algoParams);
00414
00415 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00416 *out << "\n*** Set AlgorithmA verbosity level to medium and the output file \"AlgorithmA.out\" through a parameter list\n\n";
00417 algoParams.sublist("VerboseObject").set("Verbosity Level","medium");
00418 algoParams.sublist("VerboseObject").set("Output File","AlgorithmA.out");
00419 algoParams.set("Algo Type","John");
00420 algoParams.set("Algo Tol",10);
00421 doAlgorithmStuff(&algoParams);
00422
00423 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00424 *out << "\n*** Set AlgorithmA verbosity level to low and the output back to default through a parameter list\n\n";
00425 algoParams.sublist("VerboseObject").set("Verbosity Level","low");
00426 algoParams.sublist("VerboseObject").set("Output File","none");
00427 algoParams.set("Algo Tol","20");
00428 doAlgorithmStuff(&algoParams);
00429
00430 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
00431 *out << "\n***\n*** Do some more simple tests to make sure things work correctly\n***\n\n";
00432
00433
00434
00435
00436
00437
00438 out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1).setShowTabCount(true);
00439 out->setProcRankAndSize(mpiSession.getRank(),mpiSession.getNProc());
00440
00441 *out << "\n***\n*** Testing basic FancyOStream and OSTab classes\n***\n\n";
00442
00443 *out << "\nThis is very good output\nand I like it a lot!\n";
00444 *out << "";
00445 *out << "\n";
00446 *out << "This should";
00447 *out << " all be";
00448 *out << " printed on";
00449 *out << " the same";
00450 *out << " line two lines below the above output!\n";
00451 RCP<FancyOStream>
00452 out2 = rcp(new FancyOStream(rcp(new std::ostringstream)," "));
00453 {
00454 OSTab tab(out);
00455 *out << "This should be indented one tab!\n";
00456 {
00457 OSTab tab(out);
00458 *out << "This should be indented two tabs!\n";
00459 *out2 << "This should be indented zero tabs from out2!\n";
00460 {
00461 OSTab tab(out2);
00462 *out << "This should be indented two tabs!\n";
00463 *out2 << "This should be indented one tab from out2!\n";
00464 }
00465 }
00466 *out << "This should be indented one tab!\n";
00467 }
00468 *out << "This should be indented zero tabs!\n";
00469
00470 *out << std::endl;
00471
00472 *out << "\n***\n*** Now outputting the latent output that was sent to out2\n***\n\n"
00473 << dyn_cast<std::ostringstream>(*out2->getOStream()).str();
00474
00475 if(success)
00476 *out << "\nEnd Result: TEST PASSED" << std::endl;
00477
00478 }
00479 TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
00480
00481 return ( success ? 0 : 1 );
00482
00483 }