43 #include "Teuchos_CommHelpers.hpp"
44 #include "Teuchos_DefaultComm.hpp"
47 #include "Teuchos_StandardParameterEntryValidators.hpp"
49 #include "Teuchos_StackedTimer.hpp"
53 #ifdef HAVE_TEUCHOS_ADD_TIME_MONITOR_TO_STACKED_TIMER
110 template<
class Ordinal,
class ScalarType,
class IndexType>
115 reduce (
const Ordinal count,
116 const std::pair<ScalarType, IndexType> inBuffer[],
117 std::pair<ScalarType, IndexType> inoutBuffer[])
const;
120 template<
class Ordinal>
121 class MaxLoc<Ordinal, double, int> :
125 reduce (
const Ordinal count,
126 const std::pair<double, int> inBuffer[],
127 std::pair<double, int> inoutBuffer[])
const
129 for (Ordinal ind = 0; ind < count; ++ind) {
130 const std::pair<double, int>& in = inBuffer[ind];
131 std::pair<double, int>& inout = inoutBuffer[ind];
133 if (in.first > inout.first) {
134 inout.first = in.first;
135 inout.second = in.second;
136 }
else if (in.first < inout.first) {
139 inout.first = in.first;
140 inout.second = std::min (in.second, inout.second);
172 template<
class Ordinal,
class ScalarType,
class IndexType>
177 reduce (
const Ordinal count,
178 const std::pair<ScalarType, IndexType> inBuffer[],
179 std::pair<ScalarType, IndexType> inoutBuffer[])
const;
182 template<
class Ordinal>
183 class MinLoc<Ordinal, double, int> :
187 reduce (
const Ordinal count,
188 const std::pair<double, int> inBuffer[],
189 std::pair<double, int> inoutBuffer[])
const
191 for (Ordinal ind = 0; ind < count; ++ind) {
192 const std::pair<double, int>& in = inBuffer[ind];
193 std::pair<double, int>& inout = inoutBuffer[ind];
195 if (in.first < inout.first) {
196 inout.first = in.first;
197 inout.second = in.second;
198 }
else if (in.first > inout.first) {
201 inout.first = in.first;
202 inout.second = std::min (in.second, inout.second);
211 template<
class Ordinal,
class ScalarType,
class IndexType>
216 reduce (
const Ordinal count,
217 const std::pair<ScalarType, IndexType> inBuffer[],
218 std::pair<ScalarType, IndexType> inoutBuffer[])
const;
221 template<
class Ordinal>
226 reduce (
const Ordinal count,
227 const std::pair<double, int> inBuffer[],
228 std::pair<double, int> inoutBuffer[])
const
230 for (Ordinal ind = 0; ind < count; ++ind) {
231 const std::pair<double, int>& in = inBuffer[ind];
232 std::pair<double, int>& inout = inoutBuffer[ind];
234 if ( (in.first < inout.first && in.first != 0) || (inout.first == 0 && in.first != 0) ) {
235 inout.first = in.first;
236 inout.second = in.second;
237 }
else if (in.first > inout.first) {
240 inout.first = in.first;
241 inout.second = std::min (in.second, inout.second);
251 typedef std::map<std::string, std::pair<double, int> > timer_map_t;
261 #ifdef HAVE_TEUCHOS_ADD_TIME_MONITOR_TO_STACKED_TIMER
263 stackedTimer_->start(
counter().name(),
false);
271 #ifdef HAVE_TEUCHOS_ADD_TIME_MONITOR_TO_STACKED_TIMER
274 stackedTimer_->stop(
counter().name(),
false);
276 catch (std::runtime_error&) {
277 std::ostringstream warning;
279 "\n*********************************************************************\n"
280 "WARNING: Overlapping timers detected! Near: " <<
counter().
name()<<
"\n"
281 "A TimeMonitor timer was stopped before a nested subtimer was\n"
282 "stopped. This is not allowed by the StackedTimer. This corner case\n"
283 "typically occurs if the TimeMonitor is stored in an RCP and the RCP is\n"
284 "assigned to a new timer. To disable this warning, either fix the\n"
285 "ordering of timer creation and destuction or disable the StackedTimer\n"
286 "support in the TimeMonitor by setting the StackedTimer to null\n"
288 " RCP<TimeMonitor> MM = rcp(new TimeMonitor(*(TimeMonitor::getNewTimer(\"Junk\"))));\n"
290 "MM = Teuchos::null;\n"
291 "MM = rcp(new TimeMonitor(*(TimeMonitor::getNewTimer(\"SecondJunk\"))));\n"
292 "*********************************************************************\n";
293 std::cout << warning.str() << std::endl;
305 timer == null, std::invalid_argument,
306 "TimeMonitor::disableTimer: Invalid timer \"" << name <<
"\"");
315 timer == null, std::invalid_argument,
316 "TimeMonitor::enableTimer: Invalid timer \"" << name <<
"\"");
323 typedef std::map<std::string, RCP<Time> > map_type;
324 typedef map_type::iterator iter_type;
332 for (iter_type it = ctrs.begin(); it != ctrs.end(); ++it) {
338 it->second->isRunning (), std::runtime_error,
339 "Timer \"" << it->second->name () <<
"\" is currently running. "
340 "You are not allowed to reset running timers.");
342 #endif // TEUCHOS_DEBUG
344 for (iter_type it = ctrs.begin(); it != ctrs.end(); ++it) {
345 it->second->reset ();
358 std::pair<std::string, std::pair<double, int> >
359 makeEmptyTimerDatum (
const std::string& name)
361 return std::make_pair (name, std::make_pair (
double(0),
int(0)));
382 collectLocalTimerData (timer_map_t& localData,
383 const std::map<std::string, RCP<Time> >& localCounters,
384 const std::string& filter=
"")
386 using std::make_pair;
387 typedef timer_map_t::iterator iter_t;
389 timer_map_t theLocalData;
390 for (std::map<std::string, RCP<Time> >::const_iterator it = localCounters.begin();
391 it != localCounters.end(); ++it) {
392 const std::string& name = it->second->name ();
396 const bool skipThisOne = (filter !=
"" && name.find (filter) != 0);
398 const double timing = it->second->totalElapsedTime ();
399 const int numCalls = it->second->numCalls ();
403 iter_t loc = theLocalData.find (name);
404 if (loc == theLocalData.end()) {
406 theLocalData.insert (loc, make_pair (name, make_pair (timing, numCalls)));
409 loc->second.first += timing;
410 loc->second.second += numCalls;
416 localData.swap (theLocalData);
423 filterZeroData (timer_map_t& timerData)
427 timer_map_t newTimerData;
428 for (timer_map_t::const_iterator it = timerData.begin();
429 it != timerData.end(); ++it) {
430 if (it->second.second > 0) {
431 newTimerData[it->first] = it->second;
434 timerData.swap (newTimerData);
459 collectLocalTimerDataAndNames (timer_map_t& localTimerData,
460 Array<std::string>& localTimerNames,
461 const std::map<std::string, RCP<Time> >& localTimers,
462 const bool writeZeroTimers,
463 const std::string& filter=
"")
466 collectLocalTimerData (localTimerData, localTimers, filter);
472 if (! writeZeroTimers) {
473 filterZeroData (localTimerData);
478 localTimerNames.reserve (localTimerData.size());
479 for (timer_map_t::const_iterator it = localTimerData.begin();
480 it != localTimerData.end(); ++it) {
481 localTimerNames.push_back (it->first);
520 collectGlobalTimerData (timer_map_t& globalTimerData,
521 Array<std::string>& globalTimerNames,
522 timer_map_t& localTimerData,
523 Array<std::string>& localTimerNames,
524 Ptr<
const Comm<int> > comm,
525 const bool alwaysWriteLocal,
554 const timer_map_t::size_type myNumGlobalNames = globalTimerNames.size();
555 timer_map_t::size_type minNumGlobalNames = 0;
556 timer_map_t::size_type maxNumGlobalNames = 0;
558 outArg (minNumGlobalNames));
560 outArg (maxNumGlobalNames));
562 std::logic_error,
"Min # global timer names = " << minNumGlobalNames
563 <<
" != max # global timer names = " << maxNumGlobalNames
564 <<
". Please report this bug to the Teuchos developers.");
566 std::logic_error,
"My # global timer names = " << myNumGlobalNames
567 <<
" != min # global timer names = " << minNumGlobalNames
568 <<
". Please report this bug to the Teuchos developers.");
570 #endif // TEUCHOS_DEBUG
587 timer_map_t::iterator globalMapIter = globalTimerData.begin();
588 timer_map_t::iterator localMapIter;
589 for (Array<string>::const_iterator it = globalTimerNames.begin();
590 it != globalTimerNames.end(); ++it) {
591 const std::string& globalName = *it;
592 localMapIter = localTimerData.find (globalName);
594 if (localMapIter == localTimerData.end()) {
595 if (alwaysWriteLocal) {
611 localMapIter = localTimerData.insert (localMapIter, makeEmptyTimerDatum (globalName));
616 localTimerNames.push_back (globalName);
621 globalMapIter = globalTimerData.insert (globalMapIter, makeEmptyTimerDatum (globalName));
627 globalMapIter = globalTimerData.insert (globalMapIter, std::make_pair (globalName, localMapIter->second));
631 if (alwaysWriteLocal) {
634 std::sort (localTimerNames.begin(), localTimerNames.end());
641 const timer_map_t::size_type myNumGlobalTimers = globalTimerData.size();
642 timer_map_t::size_type minNumGlobalTimers = 0;
643 timer_map_t::size_type maxNumGlobalTimers = 0;
645 outArg (minNumGlobalTimers));
647 outArg (maxNumGlobalTimers));
649 std::logic_error,
"Min # global timers = " << minNumGlobalTimers
650 <<
" != max # global timers = " << maxNumGlobalTimers
651 <<
". Please report this bug to the Teuchos developers.");
653 std::logic_error,
"My # global timers = " << myNumGlobalTimers
654 <<
" != min # global timers = " << minNumGlobalTimers
655 <<
". Please report this bug to the Teuchos developers.");
657 #endif // TEUCHOS_DEBUG
708 std::vector<std::string>& statNames,
709 Ptr<
const Comm<int> > comm,
710 const timer_map_t& globalTimerData,
711 const bool ignoreZeroTimers)
715 const int numTimers =
static_cast<int> (globalTimerData.size());
716 const int numProcs = comm->getSize();
721 Array<std::pair<double, int> > timingsAndCallCounts;
722 timingsAndCallCounts.reserve (numTimers);
723 for (timer_map_t::const_iterator it = globalTimerData.begin();
724 it != globalTimerData.end(); ++it) {
725 timingsAndCallCounts.push_back (it->second);
732 Array<std::pair<double, int> > minTimingsAndCallCounts (numTimers);
734 if (ignoreZeroTimers)
735 reduceAll (*comm, MinLocNonzero<int, double, int>(), numTimers,
736 &timingsAndCallCounts[0], &minTimingsAndCallCounts[0]);
738 reduceAll (*comm, MinLoc<int, double, int>(), numTimers,
739 &timingsAndCallCounts[0], &minTimingsAndCallCounts[0]);
746 Array<std::pair<double, int> > maxTimingsAndCallCounts (numTimers);
748 reduceAll (*comm, MaxLoc<int, double, int>(), numTimers,
749 &timingsAndCallCounts[0], &maxTimingsAndCallCounts[0]);
763 Array<double> meanOverCallCountsTimings (numTimers);
764 Array<double> meanOverProcsTimings (numTimers);
765 Array<double> meanCallCounts (numTimers);
766 Array<int> ICallThisTimer (numTimers);
767 Array<int> numProcsCallingEachTimer (numTimers);
770 if (ignoreZeroTimers) {
771 for (
int k = 0; k < numTimers; ++k) {
772 const double callCount =
static_cast<double> (timingsAndCallCounts[k].second);
773 if (callCount > 0) ICallThisTimer[k] = 1;
774 else ICallThisTimer[k] = 0;
778 &numProcsCallingEachTimer[0]);
785 Array<double> scaledTimings (numTimers);
786 Array<double> scaledCallCounts (numTimers);
787 const double P =
static_cast<double> (numProcs);
789 if (ignoreZeroTimers) {
790 for (
int k = 0; k < numTimers; ++k) {
791 const double timing = timingsAndCallCounts[k].first;
792 const double callCount =
static_cast<double> (timingsAndCallCounts[k].second);
794 scaledTimings[k] = timing / numProcsCallingEachTimer[k];
795 scaledCallCounts[k] = callCount / numProcsCallingEachTimer[k];
799 for (
int k = 0; k < numTimers; ++k) {
800 const double timing = timingsAndCallCounts[k].first;
801 const double callCount =
static_cast<double> (timingsAndCallCounts[k].second);
803 scaledTimings[k] = timing / P;
804 scaledCallCounts[k] = callCount / P;
810 &meanOverProcsTimings[0]);
816 for (
int k = 0; k < numTimers; ++k) {
817 if (meanCallCounts[k] > ScalarTraits<double>::zero ()) {
818 meanOverCallCountsTimings[k] = meanOverProcsTimings[k] / meanCallCounts[k];
830 statNames.resize (4);
831 statNames[0] =
"MinOverProcs";
832 statNames[1] =
"MeanOverProcs";
833 statNames[2] =
"MaxOverProcs";
834 statNames[3] =
"MeanOverCallCounts";
836 stat_map_type::iterator statIter = statData.end();
837 timer_map_t::const_iterator it = globalTimerData.begin();
838 for (
int k = 0; it != globalTimerData.end(); ++k, ++it) {
839 std::vector<std::pair<double, double> > curData (4);
840 curData[0] = minTimingsAndCallCounts[k];
841 curData[1] = std::make_pair (meanOverProcsTimings[k], meanCallCounts[k]);
842 curData[2] = maxTimingsAndCallCounts[k];
843 curData[3] = std::make_pair (meanOverCallCountsTimings[k], meanCallCounts[k]);
848 statIter = statData.insert (statIter, std::make_pair (it->first, curData));
869 RCP<const Comm<int> >
881 int mpiHasBeenStarted = 0;
882 MPI_Initialized (&mpiHasBeenStarted);
883 if (! mpiHasBeenStarted) {
885 comm = rcp_implicit_cast<
const Comm<int> > (
rcp (
new SerialComm<int> ()));
897 std::vector<std::string>& statNames,
900 const std::string& filter)
906 timer_map_t localTimerData;
908 const bool writeZeroTimers =
false;
909 collectLocalTimerDataAndNames (localTimerData, localTimerNames,
910 counters(), writeZeroTimers, filter);
913 timer_map_t globalTimerData;
915 const bool alwaysWriteLocal =
false;
916 collectGlobalTimerData (globalTimerData, globalTimerNames,
917 localTimerData, localTimerNames,
918 comm, alwaysWriteLocal, setOp);
920 computeGlobalTimerStats (statData, statNames, comm, globalTimerData,
false);
927 const bool alwaysWriteLocal,
928 const bool writeGlobalStats,
929 const bool writeZeroTimers,
931 const std::string& filter,
932 const bool ignoreZeroTimers)
939 const int numProcs = comm->getSize();
940 const int myRank = comm->getRank();
946 timer_map_t localTimerData;
948 collectLocalTimerDataAndNames (localTimerData, localTimerNames,
949 counters(), writeZeroTimers, filter);
955 timer_map_t globalTimerData;
958 std::vector<std::string> statNames;
959 if (writeGlobalStats) {
960 collectGlobalTimerData (globalTimerData, globalTimerNames,
961 localTimerData, localTimerNames,
962 comm, alwaysWriteLocal, setOp);
967 computeGlobalTimerStats (statData, statNames, comm, globalTimerData, ignoreZeroTimers);
973 const std::ios_base::fmtflags& flags = out.flags();
991 titles.
append (
"Timer Name");
994 TableColumn nameCol (writeGlobalStats ? globalTimerNames : localTimerNames);
995 tableColumns.
append (nameCol);
1000 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), nameCol));
1010 if (alwaysWriteLocal && numProcs > 1 && myRank == 0) {
1011 titles.
append (
"Local time (num calls)");
1017 for (timer_map_t::const_iterator it = localTimerData.begin();
1018 it != localTimerData.end(); ++it) {
1019 localTimings.
push_back (it->second.first);
1020 localNumCalls.
push_back (static_cast<double> (it->second.second));
1022 TableColumn timeAndCalls (localTimings, localNumCalls, precision, flags,
true);
1023 tableColumns.
append (timeAndCalls);
1024 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), timeAndCalls));
1027 if (writeGlobalStats) {
1032 if (numProcs == 1) {
1036 for (timer_map_t::const_iterator it = globalTimerData.begin();
1037 it != globalTimerData.end(); ++it) {
1038 globalTimings.
push_back (it->second.first);
1039 globalNumCalls.
push_back (static_cast<double> (it->second.second));
1042 titles.
append (
"Global time (num calls)");
1043 TableColumn timeAndCalls (globalTimings, globalNumCalls, precision, flags,
true);
1044 tableColumns.
append (timeAndCalls);
1045 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), timeAndCalls));
1052 const timer_map_t::size_type numGlobalTimers = globalTimerData.
size();
1053 for (std::vector<std::string>::size_type statInd = 0; statInd < statNames.size(); ++statInd) {
1058 stat_map_type::const_iterator it = statData.begin();
1059 for (
int k = 0; it != statData.end(); ++it, ++k) {
1060 statTimings[k] = (it->second[statInd]).first;
1061 statCallCounts[k] = (it->second[statInd]).second;
1064 const std::string& statisticName = statNames[statInd];
1065 const std::string titleString = statisticName;
1066 titles.
append (titleString);
1067 TableColumn timeAndCalls (statTimings, statCallCounts, precision, flags,
true);
1068 tableColumns.
append (timeAndCalls);
1069 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), timeAndCalls));
1077 std::ostringstream theTitle;
1078 theTitle <<
"TimeMonitor results over " << numProcs <<
" processor"
1079 << (numProcs > 1 ?
"s" :
"");
1086 const bool alwaysWriteLocal,
1087 const bool writeGlobalStats,
1088 const bool writeZeroTimers,
1090 const std::string& filter,
1091 const bool ignoreZeroTimers)
1099 writeGlobalStats, writeZeroTimers, setOp, filter, ignoreZeroTimers);
1104 std::vector<std::string>& statNames,
1106 const std::string& filter)
1142 quoteLabelForYaml (
const std::string& label)
1147 if (label.empty ()) {
1154 const bool alreadyQuoted = label.size () >= 2 &&
1155 label[0] ==
'"' && label[label.size() - 1] ==
'"';
1160 bool needToQuote =
false;
1163 out.reserve (label.size ());
1165 const size_t startPos = alreadyQuoted ? 1 : 0;
1166 const size_t endPos = alreadyQuoted ? label.size () - 1 : label.size ();
1167 for (
size_t i = startPos; i < endPos; ++i) {
1168 const char c = label[i];
1169 if (c ==
'"' || c ==
'\\') {
1170 out.push_back (
'\\');
1173 else if (c ==
':') {
1179 if (needToQuote || alreadyQuoted) {
1182 return "\"" + out +
"\"";
1193 summarizeToYaml (Ptr<
const Comm<int> > comm,
1195 const ETimeMonitorYamlFormat yamlStyle,
1196 const std::string& filter)
1199 using Teuchos::fancyOStream;
1200 using Teuchos::getFancyOStream;
1203 using Teuchos::rcpFromRef;
1205 typedef std::vector<std::string>::size_type size_type;
1207 const bool compact = (yamlStyle == YAML_FORMAT_COMPACT);
1215 std::vector<std::string> statNames;
1218 const int numProcs = comm->getSize();
1231 RCP<FancyOStream> pfout = getFancyOStream (rcpFromRef (out));
1232 pfout->setTabIndentStr (
" ");
1235 fout <<
"# Teuchos::TimeMonitor report" << endl
1247 fout <<
"Output mode: " << (compact ?
"compact" :
"spacious") << endl
1248 <<
"Number of processes: " << numProcs << endl
1249 <<
"Time unit: s" << endl;
1253 fout <<
"Statistics collected: ";
1257 for (size_type i = 0; i < statNames.size (); ++i) {
1258 fout << quoteLabelForYaml (statNames[i]);
1259 if (i + 1 < statNames.size ()) {
1263 fout <<
"]" << endl;
1268 for (size_type i = 0; i < statNames.size (); ++i) {
1269 fout <<
"- " << quoteLabelForYaml (statNames[i]) << endl;
1278 fout <<
"Timer names: ";
1282 for (stat_map_type::const_iterator it = statData.begin();
1283 it != statData.end(); ++it, ++ind) {
1284 fout << quoteLabelForYaml (it->first);
1285 if (ind + 1 < statData.size ()) {
1289 fout <<
"]" << endl;
1294 for (stat_map_type::const_iterator it = statData.begin();
1295 it != statData.end(); ++it) {
1296 fout <<
"- " << quoteLabelForYaml (it->first) << endl;
1301 fout <<
"Total times: ";
1304 size_type outerInd = 0;
1305 for (stat_map_type::const_iterator outerIter = statData.begin();
1306 outerIter != statData.end(); ++outerIter, ++outerInd) {
1308 fout << quoteLabelForYaml (outerIter->first) <<
": ";
1310 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1312 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1313 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1314 << curData[innerInd].first;
1315 if (innerInd + 1 < curData.size ()) {
1320 if (outerInd + 1 < statData.size ()) {
1324 fout <<
"}" << endl;
1329 size_type outerInd = 0;
1330 for (stat_map_type::const_iterator outerIter = statData.begin();
1331 outerIter != statData.end(); ++outerIter, ++outerInd) {
1333 fout << quoteLabelForYaml (outerIter->first) <<
": " << endl;
1336 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1337 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1338 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1339 << curData[innerInd].first << endl;
1345 fout <<
"Call counts:";
1348 size_type outerInd = 0;
1349 for (stat_map_type::const_iterator outerIter = statData.begin();
1350 outerIter != statData.end(); ++outerIter, ++outerInd) {
1352 fout << quoteLabelForYaml (outerIter->first) <<
": ";
1354 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1356 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1357 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1358 << curData[innerInd].second;
1359 if (innerInd + 1 < curData.size ()) {
1364 if (outerInd + 1 < statData.size ()) {
1368 fout <<
"}" << endl;
1373 size_type outerInd = 0;
1374 for (stat_map_type::const_iterator outerIter = statData.begin();
1375 outerIter != statData.end(); ++outerIter, ++outerInd) {
1377 fout << quoteLabelForYaml (outerIter->first) <<
": " << endl;
1380 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1381 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1382 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1383 << curData[innerInd].second << endl;
1390 summarizeToYaml (std::ostream &out,
1391 const ETimeMonitorYamlFormat yamlStyle,
1392 const std::string& filter)
1397 RCP<const Comm<int> > comm = getDefaultComm ();
1399 summarizeToYaml (comm.ptr (), out, yamlStyle, filter);
1404 bool TimeMonitor::setParams_ =
false;
1407 TimeMonitor::ETimeMonitorReportFormat TimeMonitor::reportFormat_ = TimeMonitor::REPORT_FORMAT_TABLE;
1408 TimeMonitor::ETimeMonitorYamlFormat TimeMonitor::yamlStyle_ = TimeMonitor::YAML_FORMAT_SPACIOUS;
1410 bool TimeMonitor::alwaysWriteLocal_ =
false;
1411 bool TimeMonitor::writeGlobalStats_ =
true;
1412 bool TimeMonitor::writeZeroTimers_ =
true;
1415 TimeMonitor::setReportFormatParameter (ParameterList& plist)
1417 const std::string name (
"Report format");
1418 const std::string defaultValue (
"Table");
1419 const std::string docString (
"Output format for report of timer statistics");
1420 Array<std::string> strings;
1421 Array<std::string> docs;
1422 Array<ETimeMonitorReportFormat> values;
1424 strings.push_back (
"YAML");
1425 docs.push_back (
"YAML (see yaml.org) format");
1426 values.push_back (REPORT_FORMAT_YAML);
1427 strings.push_back (
"Table");
1428 docs.push_back (
"Tabular format via Teuchos::TableFormat");
1429 values.push_back (REPORT_FORMAT_TABLE);
1431 setStringToIntegralParameter<ETimeMonitorReportFormat> (name, defaultValue,
1433 strings (), docs (),
1438 TimeMonitor::setYamlFormatParameter (ParameterList& plist)
1440 const std::string name (
"YAML style");
1441 const std::string defaultValue (
"spacious");
1442 const std::string docString (
"YAML-specific output format");
1443 Array<std::string> strings;
1444 Array<std::string> docs;
1445 Array<ETimeMonitorYamlFormat> values;
1447 strings.push_back (
"compact");
1448 docs.push_back (
"Compact format: use \"flow style\" (see YAML 1.2 spec at "
1449 "yaml.org) for most sequences except the outermost sequence");
1450 values.push_back (YAML_FORMAT_COMPACT);
1452 strings.push_back (
"spacious");
1453 docs.push_back (
"Spacious format: avoid flow style");
1454 values.push_back (YAML_FORMAT_SPACIOUS);
1456 setStringToIntegralParameter<ETimeMonitorYamlFormat> (name, defaultValue,
1458 strings (), docs (),
1463 TimeMonitor::setSetOpParameter (ParameterList& plist)
1465 const std::string name (
"How to merge timer sets");
1466 const std::string defaultValue (
"Intersection");
1467 const std::string docString (
"How to merge differing sets of timers "
1468 "across processes");
1469 Array<std::string> strings;
1470 Array<std::string> docs;
1471 Array<ECounterSetOp> values;
1473 strings.push_back (
"Intersection");
1474 docs.push_back (
"Compute intersection of timer sets over processes");
1475 values.push_back (Intersection);
1476 strings.push_back (
"Union");
1477 docs.push_back (
"Compute union of timer sets over processes");
1478 values.push_back (Union);
1480 setStringToIntegralParameter<ECounterSetOp> (name, defaultValue, docString,
1481 strings (), docs (), values (),
1494 return stackedTimer_;
1505 const bool alwaysWriteLocal =
false;
1506 const bool writeGlobalStats =
true;
1507 const bool writeZeroTimers =
true;
1509 setReportFormatParameter (*plist);
1510 setYamlFormatParameter (*plist);
1511 setSetOpParameter (*plist);
1512 plist->set (
"alwaysWriteLocal", alwaysWriteLocal,
1513 "Always output local timers' values on Proc 0");
1514 plist->set (
"writeGlobalStats", writeGlobalStats,
"Always output global "
1515 "statistics, even if there is only one process in the "
1517 plist->set (
"writeZeroTimers", writeZeroTimers,
"Generate output for "
1518 "timers that have never been called");
1526 ETimeMonitorReportFormat reportFormat = REPORT_FORMAT_TABLE;
1527 ETimeMonitorYamlFormat yamlStyle = YAML_FORMAT_SPACIOUS;
1529 bool alwaysWriteLocal =
false;
1530 bool writeGlobalStats =
true;
1531 bool writeZeroTimers =
true;
1543 reportFormat = getIntegralValue<ETimeMonitorReportFormat> (*params,
"Report format");
1544 yamlStyle = getIntegralValue<ETimeMonitorYamlFormat> (*params,
"YAML style");
1545 setOp = getIntegralValue<ECounterSetOp> (*params,
"How to merge timer sets");
1546 alwaysWriteLocal = params->
get<
bool> (
"alwaysWriteLocal");
1547 writeGlobalStats = params->get<
bool> (
"writeGlobalStats");
1548 writeZeroTimers = params->get<
bool> (
"writeZeroTimers");
1553 reportFormat_ = reportFormat;
1554 yamlStyle_ = yamlStyle;
1556 alwaysWriteLocal_ = alwaysWriteLocal;
1557 writeGlobalStats_ = writeGlobalStats;
1558 writeZeroTimers_ = writeZeroTimers;
1566 const std::string& filter,
1569 setReportParameters (params);
1571 if (reportFormat_ == REPORT_FORMAT_YAML) {
1572 summarizeToYaml (comm, out, yamlStyle_, filter);
1574 else if (reportFormat_ == REPORT_FORMAT_TABLE) {
1575 summarize (comm, out, alwaysWriteLocal_, writeGlobalStats_,
1576 writeZeroTimers_, setOp_, filter);
1580 "Invalid report format. This should never happen; ParameterList "
1581 "validation should have caught this. Please report this bug to the "
1582 "Teuchos developers.");
1591 report (comm, out,
"", params);
1596 const std::string& filter,
1600 report (comm.
ptr (), out, filter, params);
static Teuchos::RCP< Teuchos::StackedTimer > getStackedTimer()
The StackedTimer used by the TimeMonitor.
Array< T > & append(const T &x)
Add a new entry at the end of the array.
std::map< std::string, std::vector< std::pair< double, double > > > stat_map_type
Global statistics collected from timer data.
basic_OSTab< char > OSTab
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
basic_FancyOStream< char > FancyOStream
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
TimeMonitor()=delete
Default constructor is deleted, since it would be unsafe.
static void disableTimer(const std::string &name)
Disable the timer with the given name.
Teuchos version of MPI_MINLOC.
void reduce(const Ordinal count, const std::pair< ScalarType, IndexType > inBuffer[], std::pair< ScalarType, IndexType > inoutBuffer[]) const
T * get() const
Get the raw C++ pointer to the underlying object.
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
Return the default global communicator.
static RCP< const ParameterList > getValidReportParameters()
Default parameters (with validators) for report().
This structure defines some basic traits for a scalar field type.
Teuchos version of MPI_MAXLOC.
Base interface class for user-defined reduction operations for objects that use value semantics...
void reduce(const Ordinal count, const std::pair< ScalarType, IndexType > inBuffer[], std::pair< ScalarType, IndexType > inoutBuffer[]) const
void start(bool reset=false)
Start the timer, if the timer is enabled (see disable()).
~TimeMonitor() override
Destructor: stops the timer.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
A column of TableEntry objects.
static void summarize(Ptr< const Comm< int > > comm, std::ostream &out=std::cout, const bool alwaysWriteLocal=false, const bool writeGlobalStats=true, const bool writeZeroTimers=true, const ECounterSetOp setOp=Intersection, const std::string &filter="", const bool ignoreZeroTimers=false)
Print summary statistics for all timers on the given communicator.
double stop()
Stop the timer, if the timer is enabled (see disable()).
Ptr< T > ptr() const
Get a safer wrapper raw C++ pointer to the underlying object.
static void computeGlobalTimerStatistics(stat_map_type &statData, std::vector< std::string > &statNames, Ptr< const Comm< int > > comm, const ECounterSetOp setOp=Intersection, const std::string &filter="")
Compute global timer statistics for all timers on the given communicator.
static void setStackedTimer(const Teuchos::RCP< Teuchos::StackedTimer > &t)
Sets the StackedTimer into which the TimeMonitor will insert timings.
void reduce(const Ordinal count, const std::pair< ScalarType, IndexType > inBuffer[], std::pair< ScalarType, IndexType > inoutBuffer[]) const
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
Deprecated .
void mergeCounterNames(const Comm< int > &comm, const Array< std::string > &localNames, Array< std::string > &globalNames, const ECounterSetOp setOp)
Merge counter names over all processors.
const std::string & name() const
The name of this timer.
A list of parameters of arbitrary type.
Abstract interface for distributed-memory communication.
void push_back(const value_type &x)
Defines basic traits for the scalar field type.
static T zero()
Returns representation of zero for this scalar type.
Scope guard for Teuchos::Time, with MPI collective timer reporting.
Smart reference counting pointer class for automatic garbage collection.
This class allows one to push and pop timers on and off a stack.
ECounterSetOp
Set operation type for mergeCounterNames() to perform.
same as MinLoc, but don't allow zero
Simple wrapper class for raw pointers to single objects where no persisting relationship exists...
static void enableTimer(const std::string &name)
Enable the timer with the given name.
static void zeroOutTimers()
Reset all global timers to zero.
static void report(Ptr< const Comm< int > > comm, std::ostream &out, const std::string &filter, const RCP< ParameterList > ¶ms=null)
Report timer statistics to the given output stream.
bool is_null() const
Returns true if the underlying pointer is null.