11 #include "Teuchos_CommHelpers.hpp"
12 #include "Teuchos_DefaultComm.hpp"
15 #include "Teuchos_StandardParameterEntryValidators.hpp"
17 #include "Teuchos_StackedTimer.hpp"
21 #ifdef HAVE_TEUCHOS_ADD_TIME_MONITOR_TO_STACKED_TIMER
78 template<
class Ordinal,
class ScalarType,
class IndexType>
83 reduce (
const Ordinal count,
84 const std::pair<ScalarType, IndexType> inBuffer[],
85 std::pair<ScalarType, IndexType> inoutBuffer[])
const;
88 template<
class Ordinal>
89 class MaxLoc<Ordinal, double, int> :
93 reduce (
const Ordinal count,
94 const std::pair<double, int> inBuffer[],
95 std::pair<double, int> inoutBuffer[])
const
97 for (Ordinal ind = 0; ind < count; ++ind) {
98 const std::pair<double, int>& in = inBuffer[ind];
99 std::pair<double, int>& inout = inoutBuffer[ind];
101 if (in.first > inout.first) {
102 inout.first = in.first;
103 inout.second = in.second;
104 }
else if (in.first < inout.first) {
107 inout.first = in.first;
108 inout.second = std::min (in.second, inout.second);
140 template<
class Ordinal,
class ScalarType,
class IndexType>
145 reduce (
const Ordinal count,
146 const std::pair<ScalarType, IndexType> inBuffer[],
147 std::pair<ScalarType, IndexType> inoutBuffer[])
const;
150 template<
class Ordinal>
151 class MinLoc<Ordinal, double, int> :
155 reduce (
const Ordinal count,
156 const std::pair<double, int> inBuffer[],
157 std::pair<double, int> inoutBuffer[])
const
159 for (Ordinal ind = 0; ind < count; ++ind) {
160 const std::pair<double, int>& in = inBuffer[ind];
161 std::pair<double, int>& inout = inoutBuffer[ind];
163 if (in.first < inout.first) {
164 inout.first = in.first;
165 inout.second = in.second;
166 }
else if (in.first > inout.first) {
169 inout.first = in.first;
170 inout.second = std::min (in.second, inout.second);
179 template<
class Ordinal,
class ScalarType,
class IndexType>
184 reduce (
const Ordinal count,
185 const std::pair<ScalarType, IndexType> inBuffer[],
186 std::pair<ScalarType, IndexType> inoutBuffer[])
const;
189 template<
class Ordinal>
194 reduce (
const Ordinal count,
195 const std::pair<double, int> inBuffer[],
196 std::pair<double, int> inoutBuffer[])
const
198 for (Ordinal ind = 0; ind < count; ++ind) {
199 const std::pair<double, int>& in = inBuffer[ind];
200 std::pair<double, int>& inout = inoutBuffer[ind];
202 if ( (in.first < inout.first && in.first != 0) || (inout.first == 0 && in.first != 0) ) {
203 inout.first = in.first;
204 inout.second = in.second;
205 }
else if (in.first > inout.first) {
208 inout.first = in.first;
209 inout.second = std::min (in.second, inout.second);
215 constexpr
const std::string_view defaultStackedTimerName =
"Teuchos::StackedTimer";
221 typedef std::map<std::string, std::pair<double, int> > timer_map_t;
231 #ifdef HAVE_TEUCHOS_ADD_TIME_MONITOR_TO_STACKED_TIMER
241 #ifdef HAVE_TEUCHOS_ADD_TIME_MONITOR_TO_STACKED_TIMER
246 catch (std::runtime_error& e) {
247 std::ostringstream warning;
249 "\n*********************************************************************\n"
250 "WARNING: Overlapping timers detected! Near: " <<
counter().
name()<<
"\n"
251 "A TimeMonitor timer was stopped before a nested subtimer was\n"
252 "stopped. This is not allowed by the StackedTimer. This corner case\n"
253 "typically occurs if the TimeMonitor is stored in an RCP and the RCP is\n"
254 "assigned to a new timer. To disable this warning, either fix the\n"
255 "ordering of timer creation and destuction or disable the StackedTimer\n"
256 "support in the TimeMonitor by setting the StackedTimer to null\n"
258 " RCP<TimeMonitor> MM = rcp(new TimeMonitor(*(TimeMonitor::getNewTimer(\"Junk\"))));\n"
260 "MM = Teuchos::null;\n"
261 "MM = rcp(new TimeMonitor(*(TimeMonitor::getNewTimer(\"SecondJunk\"))));\n"
262 "*********************************************************************\n";
263 std::cout << warning.str() << std::endl << e.what() << std::endl;
275 timer == null, std::invalid_argument,
276 "TimeMonitor::disableTimer: Invalid timer \"" << name <<
"\"");
285 timer == null, std::invalid_argument,
286 "TimeMonitor::enableTimer: Invalid timer \"" << name <<
"\"");
293 typedef std::map<std::string, RCP<Time> > map_type;
294 typedef map_type::iterator iter_type;
302 for (iter_type it = ctrs.begin(); it != ctrs.end(); ++it) {
308 it->second->isRunning (), std::runtime_error,
309 "Timer \"" << it->second->name () <<
"\" is currently running. "
310 "You are not allowed to reset running timers.");
312 #endif // TEUCHOS_DEBUG
314 for (iter_type it = ctrs.begin(); it != ctrs.end(); ++it) {
315 it->second->reset ();
328 std::pair<std::string, std::pair<double, int> >
329 makeEmptyTimerDatum (
const std::string& name)
331 return std::make_pair (name, std::make_pair (
double(0),
int(0)));
352 collectLocalTimerData (timer_map_t& localData,
353 const std::map<std::string, RCP<Time> >& localCounters,
354 const std::string& filter=
"")
356 using std::make_pair;
357 typedef timer_map_t::iterator iter_t;
359 timer_map_t theLocalData;
360 for (std::map<std::string, RCP<Time> >::const_iterator it = localCounters.begin();
361 it != localCounters.end(); ++it) {
362 const std::string& name = it->second->name ();
366 const bool skipThisOne = (filter !=
"" && name.find (filter) != 0);
368 const double timing = it->second->totalElapsedTime ();
369 const int numCalls = it->second->numCalls ();
373 iter_t loc = theLocalData.find (name);
374 if (loc == theLocalData.end()) {
376 theLocalData.insert (loc, make_pair (name, make_pair (timing, numCalls)));
379 loc->second.first += timing;
380 loc->second.second += numCalls;
386 localData.swap (theLocalData);
393 filterZeroData (timer_map_t& timerData)
397 timer_map_t newTimerData;
398 for (timer_map_t::const_iterator it = timerData.begin();
399 it != timerData.end(); ++it) {
400 if (it->second.second > 0) {
401 newTimerData[it->first] = it->second;
404 timerData.swap (newTimerData);
429 collectLocalTimerDataAndNames (timer_map_t& localTimerData,
430 Array<std::string>& localTimerNames,
431 const std::map<std::string, RCP<Time> >& localTimers,
432 const bool writeZeroTimers,
433 const std::string& filter=
"")
436 collectLocalTimerData (localTimerData, localTimers, filter);
442 if (! writeZeroTimers) {
443 filterZeroData (localTimerData);
448 localTimerNames.reserve (localTimerData.size());
449 for (timer_map_t::const_iterator it = localTimerData.begin();
450 it != localTimerData.end(); ++it) {
451 localTimerNames.push_back (it->first);
490 collectGlobalTimerData (timer_map_t& globalTimerData,
491 Array<std::string>& globalTimerNames,
492 timer_map_t& localTimerData,
493 Array<std::string>& localTimerNames,
494 Ptr<
const Comm<int> > comm,
495 const bool alwaysWriteLocal,
524 const timer_map_t::size_type myNumGlobalNames = globalTimerNames.size();
525 timer_map_t::size_type minNumGlobalNames = 0;
526 timer_map_t::size_type maxNumGlobalNames = 0;
527 reduceAll (*comm,
REDUCE_MIN, myNumGlobalNames,
528 outArg (minNumGlobalNames));
529 reduceAll (*comm,
REDUCE_MAX, myNumGlobalNames,
530 outArg (maxNumGlobalNames));
532 std::logic_error,
"Min # global timer names = " << minNumGlobalNames
533 <<
" != max # global timer names = " << maxNumGlobalNames
534 <<
". Please report this bug to the Teuchos developers.");
536 std::logic_error,
"My # global timer names = " << myNumGlobalNames
537 <<
" != min # global timer names = " << minNumGlobalNames
538 <<
". Please report this bug to the Teuchos developers.");
540 #endif // TEUCHOS_DEBUG
557 timer_map_t::iterator globalMapIter = globalTimerData.begin();
558 timer_map_t::iterator localMapIter;
559 for (Array<string>::const_iterator it = globalTimerNames.begin();
560 it != globalTimerNames.end(); ++it) {
561 const std::string& globalName = *it;
562 localMapIter = localTimerData.find (globalName);
564 if (localMapIter == localTimerData.end()) {
565 if (alwaysWriteLocal) {
581 localMapIter = localTimerData.insert (localMapIter, makeEmptyTimerDatum (globalName));
586 localTimerNames.push_back (globalName);
591 globalMapIter = globalTimerData.insert (globalMapIter, makeEmptyTimerDatum (globalName));
597 globalMapIter = globalTimerData.insert (globalMapIter, std::make_pair (globalName, localMapIter->second));
601 if (alwaysWriteLocal) {
604 std::sort (localTimerNames.begin(), localTimerNames.end());
611 const timer_map_t::size_type myNumGlobalTimers = globalTimerData.size();
612 timer_map_t::size_type minNumGlobalTimers = 0;
613 timer_map_t::size_type maxNumGlobalTimers = 0;
614 reduceAll (*comm,
REDUCE_MIN, myNumGlobalTimers,
615 outArg (minNumGlobalTimers));
616 reduceAll (*comm,
REDUCE_MAX, myNumGlobalTimers,
617 outArg (maxNumGlobalTimers));
619 std::logic_error,
"Min # global timers = " << minNumGlobalTimers
620 <<
" != max # global timers = " << maxNumGlobalTimers
621 <<
". Please report this bug to the Teuchos developers.");
623 std::logic_error,
"My # global timers = " << myNumGlobalTimers
624 <<
" != min # global timers = " << minNumGlobalTimers
625 <<
". Please report this bug to the Teuchos developers.");
627 #endif // TEUCHOS_DEBUG
678 std::vector<std::string>& statNames,
679 Ptr<
const Comm<int> > comm,
680 const timer_map_t& globalTimerData,
681 const bool ignoreZeroTimers)
685 const int numTimers =
static_cast<int> (globalTimerData.size());
686 const int numProcs = comm->getSize();
691 Array<std::pair<double, int> > timingsAndCallCounts;
692 timingsAndCallCounts.reserve (numTimers);
693 for (timer_map_t::const_iterator it = globalTimerData.begin();
694 it != globalTimerData.end(); ++it) {
695 timingsAndCallCounts.push_back (it->second);
702 Array<std::pair<double, int> > minTimingsAndCallCounts (numTimers);
704 if (ignoreZeroTimers)
705 reduceAll (*comm, MinLocNonzero<int, double, int>(), numTimers,
706 &timingsAndCallCounts[0], &minTimingsAndCallCounts[0]);
708 reduceAll (*comm, MinLoc<int, double, int>(), numTimers,
709 &timingsAndCallCounts[0], &minTimingsAndCallCounts[0]);
716 Array<std::pair<double, int> > maxTimingsAndCallCounts (numTimers);
718 reduceAll (*comm, MaxLoc<int, double, int>(), numTimers,
719 &timingsAndCallCounts[0], &maxTimingsAndCallCounts[0]);
733 Array<double> meanOverCallCountsTimings (numTimers);
734 Array<double> meanOverProcsTimings (numTimers);
735 Array<double> meanCallCounts (numTimers);
736 Array<int> ICallThisTimer (numTimers);
737 Array<int> numProcsCallingEachTimer (numTimers);
740 if (ignoreZeroTimers) {
741 for (
int k = 0; k < numTimers; ++k) {
742 const double callCount =
static_cast<double> (timingsAndCallCounts[k].second);
743 if (callCount > 0) ICallThisTimer[k] = 1;
744 else ICallThisTimer[k] = 0;
747 reduceAll (*comm,
REDUCE_SUM, numTimers, &ICallThisTimer[0],
748 &numProcsCallingEachTimer[0]);
755 Array<double> scaledTimings (numTimers);
756 Array<double> scaledCallCounts (numTimers);
757 const double P =
static_cast<double> (numProcs);
759 if (ignoreZeroTimers) {
760 for (
int k = 0; k < numTimers; ++k) {
761 const double timing = timingsAndCallCounts[k].first;
762 const double callCount =
static_cast<double> (timingsAndCallCounts[k].second);
764 scaledTimings[k] = timing / numProcsCallingEachTimer[k];
765 scaledCallCounts[k] = callCount / numProcsCallingEachTimer[k];
769 for (
int k = 0; k < numTimers; ++k) {
770 const double timing = timingsAndCallCounts[k].first;
771 const double callCount =
static_cast<double> (timingsAndCallCounts[k].second);
773 scaledTimings[k] = timing / P;
774 scaledCallCounts[k] = callCount / P;
779 reduceAll (*comm,
REDUCE_SUM, numTimers, &scaledTimings[0],
780 &meanOverProcsTimings[0]);
781 reduceAll (*comm,
REDUCE_SUM, numTimers, &scaledCallCounts[0],
786 for (
int k = 0; k < numTimers; ++k) {
787 if (meanCallCounts[k] > ScalarTraits<double>::zero ()) {
788 meanOverCallCountsTimings[k] = meanOverProcsTimings[k] / meanCallCounts[k];
800 statNames.resize (4);
801 statNames[0] =
"MinOverProcs";
802 statNames[1] =
"MeanOverProcs";
803 statNames[2] =
"MaxOverProcs";
804 statNames[3] =
"MeanOverCallCounts";
806 stat_map_type::iterator statIter = statData.end();
807 timer_map_t::const_iterator it = globalTimerData.begin();
808 for (
int k = 0; it != globalTimerData.end(); ++k, ++it) {
809 std::vector<std::pair<double, double> > curData (4);
810 curData[0] = minTimingsAndCallCounts[k];
811 curData[1] = std::make_pair (meanOverProcsTimings[k], meanCallCounts[k]);
812 curData[2] = maxTimingsAndCallCounts[k];
813 curData[3] = std::make_pair (meanOverCallCountsTimings[k], meanCallCounts[k]);
818 statIter = statData.insert (statIter, std::make_pair (it->first, curData));
839 RCP<const Comm<int> >
851 int mpiHasBeenStarted = 0;
852 MPI_Initialized (&mpiHasBeenStarted);
853 if (! mpiHasBeenStarted) {
855 comm = rcp_implicit_cast<
const Comm<int> > (
rcp (
new SerialComm<int> ()));
867 std::vector<std::string>& statNames,
870 const std::string& filter)
876 timer_map_t localTimerData;
878 const bool writeZeroTimers =
false;
879 collectLocalTimerDataAndNames (localTimerData, localTimerNames,
880 counters(), writeZeroTimers, filter);
883 timer_map_t globalTimerData;
885 const bool alwaysWriteLocal =
false;
886 collectGlobalTimerData (globalTimerData, globalTimerNames,
887 localTimerData, localTimerNames,
888 comm, alwaysWriteLocal, setOp);
890 computeGlobalTimerStats (statData, statNames, comm, globalTimerData,
false);
897 const bool alwaysWriteLocal,
898 const bool writeGlobalStats,
899 const bool writeZeroTimers,
901 const std::string& filter,
902 const bool ignoreZeroTimers)
909 const int numProcs = comm->getSize();
910 const int myRank = comm->getRank();
916 timer_map_t localTimerData;
918 collectLocalTimerDataAndNames (localTimerData, localTimerNames,
919 counters(), writeZeroTimers, filter);
925 timer_map_t globalTimerData;
928 std::vector<std::string> statNames;
929 if (writeGlobalStats) {
930 collectGlobalTimerData (globalTimerData, globalTimerNames,
931 localTimerData, localTimerNames,
932 comm, alwaysWriteLocal, setOp);
937 computeGlobalTimerStats (statData, statNames, comm, globalTimerData, ignoreZeroTimers);
943 const std::ios_base::fmtflags& flags = out.flags();
961 titles.
append (
"Timer Name");
964 TableColumn nameCol (writeGlobalStats ? globalTimerNames : localTimerNames);
965 tableColumns.
append (nameCol);
970 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), nameCol));
980 if (alwaysWriteLocal && numProcs > 1 && myRank == 0) {
981 titles.
append (
"Local time (num calls)");
987 for (timer_map_t::const_iterator it = localTimerData.begin();
988 it != localTimerData.end(); ++it) {
989 localTimings.
push_back (it->second.first);
990 localNumCalls.
push_back (static_cast<double> (it->second.second));
992 TableColumn timeAndCalls (localTimings, localNumCalls, precision, flags,
true);
993 tableColumns.
append (timeAndCalls);
994 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), timeAndCalls));
997 if (writeGlobalStats) {
1002 if (numProcs == 1) {
1006 for (timer_map_t::const_iterator it = globalTimerData.begin();
1007 it != globalTimerData.end(); ++it) {
1008 globalTimings.
push_back (it->second.first);
1009 globalNumCalls.
push_back (static_cast<double> (it->second.second));
1012 titles.
append (
"Global time (num calls)");
1013 TableColumn timeAndCalls (globalTimings, globalNumCalls, precision, flags,
true);
1014 tableColumns.
append (timeAndCalls);
1015 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), timeAndCalls));
1022 const timer_map_t::size_type numGlobalTimers = globalTimerData.
size();
1023 for (std::vector<std::string>::size_type statInd = 0; statInd < statNames.size(); ++statInd) {
1028 stat_map_type::const_iterator it = statData.begin();
1029 for (
int k = 0; it != statData.end(); ++it, ++k) {
1030 statTimings[k] = (it->second[statInd]).first;
1031 statCallCounts[k] = (it->second[statInd]).second;
1034 const std::string& statisticName = statNames[statInd];
1035 const std::string titleString = statisticName;
1036 titles.
append (titleString);
1037 TableColumn timeAndCalls (statTimings, statCallCounts, precision, flags,
true);
1038 tableColumns.
append (timeAndCalls);
1039 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), timeAndCalls));
1047 std::ostringstream theTitle;
1048 theTitle <<
"TimeMonitor results over " << numProcs <<
" processor"
1049 << (numProcs > 1 ?
"s" :
"");
1056 const bool alwaysWriteLocal,
1057 const bool writeGlobalStats,
1058 const bool writeZeroTimers,
1060 const std::string& filter,
1061 const bool ignoreZeroTimers)
1069 writeGlobalStats, writeZeroTimers, setOp, filter, ignoreZeroTimers);
1074 std::vector<std::string>& statNames,
1076 const std::string& filter)
1120 quoteLabelForYaml (
const std::string& label)
1125 if (label.empty ()) {
1132 const bool alreadyQuoted = label.size () >= 2 &&
1133 label[0] ==
'"' && label[label.size() - 1] ==
'"';
1138 bool needToQuote =
false;
1141 out.reserve (label.size ());
1143 const size_t startPos = alreadyQuoted ? 1 : 0;
1144 const size_t endPos = alreadyQuoted ? label.size () - 1 : label.size ();
1145 for (
size_t i = startPos; i < endPos; ++i) {
1146 const char c = label[i];
1147 if (c ==
'"' || c ==
'\\') {
1148 out.push_back (
'\\');
1151 else if (c ==
':') {
1157 if (needToQuote || alreadyQuoted) {
1160 return "\"" + out +
"\"";
1171 summarizeToYaml (Ptr<
const Comm<int> > comm,
1173 const ETimeMonitorYamlFormat yamlStyle,
1174 const std::string& filter)
1177 using Teuchos::fancyOStream;
1178 using Teuchos::getFancyOStream;
1181 using Teuchos::rcpFromRef;
1183 typedef std::vector<std::string>::size_type size_type;
1185 const bool compact = (yamlStyle == YAML_FORMAT_COMPACT);
1193 std::vector<std::string> statNames;
1196 const int numProcs = comm->getSize();
1209 RCP<FancyOStream> pfout = getFancyOStream (rcpFromRef (out));
1210 pfout->setTabIndentStr (
" ");
1213 fout <<
"# Teuchos::TimeMonitor report" << endl
1225 fout <<
"Output mode: " << (compact ?
"compact" :
"spacious") << endl
1226 <<
"Number of processes: " << numProcs << endl
1227 <<
"Time unit: s" << endl;
1231 fout <<
"Statistics collected: ";
1235 for (size_type i = 0; i < statNames.size (); ++i) {
1236 fout << quoteLabelForYaml (statNames[i]);
1237 if (i + 1 < statNames.size ()) {
1241 fout <<
"]" << endl;
1246 for (size_type i = 0; i < statNames.size (); ++i) {
1247 fout <<
"- " << quoteLabelForYaml (statNames[i]) << endl;
1256 fout <<
"Timer names: ";
1260 for (stat_map_type::const_iterator it = statData.begin();
1261 it != statData.end(); ++it, ++ind) {
1262 fout << quoteLabelForYaml (it->first);
1263 if (ind + 1 < statData.size ()) {
1267 fout <<
"]" << endl;
1272 for (stat_map_type::const_iterator it = statData.begin();
1273 it != statData.end(); ++it) {
1274 fout <<
"- " << quoteLabelForYaml (it->first) << endl;
1279 fout <<
"Total times: ";
1282 size_type outerInd = 0;
1283 for (stat_map_type::const_iterator outerIter = statData.begin();
1284 outerIter != statData.end(); ++outerIter, ++outerInd) {
1286 fout << quoteLabelForYaml (outerIter->first) <<
": ";
1288 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1290 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1291 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1292 << curData[innerInd].first;
1293 if (innerInd + 1 < curData.size ()) {
1298 if (outerInd + 1 < statData.size ()) {
1302 fout <<
"}" << endl;
1307 size_type outerInd = 0;
1308 for (stat_map_type::const_iterator outerIter = statData.begin();
1309 outerIter != statData.end(); ++outerIter, ++outerInd) {
1311 fout << quoteLabelForYaml (outerIter->first) <<
": " << endl;
1314 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1315 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1316 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1317 << curData[innerInd].first << endl;
1323 fout <<
"Call counts:";
1326 size_type outerInd = 0;
1327 for (stat_map_type::const_iterator outerIter = statData.begin();
1328 outerIter != statData.end(); ++outerIter, ++outerInd) {
1330 fout << quoteLabelForYaml (outerIter->first) <<
": ";
1332 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1334 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1335 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1336 << curData[innerInd].second;
1337 if (innerInd + 1 < curData.size ()) {
1342 if (outerInd + 1 < statData.size ()) {
1346 fout <<
"}" << endl;
1351 size_type outerInd = 0;
1352 for (stat_map_type::const_iterator outerIter = statData.begin();
1353 outerIter != statData.end(); ++outerIter, ++outerInd) {
1355 fout << quoteLabelForYaml (outerIter->first) <<
": " << endl;
1358 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1359 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1360 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1361 << curData[innerInd].second << endl;
1368 summarizeToYaml (std::ostream &out,
1369 const ETimeMonitorYamlFormat yamlStyle,
1370 const std::string& filter)
1375 RCP<const Comm<int> > comm = getDefaultComm ();
1377 summarizeToYaml (comm.ptr (), out, yamlStyle, filter);
1382 bool TimeMonitor::setParams_ =
false;
1385 TimeMonitor::ETimeMonitorReportFormat TimeMonitor::reportFormat_ = TimeMonitor::REPORT_FORMAT_TABLE;
1386 TimeMonitor::ETimeMonitorYamlFormat TimeMonitor::yamlStyle_ = TimeMonitor::YAML_FORMAT_SPACIOUS;
1388 bool TimeMonitor::alwaysWriteLocal_ =
false;
1389 bool TimeMonitor::writeGlobalStats_ =
true;
1390 bool TimeMonitor::writeZeroTimers_ =
true;
1393 TimeMonitor::setReportFormatParameter (ParameterList& plist)
1395 const std::string name (
"Report format");
1396 const std::string defaultValue (
"Table");
1397 const std::string docString (
"Output format for report of timer statistics");
1398 Array<std::string> strings;
1399 Array<std::string> docs;
1400 Array<ETimeMonitorReportFormat> values;
1402 strings.push_back (
"YAML");
1403 docs.push_back (
"YAML (see yaml.org) format");
1404 values.push_back (REPORT_FORMAT_YAML);
1405 strings.push_back (
"Table");
1406 docs.push_back (
"Tabular format via Teuchos::TableFormat");
1407 values.push_back (REPORT_FORMAT_TABLE);
1409 setStringToIntegralParameter<ETimeMonitorReportFormat> (name, defaultValue,
1411 strings (), docs (),
1416 TimeMonitor::setYamlFormatParameter (ParameterList& plist)
1418 const std::string name (
"YAML style");
1419 const std::string defaultValue (
"spacious");
1420 const std::string docString (
"YAML-specific output format");
1421 Array<std::string> strings;
1422 Array<std::string> docs;
1423 Array<ETimeMonitorYamlFormat> values;
1425 strings.push_back (
"compact");
1426 docs.push_back (
"Compact format: use \"flow style\" (see YAML 1.2 spec at "
1427 "yaml.org) for most sequences except the outermost sequence");
1428 values.push_back (YAML_FORMAT_COMPACT);
1430 strings.push_back (
"spacious");
1431 docs.push_back (
"Spacious format: avoid flow style");
1432 values.push_back (YAML_FORMAT_SPACIOUS);
1434 setStringToIntegralParameter<ETimeMonitorYamlFormat> (name, defaultValue,
1436 strings (), docs (),
1441 TimeMonitor::setSetOpParameter (ParameterList& plist)
1443 const std::string name (
"How to merge timer sets");
1444 const std::string defaultValue (
"Intersection");
1445 const std::string docString (
"How to merge differing sets of timers "
1446 "across processes");
1447 Array<std::string> strings;
1448 Array<std::string> docs;
1449 Array<ECounterSetOp> values;
1451 strings.push_back (
"Intersection");
1452 docs.push_back (
"Compute intersection of timer sets over processes");
1453 values.push_back (Intersection);
1454 strings.push_back (
"Union");
1455 docs.push_back (
"Compute union of timer sets over processes");
1456 values.push_back (Union);
1458 setStringToIntegralParameter<ECounterSetOp> (name, defaultValue, docString,
1459 strings (), docs (), values (),
1476 TimeMonitor::stackedTimerNameIsDefault() {
1480 RCP<const ParameterList>
1488 const bool alwaysWriteLocal =
false;
1489 const bool writeGlobalStats =
true;
1490 const bool writeZeroTimers =
true;
1492 setReportFormatParameter (*plist);
1493 setYamlFormatParameter (*plist);
1494 setSetOpParameter (*plist);
1495 plist->set (
"alwaysWriteLocal", alwaysWriteLocal,
1496 "Always output local timers' values on Proc 0");
1497 plist->set (
"writeGlobalStats", writeGlobalStats,
"Always output global "
1498 "statistics, even if there is only one process in the "
1500 plist->set (
"writeZeroTimers", writeZeroTimers,
"Generate output for "
1501 "timers that have never been called");
1509 ETimeMonitorReportFormat reportFormat = REPORT_FORMAT_TABLE;
1510 ETimeMonitorYamlFormat yamlStyle = YAML_FORMAT_SPACIOUS;
1512 bool alwaysWriteLocal =
false;
1513 bool writeGlobalStats =
true;
1514 bool writeZeroTimers =
true;
1526 reportFormat = getIntegralValue<ETimeMonitorReportFormat> (*params,
"Report format");
1527 yamlStyle = getIntegralValue<ETimeMonitorYamlFormat> (*params,
"YAML style");
1528 setOp = getIntegralValue<ECounterSetOp> (*params,
"How to merge timer sets");
1529 alwaysWriteLocal = params->
get<
bool> (
"alwaysWriteLocal");
1530 writeGlobalStats = params->get<
bool> (
"writeGlobalStats");
1531 writeZeroTimers = params->get<
bool> (
"writeZeroTimers");
1536 reportFormat_ = reportFormat;
1537 yamlStyle_ = yamlStyle;
1539 alwaysWriteLocal_ = alwaysWriteLocal;
1540 writeGlobalStats_ = writeGlobalStats;
1541 writeZeroTimers_ = writeZeroTimers;
1549 const std::string& filter,
1552 setReportParameters (params);
1554 if (reportFormat_ == REPORT_FORMAT_YAML) {
1555 summarizeToYaml (comm, out, yamlStyle_, filter);
1557 else if (reportFormat_ == REPORT_FORMAT_TABLE) {
1558 summarize (comm, out, alwaysWriteLocal_, writeGlobalStats_,
1559 writeZeroTimers_, setOp_, filter);
1563 "Invalid report format. This should never happen; ParameterList "
1564 "validation should have caught this. Please report this bug to the "
1565 "Teuchos developers.");
1574 report (comm, out,
"", params);
1579 const std::string& filter,
1583 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.