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);
219 typedef std::map<std::string, std::pair<double, int> > timer_map_t;
229 #ifdef HAVE_TEUCHOS_ADD_TIME_MONITOR_TO_STACKED_TIMER
239 #ifdef HAVE_TEUCHOS_ADD_TIME_MONITOR_TO_STACKED_TIMER
244 catch (std::runtime_error& e) {
245 std::ostringstream warning;
247 "\n*********************************************************************\n"
248 "WARNING: Overlapping timers detected! Near: " <<
counter().
name()<<
"\n"
249 "A TimeMonitor timer was stopped before a nested subtimer was\n"
250 "stopped. This is not allowed by the StackedTimer. This corner case\n"
251 "typically occurs if the TimeMonitor is stored in an RCP and the RCP is\n"
252 "assigned to a new timer. To disable this warning, either fix the\n"
253 "ordering of timer creation and destuction or disable the StackedTimer\n"
254 "support in the TimeMonitor by setting the StackedTimer to null\n"
256 " RCP<TimeMonitor> MM = rcp(new TimeMonitor(*(TimeMonitor::getNewTimer(\"Junk\"))));\n"
258 "MM = Teuchos::null;\n"
259 "MM = rcp(new TimeMonitor(*(TimeMonitor::getNewTimer(\"SecondJunk\"))));\n"
260 "*********************************************************************\n";
261 std::cout << warning.str() << std::endl << e.what() << std::endl;
273 timer == null, std::invalid_argument,
274 "TimeMonitor::disableTimer: Invalid timer \"" << name <<
"\"");
283 timer == null, std::invalid_argument,
284 "TimeMonitor::enableTimer: Invalid timer \"" << name <<
"\"");
291 typedef std::map<std::string, RCP<Time> > map_type;
292 typedef map_type::iterator iter_type;
300 for (iter_type it = ctrs.begin(); it != ctrs.end(); ++it) {
306 it->second->isRunning (), std::runtime_error,
307 "Timer \"" << it->second->name () <<
"\" is currently running. "
308 "You are not allowed to reset running timers.");
310 #endif // TEUCHOS_DEBUG
312 for (iter_type it = ctrs.begin(); it != ctrs.end(); ++it) {
313 it->second->reset ();
326 std::pair<std::string, std::pair<double, int> >
327 makeEmptyTimerDatum (
const std::string& name)
329 return std::make_pair (name, std::make_pair (
double(0),
int(0)));
350 collectLocalTimerData (timer_map_t& localData,
351 const std::map<std::string, RCP<Time> >& localCounters,
352 const std::string& filter=
"")
354 using std::make_pair;
355 typedef timer_map_t::iterator iter_t;
357 timer_map_t theLocalData;
358 for (std::map<std::string, RCP<Time> >::const_iterator it = localCounters.begin();
359 it != localCounters.end(); ++it) {
360 const std::string& name = it->second->name ();
364 const bool skipThisOne = (filter !=
"" && name.find (filter) != 0);
366 const double timing = it->second->totalElapsedTime ();
367 const int numCalls = it->second->numCalls ();
371 iter_t loc = theLocalData.find (name);
372 if (loc == theLocalData.end()) {
374 theLocalData.insert (loc, make_pair (name, make_pair (timing, numCalls)));
377 loc->second.first += timing;
378 loc->second.second += numCalls;
384 localData.swap (theLocalData);
391 filterZeroData (timer_map_t& timerData)
395 timer_map_t newTimerData;
396 for (timer_map_t::const_iterator it = timerData.begin();
397 it != timerData.end(); ++it) {
398 if (it->second.second > 0) {
399 newTimerData[it->first] = it->second;
402 timerData.swap (newTimerData);
427 collectLocalTimerDataAndNames (timer_map_t& localTimerData,
428 Array<std::string>& localTimerNames,
429 const std::map<std::string, RCP<Time> >& localTimers,
430 const bool writeZeroTimers,
431 const std::string& filter=
"")
434 collectLocalTimerData (localTimerData, localTimers, filter);
440 if (! writeZeroTimers) {
441 filterZeroData (localTimerData);
446 localTimerNames.reserve (localTimerData.size());
447 for (timer_map_t::const_iterator it = localTimerData.begin();
448 it != localTimerData.end(); ++it) {
449 localTimerNames.push_back (it->first);
488 collectGlobalTimerData (timer_map_t& globalTimerData,
489 Array<std::string>& globalTimerNames,
490 timer_map_t& localTimerData,
491 Array<std::string>& localTimerNames,
492 Ptr<
const Comm<int> > comm,
493 const bool alwaysWriteLocal,
522 const timer_map_t::size_type myNumGlobalNames = globalTimerNames.size();
523 timer_map_t::size_type minNumGlobalNames = 0;
524 timer_map_t::size_type maxNumGlobalNames = 0;
525 reduceAll (*comm,
REDUCE_MIN, myNumGlobalNames,
526 outArg (minNumGlobalNames));
527 reduceAll (*comm,
REDUCE_MAX, myNumGlobalNames,
528 outArg (maxNumGlobalNames));
530 std::logic_error,
"Min # global timer names = " << minNumGlobalNames
531 <<
" != max # global timer names = " << maxNumGlobalNames
532 <<
". Please report this bug to the Teuchos developers.");
534 std::logic_error,
"My # global timer names = " << myNumGlobalNames
535 <<
" != min # global timer names = " << minNumGlobalNames
536 <<
". Please report this bug to the Teuchos developers.");
538 #endif // TEUCHOS_DEBUG
555 timer_map_t::iterator globalMapIter = globalTimerData.begin();
556 timer_map_t::iterator localMapIter;
557 for (Array<string>::const_iterator it = globalTimerNames.begin();
558 it != globalTimerNames.end(); ++it) {
559 const std::string& globalName = *it;
560 localMapIter = localTimerData.find (globalName);
562 if (localMapIter == localTimerData.end()) {
563 if (alwaysWriteLocal) {
579 localMapIter = localTimerData.insert (localMapIter, makeEmptyTimerDatum (globalName));
584 localTimerNames.push_back (globalName);
589 globalMapIter = globalTimerData.insert (globalMapIter, makeEmptyTimerDatum (globalName));
595 globalMapIter = globalTimerData.insert (globalMapIter, std::make_pair (globalName, localMapIter->second));
599 if (alwaysWriteLocal) {
602 std::sort (localTimerNames.begin(), localTimerNames.end());
609 const timer_map_t::size_type myNumGlobalTimers = globalTimerData.size();
610 timer_map_t::size_type minNumGlobalTimers = 0;
611 timer_map_t::size_type maxNumGlobalTimers = 0;
612 reduceAll (*comm,
REDUCE_MIN, myNumGlobalTimers,
613 outArg (minNumGlobalTimers));
614 reduceAll (*comm,
REDUCE_MAX, myNumGlobalTimers,
615 outArg (maxNumGlobalTimers));
617 std::logic_error,
"Min # global timers = " << minNumGlobalTimers
618 <<
" != max # global timers = " << maxNumGlobalTimers
619 <<
". Please report this bug to the Teuchos developers.");
621 std::logic_error,
"My # global timers = " << myNumGlobalTimers
622 <<
" != min # global timers = " << minNumGlobalTimers
623 <<
". Please report this bug to the Teuchos developers.");
625 #endif // TEUCHOS_DEBUG
676 std::vector<std::string>& statNames,
677 Ptr<
const Comm<int> > comm,
678 const timer_map_t& globalTimerData,
679 const bool ignoreZeroTimers)
683 const int numTimers =
static_cast<int> (globalTimerData.size());
684 const int numProcs = comm->getSize();
689 Array<std::pair<double, int> > timingsAndCallCounts;
690 timingsAndCallCounts.reserve (numTimers);
691 for (timer_map_t::const_iterator it = globalTimerData.begin();
692 it != globalTimerData.end(); ++it) {
693 timingsAndCallCounts.push_back (it->second);
700 Array<std::pair<double, int> > minTimingsAndCallCounts (numTimers);
702 if (ignoreZeroTimers)
703 reduceAll (*comm, MinLocNonzero<int, double, int>(), numTimers,
704 &timingsAndCallCounts[0], &minTimingsAndCallCounts[0]);
706 reduceAll (*comm, MinLoc<int, double, int>(), numTimers,
707 &timingsAndCallCounts[0], &minTimingsAndCallCounts[0]);
714 Array<std::pair<double, int> > maxTimingsAndCallCounts (numTimers);
716 reduceAll (*comm, MaxLoc<int, double, int>(), numTimers,
717 &timingsAndCallCounts[0], &maxTimingsAndCallCounts[0]);
731 Array<double> meanOverCallCountsTimings (numTimers);
732 Array<double> meanOverProcsTimings (numTimers);
733 Array<double> meanCallCounts (numTimers);
734 Array<int> ICallThisTimer (numTimers);
735 Array<int> numProcsCallingEachTimer (numTimers);
738 if (ignoreZeroTimers) {
739 for (
int k = 0; k < numTimers; ++k) {
740 const double callCount =
static_cast<double> (timingsAndCallCounts[k].second);
741 if (callCount > 0) ICallThisTimer[k] = 1;
742 else ICallThisTimer[k] = 0;
745 reduceAll (*comm,
REDUCE_SUM, numTimers, &ICallThisTimer[0],
746 &numProcsCallingEachTimer[0]);
753 Array<double> scaledTimings (numTimers);
754 Array<double> scaledCallCounts (numTimers);
755 const double P =
static_cast<double> (numProcs);
757 if (ignoreZeroTimers) {
758 for (
int k = 0; k < numTimers; ++k) {
759 const double timing = timingsAndCallCounts[k].first;
760 const double callCount =
static_cast<double> (timingsAndCallCounts[k].second);
762 scaledTimings[k] = timing / numProcsCallingEachTimer[k];
763 scaledCallCounts[k] = callCount / numProcsCallingEachTimer[k];
767 for (
int k = 0; k < numTimers; ++k) {
768 const double timing = timingsAndCallCounts[k].first;
769 const double callCount =
static_cast<double> (timingsAndCallCounts[k].second);
771 scaledTimings[k] = timing / P;
772 scaledCallCounts[k] = callCount / P;
777 reduceAll (*comm,
REDUCE_SUM, numTimers, &scaledTimings[0],
778 &meanOverProcsTimings[0]);
779 reduceAll (*comm,
REDUCE_SUM, numTimers, &scaledCallCounts[0],
784 for (
int k = 0; k < numTimers; ++k) {
785 if (meanCallCounts[k] > ScalarTraits<double>::zero ()) {
786 meanOverCallCountsTimings[k] = meanOverProcsTimings[k] / meanCallCounts[k];
798 statNames.resize (4);
799 statNames[0] =
"MinOverProcs";
800 statNames[1] =
"MeanOverProcs";
801 statNames[2] =
"MaxOverProcs";
802 statNames[3] =
"MeanOverCallCounts";
804 stat_map_type::iterator statIter = statData.end();
805 timer_map_t::const_iterator it = globalTimerData.begin();
806 for (
int k = 0; it != globalTimerData.end(); ++k, ++it) {
807 std::vector<std::pair<double, double> > curData (4);
808 curData[0] = minTimingsAndCallCounts[k];
809 curData[1] = std::make_pair (meanOverProcsTimings[k], meanCallCounts[k]);
810 curData[2] = maxTimingsAndCallCounts[k];
811 curData[3] = std::make_pair (meanOverCallCountsTimings[k], meanCallCounts[k]);
816 statIter = statData.insert (statIter, std::make_pair (it->first, curData));
837 RCP<const Comm<int> >
849 int mpiHasBeenStarted = 0;
850 MPI_Initialized (&mpiHasBeenStarted);
851 if (! mpiHasBeenStarted) {
853 comm = rcp_implicit_cast<
const Comm<int> > (
rcp (
new SerialComm<int> ()));
865 std::vector<std::string>& statNames,
868 const std::string& filter)
874 timer_map_t localTimerData;
876 const bool writeZeroTimers =
false;
877 collectLocalTimerDataAndNames (localTimerData, localTimerNames,
878 counters(), writeZeroTimers, filter);
881 timer_map_t globalTimerData;
883 const bool alwaysWriteLocal =
false;
884 collectGlobalTimerData (globalTimerData, globalTimerNames,
885 localTimerData, localTimerNames,
886 comm, alwaysWriteLocal, setOp);
888 computeGlobalTimerStats (statData, statNames, comm, globalTimerData,
false);
895 const bool alwaysWriteLocal,
896 const bool writeGlobalStats,
897 const bool writeZeroTimers,
899 const std::string& filter,
900 const bool ignoreZeroTimers)
907 const int numProcs = comm->getSize();
908 const int myRank = comm->getRank();
914 timer_map_t localTimerData;
916 collectLocalTimerDataAndNames (localTimerData, localTimerNames,
917 counters(), writeZeroTimers, filter);
923 timer_map_t globalTimerData;
926 std::vector<std::string> statNames;
927 if (writeGlobalStats) {
928 collectGlobalTimerData (globalTimerData, globalTimerNames,
929 localTimerData, localTimerNames,
930 comm, alwaysWriteLocal, setOp);
935 computeGlobalTimerStats (statData, statNames, comm, globalTimerData, ignoreZeroTimers);
941 const std::ios_base::fmtflags& flags = out.flags();
959 titles.
append (
"Timer Name");
962 TableColumn nameCol (writeGlobalStats ? globalTimerNames : localTimerNames);
963 tableColumns.
append (nameCol);
968 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), nameCol));
978 if (alwaysWriteLocal && numProcs > 1 && myRank == 0) {
979 titles.
append (
"Local time (num calls)");
985 for (timer_map_t::const_iterator it = localTimerData.begin();
986 it != localTimerData.end(); ++it) {
987 localTimings.
push_back (it->second.first);
988 localNumCalls.
push_back (static_cast<double> (it->second.second));
990 TableColumn timeAndCalls (localTimings, localNumCalls, precision, flags,
true);
991 tableColumns.
append (timeAndCalls);
992 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), timeAndCalls));
995 if (writeGlobalStats) {
1000 if (numProcs == 1) {
1004 for (timer_map_t::const_iterator it = globalTimerData.begin();
1005 it != globalTimerData.end(); ++it) {
1006 globalTimings.
push_back (it->second.first);
1007 globalNumCalls.
push_back (static_cast<double> (it->second.second));
1010 titles.
append (
"Global time (num calls)");
1011 TableColumn timeAndCalls (globalTimings, globalNumCalls, precision, flags,
true);
1012 tableColumns.
append (timeAndCalls);
1013 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), timeAndCalls));
1020 const timer_map_t::size_type numGlobalTimers = globalTimerData.
size();
1021 for (std::vector<std::string>::size_type statInd = 0; statInd < statNames.size(); ++statInd) {
1026 stat_map_type::const_iterator it = statData.begin();
1027 for (
int k = 0; it != statData.end(); ++it, ++k) {
1028 statTimings[k] = (it->second[statInd]).first;
1029 statCallCounts[k] = (it->second[statInd]).second;
1032 const std::string& statisticName = statNames[statInd];
1033 const std::string titleString = statisticName;
1034 titles.
append (titleString);
1035 TableColumn timeAndCalls (statTimings, statCallCounts, precision, flags,
true);
1036 tableColumns.
append (timeAndCalls);
1037 columnWidths.
append (
format().computeRequiredColumnWidth (titles.
back(), timeAndCalls));
1045 std::ostringstream theTitle;
1046 theTitle <<
"TimeMonitor results over " << numProcs <<
" processor"
1047 << (numProcs > 1 ?
"s" :
"");
1054 const bool alwaysWriteLocal,
1055 const bool writeGlobalStats,
1056 const bool writeZeroTimers,
1058 const std::string& filter,
1059 const bool ignoreZeroTimers)
1067 writeGlobalStats, writeZeroTimers, setOp, filter, ignoreZeroTimers);
1072 std::vector<std::string>& statNames,
1074 const std::string& filter)
1118 quoteLabelForYaml (
const std::string& label)
1123 if (label.empty ()) {
1130 const bool alreadyQuoted = label.size () >= 2 &&
1131 label[0] ==
'"' && label[label.size() - 1] ==
'"';
1136 bool needToQuote =
false;
1139 out.reserve (label.size ());
1141 const size_t startPos = alreadyQuoted ? 1 : 0;
1142 const size_t endPos = alreadyQuoted ? label.size () - 1 : label.size ();
1143 for (
size_t i = startPos; i < endPos; ++i) {
1144 const char c = label[i];
1145 if (c ==
'"' || c ==
'\\') {
1146 out.push_back (
'\\');
1149 else if (c ==
':') {
1155 if (needToQuote || alreadyQuoted) {
1158 return "\"" + out +
"\"";
1169 summarizeToYaml (Ptr<
const Comm<int> > comm,
1171 const ETimeMonitorYamlFormat yamlStyle,
1172 const std::string& filter)
1175 using Teuchos::fancyOStream;
1176 using Teuchos::getFancyOStream;
1179 using Teuchos::rcpFromRef;
1181 typedef std::vector<std::string>::size_type size_type;
1183 const bool compact = (yamlStyle == YAML_FORMAT_COMPACT);
1191 std::vector<std::string> statNames;
1194 const int numProcs = comm->getSize();
1207 RCP<FancyOStream> pfout = getFancyOStream (rcpFromRef (out));
1208 pfout->setTabIndentStr (
" ");
1211 fout <<
"# Teuchos::TimeMonitor report" << endl
1223 fout <<
"Output mode: " << (compact ?
"compact" :
"spacious") << endl
1224 <<
"Number of processes: " << numProcs << endl
1225 <<
"Time unit: s" << endl;
1229 fout <<
"Statistics collected: ";
1233 for (size_type i = 0; i < statNames.size (); ++i) {
1234 fout << quoteLabelForYaml (statNames[i]);
1235 if (i + 1 < statNames.size ()) {
1239 fout <<
"]" << endl;
1244 for (size_type i = 0; i < statNames.size (); ++i) {
1245 fout <<
"- " << quoteLabelForYaml (statNames[i]) << endl;
1254 fout <<
"Timer names: ";
1258 for (stat_map_type::const_iterator it = statData.begin();
1259 it != statData.end(); ++it, ++ind) {
1260 fout << quoteLabelForYaml (it->first);
1261 if (ind + 1 < statData.size ()) {
1265 fout <<
"]" << endl;
1270 for (stat_map_type::const_iterator it = statData.begin();
1271 it != statData.end(); ++it) {
1272 fout <<
"- " << quoteLabelForYaml (it->first) << endl;
1277 fout <<
"Total times: ";
1280 size_type outerInd = 0;
1281 for (stat_map_type::const_iterator outerIter = statData.begin();
1282 outerIter != statData.end(); ++outerIter, ++outerInd) {
1284 fout << quoteLabelForYaml (outerIter->first) <<
": ";
1286 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1288 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1289 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1290 << curData[innerInd].first;
1291 if (innerInd + 1 < curData.size ()) {
1296 if (outerInd + 1 < statData.size ()) {
1300 fout <<
"}" << endl;
1305 size_type outerInd = 0;
1306 for (stat_map_type::const_iterator outerIter = statData.begin();
1307 outerIter != statData.end(); ++outerIter, ++outerInd) {
1309 fout << quoteLabelForYaml (outerIter->first) <<
": " << endl;
1312 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1313 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1314 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1315 << curData[innerInd].first << endl;
1321 fout <<
"Call counts:";
1324 size_type outerInd = 0;
1325 for (stat_map_type::const_iterator outerIter = statData.begin();
1326 outerIter != statData.end(); ++outerIter, ++outerInd) {
1328 fout << quoteLabelForYaml (outerIter->first) <<
": ";
1330 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1332 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1333 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1334 << curData[innerInd].second;
1335 if (innerInd + 1 < curData.size ()) {
1340 if (outerInd + 1 < statData.size ()) {
1344 fout <<
"}" << endl;
1349 size_type outerInd = 0;
1350 for (stat_map_type::const_iterator outerIter = statData.begin();
1351 outerIter != statData.end(); ++outerIter, ++outerInd) {
1353 fout << quoteLabelForYaml (outerIter->first) <<
": " << endl;
1356 const std::vector<std::pair<double, double> >& curData = outerIter->second;
1357 for (size_type innerInd = 0; innerInd < curData.size (); ++innerInd) {
1358 fout << quoteLabelForYaml (statNames[innerInd]) <<
": "
1359 << curData[innerInd].second << endl;
1366 summarizeToYaml (std::ostream &out,
1367 const ETimeMonitorYamlFormat yamlStyle,
1368 const std::string& filter)
1373 RCP<const Comm<int> > comm = getDefaultComm ();
1375 summarizeToYaml (comm.ptr (), out, yamlStyle, filter);
1380 bool TimeMonitor::setParams_ =
false;
1383 TimeMonitor::ETimeMonitorReportFormat TimeMonitor::reportFormat_ = TimeMonitor::REPORT_FORMAT_TABLE;
1384 TimeMonitor::ETimeMonitorYamlFormat TimeMonitor::yamlStyle_ = TimeMonitor::YAML_FORMAT_SPACIOUS;
1386 bool TimeMonitor::alwaysWriteLocal_ =
false;
1387 bool TimeMonitor::writeGlobalStats_ =
true;
1388 bool TimeMonitor::writeZeroTimers_ =
true;
1391 TimeMonitor::setReportFormatParameter (ParameterList& plist)
1393 const std::string name (
"Report format");
1394 const std::string defaultValue (
"Table");
1395 const std::string docString (
"Output format for report of timer statistics");
1396 Array<std::string> strings;
1397 Array<std::string> docs;
1398 Array<ETimeMonitorReportFormat> values;
1400 strings.push_back (
"YAML");
1401 docs.push_back (
"YAML (see yaml.org) format");
1402 values.push_back (REPORT_FORMAT_YAML);
1403 strings.push_back (
"Table");
1404 docs.push_back (
"Tabular format via Teuchos::TableFormat");
1405 values.push_back (REPORT_FORMAT_TABLE);
1407 setStringToIntegralParameter<ETimeMonitorReportFormat> (name, defaultValue,
1409 strings (), docs (),
1414 TimeMonitor::setYamlFormatParameter (ParameterList& plist)
1416 const std::string name (
"YAML style");
1417 const std::string defaultValue (
"spacious");
1418 const std::string docString (
"YAML-specific output format");
1419 Array<std::string> strings;
1420 Array<std::string> docs;
1421 Array<ETimeMonitorYamlFormat> values;
1423 strings.push_back (
"compact");
1424 docs.push_back (
"Compact format: use \"flow style\" (see YAML 1.2 spec at "
1425 "yaml.org) for most sequences except the outermost sequence");
1426 values.push_back (YAML_FORMAT_COMPACT);
1428 strings.push_back (
"spacious");
1429 docs.push_back (
"Spacious format: avoid flow style");
1430 values.push_back (YAML_FORMAT_SPACIOUS);
1432 setStringToIntegralParameter<ETimeMonitorYamlFormat> (name, defaultValue,
1434 strings (), docs (),
1439 TimeMonitor::setSetOpParameter (ParameterList& plist)
1441 const std::string name (
"How to merge timer sets");
1442 const std::string defaultValue (
"Intersection");
1443 const std::string docString (
"How to merge differing sets of timers "
1444 "across processes");
1445 Array<std::string> strings;
1446 Array<std::string> docs;
1447 Array<ECounterSetOp> values;
1449 strings.push_back (
"Intersection");
1450 docs.push_back (
"Compute intersection of timer sets over processes");
1451 values.push_back (Intersection);
1452 strings.push_back (
"Union");
1453 docs.push_back (
"Compute union of timer sets over processes");
1454 values.push_back (Union);
1456 setStringToIntegralParameter<ECounterSetOp> (name, defaultValue, docString,
1457 strings (), docs (), values (),
1481 const bool alwaysWriteLocal =
false;
1482 const bool writeGlobalStats =
true;
1483 const bool writeZeroTimers =
true;
1485 setReportFormatParameter (*plist);
1486 setYamlFormatParameter (*plist);
1487 setSetOpParameter (*plist);
1488 plist->set (
"alwaysWriteLocal", alwaysWriteLocal,
1489 "Always output local timers' values on Proc 0");
1490 plist->set (
"writeGlobalStats", writeGlobalStats,
"Always output global "
1491 "statistics, even if there is only one process in the "
1493 plist->set (
"writeZeroTimers", writeZeroTimers,
"Generate output for "
1494 "timers that have never been called");
1502 ETimeMonitorReportFormat reportFormat = REPORT_FORMAT_TABLE;
1503 ETimeMonitorYamlFormat yamlStyle = YAML_FORMAT_SPACIOUS;
1505 bool alwaysWriteLocal =
false;
1506 bool writeGlobalStats =
true;
1507 bool writeZeroTimers =
true;
1519 reportFormat = getIntegralValue<ETimeMonitorReportFormat> (*params,
"Report format");
1520 yamlStyle = getIntegralValue<ETimeMonitorYamlFormat> (*params,
"YAML style");
1521 setOp = getIntegralValue<ECounterSetOp> (*params,
"How to merge timer sets");
1522 alwaysWriteLocal = params->
get<
bool> (
"alwaysWriteLocal");
1523 writeGlobalStats = params->get<
bool> (
"writeGlobalStats");
1524 writeZeroTimers = params->get<
bool> (
"writeZeroTimers");
1529 reportFormat_ = reportFormat;
1530 yamlStyle_ = yamlStyle;
1532 alwaysWriteLocal_ = alwaysWriteLocal;
1533 writeGlobalStats_ = writeGlobalStats;
1534 writeZeroTimers_ = writeZeroTimers;
1542 const std::string& filter,
1545 setReportParameters (params);
1547 if (reportFormat_ == REPORT_FORMAT_YAML) {
1548 summarizeToYaml (comm, out, yamlStyle_, filter);
1550 else if (reportFormat_ == REPORT_FORMAT_TABLE) {
1551 summarize (comm, out, alwaysWriteLocal_, writeGlobalStats_,
1552 writeZeroTimers_, setOp_, filter);
1556 "Invalid report format. This should never happen; ParameterList "
1557 "validation should have caught this. Please report this bug to the "
1558 "Teuchos developers.");
1567 report (comm, out,
"", params);
1572 const std::string& filter,
1576 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.