00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "Teuchos_PerformanceMonitorUtils.hpp"
00030 #include "Teuchos_MPIContainerComm.hpp"
00031 #include "Teuchos_ConfigDefs.hpp"
00032 using namespace Teuchos;
00033
00034
00035 void PerformanceMonitorUtils::synchNames(const MPIComm& comm,
00036 const Array<std::string>& localNames,
00037 Array<std::string>& allNames)
00038 {
00039 if (comm.getNProc() > 1)
00040 {
00041
00042 int root = 0;
00043 std::set<std::string> nameSet;
00044 Array<Array<std::string> > namesForAllProcs;
00045 MPIContainerComm<std::string>::gatherv(localNames, namesForAllProcs,
00046 root, comm);
00047
00048
00049 if (comm.getRank()==0)
00050 {
00051 for (unsigned int p=0; p<namesForAllProcs.size(); p++)
00052 {
00053 for (unsigned int i=0; i<namesForAllProcs[p].size(); i++)
00054 {
00055 nameSet.insert(namesForAllProcs[p][i]);
00056 }
00057 }
00058 }
00059
00060
00061 allNames.resize(0);
00062 for (std::set<std::string>::const_iterator i=nameSet.begin(); i!=nameSet.end(); i++)
00063 {
00064 allNames.append(*i);
00065 }
00066
00067 MPIContainerComm<std::string>::bcast(allNames, root, comm);
00068 }
00069 else
00070 {
00071 allNames = localNames;
00072 }
00073 }
00074
00075 void PerformanceMonitorUtils
00076 ::synchValues(const MPIComm& comm,
00077 const Array<std::string>& localNames,
00078 const Array<Array<double> >& localValues,
00079 Array<std::string>& allNames,
00080 Array<Array<double> >& allValues)
00081 {
00082 std::map<std::string, Array<double> > localNameToValMap;
00083
00084 for (unsigned int i=0; i<localNames.size(); i++)
00085 {
00086 Array<double> tmp(localValues.size());
00087 for (unsigned int j=0; j<localValues.size(); j++)
00088 {
00089 tmp[j] = localValues[j][i];
00090 }
00091 localNameToValMap[localNames[i]] = tmp;
00092 }
00093
00094 synchNames(comm, localNames, allNames);
00095
00096 allValues.resize(localValues.size());
00097 for (unsigned int i=0; i<allValues.size(); i++)
00098 {
00099 allValues[i].resize(allNames.size());
00100 }
00101
00102 for (unsigned int i=0; i<allNames.size(); i++)
00103 {
00104 const std::string& name = allNames[i];
00105 if (localNameToValMap.find(name) != localNameToValMap.end())
00106 {
00107 const Array<double>& tmp = localNameToValMap[name];
00108 for (unsigned int j=0; j<tmp.size(); j++)
00109 {
00110 allValues[j][i] = tmp[j];
00111 }
00112 }
00113 else
00114 {
00115 for (unsigned int j=0; j<allValues.size(); j++)
00116 {
00117 allValues[j][i] = 0.0;
00118 }
00119 }
00120 }
00121 }
00122
00123
00124 void PerformanceMonitorUtils::reduce(const MPIComm& comm,
00125 const EMetricReduction& reductionType,
00126 const Array<double>& localVals,
00127 Array<double>& reducedVals)
00128 {
00129
00130
00131 if (comm.getNProc()==1 || reductionType==ELocal)
00132 {
00133 reducedVals = localVals;
00134 return;
00135 }
00136
00137
00138 reducedVals.resize(localVals.size());
00139
00140 int op = MPIComm::SUM;
00141 if (reductionType==EMax) op = MPIComm::MAX;
00142 if (reductionType==EMin) op = MPIComm::MIN;
00143
00144 int sendCount = localVals.size();
00145
00146 if (sendCount==0) return;
00147
00148 double* sendBuf = const_cast<double*>(&localVals[0]);
00149 double* recvBuf = const_cast<double*>(&reducedVals[0]);
00150
00151 comm.allReduce( (void*) sendBuf, (void*) recvBuf, sendCount, MPIComm::DOUBLE, op);
00152
00153 if (reductionType==EAvg)
00154 {
00155 for (unsigned int i=0; i<reducedVals.size(); i++)
00156 {
00157 reducedVals[i] /= ((double) comm.getNProc());
00158 }
00159 }
00160 }
00161
00162
00163
00164