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:
00172 virtual ~SpanningTreeStrategy(){}
00174 virtual SpanningTreeVertex* buildNextGen(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2) = 0;
00175 };
00176
00177
00178
00179
00193 template <typename Iterator>
00194 inline SpanningTreeVertex* buildSpanningTreeGeneration(const Iterator firstVtx,
00195 const Iterator beyondLastVtx,
00196 const int maxBranches,
00197 SpanningTreeStrategy<Iterator> *bldr
00198 )
00199 {
00200 CkAssert(NULL != bldr);
00201
00203 if (maxBranches < 1 || firstVtx == beyondLastVtx)
00204 return new SpanningTreeVertex();
00205 else
00207 return bldr->buildNextGen(firstVtx,beyondLastVtx,maxBranches);
00208 }
00209
00210
00211
00212 template <typename Iterator>
00213 inline SpanningTreeVertex* buildSpanningTreeGeneration(const Iterator firstVtx,
00214 const Iterator beyondLastVtx,
00215 const int maxBranches
00216 )
00217 {
00218 SpanningTreeStrategy<Iterator> *bldr =
00219 getSpanningTreeStrategy(firstVtx,beyondLastVtx,maxBranches);
00220 SpanningTreeVertex *result = buildSpanningTreeGeneration(firstVtx, beyondLastVtx, maxBranches, bldr);
00221 delete bldr;
00222 return result;
00223 }
00224
00225
00226
00228 namespace impl {
00229
00231 template <typename Iterator>
00232 void buildSpanningTree(SpanningTreeVertex* dispatchTag,
00233 const Iterator firstVtx,
00234 const Iterator beyondLastVtx,
00235 const int maxBranches,
00236 SpanningTreeStrategy<Iterator> *bldr
00237 )
00238 {
00240 if (maxBranches < 1 || firstVtx == beyondLastVtx)
00241 return;
00242
00244 SpanningTreeVertex *tmp = buildSpanningTreeGeneration(firstVtx,beyondLastVtx,maxBranches,bldr);
00246 delete tmp;
00247
00248 int numChildren = (*firstVtx).childIndex.size();
00250 for (int i=0; i< numChildren; i++)
00251 {
00253 Iterator start = firstVtx, end = firstVtx;
00254 std::advance(start, (*firstVtx).childIndex[i] );
00255 if (i < numChildren -1)
00256 std::advance(end, (*firstVtx).childIndex[i+1] );
00257 else
00258 end = beyondLastVtx;
00260 buildSpanningTree(dispatchTag,start,end,maxBranches,bldr);
00261 }
00262 }
00263
00264 }
00265
00266
00267
00268
00274 template <typename Iterator>
00275 inline void buildSpanningTree(const Iterator firstVtx,
00276 const Iterator beyondLastVtx,
00277 const int maxBranches,
00278 SpanningTreeStrategy<Iterator> *bldr
00279 )
00280 {
00281 CkAssert(NULL != bldr);
00283 typename std::iterator_traits<Iterator>::value_type *tag = 0;
00285 impl::buildSpanningTree(tag,firstVtx,beyondLastVtx,maxBranches,bldr);
00286 }
00287
00288
00289
00290 template <typename Iterator>
00291 inline void buildSpanningTree(const Iterator firstVtx,
00292 const Iterator beyondLastVtx,
00293 const int maxBranches
00294 )
00295 {
00296 SpanningTreeStrategy<Iterator> *bldr =
00297 getSpanningTreeStrategy(firstVtx,beyondLastVtx,maxBranches);
00298 buildSpanningTree(firstVtx, beyondLastVtx, maxBranches, bldr);
00299 delete bldr;
00300 }
00301
00302 }
00303
00304
00305
00310 #if XE6_TOPOLOGY
00311 #define MAX_TORUS_DIM_SIZE 24
00312 #endif
00313 #include "treeStrategy_topoUnaware.h"
00314 #include "treeStrategy_nodeAware_minGens.h"
00315 #include "treeStrategy_nodeAware_minBytes.h"
00316 #include "treeStrategy_3dTorus_minHops.h"
00317 #include "treeStrategy_3dTorus_minBytesHops.h"
00318
00319 namespace topo {
00320
00330 template <typename Iterator>
00331 inline SpanningTreeStrategy<Iterator>* getSpanningTreeStrategy(const Iterator firstVtx,
00332 const Iterator beyondLastVtx,
00333 const int maxBranches)
00334 {
00335 #if XT3_TOPOLOGY || XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
00336 return ( new SpanningTreeStrategy_3dTorus_minBytesHops<Iterator>() );
00337 #else
00339 class NumOnNode
00340 {
00341 public:
00342 inline int operator() (const vtxType vtx) { return CmiNumPesOnPhysicalNode( CmiPhysicalNodeID(vtx) ); }
00343 inline int operator() (const SpanningTreeVertex &vtx) { return CmiNumPesOnPhysicalNode( CmiPhysicalNodeID(vtx.id) ); }
00344 } findNumPEsOnNode;
00345
00347 int numPEsOnNode = findNumPEsOnNode(*firstVtx);
00348
00350 if (numPEsOnNode <= 4 && maxBranches < 4)
00351 return ( new SpanningTreeStrategy_nodeAware_minGens<Iterator>() );
00352 else
00353 return ( new SpanningTreeStrategy_nodeAware_minBytes<Iterator>() );
00354 #endif
00355 }
00356
00357 }
00358
00359 #endif // SPANNING_TREE_STRATEGY
00360