Teuchos - Trilinos Tools Package Version of the Day
Teuchos_TimeMonitor.cpp
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 
00030 #include "Teuchos_TimeMonitor.hpp"
00031 #include "Teuchos_TableColumn.hpp"
00032 #include "Teuchos_TableFormat.hpp"
00033 #include "Teuchos_MPIContainerComm.hpp"
00034 
00035 
00036 namespace Teuchos {
00037 
00038 
00039 void TimeMonitor::zeroOutTimers()
00040 {
00041   
00042   const Array<RCP<Time> > timers = counters();
00043   
00044   const int numTimers = timers.size();
00045   
00046   for( int i = 0; i < numTimers; ++i ) {
00047     Time &timer = *timers[i];
00048 #ifdef TEUCHOS_DEBUG
00049     TEST_FOR_EXCEPTION(
00050       timer.isRunning(), std::logic_error,
00051       "Teuchos::TimeMonitor::zeroOutTimers():\n\n"
00052       "Error, the timer i = " << i << " with name \"" << timer.name() << "\""
00053       " is current running and not not be set to zero!"
00054       );
00055 #endif
00056     timer.reset();
00057   }
00058   
00059 }
00060 
00061 
00062 void TimeMonitor::summarize(
00063   std::ostream &out,
00064   const bool alwaysWriteLocal,
00065   const bool writeGlobalStats,
00066   const bool writeZeroTimers
00067   )
00068 {
00069 
00070   Array<std::string> localNames(counters().length());
00071   Array<double> localTimings(counters().length());
00072   Array<double> localCallCounts(counters().length());
00073 
00074   for (int i=0; i<counters().length(); i++)
00075   {
00076     localNames[i] = counters()[i]->name();
00077     localTimings[i] = counters()[i]->totalElapsedTime();
00078     localCallCounts[i] = counters()[i]->numCalls();
00079   }
00080   
00081   // Gather timings from all procs, in case some timers have been activated on
00082   // other processors but not on this one.
00083   Array<std::string> names;
00084   Array<Array<double> > data(2);
00085   PerformanceMonitorUtils::synchValues(MPIComm::world(), localNames, 
00086     tuple(localTimings, localCallCounts),
00087     names, data);
00088   
00089   Array<double>& timings = data[0];
00090   Array<double>& calls = data[1];
00091 
00092   // Remove zero rows
00093   if (!writeZeroTimers) {
00094     Teuchos::Array<std::string>::iterator nms=names.end();
00095     Teuchos::Array<double>::iterator tms=timings.end();
00096     Teuchos::Array<double>::iterator cls=calls.end();
00097     for (int i=names.length()-1; i>=0; i--)  {
00098       cls--; nms--; tms--;
00099       if (calls[i]<0.1) {
00100         calls.erase(cls);
00101         names.erase(nms);
00102         timings.erase(tms);
00103       }
00104     }
00105   }
00106   
00107   // Form the table data
00108   MPIComm comm = MPIComm::world();
00109   int np = comm.getNProc();
00110 
00111   int precision = format().precision();
00112 
00113   Array<TableColumn> columnsToWrite;
00114 
00115   TableColumn nameCol(names);
00116   Array<std::string> titles;
00117   titles.append("Timer Name");
00118 
00119   columnsToWrite.append(nameCol);
00120 
00121   Array<int> columnWidths;
00122   columnWidths.append(format().computeRequiredColumnWidth(titles[titles.size()-1], 
00123       nameCol));
00124 
00125     if (np==1 || alwaysWriteLocal)
00126     {
00127       TableColumn timeAndCalls(timings, calls, precision, true);
00128       titles.append("Local time (num calls)");
00129       columnsToWrite.append(timeAndCalls);
00130       columnWidths.append(format().computeRequiredColumnWidth(titles[titles.size()-1], 
00131     timeAndCalls));
00132     }
00133     
00134     if (np > 1 && writeGlobalStats)
00135     {
00136 
00137       titles.append("Min over procs");
00138         
00139       Array<double> minTimings;
00140       PerformanceMonitorUtils::reduce(comm, EMin, timings, minTimings);
00141         
00142       Array<double> minCalls;
00143       PerformanceMonitorUtils::reduce(comm, EMin, calls, minCalls);
00144 
00145       TableColumn timeAndCalls(minTimings, minCalls, precision, true);
00146       columnsToWrite.append(timeAndCalls);
00147         
00148       columnWidths.append(format().computeRequiredColumnWidth(titles[titles.size()-1], 
00149     timeAndCalls));
00150 
00151     }
00152     
00153     if (np > 1 && writeGlobalStats)
00154     {
00155 
00156       titles.append("Avg over procs");
00157         
00158       Array<double> avgTimings;
00159       PerformanceMonitorUtils::reduce(comm, EAvg, timings, avgTimings);
00160         
00161       Array<double> avgCalls;
00162       PerformanceMonitorUtils::reduce(comm, EAvg, calls, avgCalls);
00163 
00164       TableColumn timeAndCalls(avgTimings, avgCalls, precision, true);
00165       columnsToWrite.append(timeAndCalls);
00166         
00167       columnWidths.append(format().computeRequiredColumnWidth(titles[titles.size()-1], 
00168     timeAndCalls));
00169 
00170     }
00171     
00172     if (np > 1 && writeGlobalStats)
00173     {
00174 
00175       titles.append("Max over procs");
00176         
00177       Array<double> maxTimings;
00178       PerformanceMonitorUtils::reduce(comm, EMax, timings, maxTimings);
00179         
00180       Array<double> maxCalls;
00181       PerformanceMonitorUtils::reduce(comm, EMax, calls, maxCalls);
00182 
00183       TableColumn timeAndCalls(maxTimings, maxCalls, precision, true);
00184       columnsToWrite.append(timeAndCalls);
00185         
00186       columnWidths.append(format().computeRequiredColumnWidth(titles[titles.size()-1], 
00187     timeAndCalls));
00188 
00189     }
00190 
00191     format().setColumnWidths(columnWidths);
00192 
00193     const bool writeOnThisProcessor = ( comm.getRank()==0 || alwaysWriteLocal );
00194     if (writeOnThisProcessor)
00195     {
00196       format().writeWholeTable(out, "TimeMonitor Results",
00197         titles, columnsToWrite);
00198     }
00199 
00200   }
00201 
00202 
00203   } // namespace Tuechos
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines