00001 #include <algorithm>
00002 #include "charm++.h"
00003
00004 #if __DEBUG_SPANNING_TREE_
00005 #include <sstream>
00006 #include <fstream>
00007 #endif
00008
00009 #ifndef TREE_STRATEGY_3D_TORUS_MIN_BYTES_HOPS
00010 #define TREE_STRATEGY_3D_TORUS_MIN_BYTES_HOPS
00011 namespace topo {
00012
00025 template <typename Iterator,typename ValueType = typename std::iterator_traits<Iterator>::value_type>
00026 class SpanningTreeStrategy_3dTorus_minBytesHops: public SpanningTreeStrategy<Iterator>
00027 {
00028 public:
00029 virtual SpanningTreeVertex* buildNextGen(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2) = 0;
00030 };
00031
00032
00033
00036 template <typename Iterator>
00037 class SpanningTreeStrategy_3dTorus_minBytesHops<Iterator,SpanningTreeVertex>: public SpanningTreeStrategy<Iterator>
00038 {
00039 public:
00040 virtual SpanningTreeVertex* buildNextGen(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2);
00041 };
00042
00043
00044
00050 template <typename Iterator>
00051 class SpanningTreeStrategy_3dTorus_minBytesHops<Iterator,vtxType>: public SpanningTreeStrategy<Iterator>
00052 {
00053 public:
00054 virtual SpanningTreeVertex* buildNextGen(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2)
00055 {
00057 std::vector<SpanningTreeVertex> tree;
00058 for (Iterator itr = firstVtx; itr != beyondLastVtx; itr++)
00059 tree.push_back( SpanningTreeVertex(*itr) );
00061 SpanningTreeStrategy_3dTorus_minBytesHops< std::vector<SpanningTreeVertex>::iterator > theRealBuilder;
00062 SpanningTreeVertex *result = theRealBuilder.buildNextGen(tree.begin(),tree.end(),maxBranches);
00064 int indx=0;
00065 for (Iterator itr = firstVtx; itr != beyondLastVtx; itr++)
00066 {
00067 *itr = tree[indx].id;
00068 indx++;
00069 }
00071 return result;
00072 }
00073 };
00074
00075 }
00076
00077
00078 #include "TopoManager.h"
00079
00080 namespace topo {
00081
00082 #if __DEBUG_SPANNING_TREE_ && XE6_TOPOLOGY
00083 void writeAllocTopoManager(const char *fileName) {
00084 std::ofstream outfile(fileName);
00085 outfile << "x y z t" << std::endl;
00086 int coords[4];
00087 for (int i=0; i < CkNumPes(); i++) {
00088 TopoManager_getPeCoordinates(i, coords);
00089 outfile << coords[0] << " " << coords[1] << " " << coords[2] << " " << std::endl;
00090 }
00091 outfile.close();
00092 }
00093
00094 template <typename Iterator>
00095 void writeCoordinatesPEList(const char *fileName, const Iterator start, const Iterator end) {
00096 std::ofstream outfile(fileName);
00097 outfile << "x y z t" << std::endl;
00098 for (Iterator itr = start; itr != end; itr++) {
00099 for (int j=0; j < 3; j++) outfile << (*itr).X[j] << " ";
00100 outfile << std::endl;
00101 }
00102 outfile.close();
00103 }
00104 #endif
00105
00106 template <typename Iterator>
00107 SpanningTreeVertex* SpanningTreeStrategy_3dTorus_minBytesHops<Iterator,SpanningTreeVertex>::buildNextGen(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches)
00108 {
00110 (*firstVtx).childIndex.clear();
00111 (*firstVtx).childIndex.reserve(maxBranches);
00112
00114 TopoManager *aTopoMgr = TopoManager::getTopoManager();
00116 int numLocalDestinations = -1, numRemoteDestinations = 0;
00117 Iterator beyondLastLocal = firstVtx;
00118
00120 for (Iterator itr = firstVtx; itr != beyondLastVtx; itr++)
00121 {
00122 (*itr).X.reserve(3);
00123 (*itr).X.assign(3,0);
00124 int coreNum;
00125
00126 aTopoMgr->rankToCoordinates( (*itr).id, (*itr).X[0], (*itr).X[1], (*itr).X[2], coreNum );
00128 if (!(*firstVtx).sameCoordinates(*itr))
00129 numRemoteDestinations++;
00130 else
00131 {
00132 numLocalDestinations++;
00134 if (itr != beyondLastLocal)
00135 std::iter_swap(beyondLastLocal,itr);
00137 beyondLastLocal++;
00138 }
00139 }
00140 impl::TreeBoundingBoxOn3dTorus<Iterator> treePart;
00141 #if XE6_TOPOLOGY
00142 if ((aTopoMgr->getDimNX() > MAX_TORUS_DIM_SIZE) ||
00143 (aTopoMgr->getDimNY() > MAX_TORUS_DIM_SIZE) ||
00144 (aTopoMgr->getDimNZ() > MAX_TORUS_DIM_SIZE)) {
00145 CkAbort("Torus dimension size larger than supported limit. Please increase limit");
00146 }
00147 #if __DEBUG_SPANNING_TREE_
00148 if (CkMyPe() == 0) {
00149 writeAllocTopoManager("alloc_tmgr.txt");
00150 writeCoordinatesPEList("pe_coords.txt", firstVtx, beyondLastVtx);
00151 CkPrintf("numRemoteDestinations = %d\n", numRemoteDestinations);
00152 CkPrintf("numLocalDestinations = %d\n", numLocalDestinations);
00153 }
00154 #endif
00155 treePart.translateCoordinates(firstVtx, beyondLastVtx, 3);
00156 #if __DEBUG_SPANNING_TREE_
00157 if (CkMyPe() == 0) {
00158 writeCoordinatesPEList("pe_coords_translated.txt", firstVtx, beyondLastVtx);
00159 }
00160 #endif
00161 #endif
00162
00164 int numLocalBranches = 0;
00166 if (numLocalDestinations > 0)
00167 {
00168 numLocalBranches = (numRemoteDestinations >= maxBranches)? 1 : (maxBranches - numRemoteDestinations);
00170 SpanningTreeVertex *localTree = impl::buildNextGen_topoUnaware(firstVtx,beyondLastLocal,numLocalBranches);
00172 for (int i=0,n=localTree->childIndex.size(); i<n; i++)
00173 firstVtx->childIndex.push_back( localTree->childIndex[i] );
00175 delete localTree;
00176 #if __DEBUG_SPANNING_TREE_
00177 if (CkMyPe() == 0) {
00178 std::cout << "Local destinations are:" << std::endl;
00179 for (Iterator itr = firstVtx; itr != beyondLastLocal; itr++) std::cout << (*itr).id << " ";
00180 std::cout << std::endl;
00181 }
00182 #endif
00183 }
00184
00186 treePart.partition(firstVtx,beyondLastLocal,beyondLastVtx,maxBranches);
00187
00189 for (int i=numLocalBranches, numChildren=(*firstVtx).childIndex.size(); i<numChildren; i++)
00190 {
00191 Iterator rangeStart = firstVtx;
00192 std::advance(rangeStart,(*firstVtx).childIndex[i]);
00193 Iterator rangeEnd = firstVtx;
00194 if (i+1 == numChildren)
00195 rangeEnd = beyondLastVtx;
00196 else
00197 std::advance(rangeEnd, (*firstVtx).childIndex[i+1] );
00198 Iterator closestItr = pickClosest(*firstVtx,rangeStart,rangeEnd);
00199 #if __DEBUG_SPANNING_TREE_
00200 if (CkMyPe() == 0) {
00201 CkPrintf("Closest PE in subtree %d is %d with distance %d\n", i, (*closestItr).id, numHops(*firstVtx,*closestItr));
00202 }
00203 #endif
00204 std::iter_swap(rangeStart,closestItr);
00205 }
00206 #if __DEBUG_SPANNING_TREE_
00207
00208 char dbout[1024];
00209 int offset = 0;
00210 int coords[4];
00211 int numChildren = (*firstVtx).childIndex.size();
00212 TopoManager_getPeCoordinates(getProcID(*firstVtx), coords);
00213 offset += sprintf(dbout, "TREE: %d (%d,%d,%d) %d ", getProcID(*firstVtx), coords[0], coords[1], coords[2], numChildren);
00214 for (int i=0; i < numChildren; i++) {
00215 Iterator rangeStart = firstVtx;
00216 std::advance(rangeStart,(*firstVtx).childIndex[i]);
00217 int childPE = getProcID(*rangeStart);
00218 TopoManager_getPeCoordinates(childPE, coords);
00219 offset += sprintf(dbout + offset, "%d (%d,%d,%d) ", childPE, coords[0], coords[1], coords[2]);
00220 }
00221 sprintf(dbout + offset, "\n");
00222 CkPrintf(dbout);
00223 #endif
00225 return (new SpanningTreeVertex(*firstVtx) );
00226 }
00227
00228 }
00229 #endif // TREE_STRATEGY_3D_TORUS_MIN_BYTES_HOPS
00230