fully implement some missing features for some special cases since now skipCld also...
[charm.git] / src / conv-ldb / cldb.bluegene.c
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 /****
9   converse ldb for Blue Gene, this is the first version, full of hack and 
10   need more work.
11 ***/
12
13 #include "converse.h"
14 #include "blue.h"
15 #include "cldb.h"
16 #include "queueing.h"
17 #include <stdlib.h>
18
19 #define  DEBUGF(x)   /*CmiPrintf x;*/
20
21 extern int CldPresentPE(int pe);
22
23 void LoadNotifyFn(int l)
24 {
25 }
26
27 char *CldGetStrategy(void)
28 {
29   return "rand";
30 }
31
32 void CldBalanceHandler(void *msg)
33 {
34   CldRestoreHandler((char *)msg);
35   CldPutToken((char *)msg);
36 }
37
38 void CldHandler(char *msg)
39 {
40   int len, queueing, priobits;
41   unsigned int *prioptr; 
42   CldInfoFn ifn; CldPackFn pfn;
43
44   CldRestoreHandler(msg);
45   ifn = (CldInfoFn)CmiHandlerToFunction(CmiGetInfo(msg));
46   ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
47   CsdEnqueueGeneral(msg, queueing, priobits, prioptr);
48 }
49
50 void CldEnqueueMulti(int npes, int *pes, void *msg, int infofn)
51 {
52   int len, queueing, priobits,i; unsigned int *prioptr;
53   CldInfoFn ifn = (CldInfoFn)CmiHandlerToFunction(infofn);
54   CldPackFn pfn;
55   ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
56   if (pfn) {
57     pfn(&msg);
58     ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
59   }
60   CldSwitchHandler((char *)msg, CpvAccess(CldHandlerIndex));
61   CmiSetInfo(msg,infofn);
62   for(i=0;i<npes;i++) {
63     CmiSyncSend(pes[i], len, (char *)msg);
64   }
65   CmiFree(msg);
66 }
67
68 #if CMK_BLUEGENE_NODE
69 static int BgMyPe() { return BgMyNode(); }
70 static int BgNumPes() { int x,y,z; BgGetSize(&x, &y, &z); return (x*y*z); }
71 #   define BGSENDPE(pe, msg, len)  {    \
72       int x,y,z;        \
73       BgGetXYZ(pe, &x, &y, &z); \
74       DEBUGF(("send to: (%d %d %d, %d) handle:%d\n", x,y,z,t, CmiGetHandler(msg)));  \
75       BgSendPacket(x,y,z, ANYTHREAD, CmiGetHandler(msg), LARGE_WORK, \
76                    len, (char *)msg);   \
77       }
78 #   define BGBDCASTALL(len, msg)        \
79       BgBroadcastAllPacket(CmiGetHandler(msg), LARGE_WORK, len, msg);
80 #   define BGBDCAST(len, msg)   \
81       BgBroadcastPacketExcept(BgMyNode(), ANYTHREAD, CmiGetHandler(msg), \
82                               LARGE_WORK, len, msg);
83
84 #elif CMK_BLUEGENE_THREAD
85 static int BgMyPe() { return BgGetGlobalWorkerThreadID(); }
86 static int BgNumPes() { return BgGetTotalSize()*BgGetNumWorkThread(); }
87 #   define BGSENDPE(pe, msg, len)  {    \
88       int x,y,z,t;      \
89       t = (pe)%BgGetNumWorkThread();    \
90       pe = (pe)/BgGetNumWorkThread();   \
91       BgGetXYZ(pe, &x, &y, &z); \
92       DEBUGF(("send to: (%d %d %d, %d) handle:%d\n", x,y,z,t, CmiGetHandler(msg)));  \
93       BgSendPacket(x,y,z, t, CmiGetHandler(msg), LARGE_WORK, len, (char *)msg); \
94       }
95 #   define BGBDCASTALL(len, msg)        \
96       BgThreadBroadcastAllPacket(CmiGetHandler(msg), LARGE_WORK, len, msg);
97 #   define BGBDCAST(len, msg)   \
98       BgThreadBroadcastPacketExcept(BgMyNode(), BgGetThreadID(), \
99                                     CmiGetHandler(msg), LARGE_WORK, len, msg);
100 #endif
101
102
103 void CldEnqueue(int pe, void *msg, int infofn)
104 {
105   int len, queueing, priobits; unsigned int *prioptr;
106   CldInfoFn ifn = (CldInfoFn)CmiHandlerToFunction(infofn);
107   CldPackFn pfn;
108
109   DEBUGF(("[%d>] CldEnqueue pe: %d infofn:%d\n", BgMyNode(), pe, infofn));
110   if (pe == CLD_ANYWHERE) {
111     pe = (((CrnRand()+BgMyPe())&0x7FFFFFFF)%BgNumPes());
112 /*
113     while (!CldPresentPE(pe))
114       pe = (((CrnRand()+BgMyPe())&0x7FFFFFFF)%BgNumPes());
115 */
116     if (pe != BgMyPe())
117       CpvAccess(CldRelocatedMessages)++;
118     if (pe == BgMyPe()) {
119       ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
120       CmiSetInfo(msg,infofn);
121       DEBUGF(("CldEnqueue CLD_ANYWHERE (pe == BgMyPe)\n"));
122 /*
123       CldPutToken((char *)msg);
124 */
125       BGSENDPE(pe, msg, len);
126     } 
127     else {
128       ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
129       if (pfn) {
130         pfn(&msg);
131         ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
132       }
133       DEBUGF(("CldEnqueue at 2 pe=%d\n", pe));
134 /*
135       CldSwitchHandler((char *)msg, CpvAccess(CldBalanceHandlerIndex));
136       CmiSetInfo(msg,infofn);
137       CmiSyncSendAndFree(pe, len, (char *)msg);
138 */
139       BGSENDPE(pe, msg, len);
140     }
141   }
142   else if ((pe == BgMyPe()) || (BgNumPes() == 1)) {
143     DEBUGF(("CldEnqueue pe == CmiMyPe()\n"));
144     ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
145     CmiSetInfo(msg,infofn);
146 /*
147     CsdEnqueueGeneral(msg, CQS_QUEUEING_LIFO, priobits, prioptr);
148 */
149     BGSENDPE(pe, msg, len);
150   }
151   else {
152     ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
153     if (pfn) {
154       pfn(&msg);
155       ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
156     }
157 /*
158     CldSwitchHandler((char *)msg, CpvAccess(CldHandlerIndex));
159 */
160     CmiSetInfo(msg,infofn);
161     DEBUGF(("CldEnqueue pe=%d\n", pe));
162     if (pe==CLD_BROADCAST) { 
163 CmiPrintf("CldEnqueue pe=%d\n", pe); CmiAbort("");
164 /*
165       CmiSyncBroadcastAndFree(len, (char *)msg);
166 */
167       BGBDCAST(len, (char *)msg);
168     }
169     else if (pe==CLD_BROADCAST_ALL) { 
170 /*
171       CmiSyncBroadcastAllAndFree(len, (char *)msg); 
172 */
173       BGBDCASTALL(len, (char *)msg);
174     }
175     else {
176 /*
177       CmiSyncSendAndFree(pe, len, (char *)msg);
178 */
179       BGSENDPE(pe, msg, len);
180     }
181   }
182 }
183
184 void CldNodeEnqueue(int node, void *msg, int infofn)
185 {
186   int len, queueing, priobits; unsigned int *prioptr;
187   CldInfoFn ifn = (CldInfoFn)CmiHandlerToFunction(infofn);
188   CldPackFn pfn;
189   if (node == CLD_ANYWHERE) {
190     /* node = (((rand()+CmiMyNode())&0x7FFFFFFF)%CmiNumNodes()); */
191     node = (((CrnRand()+CmiMyNode())&0x7FFFFFFF)%CmiNumNodes());
192     if (node != CmiMyNode())
193       CpvAccess(CldRelocatedMessages)++;
194   }
195   if (node == CmiMyNode()) {
196     ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
197     CsdNodeEnqueueGeneral(msg, queueing, priobits, prioptr);
198   } 
199   else {
200     ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
201     if (pfn) {
202       pfn(&msg);
203       ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
204     }
205     CldSwitchHandler((char *)msg, CpvAccess(CldHandlerIndex));
206     CmiSetInfo(msg,infofn);
207     if (node==CLD_BROADCAST) { CmiSyncNodeBroadcastAndFree(len, (char *)msg); }
208     else if (node==CLD_BROADCAST_ALL){CmiSyncNodeBroadcastAllAndFree(len,(char *)msg);}
209     else CmiSyncNodeSendAndFree(node, len, (char *)msg);
210   }
211 }
212
213 void CldModuleInit()
214 {
215   CpvInitialize(int, CldHandlerIndex);
216   CpvInitialize(int, CldBalanceHandlerIndex);
217   CpvAccess(CldHandlerIndex) = CmiRegisterHandler(CldHandler);
218   CpvAccess(CldBalanceHandlerIndex) = CmiRegisterHandler(CldBalanceHandler);
219   CpvInitialize(int, CldRelocatedMessages);
220   CpvInitialize(int, CldLoadBalanceMessages);
221   CpvInitialize(int, CldMessageChunks);
222   CpvAccess(CldRelocatedMessages) = CpvAccess(CldLoadBalanceMessages) = 
223     CpvAccess(CldMessageChunks) = 0;
224   CldModuleGeneralInit();
225 }
226