Adding communication library in src/ck-com and src/conv-com
[charm.git] / src / conv-com / hypercubetopology.C
1
2 #include "hypercubetopology.h"
3
4 inline int neighbor(int pe, int dim)
5 {
6     return(pe ^ (1<<dim));
7 }
8
9 inline int maxdim(int n)
10 {
11     int maxpes=1, dim=0;
12
13     while (maxpes< n) {
14         maxpes *=2;
15         dim++;
16     }
17     if (maxpes==n) return(dim);
18     else return(dim-1);
19 }
20
21 inline int adjust(int dim, int pe)
22 {
23     int mymax=1<<dim;
24     if (pe >= mymax) return(neighbor(pe, dim));
25     else return(pe);
26 }
27
28 HypercubeTopology::HypercubeTopology(int npes, int mype) {
29     
30     int i = 0;
31     NumPes = npes;
32     MyPe = mype;
33     Dim = maxdim(npes);
34
35     next = new int *[Dim];
36     for (i=0;i<Dim;i++) {
37         next[i]=new int[NumPes];
38         for (int j=0;j<NumPes;j++) next[i][j]=-1;
39     }
40     
41     //Create and initialize the indexes to the above table
42     penum=new int[NumPes];
43     int *dp=new int[NumPes];
44     for (i=0;i<NumPes;i++) {
45         penum[i]=0;
46         dp[i]=i;
47     }
48     
49     CreateStageTable(NumPes, dp);
50     delete(dp);
51 }
52
53 void HypercubeTopology::getNeighbors(int &np, int *pelist){
54     np = Dim;
55
56     for(int count = 0; count < Dim; count ++)
57         pelist[count] = MyPe ^ (1 << (Dim - count - 1));
58 }
59
60 int HypercubeTopology::getNumStages(){
61     return Dim;
62 }
63
64 int HypercubeTopology::getNumSteps(int stage) {
65     return 1;
66 }
67
68 void HypercubeTopology::getPesToSend(int step, int stage, int &np, 
69                                      int *pelist, int &nextpe) {
70     if(step > 0) {
71         np = 0;
72         return;
73     }
74
75     np = penum[Dim - stage - 1];
76     memcpy(pelist, next[Dim - stage - 1], np *sizeof(int));
77         
78     nextpe = neighbor(MyPe, Dim - stage - 1);
79 }
80
81 int HypercubeTopology::getNumMessagesExpected(int stage) {
82     return 1;
83 }
84
85 void HypercubeTopology::CreateStageTable(int numpes, int *destpes)
86 {
87     int *dir=new int[numpes];
88     int nextdim, j, i;
89     for (i=0;i<numpes;i++) {
90         dir[i]=MyPe ^ adjust(Dim, destpes[i]);
91     }
92     
93     for (nextdim=Dim-1; nextdim>=0; nextdim--) {
94         int mask=1<<nextdim;
95         for (i=0;i<numpes;i++) {
96             if (dir[i] & mask) {
97                 dir[i]=0;
98                 for (j=0;(j<penum[nextdim]) && (destpes[i]!=next[nextdim][j]);j++);
99                 if (destpes[i]==next[nextdim][j]) { 
100                     //CmiPrintf("EQUAL %d\n", destpes[i]);
101                     continue;
102                 }
103                 next[nextdim][penum[nextdim]]=destpes[i];
104                 penum[nextdim]+=1;
105                 //CmiPrintf("%d next[%d][%d]=%d\n",MyPe, nextdim, penum[nextdim],destpes[i]);
106             }
107         }
108     }
109     delete dir;
110     return;
111 }