00001 #ifndef TRANS_MST_CLUSTER_MAKER_CPP
00002 #define TRANS_MST_CLUSTER_MAKER_CPP
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
00030
00031
00032
00033
00034
00035
00036
00037 #include "TransMSTClusterMaker.h"
00038 #include "HeuristicFactory.h"
00039 #include "TVHeuristic.h"
00040 #include "MPIStats.h"
00041
00042 float TransMSTClusterMaker::badMetric = 0;
00043
00044 TransMSTClusterMaker::TransMSTClusterMaker(ESTAnalyzer *analyzer,
00045 const int refESTidx,
00046 const std::string& outputFile) :
00047 MSTClusterMaker(analyzer, refESTidx, outputFile) {
00048
00049 currRefESTidx = 0;
00050
00051 analyzeCount = 0;
00052 successCount = 0;
00053
00054 badMetric = analyzer->getInvalidMetric();
00055 }
00056
00057 TransMSTClusterMaker::~TransMSTClusterMaker() {
00058 int startESTidx, endESTidx;
00059 getOwnedESTidx(startESTidx, endESTidx);
00060 for (int i = startESTidx; (i < endESTidx); i++) {
00061 if (metricCache[i] != NULL) {
00062 delete metricCache[i];
00063 }
00064 }
00065 }
00066
00067 void
00068 TransMSTClusterMaker::displayStats(std::ostream& os) {
00069
00070 MSTClusterMaker::displayStats(os);
00071
00072 os << " Total calls to analyze : " << analyzeCount << "\n"
00073 << " Successful transitivity : " << successCount << "\n";
00074 }
00075
00076 int
00077 TransMSTClusterMaker::initialize() {
00078 int result = MSTClusterMaker::initialize();
00079 if (result != NO_ERROR) {
00080
00081 return result;
00082 }
00083 if (analyzer->getHeuristicChain() == NULL) {
00084 std::cerr << "TransMSTClusterMaker: No suitable heuristic found!"
00085 << "\n";
00086 return ERROR_NO_HEURISTIC;
00087 }
00088
00089
00090 metricCache.reserve(EST::getESTList().size());
00091 metricCache.insert(metricCache.begin(), EST::getESTList().size(), NULL);
00092 return NO_ERROR;
00093 }
00094
00095 float
00096 TransMSTClusterMaker::analyze(const int otherEST) {
00097
00098 analyzeCount++;
00099
00100 if (analyzer->compareMetrics(analyzer->analyze(otherEST, true, false),
00101 badMetric)) {
00102 ASSERT ( currRefESTidx >= 0 );
00103
00104 TransCacheEntry* mainEntry = metricCache[otherEST];
00105 float transMetric;
00106 if (mainEntry != NULL &&
00107 mainEntry->getMetric(currRefESTidx, transMetric)) {
00108
00109
00110 successCount++;
00111 return transMetric;
00112 }
00113
00114
00115 return analyzer->analyze(otherEST, false);
00116 }
00117
00118 return badMetric;
00119 }
00120
00121 void
00122 TransMSTClusterMaker::pruneMetricEntries(const SMList& list,
00123 SMList& goodEntries) {
00124
00125
00126 goodEntries.reserve(list.size());
00127 for(SMList::const_iterator entry = list.begin();
00128 (entry != list.end()); entry++) {
00129 if ((analyzer->compareMetrics(entry->metric, badMetric))) {
00130
00131 goodEntries.push_back(*entry);
00132 }
00133 }
00134
00135
00136 if (goodEntries.empty()) {
00137 CachedESTInfo dummy(-1, -1, badMetric, -1, -1);
00138 goodEntries.push_back(dummy);
00139 }
00140 }
00141
00142 void
00143 TransMSTClusterMaker::populateCache(const int estIdx,
00144 SMList* UNREFERENCED_PARAMETER(metricList)) {
00145 currRefESTidx = estIdx;
00146
00147
00148 SMList smList;
00149 MSTClusterMaker::populateCache(estIdx, &smList);
00150
00151
00152
00153 const int ownerRank = getOwnerProcess(estIdx);
00154 if (ownerRank == MPI_GET_RANK()) {
00155
00156
00157
00158 SMList goodEntries;
00159 pruneMetricEntries(smList, goodEntries);
00160 const int MsgSize = goodEntries.size() * sizeof(CachedESTInfo);
00161 const int ProcessCount = MPI_GET_SIZE();
00162
00163 const char *data = reinterpret_cast<char*>(&goodEntries[0]);
00164
00165
00166
00167 for(int rank = 0; (rank < ProcessCount); rank++) {
00168 if (rank != ownerRank) {
00169 MPI_SEND(data, MsgSize, MPI_CHAR, rank, TRANSITIVITY_LIST);
00170 }
00171 }
00172 if ((goodEntries.size() == 1) && (goodEntries[0].estIdx == -1)) {
00173
00174 return;
00175 }
00176 processMetricList(goodEntries);
00177
00178
00179 delete metricCache[estIdx];
00180 metricCache[estIdx] = NULL;
00181 } else {
00182
00183
00184
00185 MPI_STATUS msgInfo;
00186 MPI_PROBE(ownerRank, TRANSITIVITY_LIST, msgInfo);
00187
00188 const int dataSize = msgInfo.Get_count(MPI_TYPE_CHAR);
00189 SMList remoteList(dataSize / sizeof(CachedESTInfo));
00190 TRACK_IDLE_TIME(MPI_RECV(&remoteList[0], dataSize, MPI_CHAR,
00191 ownerRank, TRANSITIVITY_LIST));
00192
00193
00194
00195 if ((remoteList.size() == 1) && (remoteList[0].estIdx == -1)) {
00196
00197 return;
00198 }
00199 processMetricList(remoteList);
00200 }
00201 }
00202
00203 void
00204 TransMSTClusterMaker::processMetricList(SMList& metricList) {
00205
00206
00207
00208 int startESTidx, endESTidx;
00209 getOwnedESTidx(startESTidx, endESTidx);
00210
00211
00212 for(size_t i = 0; (i < metricList.size()); i++) {
00213
00214 if (metricList[i].estIdx >= startESTidx &&
00215 metricList[i].estIdx < endESTidx) {
00216 TransCacheEntry* entry = metricCache[metricList[i].estIdx];
00217 if (entry == NULL) {
00218 entry = new TransCacheEntry(metricList[i].estIdx);
00219 }
00220 entry->addEntries(metricList[i], metricList,
00221 startESTidx, endESTidx);
00222 metricCache[metricList[i].estIdx] = entry;
00223 }
00224 }
00225 }
00226
00227 #endif