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