00001 #include <iostream>
00002 #include <vector>
00003 #include <iterator>
00004 #include <cstdlib>
00005
00006 #include "conv-config.h"
00007 #include "spanningTreeVertex.h"
00008
00009 #ifndef SPANNING_TREE_STRATEGY
00010 #define SPANNING_TREE_STRATEGY
00011
00012 #if ! CMK_HAS_ITERATOR_TRAITS
00013 namespace std {
00014
00015 template <class Iterator>
00016 struct iterator_traits {
00017 typedef typename Iterator::iterator_category iterator_category;
00018 typedef typename Iterator::value_type value_type;
00019 typedef typename Iterator::difference_type difference_type;
00020 typedef typename Iterator::pointer pointer;
00021 typedef typename Iterator::reference reference;
00022 };
00023
00024 template <class T>
00025 struct iterator_traits<T*> {
00026 typedef random_access_iterator_tag iterator_category;
00027 typedef T value_type;
00028 typedef ptrdiff_t difference_type;
00029 typedef T* pointer;
00030 typedef T& reference;
00031 };
00032
00033 }
00034
00035 #endif
00036
00037 #if ! CMK_HAS_STD_DISTANCE
00038 namespace std {
00039
00040 template <class Iterator>
00041 int distance(Iterator first, Iterator last)
00042 {
00043 int n=0;
00044 while (first!=last)
00045 {
00046 ++first;
00047 ++n;
00048 }
00049
00050 return n;
00051 }
00052 }
00053 #endif
00054
00108
00109
00111 namespace topo {
00112
00114 typedef int vtxType;
00115
00117 class SpanningTreeVertex;
00118
00120 template <typename Iterator,typename ValueType = typename std::iterator_traits<Iterator>::value_type>
00121 class SpanningTreeStrategy;
00122
00124
00125
00126 template <typename Iterator>
00127 SpanningTreeVertex* buildSpanningTreeGeneration
00128 (const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2);
00129
00130 template <typename Iterator>
00131 SpanningTreeVertex* buildSpanningTreeGeneration
00132 (const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches, SpanningTreeStrategy<Iterator> *bldr);
00134
00136
00137
00138 template <typename Iterator>
00139 void buildSpanningTree
00140 (const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2);
00141
00142 template <typename Iterator>
00143 void buildSpanningTree
00144 (const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches, SpanningTreeStrategy<Iterator> *bldr);
00146
00148 template <typename Iterator>
00149 SpanningTreeStrategy<Iterator>* getSpanningTreeStrategy
00150 (const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches);
00151
00152 }
00153
00154
00155
00156
00157 namespace topo {
00158
00168 template <typename Iterator,typename ValueType>
00169 class SpanningTreeStrategy
00170 {
00171 public:
00173 virtual SpanningTreeVertex* buildNextGen(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2) = 0;
00174 };
00175
00176
00177
00178
00192 template <typename Iterator>
00193 inline SpanningTreeVertex* buildSpanningTreeGeneration(const Iterator firstVtx,
00194 const Iterator beyondLastVtx,
00195 const int maxBranches,
00196 SpanningTreeStrategy<Iterator> *bldr
00197 )
00198 {
00199 CkAssert(NULL != bldr);
00200
00202 if (maxBranches < 1 || firstVtx == beyondLastVtx)
00203 return new SpanningTreeVertex();
00204 else
00206 return bldr->buildNextGen(firstVtx,beyondLastVtx,maxBranches);
00207 }
00208
00209
00210
00211 template <typename Iterator>
00212 inline SpanningTreeVertex* buildSpanningTreeGeneration(const Iterator firstVtx,
00213 const Iterator beyondLastVtx,
00214 const int maxBranches
00215 )
00216 {
00217 SpanningTreeStrategy<Iterator> *bldr =
00218 getSpanningTreeStrategy(firstVtx,beyondLastVtx,maxBranches);
00219 SpanningTreeVertex *result = buildSpanningTreeGeneration(firstVtx, beyondLastVtx, maxBranches, bldr);
00220 delete bldr;
00221 return result;
00222 }
00223
00224
00225
00227 namespace impl {
00228
00230 template <typename Iterator>
00231 void buildSpanningTree(SpanningTreeVertex* dispatchTag,
00232 const Iterator firstVtx,
00233 const Iterator beyondLastVtx,
00234 const int maxBranches,
00235 SpanningTreeStrategy<Iterator> *bldr
00236 )
00237 {
00239 if (maxBranches < 1 || firstVtx == beyondLastVtx)
00240 return;
00241
00243 SpanningTreeVertex *tmp = buildSpanningTreeGeneration(firstVtx,beyondLastVtx,maxBranches,bldr);
00245 delete tmp;
00246
00247 int numChildren = (*firstVtx).childIndex.size();
00249 for (int i=0; i< numChildren; i++)
00250 {
00252 Iterator start = firstVtx, end = firstVtx;
00253 std::advance(start, (*firstVtx).childIndex[i] );
00254 if (i < numChildren -1)
00255 std::advance(end, (*firstVtx).childIndex[i+1] );
00256 else
00257 end = beyondLastVtx;
00259 buildSpanningTree(dispatchTag,start,end,maxBranches,bldr);
00260 }
00261 }
00262
00263 }
00264
00265
00266
00267
00273 template <typename Iterator>
00274 inline void buildSpanningTree(const Iterator firstVtx,
00275 const Iterator beyondLastVtx,
00276 const int maxBranches,
00277 SpanningTreeStrategy<Iterator> *bldr
00278 )
00279 {
00280 CkAssert(NULL != bldr);
00282 typename std::iterator_traits<Iterator>::value_type *tag = 0;
00284 impl::buildSpanningTree(tag,firstVtx,beyondLastVtx,maxBranches,bldr);
00285 }
00286
00287
00288
00289 template <typename Iterator>
00290 inline void buildSpanningTree(const Iterator firstVtx,
00291 const Iterator beyondLastVtx,
00292 const int maxBranches
00293 )
00294 {
00295 SpanningTreeStrategy<Iterator> *bldr =
00296 getSpanningTreeStrategy(firstVtx,beyondLastVtx,maxBranches);
00297 buildSpanningTree(firstVtx, beyondLastVtx, maxBranches, bldr);
00298 delete bldr;
00299 }
00300
00301 }
00302
00303
00304
00309 #include "treeStrategy_topoUnaware.h"
00310 #include "treeStrategy_nodeAware_minGens.h"
00311 #include "treeStrategy_nodeAware_minBytes.h"
00312 #include "treeStrategy_3dTorus_minHops.h"
00313 #include "treeStrategy_3dTorus_minBytesHops.h"
00314
00315 namespace topo {
00316
00326 template <typename Iterator>
00327 inline SpanningTreeStrategy<Iterator>* getSpanningTreeStrategy(const Iterator firstVtx,
00328 const Iterator beyondLastVtx,
00329 const int maxBranches)
00330 {
00331 #if CMK_BLUEGENEL || CMK_BLUEGENEP
00332 return ( new SpanningTreeStrategy_3dTorus_minBytesHops<Iterator>() );
00333 #elif XT3_TOPOLOGY || XT4_TOPOLOGY || XT5_TOPOLOGY
00334 return ( new SpanningTreeStrategy_3dTorus_minBytesHops<Iterator>() );
00335 #else
00337 class NumOnNode
00338 {
00339 public:
00340 inline int operator() (const vtxType vtx) { return CmiNumPesOnPhysicalNode( CmiPhysicalNodeID(vtx) ); }
00341 inline int operator() (const SpanningTreeVertex &vtx) { return CmiNumPesOnPhysicalNode( CmiPhysicalNodeID(vtx.id) ); }
00342 } findNumPEsOnNode;
00343
00345 int numPEsOnNode = findNumPEsOnNode(*firstVtx);
00346
00348 if (numPEsOnNode <= 4 && maxBranches < 4)
00349 return ( new SpanningTreeStrategy_nodeAware_minGens<Iterator>() );
00350 else
00351 return ( new SpanningTreeStrategy_nodeAware_minBytes<Iterator>() );
00352 #endif
00353 }
00354
00355 }
00356
00357 #endif // SPANNING_TREE_STRATEGY
00358