00001 #include "charm++.h"
00002 #include <algorithm>
00003
00004 #ifndef TREE_STRATEGY_NODE_AWARE_MIN_BYTES
00005 #define TREE_STRATEGY_NODE_AWARE_MIN_BYTES
00006 namespace topo {
00007
00009 namespace impl {
00010 template <typename Iterator>
00011 SpanningTreeVertex* buildNextGen_nodeAware_minBytes(const vtxType parentPE, const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2);
00012 }
00013
00024 template <typename Iterator,typename ValueType = typename std::iterator_traits<Iterator>::value_type>
00025 class SpanningTreeStrategy_nodeAware_minBytes: public SpanningTreeStrategy<Iterator>
00026 {
00027 public:
00028 inline virtual SpanningTreeVertex* buildNextGen(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2)
00029 { return impl::buildNextGen_nodeAware_minBytes(*firstVtx, firstVtx,beyondLastVtx,maxBranches); }
00030 };
00031
00032
00033
00039 template <typename Iterator>
00040 class SpanningTreeStrategy_nodeAware_minBytes<Iterator,SpanningTreeVertex>: public SpanningTreeStrategy<Iterator>
00041 {
00042 public:
00043 inline virtual SpanningTreeVertex* buildNextGen(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches=2)
00044 {
00046 (*firstVtx).childIndex.clear();
00048 SpanningTreeVertex *parent = impl::buildNextGen_nodeAware_minBytes((*firstVtx).id,firstVtx,beyondLastVtx,maxBranches);
00050 *firstVtx = *parent;
00052 return parent;
00053 }
00054 };
00055
00056
00057 namespace impl {
00061 template <typename Iterator>
00062 SpanningTreeVertex* buildNextGen_nodeAware_minBytes(const vtxType parentPE, const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches)
00063 {
00065 CkAssert(parentPE < CkNumPes() );
00066 int numOnNode, *pesOnNode;
00067 CmiGetPesOnPhysicalNode(CmiPhysicalNodeID(parentPE),&pesOnNode,&numOnNode);
00068
00071 int numLocalDestinations = 0, numLocalBranches = 0;
00073 SpanningTreeVertex *parent = 0;
00075 Iterator itr = firstVtx, lastLocal = firstVtx;
00076
00078 while ( numLocalDestinations < numOnNode -1 && itr != beyondLastVtx)
00079 {
00081 itr = std::find_first_of(++itr,beyondLastVtx,pesOnNode,pesOnNode + numOnNode
00082 #if CMK_FIND_FIRST_OF_PREDICATE
00083 , vtxEqual()
00084 #endif
00085 );
00086
00088 if (itr != beyondLastVtx)
00089 {
00090 numLocalDestinations++;
00091 if (itr != ++lastLocal)
00092 std::iter_swap(itr,lastLocal);
00093 }
00094 }
00095
00098 if (numLocalDestinations > 0)
00099 {
00101 int numRemoteDestinations = std::distance(firstVtx,beyondLastVtx) -1 - numLocalDestinations;
00102 numLocalBranches = (numRemoteDestinations >= maxBranches)? 1 : (maxBranches - numRemoteDestinations);
00103
00105 Iterator beyondLastLocal = lastLocal;
00106 parent = buildNextGen_topoUnaware(firstVtx,++beyondLastLocal,numLocalBranches);
00107
00109 SpanningTreeVertex *remoteSubTrees = buildNextGen_topoUnaware(lastLocal,beyondLastVtx,maxBranches);
00110
00112 for (int i=0, n=remoteSubTrees->childIndex.size(); i< n; i++)
00113 parent->childIndex.push_back(remoteSubTrees->childIndex[i] + numLocalDestinations);
00114 delete remoteSubTrees;
00115 }
00116 else
00117 parent = buildNextGen_topoUnaware(firstVtx,beyondLastVtx,maxBranches);
00118
00120 return parent;
00121 }
00122 }
00123
00124 }
00125 #endif // TREE_STRATEGY_NODE_AWARE_MIN_BYTES
00126