00001 #include "charm++.h"
00002
00003 #include <map>
00004
00005 #ifndef TREE_STRATEGY_TOPO_UNAWARE
00006 #define TREE_STRATEGY_TOPO_UNAWARE
00007 namespace topo {
00008
00010 namespace impl {
00011 template <typename Iterator>
00012 SpanningTreeVertex* buildNextGen_topoUnaware(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches);
00013 }
00014
00025 template <typename Iterator,typename ValueType = typename std::iterator_traits<Iterator>::value_type>
00026 class SpanningTreeStrategy_topoUnaware: 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_topoUnaware(firstVtx,beyondLastVtx,maxBranches); }
00031 };
00032
00033
00034
00039 template <typename Iterator>
00040 class SpanningTreeStrategy_topoUnaware<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_topoUnaware(firstVtx,beyondLastVtx,maxBranches);
00050 *firstVtx = *parent;
00052 return parent;
00053 }
00054 };
00055
00056
00057 namespace impl {
00058 template <typename Iterator>
00059 SpanningTreeVertex* buildNextGen_topoUnaware(const Iterator firstVtx, const Iterator beyondLastVtx, const int maxBranches)
00060 {
00062 if (maxBranches < 1 || firstVtx == beyondLastVtx) return new SpanningTreeVertex();
00063
00065 SpanningTreeVertex *parent = new SpanningTreeVertex(*firstVtx);
00066
00067
00068 if(firstVtx+1 == beyondLastVtx) return parent;
00069
00070
00071 std::vector<int> nodesSeq;
00072 #if CMK_SMP
00073
00074 std::map<int, int> nodesMap;
00075 int localIndex = 1;
00076 for(Iterator vtx=firstVtx+1; vtx!=beyondLastVtx; vtx++, localIndex++){
00077 int nid = CmiNodeOf(topo::getProcID(*vtx));
00078 if(nodesMap.find(nid) == nodesMap.end()){
00079
00080 nodesMap[nid] = localIndex;
00081 nodesSeq.push_back(localIndex);
00082 }
00083 }
00084 nodesMap.clear();
00085 int totalNodes = nodesSeq.size();
00086
00087
00088 int pnid = CmiNodeOf(topo::getProcID(*firstVtx));
00089 int fnid = CmiNodeOf(topo::getProcID(*(firstVtx+1)));
00090 int forRemoteNodes = (pnid != fnid);
00091 #else
00092
00093
00094 int totalNodes = 0;
00095 int forRemoteNodes=0;
00096 #endif
00097
00098 if(totalNodes <= 1 && !forRemoteNodes){
00100 const int numDescendants = std::distance(firstVtx,beyondLastVtx) - 1;
00101 int numInSubTree = numDescendants / maxBranches;
00102 int remainder = numDescendants % maxBranches;
00103
00105 for (int i=0, indx=1; (i<maxBranches && indx<=numDescendants); i++, indx += numInSubTree)
00106 {
00107 parent->childIndex.push_back(indx);
00109 if (remainder-- > 0) indx++;
00110 }
00111 }else{
00113 const int numDescendants = totalNodes;
00114 int numInSubTree = numDescendants / maxBranches;
00115 int remainder = numDescendants % maxBranches;
00116
00118 for (int i=0, indx=0; (i<maxBranches && indx<numDescendants); i++, indx += numInSubTree)
00119 {
00120 parent->childIndex.push_back(nodesSeq[indx]);
00122 if (remainder-- > 0) indx++;
00123 }
00124 }
00125 nodesSeq.clear();
00127 return parent;
00128 }
00129 }
00130
00131 }
00132 #endif // TREE_STRATEGY_TOPO_UNAWARE
00133