#include "Teuchos_VerboseObject.hpp"
#include "Teuchos_StandardCatchMacros.hpp"
#include "Teuchos_GlobalMPISession.hpp"
#include "Teuchos_CommandLineProcessor.hpp"
#include "Teuchos_ParameterListAcceptor.hpp"
#include "Teuchos_StandardParameterEntryValidators.hpp"
#include "Teuchos_VerboseObjectParameterListHelpers.hpp"
#include "Teuchos_dyn_cast.hpp"
#include "Teuchos_Version.hpp"
void someDumbFunction( std::ostream &out, const std::string &indentSpacer )
{
out << "\nEntering someDumbFunction(...)\n";
{
out << std::endl << indentSpacer << "I am \"dumb\" code that knows nothing of FancyOStream and does indenting manually! ...\n";
}
out << "\nLeaving someDumbFunction(...)\n";
}
void someLessDumbFunction( std::ostream &out_arg )
{
using Teuchos::OSTab;
Teuchos::RCP<Teuchos::FancyOStream>
out = Teuchos::getFancyOStream(Teuchos::rcp(&out_arg,false));
OSTab tab(out,1,"LDUMBALGO");
*out << "\nEntering someLessDumbFunction(...)\n";
{
Teuchos::OSTab(out_arg).o()
<< std::endl << "I am less \"dumb\" code that knows about FancyOStream but my interface does not support it directly! ...\n";
*Teuchos::tab(out)
<< std::endl << "Another print from this less \"dumb\" code ...\n";
}
*out << "\nLeaving someLessDumbFunction(...)\n";
}
class AlgorithmA
: public Teuchos::VerboseObject<AlgorithmA>,
public Teuchos::ParameterListAcceptor
{
public:
AlgorithmA();
void setParameterList(Teuchos::RCP<Teuchos::ParameterList> const& paramList);
Teuchos::RCP<Teuchos::ParameterList> getNonconstParameterList();
Teuchos::RCP<Teuchos::ParameterList> unsetParameterList();
Teuchos::RCP<const Teuchos::ParameterList> getParameterList() const;
Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const;
void doAlgorithm();
private:
enum EAlgoType { ALGO_BOB, ALGO_JOHN, ALGO_HARRY };
static const std::string toString( AlgorithmA::EAlgoType algoType );
Teuchos::RCP<Teuchos::ParameterList> paramList_;
EAlgoType algoType_;
double algoTol_;
};
namespace {
const std::string AlgoType_name = "Algo Type";
const std::string AlgoType_default = "Bob";
const std::string AlgoTol_name = "Algo Tol";
const double AlgoTol_default = 1e-5;
}
const std::string AlgorithmA::toString( AlgorithmA::EAlgoType algoType )
{
switch(algoType) {
case ALGO_BOB: return "Bob";
case ALGO_JOHN: return "John";
case ALGO_HARRY: return "Harry";
default: TEST_FOR_EXCEPT("Should never get here!");
}
return "";
}
AlgorithmA::AlgorithmA()
: algoType_(ALGO_BOB), algoTol_(AlgoTol_default)
{
this->setLinePrefix("ALGO_A");
}
void AlgorithmA::setParameterList(
Teuchos::RCP<Teuchos::ParameterList> const& paramList
)
{
TEST_FOR_EXCEPT(is_null(paramList));
paramList->validateParametersAndSetDefaults(*this->getValidParameters(),0);
paramList_ = paramList;
algoType_ = Teuchos::getIntegralValue<EAlgoType>(*paramList_,AlgoType_name);
algoTol_ = Teuchos::getParameter<double>(*paramList_,AlgoTol_name);
Teuchos::readVerboseObjectSublist(&*paramList_,this);
#ifdef TEUCHOS_DEBUG
paramList_->validateParameters(*this->getValidParameters());
#endif
}
Teuchos::RCP<Teuchos::ParameterList>
AlgorithmA::getNonconstParameterList()
{
return paramList_;
}
Teuchos::RCP<Teuchos::ParameterList>
AlgorithmA::unsetParameterList()
{
Teuchos::RCP<Teuchos::ParameterList> paramList = paramList_;
paramList_ = Teuchos::null;
return paramList;
}
Teuchos::RCP<const Teuchos::ParameterList>
AlgorithmA::getParameterList() const
{
return paramList_;
}
Teuchos::RCP<const Teuchos::ParameterList>
AlgorithmA::getValidParameters() const
{
using Teuchos::RCP; using Teuchos::ParameterList;
using Teuchos::setStringToIntegralParameter;
using Teuchos::tuple;
static RCP<const ParameterList> validParams;
if (is_null(validParams)) {
RCP<ParameterList>
pl = Teuchos::rcp(new ParameterList("AlgorithmA"));
setStringToIntegralParameter<EAlgoType>(
AlgoType_name, AlgoType_default,
"The algorithm type to use",
tuple<std::string>("Bob", "John", "Harry"),
tuple<EAlgoType>(ALGO_BOB, ALGO_JOHN, ALGO_HARRY),
&*pl
);
Teuchos::setDoubleParameter(
AlgoTol_name, AlgoTol_default,
"The tolerance for the algorithm.",
&*pl
);
Teuchos::setupVerboseObjectSublist(&*pl);
validParams = pl;
}
return validParams;
}
void AlgorithmA::doAlgorithm()
{
using Teuchos::OSTab;
Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
OSTab tab = this->getOSTab();
if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
*out << "\nEntering AlgorithmA::doAlgorithm() with verbLevel="<<Teuchos::toString(verbLevel)<<"\n";
{
TEUCHOS_OSTAB;
if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
*out
<< "\nI am \"smart\" code that knows about FancyOStream and OSTab ...\n"
<< "\nDoing algorithm of type \""<<toString(algoType_)<<"\""
<< "\nUsing tolerance of " << algoTol_ << "\n";
{
OSTab tab2 = this->getOSTab(OSTab::DISABLE_TABBING);
if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
*out << "\n***\n*** Warning, I am doing something very dangerous so watch out!!!\n***\n";
}
if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
*out << "\nHere I am doing some more stuff and printing with indenting turned back on!\n";
{
OSTab tab2 = this->getOSTab(1,"DUMBALGO");
someDumbFunction(*out,out->getTabIndentStr());
}
someLessDumbFunction(*out);
}
if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
*out << "\nLeaving AlgorithmA::doAlgorithm()\n";
}
void doAlgorithmStuff( Teuchos::ParameterList *algoParams = 0 )
{
AlgorithmA algoA;
if(algoParams)
algoA.setParameterList(Teuchos::rcp(algoParams,false));
algoA.doAlgorithm();
*algoA.getOStream() << std::endl;
}
class TestVerboseObjectBaseInitialization {
public:
TestVerboseObjectBaseInitialization()
{
Teuchos::EVerbosityLevel verbLevel = Teuchos::VerboseObject<AlgorithmA>::getDefaultVerbLevel();
TEST_FOR_EXCEPT_PRINT(verbLevel!=Teuchos::VERB_DEFAULT,&std::cerr);
*Teuchos::VerboseObjectBase::getDefaultOStream()
<< "\n***\n*** Printing to default OStream before main() even starts!\n***\n\n"
<< std::flush;
}
};
static TestVerboseObjectBaseInitialization testVerboseObjectBaseInitialization;
int main(int argc, char* argv[])
{
using Teuchos::RCP;
using Teuchos::rcp;
using Teuchos::FancyOStream;
using Teuchos::VerboseObjectBase;
using Teuchos::OSTab;
using Teuchos::dyn_cast;
using Teuchos::CommandLineProcessor;
bool success = true;
Teuchos::GlobalMPISession mpiSession(&argc,&argv);
const int numProcs = Teuchos::GlobalMPISession::getNProc();
try {
CommandLineProcessor clp;
clp.throwExceptions(false);
clp.addOutputSetupOptions(true);
CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
RCP<FancyOStream>
out = VerboseObjectBase::getDefaultOStream();
*out << std::endl << Teuchos::Teuchos_Version() << std::endl << std::endl;
*out << "\n***\n*** Testing VerboseObject base class use\n***\n";
*out << "\n*** Algorithm output with default formatting\n\n";
doAlgorithmStuff();
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Algorithm output with no front matter\n\n";
out->setShowAllFrontMatter(false);
doAlgorithmStuff();
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Algorithm output with processor ranks\n\n";
out->setShowAllFrontMatter(false).setShowProcRank(true);
doAlgorithmStuff();
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Algorithm output with line prefix names\n\n";
out->setShowAllFrontMatter(false).setShowLinePrefix(true);
doAlgorithmStuff();
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Algorithm output with tab counts\n\n";
out->setShowAllFrontMatter(false).setShowTabCount(true);
doAlgorithmStuff();
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Algorithm output with line prefix names and tab counts\n\n";
out->setShowAllFrontMatter(false).setShowLinePrefix(true).setShowTabCount(true);
doAlgorithmStuff();
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Algorithm output with processor ranks and line prefix names\n\n";
out->setShowAllFrontMatter(false).setShowProcRank(true).setShowLinePrefix(true);
doAlgorithmStuff();
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Algorithm output with processor ranks and tab counts\n\n";
out->setShowAllFrontMatter(false).setShowProcRank(true).setShowTabCount(true);
doAlgorithmStuff();
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Algorithm output with processor ranks, line prefix names, and tab counts\n\n";
out->setShowAllFrontMatter(false).setShowProcRank(true).setShowLinePrefix(true).setShowTabCount(true);
doAlgorithmStuff();
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Algorithm output with processor ranks, line prefix names, and tab counts but no output for AlgorithmA\n\n";
Teuchos::VerboseObject<AlgorithmA>::setDefaultVerbLevel(Teuchos::VERB_NONE);
out->setShowAllFrontMatter(false).setShowProcRank(true).setShowLinePrefix(true).setShowTabCount(true);
doAlgorithmStuff();
Teuchos::VerboseObject<AlgorithmA>::setDefaultVerbLevel(Teuchos::VERB_DEFAULT);
*out << "\n*** Running the algorithm by setting parameters in the parameter list ...\n";
Teuchos::ParameterList algoParams("AlgorithmA");
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Set AlgorithmA verbosity level to extreme through a parameter list\n\n";
algoParams.sublist("VerboseObject").set("Verbosity Level","extreme");
algoParams.set("Algo Type","Harry");
algoParams.set("Algo Tol",0.3);
doAlgorithmStuff(&algoParams);
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Set AlgorithmA verbosity level to medium and the output file \"AlgorithmA.out\" through a parameter list\n\n";
algoParams.sublist("VerboseObject").set("Verbosity Level","medium");
algoParams.sublist("VerboseObject").set("Output File","AlgorithmA.out");
algoParams.set("Algo Type","John");
algoParams.set("Algo Tol",10);
doAlgorithmStuff(&algoParams);
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n*** Set AlgorithmA verbosity level to low and the output back to default through a parameter list\n\n";
algoParams.sublist("VerboseObject").set("Verbosity Level","low");
algoParams.sublist("VerboseObject").set("Output File","none");
algoParams.set("Algo Tol","20");
doAlgorithmStuff(&algoParams);
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
*out << "\n***\n*** Do some more simple tests to make sure things work correctly\n***\n\n";
out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1).setShowTabCount(true);
out->setProcRankAndSize(mpiSession.getRank(),mpiSession.getNProc());
*out << "\n***\n*** Testing basic FancyOStream and OSTab classes\n***\n\n";
*out << "\nThis is very good output\nand I like it a lot!\n";
*out << "";
*out << "\n";
*out << "This should";
*out << " all be";
*out << " printed on";
*out << " the same";
*out << " line two lines below the above output!\n";
RCP<FancyOStream>
out2 = rcp(new FancyOStream(rcp(new std::ostringstream)," "));
{
OSTab tab1(out);
*out << "This should be indented one tab!\n";
{
OSTab tab2(out);
*out << "This should be indented two tabs!\n";
*out2 << "This should be indented zero tabs from out2!\n";
{
OSTab tab3(out2);
*out << "This should be indented two tabs!\n";
*out2 << "This should be indented one tab from out2!\n";
}
}
*out << "This should be indented one tab!\n";
}
*out << "This should be indented zero tabs!\n";
*out << std::endl;
*out << "\n***\n*** Now outputting the latent output that was sent to out2\n***\n\n"
<< dyn_cast<std::ostringstream>(*out2->getOStream()).str();
if(success)
*out << "\nEnd Result: TEST PASSED" << std::endl;
}
TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
return ( success ? 0 : 1 );
}