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