|
Teuchos Package Browser (Single Doxygen Collection) Version of the Day
|
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 #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 /* gather names of counters from all processors */ 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 /* on the root processor, compile the set union of all names */ 00049 if (comm.getRank()==0) 00050 { 00051 for (Array<Array<std::string> >::size_type p=0; p<namesForAllProcs.size(); p++) 00052 { 00053 for (Array<std::string>::size_type i=0; i<namesForAllProcs[p].size(); i++) 00054 { 00055 nameSet.insert(namesForAllProcs[p][i]); 00056 } 00057 } 00058 } 00059 00060 /* convert the set to an array so we can send it out by MPI */ 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 /* broadcast the union of all names to all processors */ 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 (Array<std::string>::size_type i=0; i<localNames.size(); i++) 00085 { 00086 Array<double> tmp(localValues.size()); 00087 for (Array<Array<double> >::size_type 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 (Array<Array<double> >::size_type i=0; i<allValues.size(); i++) 00098 { 00099 allValues[i].resize(allNames.size()); 00100 } 00101 00102 for (Array<std::string>::size_type 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 (Array<double>::size_type j=0; j<tmp.size(); j++) 00109 { 00110 allValues[j][i] = tmp[j]; 00111 } 00112 } 00113 else 00114 { 00115 for (Array<Array<double> >::size_type 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 /* if we're asking for local values, do nothing but copy the local array 00130 * to the reduced array. */ 00131 if (comm.getNProc()==1 || reductionType==ELocal) 00132 { 00133 reducedVals = localVals; 00134 return; 00135 } 00136 00137 /* If we're to this point we must do a reduction */ 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 (Array<double>::size_type i=0; i<reducedVals.size(); i++) 00156 { 00157 reducedVals[i] /= ((double) comm.getNProc()); 00158 } 00159 } 00160 } 00161 00162 00163 00164
1.7.4