00001 #include "charm++.h"
00002 #include <algorithm>
00003 
00004 #ifndef TREE_STRATEGY_NODE_AWARE_MIN_GENS
00005 #define TREE_STRATEGY_NODE_AWARE_MIN_GENS
00006 namespace topo {
00007 
00009 namespace impl {
00010     template <typename Iterator>
00011     SpanningTreeVertex* buildNextGen_nodeAware_minGens(const vtxType parentPE, const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2);
00012 }
00013 
00025 template <typename Iterator,typename ValueType = typename std::iterator_traits<Iterator>::value_type>
00026 class SpanningTreeStrategy_nodeAware_minGens: public SpanningTreeStrategy<Iterator>
00027 {
00028     public:
00029         inline virtual SpanningTreeVertex* buildNextGen(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2)
00030         { return impl::buildNextGen_nodeAware_minGens(*firstVtx, firstVtx,beyondLastVtx,maxBranches); }
00031 };
00032 
00033 
00034 
00040 template <typename Iterator>
00041 class SpanningTreeStrategy_nodeAware_minGens<Iterator,SpanningTreeVertex>: public SpanningTreeStrategy<Iterator>
00042 {
00043     public:
00044         inline virtual SpanningTreeVertex* buildNextGen(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2)
00045         {
00047             (*firstVtx).childIndex.clear();
00049             SpanningTreeVertex *parent = impl::buildNextGen_nodeAware_minGens((*firstVtx).id,firstVtx,beyondLastVtx,maxBranches);
00051             *firstVtx = *parent;
00053             return parent;
00054         }
00055 };
00056 
00057 
00058 namespace impl {
00059 
00060     #if CMK_FIND_FIRST_OF_PREDICATE
00061 
00076     class vtxEqual
00077     {
00078         public:
00079             inline bool operator() (const SpanningTreeVertex &vtx, const int num) { return vtx.id == num; }
00080             inline bool operator() (const int num, const SpanningTreeVertex &vtx) { return vtx.id == num; }
00081             inline bool operator() (const int a, const int b) { return a == b; }
00082     };
00083     #endif
00084 
00091     template <typename Iterator>
00092     SpanningTreeVertex* buildNextGen_nodeAware_minGens(const vtxType parentPE, const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches)
00093     {
00095         SpanningTreeVertex *parent = impl::buildNextGen_topoUnaware(firstVtx,beyondLastVtx,maxBranches);
00096 
00098         CkAssert(parentPE < CkNumPes() );
00099         int numOnNode, *pesOnNode;
00100         CmiGetPesOnPhysicalNode(CmiPhysicalNodeID(parentPE),&pesOnNode,&numOnNode);
00101 
00103         if (numOnNode > 0 && parent->childIndex.size() > 0)
00104         {
00105             Iterator itr = firstVtx;
00106             int brNum = 0, numBranches = parent->childIndex.size();
00107 
00109             while ( brNum < numBranches && itr != beyondLastVtx)
00110             {
00111                 std::vector<int>::iterator isChild;
00113                 do {
00114             itr = std::find_first_of(++itr,beyondLastVtx,pesOnNode,pesOnNode + numOnNode
00115 #if CMK_FIND_FIRST_OF_PREDICATE
00116                          , vtxEqual()
00117 #endif
00118             );
00119                     int dist = std::distance(firstVtx,itr);
00121                     isChild = std::find(parent->childIndex.begin(),parent->childIndex.end(),dist);
00122                 } while (itr != beyondLastVtx && isChild != parent->childIndex.end());
00123 
00124                 Iterator childLoc;
00125                 int *pos;
00127                 do {
00128                     childLoc = firstVtx;
00129                     std::advance(childLoc,parent->childIndex[brNum]);
00131                     pos = std::find(pesOnNode,pesOnNode+numOnNode,*childLoc);
00132                 } while( pos < (numOnNode+pesOnNode) && ++brNum < numBranches );
00133 
00135                 if (itr != beyondLastVtx && brNum < numBranches)
00136                 {
00137                     std::iter_swap(itr,childLoc);
00138                     brNum++;
00139                 }
00140             }
00141         }
00142 
00144         return parent;
00145     }
00146 } 
00147 
00148 } 
00149 #endif // TREE_STRATEGY_NODE_AWARE_MIN_GENS
00150