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
271 #ifdef HAVE_TEUCHOS_ADD_TIME_MONITOR_TO_STACKED_TIMER
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;
557 reduceAll (*comm,
REDUCE_MIN, myNumGlobalNames,
558 outArg (minNumGlobalNames));
559 reduceAll (*comm,
REDUCE_MAX, myNumGlobalNames,
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;
644 reduceAll (*comm,
REDUCE_MIN, myNumGlobalTimers,
645 outArg (minNumGlobalTimers));
646 reduceAll (*comm,
REDUCE_MAX, myNumGlobalTimers,
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;
777 reduceAll (*comm,
REDUCE_SUM, numTimers, &ICallThisTimer[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;
809 reduceAll (*comm,
REDUCE_SUM, numTimers, &scaledTimings[0],
810 &meanOverProcsTimings[0]);
811 reduceAll (*comm,
REDUCE_SUM, numTimers, &scaledCallCounts[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)
1150 quoteLabelForYaml (
const std::string& label)
1155 if (label.empty ()) {
1162 const bool alreadyQuoted = label.size () >= 2 &&
1163 label[0] ==
'"' && label[label.size() - 1] ==
'"';
1168 bool needToQuote =
false;
1171 out.reserve (label.size ());
1173 const size_t startPos = alreadyQuoted ? 1 : 0;
1174 const size_t endPos = alreadyQuoted ? label.size () - 1 : label.size ();
1175 for (
size_t i = startPos; i < endPos; ++i) {
1176 const char c = label[i];
1177 if (c ==
'"' || c ==
'\\') {
1178 out.push_back (
'\\');
1181 else if (c ==
':') {
1187 if (needToQuote || alreadyQuoted) {
1190 return "\"" + out +
"\"";
1201 summarizeToYaml (Ptr<
const Comm<int> > comm,
1203 const ETimeMonitorYamlFormat yamlStyle,
1204 const std::string& filter)
1207 using Teuchos::fancyOStream;
1208 using Teuchos::getFancyOStream;
1211 using Teuchos::rcpFromRef;
1213 typedef std::vector<std::string>::size_type size_type;
1215 const bool compact = (yamlStyle == YAML_FORMAT_COMPACT);
1223 std::vector<std::string> statNames;
1226 const int numProcs = comm->getSize();
1239 RCP<FancyOStream> pfout = getFancyOStream (rcpFromRef (out));
1240 pfout->setTabIndentStr (
" ");
1243 fout <<
"# Teuchos::TimeMonitor report" << endl
1255 fout <<
"Output mode: " << (compact ?
"compact" :
"spacious") << endl
1256 <<
"Number of processes: " << numProcs << endl
1257 <<
"Time unit: s" << endl;
1261 fout <<
"Statistics collected: ";
1265 for (size_type i = 0; i < statNames.size (); ++i) {
1266 fout << quoteLabelForYaml (statNames[i]);
1267 if (i + 1 < statNames.size ()) {
1271 fout <<
"]" << endl;
1276 for (size_type i = 0; i < statNames.size (); ++i) {
1277 fout <<
"- " << quoteLabelForYaml (statNames[i]) << endl;
1286 fout <<
"Timer names: ";
1290 for (stat_map_type::const_iterator it = statData.begin();
1291 it != statData.end(); ++it, ++ind) {
1292 fout << quoteLabelForYaml (it->first);
1293 if (ind + 1 < statData.size ()) {
1297 fout <<
"]" << endl;
1302 for (stat_map_type::const_iterator it = statData.begin();
1303 it != statData.end(); ++it) {
1304 fout <<
"- " << quoteLabelForYaml (it->first) << endl;
1309 fout <<
"Total times: ";
1312 size_type outerInd = 0;
1313 for (stat_map_type::const_iterator outerIter = statData.begin();
1314 outerIter != statData.end(); ++outerIter, ++outerInd) {
1316 fout << quoteLabelForYaml (outerIter->first) <<
": ";
1318 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1320 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1321 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1322 << curData[innerInd].first;
1323 if (innerInd + 1 < curData.size ()) {
1328 if (outerInd + 1 < statData.size ()) {
1332 fout <<
"}" << endl;
1337 size_type outerInd = 0;
1338 for (stat_map_type::const_iterator outerIter = statData.begin();
1339 outerIter != statData.end(); ++outerIter, ++outerInd) {
1341 fout << quoteLabelForYaml (outerIter->first) <<
": " << endl;
1344 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1345 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1346 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1347 << curData[innerInd].first << endl;
1353 fout <<
"Call counts:";
1356 size_type outerInd = 0;
1357 for (stat_map_type::const_iterator outerIter = statData.begin();
1358 outerIter != statData.end(); ++outerIter, ++outerInd) {
1360 fout << quoteLabelForYaml (outerIter->first) <<
": ";
1362 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1364 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1365 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1366 << curData[innerInd].second;
1367 if (innerInd + 1 < curData.size ()) {
1372 if (outerInd + 1 < statData.size ()) {
1376 fout <<
"}" << endl;
1381 size_type outerInd = 0;
1382 for (stat_map_type::const_iterator outerIter = statData.begin();
1383 outerIter != statData.end(); ++outerIter, ++outerInd) {
1385 fout << quoteLabelForYaml (outerIter->first) <<
": " << endl;
1388 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1389 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1390 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1391 << curData[innerInd].second << endl;
1398 summarizeToYaml (std::ostream &out,
1399 const ETimeMonitorYamlFormat yamlStyle,
1400 const std::string& filter)
1405 RCP<const Comm<int> > comm = getDefaultComm ();
1407 summarizeToYaml (comm.ptr (), out, yamlStyle, filter);
1412 bool TimeMonitor::setParams_ =
false;
1415 TimeMonitor::ETimeMonitorReportFormat TimeMonitor::reportFormat_ = TimeMonitor::REPORT_FORMAT_TABLE;
1416 TimeMonitor::ETimeMonitorYamlFormat TimeMonitor::yamlStyle_ = TimeMonitor::YAML_FORMAT_SPACIOUS;
1418 bool TimeMonitor::alwaysWriteLocal_ =
false;
1419 bool TimeMonitor::writeGlobalStats_ =
true;
1420 bool TimeMonitor::writeZeroTimers_ =
true;
1423 TimeMonitor::setReportFormatParameter (ParameterList& plist)
1425 const std::string name (
"Report format");
1426 const std::string defaultValue (
"Table");
1427 const std::string docString (
"Output format for report of timer statistics");
1428 Array<std::string> strings;
1429 Array<std::string> docs;
1430 Array<ETimeMonitorReportFormat> values;
1432 strings.push_back (
"YAML");
1433 docs.push_back (
"YAML (see yaml.org) format");
1434 values.push_back (REPORT_FORMAT_YAML);
1435 strings.push_back (
"Table");
1436 docs.push_back (
"Tabular format via Teuchos::TableFormat");
1437 values.push_back (REPORT_FORMAT_TABLE);
1439 setStringToIntegralParameter<ETimeMonitorReportFormat> (name, defaultValue,
1441 strings (), docs (),
1446 TimeMonitor::setYamlFormatParameter (ParameterList& plist)
1448 const std::string name (
"YAML style");
1449 const std::string defaultValue (
"spacious");
1450 const std::string docString (
"YAML-specific output format");
1451 Array<std::string> strings;
1452 Array<std::string> docs;
1453 Array<ETimeMonitorYamlFormat> values;
1455 strings.push_back (
"compact");
1456 docs.push_back (
"Compact format: use \"flow style\" (see YAML 1.2 spec at "
1457 "yaml.org) for most sequences except the outermost sequence");
1458 values.push_back (YAML_FORMAT_COMPACT);
1460 strings.push_back (
"spacious");
1461 docs.push_back (
"Spacious format: avoid flow style");
1462 values.push_back (YAML_FORMAT_SPACIOUS);
1464 setStringToIntegralParameter<ETimeMonitorYamlFormat> (name, defaultValue,
1466 strings (), docs (),
1471 TimeMonitor::setSetOpParameter (ParameterList& plist)
1473 const std::string name (
"How to merge timer sets");
1474 const std::string defaultValue (
"Intersection");
1475 const std::string docString (
"How to merge differing sets of timers "
1476 "across processes");
1477 Array<std::string> strings;
1478 Array<std::string> docs;
1479 Array<ECounterSetOp> values;
1481 strings.push_back (
"Intersection");
1482 docs.push_back (
"Compute intersection of timer sets over processes");
1483 values.push_back (Intersection);
1484 strings.push_back (
"Union");
1485 docs.push_back (
"Compute union of timer sets over processes");
1486 values.push_back (Union);
1488 setStringToIntegralParameter<ECounterSetOp> (name, defaultValue, docString,
1489 strings (), docs (), values (),
1513 const bool alwaysWriteLocal =
false;
1514 const bool writeGlobalStats =
true;
1515 const bool writeZeroTimers =
true;
1517 setReportFormatParameter (*plist);
1518 setYamlFormatParameter (*plist);
1519 setSetOpParameter (*plist);
1520 plist->set (
"alwaysWriteLocal", alwaysWriteLocal,
1521 "Always output local timers' values on Proc 0");
1522 plist->set (
"writeGlobalStats", writeGlobalStats,
"Always output global "
1523 "statistics, even if there is only one process in the "
1525 plist->set (
"writeZeroTimers", writeZeroTimers,
"Generate output for "
1526 "timers that have never been called");
1534 ETimeMonitorReportFormat reportFormat = REPORT_FORMAT_TABLE;
1535 ETimeMonitorYamlFormat yamlStyle = YAML_FORMAT_SPACIOUS;
1537 bool alwaysWriteLocal =
false;
1538 bool writeGlobalStats =
true;
1539 bool writeZeroTimers =
true;
1551 reportFormat = getIntegralValue<ETimeMonitorReportFormat> (*params,
"Report format");
1552 yamlStyle = getIntegralValue<ETimeMonitorYamlFormat> (*params,
"YAML style");
1553 setOp = getIntegralValue<ECounterSetOp> (*params,
"How to merge timer sets");
1554 alwaysWriteLocal = params->
get<
bool> (
"alwaysWriteLocal");
1555 writeGlobalStats = params->get<
bool> (
"writeGlobalStats");
1556 writeZeroTimers = params->get<
bool> (
"writeZeroTimers");
1561 reportFormat_ = reportFormat;
1562 yamlStyle_ = yamlStyle;
1564 alwaysWriteLocal_ = alwaysWriteLocal;
1565 writeGlobalStats_ = writeGlobalStats;
1566 writeZeroTimers_ = writeZeroTimers;
1574 const std::string& filter,
1577 setReportParameters (params);
1579 if (reportFormat_ == REPORT_FORMAT_YAML) {
1580 summarizeToYaml (comm, out, yamlStyle_, filter);
1582 else if (reportFormat_ == REPORT_FORMAT_TABLE) {
1583 summarize (comm, out, alwaysWriteLocal_, writeGlobalStats_,
1584 writeZeroTimers_, setOp_, filter);
1588 "Invalid report format. This should never happen; ParameterList "
1589 "validation should have caught this. Please report this bug to the "
1590 "Teuchos developers.");
1599 report (comm, out,
"", params);
1604 const std::string& filter,
1608 report (comm.
ptr (), out, filter, params);
SyncTimeMonitor()=delete
Default constructor is deleted, since it would be unsafe.
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...
static Teuchos::RCP< Teuchos::StackedTimer > stackedTimer_
Stacked timer for optional injection of timing from TimeMonitor-enabled objects.
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
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.
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.
~SyncTimeMonitor() override
Destructor: stops the timer.
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.
Scope guard for Time, that can compute MPI collective timer statistics.
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.