00001
00005 #include "charm-api.h"
00006 #include "idxl.h"
00007 #include "tcharm.h"
00008
00009
00010
00012 CLINKAGE IDXL_t
00013 IDXL_Create(void) {
00014 const char *caller="IDXL_Create";
00015 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00016 return c->addDynamic();
00017 }
00018 FORTRAN_AS_C_RETURN(int, IDXL_CREATE,IDXL_Create,idxl_create,
00019 (void), () )
00020
00021
00022
00023 void IDXL_Print(IDXL_t l_t)
00024 {
00025 const char *caller="IDXL_Print";
00026 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00027 const IDXL &l=c->lookup(l_t,caller);
00028 if (l.isSingle()) {
00029 l.getSend().print();
00030 } else {
00031 CkPrintf("Send ");
00032 l.getSend().print();
00033 CkPrintf("Recv ");
00034 l.getRecv().print();
00035 }
00036 }
00037 FORTRAN_AS_C(IDXL_PRINT,IDXL_Print,idxl_print,
00038 (int *l), (*l) )
00039
00040
00041 CLINKAGE void
00042 IDXL_Copy(IDXL_t l,IDXL_t src) {
00043 IDXL_Combine(l,src,0,0);
00044 }
00045 FORTRAN_AS_C(IDXL_COPY,IDXL_Copy,idxl_copy,
00046 (int *l, int *src), (*l,*src))
00047
00048
00049
00050 static void shiftSide(IDXL_Side &dest,int idxShift)
00051 {
00052 int sNo,sMax=dest.size();
00053 for (sNo=0;sNo<sMax;sNo++) {
00054 IDXL_List &s=dest.setLocalList(sNo);
00055 for (int i=0;i<s.size();i++) s[i]+=idxShift;
00056 }
00057 dest.flushMap();
00058 }
00060 CLINKAGE void
00061 IDXL_Shift(IDXL_t l_t,int startSend,int startRecv) {
00062 const char *caller="IDXL_Shift";
00063 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00064 IDXL &l=c->lookup(l_t,caller);
00065 if (l.isSingle()) {
00066 if (startSend!=startRecv)
00067 IDXL_Abort(caller,"Cannot independently shift send and recv for this IDXL_t");
00068 shiftSide(l.getSend(),startSend);
00069 }
00070 else {
00071 shiftSide(l.getSend(),startSend);
00072 shiftSide(l.getRecv(),startRecv);
00073 }
00074 }
00075 FORTRAN_AS_C(IDXL_SHIFT,IDXL_Shift,idxl_shift,
00076 (int *l, int *startSend,int *startRecv),
00077 (*l, *startSend-1, *startRecv-1))
00078
00079
00080
00081 static void combineSide(IDXL_Side &dest,const IDXL_Side &src,
00082 int idxShift)
00083 {
00084 int sNo,sMax=src.size();
00085 for (sNo=0;sNo<sMax;sNo++) {
00086 const IDXL_List &s=src.getLocalList(sNo);
00087 IDXL_List &d=dest.addList(s.getDest());
00088 for (int i=0;i<s.size();i++) {
00089 d.push_back(s[i]+idxShift);
00090 }
00091 }
00092 dest.flushMap();
00093 }
00100 CLINKAGE void
00101 IDXL_Combine(IDXL_t dest_t,IDXL_t src_t,int startSend,int startRecv)
00102 {
00103 const char *caller="IDXL_Combine";
00104 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00105 const IDXL &src=c->lookup(src_t,caller);
00106 IDXL &dest=c->lookup(dest_t,caller);
00107 if (src.isSingle()!=dest.isSingle())
00108 IDXL_Abort(caller,"Cannot combine IDXL_t's %d and %d,"
00109 "because one is single and the other is double.",src_t,dest_t);
00110 if (dest.isSingle())
00111 {
00112 if (startSend!=startRecv)
00113 IDXL_Abort(caller,"Cannot independently shift send and recv for this IDXL_t");
00114 combineSide(dest.getSend(),src.getSend(),startSend);
00115 }
00116 else {
00117 combineSide(dest.getSend(),src.getSend(),startSend);
00118 combineSide(dest.getRecv(),src.getRecv(),startRecv);
00119 }
00120 }
00121 FORTRAN_AS_C(IDXL_COMBINE,IDXL_Combine,idxl_combine,
00122 (int *dest, int *src, int *startSend,int *startRecv),
00123 (*dest,*src, *startSend-1, *startRecv-1))
00124
00125
00126
00127
00128 CLINKAGE void IDXL_Sort_2d(IDXL_t l_t,double *coord2d){
00129 const char *caller = "IDXL_Sort_2d";
00130 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00131 IDXL &l=c->lookup(l_t,caller);
00132 l.sort2d(coord2d);
00133 }
00134
00135
00137
00138 CLINKAGE void IDXL_Sort_3d(IDXL_t l_t,double *coord3d){
00139 const char *caller = "IDXL_Sort_3d";
00140 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00141 IDXL &l=c->lookup(l_t,caller);
00142 l.sort3d(coord3d);
00143 }
00144
00145
00146
00147
00148
00149 void splitEntity(IDXL_Side &c,
00150 int localIdx,int nBetween,int *between,int idxbase)
00151 {
00152
00153 const IDXL_Rec *tween[20];
00154 int w,w1;
00155 for (w1=0;w1<nBetween;w1++) {
00156 tween[w1]=c.getRec(between[w1]-idxbase);
00157 if (tween[w1]==NULL)
00158 return;
00159 }
00160
00161
00162
00163 for (int zs=tween[0]->getShared()-1;zs>=0;zs--) {
00164 for (w1=0;w1<nBetween;w1++) {
00165 tween[w1]=c.getRec(between[w1]-idxbase);
00166 }
00167 int chk=tween[0]->getChk(zs);
00168
00169 for (w=0;w<nBetween;w++)
00170 if (!tween[w]->hasChk(chk))
00171 break;
00172 if (w==nBetween) {
00173 c.addNode(localIdx,chk);
00174
00175 }
00176 }
00177 }
00178
00179 static void splitEntity(IDXL &l,
00180 int localIdx,int nBetween,int *between,int idxbase)
00181 {
00182 splitEntity(l.getSend(),localIdx,nBetween,between,idxbase);
00183 if (!l.isSingle())
00184 splitEntity(l.getRecv(),localIdx,nBetween,between,idxbase);
00185 }
00186
00187 CLINKAGE void IDXL_Add_entity(IDXL_t l_t,int localIdx,int nBetween,int *between)
00188 {
00189 const char *caller="IDXL_Add_entity";
00190 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00191 IDXL &l=c->lookup(l_t,caller);
00192 splitEntity(l,localIdx,nBetween,between,0);
00193 }
00194 FLINKAGE void FTN_NAME(IDXL_ADD_ENTITY,idxl_add_entity)
00195 (int *l_t,int *localIdx,int *nBetween,int *between)
00196 {
00197 const char *caller="IDXL_Add_entity";
00198 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00199 IDXL &l=c->lookup(*l_t,caller);
00200 splitEntity(l,*localIdx-1,*nBetween,between,1);
00201 }
00202
00203
00205 CLINKAGE void IDXL_Destroy(IDXL_t l) {
00206 const char *caller="IDXL_Destroy";
00207 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00208 c->destroy(l);
00209 }
00210 FORTRAN_AS_C(IDXL_DESTROY,IDXL_Destroy,idxl_destroy, (int *l), (*l))
00211
00212
00213
00214
00215
00216
00217 const IDXL_Side &lookupSide(IDXL_Side_t s,const char *caller) {
00218 IDXL_Chunk *c=IDXL_Chunk::get(caller);
00219 if (s-IDXL_SHIFT_SIDE_T_RECV>=IDXL_DYNAMIC_IDXL_T) {
00220 IDXL_t l=s-IDXL_SHIFT_SIDE_T_RECV;
00221 return c->lookup(l,caller).getRecv();
00222 }
00223 else if (s-IDXL_SHIFT_SIDE_T_SEND>=IDXL_DYNAMIC_IDXL_T) {
00224 IDXL_t l=s-IDXL_SHIFT_SIDE_T_SEND;
00225 return c->lookup(l,caller).getSend();
00226 }
00227 else
00228 IDXL_Abort(caller,"Unrecognized IDXL_Side_t %d\n",s);
00229 return *new IDXL_Side();
00230 }
00231
00232 CLINKAGE IDXL_Side_t IDXL_Get_send(IDXL_t l) {
00233 return l+IDXL_SHIFT_SIDE_T_SEND;
00234 }
00235 FORTRAN_AS_C_RETURN(int,IDXL_GET_SEND,IDXL_Get_send,idxl_get_send, (int *l),(*l))
00236
00237 CLINKAGE IDXL_Side_t IDXL_Get_recv(IDXL_t l) {
00238 return l+IDXL_SHIFT_SIDE_T_RECV;
00239 }
00240 FORTRAN_AS_C_RETURN(int,IDXL_GET_RECV,IDXL_Get_recv,idxl_get_recv, (int *l),(*l))
00241
00242 CLINKAGE void IDXL_Get_end(IDXL_Side_t s) {
00243
00244 }
00245 FORTRAN_AS_C(IDXL_GET_END,IDXL_Get_end,idxl_get_end, (int *s),(*s))
00246
00247 CLINKAGE int IDXL_Get_partners(IDXL_Side_t s) {
00248 const char *caller="IDXL_Get_partners"; IDXLAPI(caller);
00249 return lookupSide(s,caller).size();
00250 }
00251 FORTRAN_AS_C_RETURN(int,IDXL_GET_PARTNERS,IDXL_Get_partners,idxl_get_partners,
00252 (int *s),(*s))
00253
00254 CLINKAGE int IDXL_Get_partner(IDXL_Side_t s,int partnerNo) {
00255 const char *caller="IDXL_Get_partner"; IDXLAPI(caller);
00256 return lookupSide(s,caller).getLocalList(partnerNo).getDest();
00257 }
00258 FORTRAN_AS_C_RETURN(int,IDXL_GET_PARTNER,IDXL_Get_partner,idxl_get_partner,
00259 (int *s,int *p),(*s,*p-1))
00260
00261 CLINKAGE int IDXL_Get_count(IDXL_Side_t s,int partnerNo) {
00262 const char *caller="IDXL_Get_count"; IDXLAPI(caller);
00263 return lookupSide(s,caller).getLocalList(partnerNo).size();
00264 }
00265 FORTRAN_AS_C_RETURN(int,IDXL_GET_COUNT,IDXL_Get_count,idxl_get_count,
00266 (int *s,int *p),(*s,*p-1))
00267
00268 static void getList(IDXL_Side_t s,int partnerNo,int *list,int idxBase) {
00269 const char *caller="IDXL_Get_"; IDXLAPI(caller);
00270 const IDXL_List &l=lookupSide(s,caller).getLocalList(partnerNo);
00271 for (int i=0;i<l.size();i++) list[i]=l[i]+idxBase;
00272 }
00273
00274 CLINKAGE void IDXL_Get_list(IDXL_Side_t s,int partnerNo,int *list) {
00275 getList(s,partnerNo,list,0);
00276 }
00277 FLINKAGE void FTN_NAME(IDXL_GET_LIST,idxl_get_list)
00278 (int *s,int *p,int *list) {
00279 getList(*s,*p-1,list,1);
00280 }
00281
00282 CLINKAGE int IDXL_Get_index(IDXL_Side_t s,int partnerNo,int listIndex) {
00283 const char *caller="IDXL_Get_index"; IDXLAPI(caller);
00284 return lookupSide(s,caller).getLocalList(partnerNo)[listIndex];
00285 }
00286 FLINKAGE int FTN_NAME(IDXL_GET_INDEX,idxl_get_index)(int *s,int *p,int *idx)
00287 {
00288 return IDXL_Get_index(*s,*p-1,*idx-1)+1;
00289 }
00290
00291 CLINKAGE int IDXL_Get_source(IDXL_t l_t,int localNo) {
00292 const char *caller="IDXL_Get_source"; IDXLAPI(caller);
00293 IDXL &l=IDXL_Chunk::get(caller)->lookup(l_t,caller);
00294 const IDXL_Rec *rec=l.getRecv().getRec(localNo);
00295 if (rec==NULL) CkAbort("IDXL_Get_source called on non-ghost entity!");
00296 if (rec->getShared()>1) CkAbort("IDXL_Get_source called on multiply-shared entity!");
00297 return rec->getChk(0);
00298 }
00299 FLINKAGE int FTN_NAME(IDXL_GET_SOURCE,idxl_get_source)(int *l,int *localNo) {
00300 return 1+IDXL_Get_source(*l,*localNo-1);
00301 }
00302
00303
00304 CLINKAGE IDXL_Layout_t
00305 IDXL_Layout_create(int type, int width)
00306 {
00307 const char *caller="IDXL_Create_simple_data";
00308 IDXLAPI(caller);
00309 return IDXL_Layout_List::get().put(IDXL_Layout(type, width));
00310 }
00311 FORTRAN_AS_C_RETURN(int,
00312 IDXL_LAYOUT_CREATE,IDXL_Layout_create,idxl_layout_create,
00313 (int *t,int *w), (*t,*w))
00314
00315 CLINKAGE IDXL_Layout_t
00316 IDXL_Layout_offset(int type, int width, int offsetBytes, int distanceBytes,int skewBytes)
00317 {
00318 const char *caller="IDXL_Create_data";
00319 IDXLAPI(caller);
00320 return IDXL_Layout_List::get().put(IDXL_Layout(type,width, offsetBytes,distanceBytes,skewBytes));
00321 }
00322 FORTRAN_AS_C_RETURN(int,
00323 IDXL_LAYOUT_OFFSET,IDXL_Layout_offset,idxl_layout_offset,
00324 (int *t,int *w,int *o,int *d,int *s), (*t,*w,*o,*d,*s))
00325
00326 #define GET_DATA_DECL(CAPS,Cname,lowercase, field) \
00327 CLINKAGE int Cname(IDXL_Layout_t d) \
00328 { \
00329 IDXLAPI(#Cname); \
00330 return IDXL_Layout_List::get().get(d,#Cname).field;\
00331 }\
00332 FORTRAN_AS_C_RETURN(int, IDXL_GET_LAYOUT_##CAPS,Cname,idxl_get_layout_##lowercase, \
00333 (int *d), (*d))
00334
00335 GET_DATA_DECL(TYPE,IDXL_Get_layout_type,type, type)
00336 GET_DATA_DECL(WIDTH,IDXL_Get_layout_width,width, width)
00337 GET_DATA_DECL(DISTANCE,IDXL_Get_layout_distance,distance, distance)
00338
00339 CLINKAGE void
00340 IDXL_Layout_destroy(IDXL_Layout_t l) {
00341 const char *caller="IDXL_Layout_destroy";
00342 IDXLAPI(caller);
00343 IDXL_Layout_List::get().destroy(l,caller);
00344 }
00345 FORTRAN_AS_C(IDXL_LAYOUT_DESTROY,IDXL_Layout_destroy,idxl_layout_destroy,
00346 (int *l), (*l) )
00347
00348
00350 CLINKAGE IDXL_Comm_t
00351 IDXL_Comm_begin(int tag, int context) {
00352 const char *caller="IDXL_Create_data";
00353 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00354 return c->addComm(tag,context);
00355 }
00356 FORTRAN_AS_C_RETURN(int,
00357 IDXL_COMM_BEGIN,IDXL_Comm_begin,idxl_comm_begin,
00358 (int *tag,int *context), (*tag,*context))
00359
00360
00361 #define COMM_BROILERPLATE(routineName) \
00362 const char *caller=routineName; \
00363 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller); \
00364 const IDXL &list=c->lookup(dest,caller); \
00365 const IDXL_Layout *dt=&c->layouts.get(type,caller);
00366
00368 CLINKAGE void
00369 IDXL_Comm_sendrecv(IDXL_Comm_t m,IDXL_t dest, IDXL_Layout_t type, void *data) {
00370 COMM_BROILERPLATE("IDXL_Comm_sendrecv");
00371 IDXL_Comm *comm=NULL;
00372 if (m!=0)
00373 comm=c->lookupComm(m,caller);
00374 else
00375 comm=c->lookupComm(c->addComm(0,0),caller);
00376 comm->send(&list.getSend(),dt,data);
00377 comm->recv(&list.getRecv(),dt,data);
00378 if (m==0)
00379 c->waitComm(comm);
00380 }
00381 FORTRAN_AS_C(IDXL_COMM_SENDRECV,IDXL_Comm_sendrecv,idxl_comm_sendrecv,
00382 (int *m,int *dest,int *type,void *data), (*m,*dest,*type,data))
00383
00384
00385
00386 void IDXL_Comm_sendsum(IDXL_Comm_t m,IDXL_t dest, IDXL_Layout_t type, void *data) {
00387 COMM_BROILERPLATE("IDXL_Comm_sendsum");
00388 IDXL_Comm *comm=NULL;
00389 if (m!=0)
00390 comm=c->lookupComm(m,caller);
00391 else
00392 comm=c->lookupComm(c->addComm(0,0),caller);
00393 comm->send(&list.getSend(),dt,data);
00394 comm->sum(&list.getRecv(),dt,data);
00395 if (m==0)
00396 c->waitComm(comm);
00397 }
00398 FORTRAN_AS_C(IDXL_COMM_SENDSUM,IDXL_Comm_sendsum,idxl_comm_sendsum,
00399 (int *m,int *dest,int *type,void *data), (*m,*dest,*type,data))
00400
00401
00402 void IDXL_Comm_send(IDXL_Comm_t m,IDXL_t dest, IDXL_Layout_t type, const void *srcData){
00403 COMM_BROILERPLATE("IDXL_Comm_send");
00404 c->lookupComm(m,caller)->send(&list.getSend(),dt,srcData);
00405 }
00406 FORTRAN_AS_C(IDXL_COMM_SEND,IDXL_Comm_send,idxl_comm_send,
00407 (int *m,int *dest,int *type,const void *data), (*m,*dest,*type,data))
00408
00409
00410 void IDXL_Comm_recv(IDXL_Comm_t m,IDXL_t dest, IDXL_Layout_t type, void *destData) {
00411 COMM_BROILERPLATE("IDXL_Comm_recv");
00412 c->lookupComm(m,caller)->recv(&list.getRecv(),dt,destData);
00413 }
00414 FORTRAN_AS_C(IDXL_COMM_RECV,IDXL_Comm_recv,idxl_comm_recv,
00415 (int *m,int *dest,int *type,void *data), (*m,*dest,*type,data))
00416
00417
00418 void IDXL_Comm_sum(IDXL_Comm_t m,IDXL_t dest, IDXL_Layout_t type, void *sumData) {
00419 COMM_BROILERPLATE("IDXL_Comm_recv");
00420 c->lookupComm(m,caller)->sum(&list.getRecv(),dt,sumData);
00421 }
00422 FORTRAN_AS_C(IDXL_COMM_SUM,IDXL_Comm_sum,idxl_comm_sum,
00423 (int *m,int *dest,int *type,void *data), (*m,*dest,*type,data))
00424
00425
00426 void IDXL_Comm_flush(IDXL_Comm_t m) {
00427 const char *caller="IDXL_Comm_flush";
00428 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00429 c->lookupComm(m,caller)->post();
00430 }
00431
00433 void IDXL_Comm_wait(IDXL_Comm_t m) {
00434 const char *caller="IDXL_Comm_flush";
00435 IDXLAPI(caller); IDXL_Chunk *c=IDXL_Chunk::get(caller);
00436 c->waitComm(c->lookupComm(m,caller));
00437 }
00438
00439
00440
00441
00442