00001
00008 #include "treerouter.h"
00009 #define DEGREE 4
00010 #define gmap(pe) (gpes ? gpes[pe] : pe)
00011
00012
00014 #if CMK_COMLIB_USE_VECTORIZE
00015 #define TREESENDFN(kid, u, knewmsg, khndl, knextpe) \
00016 {if (knewmsg) {\
00017 CmiSetHandler(knewmsg->msgs[0], khndl);\
00018 CmiSyncVectorSendAndFree(knextpe, -knewmsg->count, knewmsg->sizes, knewmsg->msgs);\
00019 }\
00020 else {\
00021 SendDummyMsg(kid, knextpe, u);\
00022 }\
00023 }
00024 #else
00025 #define TREESENDFN(kid, u, knewmsg, klen, khndl, knextpe) \
00026 {if (knewmsg) {\
00027 CmiSetHandler(knewmsg, khndl);\
00028 CmiSyncSendAndFree(knextpe, klen, knewmsg);\
00029 }\
00030 else {\
00031 SendDummyMsg(kid, knextpe, u);\
00032 }\
00033 }
00034 #endif
00035
00036
00037
00038
00039 TreeRouter :: TreeRouter(int n, int me, Strategy *parent) : Router(parent)
00040 {
00041 int i;
00042 MyPe=me;
00043 NumPes=n;
00044 gpes=NULL;
00045
00046 numChildren=0;
00047 for (i=0;i<DEGREE;i++) {
00048 if ((MyPe*DEGREE+i+1) < NumPes) numChildren++;
00049 }
00050
00051 PeTree = new PeTable(NumPes);
00052
00053 recvExpected=1+numChildren;
00054 InitVars();
00055
00056 }
00057
00058 TreeRouter :: ~TreeRouter()
00059 {
00060 delete PeTree;
00061 }
00062
00063 void TreeRouter :: InitVars()
00064 {
00065 recvCount=0;
00066 }
00067
00068
00069 void TreeRouter::NumDeposits(comID , int num)
00070 {
00071 }
00072
00073 void TreeRouter::EachToAllMulticast(comID id, int size, void *msg, int more)
00074 {
00075 int npe=NumPes;
00076 int * destpes=(int *)CmiAlloc(sizeof(int)*npe);
00077 for (int i=0;i<npe;i++) destpes[i]=i;
00078 EachToManyMulticast(id, size, msg, npe, destpes, more);
00079 }
00080
00081 void TreeRouter::EachToManyMulticast(comID id, int size, void *msg, int numpes, int *destpes, int more)
00082 {
00083
00084 if (size) {
00085 PeTree->InsertMsgs(numpes, destpes, size, msg);
00086 }
00087
00088 if (more >0) return;
00089
00090
00091 RecvManyMsg(id, NULL);
00092 }
00093
00094 void TreeRouter :: RecvManyMsg(comID id, char *msg)
00095 {
00096 if (msg)
00097 PeTree->UnpackAndInsert(msg);
00098 recvCount++;
00099
00100 if (recvCount == recvExpected) {
00101 if (MyPe) {
00102 int len;
00103 int parent=(MyPe-1)/DEGREE;
00104 parent=gmap(parent);
00105 #if CMK_COMLIB_USE_VECTORIZE
00106 PTvectorlist newmsg=SortBufferUp(id, 0);
00107 TREESENDFN(id, 0, newmsg, CkpvAccess(RouterRecvHandle), parent);
00108 #else
00109 char *newmsg=SortBufferUp(id, 0, &len);
00110 TREESENDFN(id, 0, newmsg, len, CkpvAccess(RouterRecvHandle), parent);
00111 #endif
00112 }
00113 else {
00114 DownStreamMsg(id);
00115 }
00116 }
00117 if (recvCount > recvExpected) DownStreamMsg(id);
00118 }
00119
00120 #if CMK_COMLIB_USE_VECTORIZE
00121 PTvectorlist TreeRouter :: SortBufferUp(comID id, int ufield)
00122 #else
00123 char * TreeRouter :: SortBufferUp(comID id, int ufield, int *len)
00124 #endif
00125 {
00126 int np=0, i;
00127 int * pelst=(int *)CmiAlloc(sizeof(int)*NumPes);
00128
00129 for (i=0;i<NumPes;i++) {
00130
00131
00132 int pe=i;
00133 while (pe!=MyPe && pe>0) pe =(pe-1)/DEGREE;
00134 if (pe == MyPe) continue;
00135
00136 pelst[np++]=i;
00137 }
00138 #if CMK_COMLIB_USE_VECTORIZE
00139 PTvectorlist newmsg=PeTree->ExtractAndVectorize(id, ufield, np, pelst);
00140 #else
00141 char *newmsg=PeTree->ExtractAndPack(id, ufield, np, pelst, len);
00142 #endif
00143 CmiFree(pelst);
00144 return(newmsg);
00145 }
00146
00147 #if CMK_COMLIB_USE_VECTORIZE
00148 PTvectorlist TreeRouter :: SortBufferDown(comID id, int ufield, int s)
00149 #else
00150 char * TreeRouter :: SortBufferDown(comID id, int ufield, int *len, int s)
00151 #endif
00152 {
00153 int np=0, i;
00154 int * plist=(int *)CmiAlloc(sizeof(int)*NumPes);
00155
00156 for (i=0;i<NumPes;i++) {
00157 if (i==MyPe) continue;
00158 int pe=i;
00159 int rep=MyPe*DEGREE+s;
00160 while (pe!=rep && pe>0) pe =(pe-1)/DEGREE;
00161 if (pe == rep) plist[np++]=i;
00162 }
00163
00164 #if CMK_COMLIB_USE_VECTORIZE
00165 PTvectorlist newmsg=PeTree->ExtractAndVectorize(id, ufield, np, plist);
00166 #else
00167 char * newmsg=PeTree->ExtractAndPack(id, ufield, np, plist, len);
00168 #endif
00169 CmiFree(plist);
00170 return(newmsg);
00171 }
00172
00173 void TreeRouter :: DownStreamMsg(comID id)
00174 {
00175 int deg=DEGREE;
00176 if (NumPes < deg) deg=NumPes;
00177
00178 for (int i=0;i<deg;i++) {
00179 int len;
00180 #if CMK_COMLIB_USE_VECTORIZE
00181 PTvectorlist newmsg=SortBufferDown(id, 0, i+1);
00182 #else
00183 char *newmsg=SortBufferDown(id, 0, &len, i+1);
00184 #endif
00185 int child=MyPe*DEGREE+i+1;
00186 if (child >=NumPes || child==MyPe) break;
00187 child=gmap(child);
00188 #if CMK_COMLIB_USE_VECTORIZE
00189 TREESENDFN(id, 0, newmsg, CkpvAccess(RouterRecvHandle), child);
00190 #else
00191 TREESENDFN(id, 0, newmsg, len, CkpvAccess(RouterRecvHandle), child);
00192 #endif
00193 }
00194
00195 LocalProcMsg(id);
00196 }
00197
00198 void TreeRouter :: ProcManyMsg(comID id, char *m)
00199 {
00200 PeTree->UnpackAndInsert(m);
00201 LocalProcMsg(id);
00202 }
00203
00204 void TreeRouter:: LocalProcMsg(comID id)
00205 {
00206 PeTree->ExtractAndDeliverLocalMsgs(MyPe, container);
00207 PeTree->Purge();
00208 InitVars();
00209 Done(id);
00210 }
00211
00212 void TreeRouter :: DummyEP(comID id, int)
00213 {
00214 RecvManyMsg(id, NULL);
00215 }
00216
00217 Router * newtreeobject(int n, int me, Strategy *strat)
00218 {
00219 Router * obj=new TreeRouter(n, me, strat);
00220 return(obj);
00221 }
00222
00223 void TreeRouter :: SetMap(int *pes)
00224 {
00225 gpes=pes;
00226 }
00227
00228