Teuchos_PerformanceMonitorUtils.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 #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 

Generated on Tue Jul 13 09:22:59 2010 for Teuchos - Trilinos Tools Package by  doxygen 1.4.7