change Ckpv to Cpv in conv-com
[charm.git] / src / conv-com / treerouter.C
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 /**
9    @addtogroup ConvComlibRouter
10    @{
11    @file 
12    @brief  Tree based converse level routing strategy 
13 */
14
15 #include "treerouter.h"
16 #define DEGREE 4
17 #define gmap(pe) (gpes ? gpes[pe] : pe)
18
19
20 /**The only communication op used. Modify this to use vector send. */
21 #if CMK_COMLIB_USE_VECTORIZE
22 #define TREESENDFN(kid, u, knewmsg, khndl, knextpe)  \
23         {if (knewmsg) {\
24           CmiSetHandler(knewmsg->msgs[0], khndl);\
25           CmiSyncVectorSendAndFree(knextpe, -knewmsg->count, knewmsg->sizes, knewmsg->msgs);\
26         }\
27         else {\
28           SendDummyMsg(kid, knextpe, u);\
29         }\
30 }
31 #else
32 #define TREESENDFN(kid, u, knewmsg, klen, khndl, knextpe)  \
33         {if (knewmsg) {\
34           CmiSetHandler(knewmsg, khndl);\
35           CmiSyncSendAndFree(knextpe, klen, knewmsg);\
36         }\
37         else {\
38           SendDummyMsg(kid, knextpe, u);\
39         }\
40 }
41 #endif
42
43
44
45
46 TreeRouter :: TreeRouter(int n, int me, Strategy *parent) : Router(parent)
47 {
48   int i;
49   MyPe=me;
50   NumPes=n;
51   gpes=NULL;
52
53   numChildren=0;
54   for (i=0;i<DEGREE;i++) {
55         if ((MyPe*DEGREE+i+1) < NumPes) numChildren++;
56   }
57
58   PeTree = new PeTable(NumPes);
59
60   recvExpected=1+numChildren;
61   InitVars();
62   //CmiPrintf("Tree with n=%d, me=%d\n", n, me);
63 }
64
65 TreeRouter :: ~TreeRouter()
66 {
67   delete PeTree;
68 }
69
70 void TreeRouter :: InitVars()
71 {
72   recvCount=0;
73 }
74
75
76 void TreeRouter::NumDeposits(comID , int num)
77 {
78 }
79
80 void TreeRouter::EachToAllMulticast(comID id, int size, void *msg, int more)
81 {
82   int npe=NumPes;
83   int * destpes=(int *)CmiAlloc(sizeof(int)*npe);
84   for (int i=0;i<npe;i++) destpes[i]=i;
85   EachToManyMulticast(id, size, msg, npe, destpes, more);
86 }
87
88 void TreeRouter::EachToManyMulticast(comID id, int size, void *msg, int numpes, int *destpes, int more)
89 {
90  //Create the message
91   if (size) {
92         PeTree->InsertMsgs(numpes, destpes, size, msg);
93   }
94
95   if (more >0) return;
96
97   //Hand it over to Recv. 
98   RecvManyMsg(id, NULL);
99 }
100
101 void TreeRouter :: RecvManyMsg(comID id, char *msg)
102 {
103   if (msg)
104         PeTree->UnpackAndInsert(msg);
105   recvCount++;
106   //CmiPrintf("%d Tree: recvCount=%d, recvExpected=%d\n",MyPe, recvCount, recvExpected);
107   if (recvCount == recvExpected) {
108         if (MyPe) {
109                 int len;
110                 int parent=(MyPe-1)/DEGREE;
111                 parent=gmap(parent);
112 #if CMK_COMLIB_USE_VECTORIZE
113                 PTvectorlist newmsg=SortBufferUp(id, 0);
114                 TREESENDFN(id, 0, newmsg, CkpvAccess(RouterRecvHandle), parent);
115 #else
116                 char *newmsg=SortBufferUp(id, 0, &len);
117                 TREESENDFN(id, 0, newmsg, len, CkpvAccess(RouterRecvHandle), parent);
118 #endif
119         }
120         else {
121                 DownStreamMsg(id);
122         }
123   }
124   if (recvCount > recvExpected) DownStreamMsg(id);
125 }
126
127 #if CMK_COMLIB_USE_VECTORIZE
128 PTvectorlist TreeRouter :: SortBufferUp(comID id, int ufield)
129 #else
130 char * TreeRouter :: SortBufferUp(comID id, int ufield, int *len)
131 #endif
132 {
133   int np=0, i;
134   int * pelst=(int *)CmiAlloc(sizeof(int)*NumPes);
135
136   for (i=0;i<NumPes;i++) {
137
138         //if (i==MyPe) continue;
139         int pe=i;
140         while (pe!=MyPe && pe>0) pe =(pe-1)/DEGREE;
141         if (pe == MyPe) continue;
142
143         pelst[np++]=i;
144   }
145 #if CMK_COMLIB_USE_VECTORIZE
146   PTvectorlist newmsg=PeTree->ExtractAndVectorize(id, ufield, np, pelst); 
147 #else
148   char *newmsg=PeTree->ExtractAndPack(id, ufield, np, pelst, len); 
149 #endif
150   CmiFree(pelst);
151   return(newmsg);
152 }
153   
154 #if CMK_COMLIB_USE_VECTORIZE
155 PTvectorlist TreeRouter :: SortBufferDown(comID id, int ufield, int s)
156 #else
157 char * TreeRouter :: SortBufferDown(comID id, int ufield, int *len, int s)
158 #endif
159 {
160   int np=0, i;
161   int * plist=(int *)CmiAlloc(sizeof(int)*NumPes);
162
163   for (i=0;i<NumPes;i++) {
164         if (i==MyPe) continue;
165         int pe=i;
166         int rep=MyPe*DEGREE+s;
167         while (pe!=rep && pe>0) pe =(pe-1)/DEGREE;
168         if (pe == rep) plist[np++]=i;
169   }
170
171 #if CMK_COMLIB_USE_VECTORIZE
172   PTvectorlist newmsg=PeTree->ExtractAndVectorize(id, ufield, np, plist); 
173 #else
174   char * newmsg=PeTree->ExtractAndPack(id, ufield, np, plist, len); 
175 #endif
176   CmiFree(plist);
177   return(newmsg);
178 }
179
180 void TreeRouter :: DownStreamMsg(comID id)
181 {
182   int deg=DEGREE;
183   if (NumPes < deg) deg=NumPes;
184
185   for (int i=0;i<deg;i++) {
186     int len;
187 #if CMK_COMLIB_USE_VECTORIZE
188     PTvectorlist newmsg=SortBufferDown(id, 0, i+1);
189 #else
190     char *newmsg=SortBufferDown(id, 0, &len, i+1);
191 #endif
192     int child=MyPe*DEGREE+i+1;
193     if (child >=NumPes || child==MyPe) break;
194     child=gmap(child);
195 #if CMK_COMLIB_USE_VECTORIZE
196     TREESENDFN(id, 0, newmsg, CkpvAccess(RouterRecvHandle), child);
197 #else
198     TREESENDFN(id, 0, newmsg, len, CkpvAccess(RouterRecvHandle), child);
199 #endif
200   }
201
202   LocalProcMsg(id);
203 }
204
205 void TreeRouter :: ProcManyMsg(comID id, char *m)
206 {
207   PeTree->UnpackAndInsert(m);
208   LocalProcMsg(id);
209 }
210
211 void TreeRouter:: LocalProcMsg(comID id)
212 {
213   PeTree->ExtractAndDeliverLocalMsgs(MyPe, container);
214   PeTree->Purge();
215   InitVars();
216   Done(id);
217 }
218
219 void TreeRouter :: DummyEP(comID id, int)
220 {
221   RecvManyMsg(id, NULL);
222 }
223
224 Router * newtreeobject(int n, int me, Strategy *strat)
225 {
226   Router * obj=new TreeRouter(n, me, strat);
227   return(obj);
228 }
229
230 void TreeRouter :: SetMap(int *pes)
231 {
232   gpes=pes;
233 }
234
235
236 /*@}*/