00001 #ifndef CHARISMA_H
00002 #define CHARISMA_H
00003
00004 #include "charisma.decl.h"
00005
00006 class Name
00007 {
00008 private:
00009 char *curname;
00010 size_t curbuflen;
00011 size_t curlen;
00012 public:
00013 Name(void)
00014 {
00015 curbuflen = 100;
00016 curname = new char[curbuflen];
00017 curname[0] = '\0';
00018 curlen = 0;
00019 }
00020 void add(const char *n)
00021 {
00022 size_t len = strlen(n);
00023 if((curlen+len+2) > curbuflen) {
00024 char *t = new char[curlen+len+2];
00025 strcpy(t, curname);
00026 delete[] curname;
00027 curname = t;
00028 curbuflen = curlen+len+2;
00029 }
00030 if(curlen!=0) {
00031 strcat(curname, ".");
00032 curlen++;
00033 }
00034 strcat(curname, n);
00035 curlen += len;
00036 }
00037 void remove(const char *n)
00038 {
00039 size_t len = strlen(n);
00040 curlen = curlen-len;
00041 curname[curlen] = '\0';
00042 if(curlen!=0) {
00043 curname[--curlen] = '\0';
00044 }
00045 }
00046 inline operator char *() const { return curname; }
00047 ~Name()
00048 {
00049 delete[] curname;
00050 }
00051 };
00052
00053 class Component
00054 {
00055 private:
00056 char *name;
00057 char *type;
00058 int idx;
00059 int pe;
00060 int nout;
00061 int nin;
00062 int ncout;
00063 int ncin;
00064 public:
00065 Component(const char *n, const char *t)
00066 {
00067 name = new char[strlen(n)+1];
00068 strcpy(name,n);
00069 type = new char[strlen(t)+1];
00070 strcpy(type,t);
00071 ncout = ncin = nout = nin = 0;
00072 idx = pe = (-1);
00073 }
00074 ~Component()
00075 {
00076 delete[] type;
00077 }
00078 char *getName(void) { return name; }
00079 char *getType(void) { return type; }
00080 void setIdx(int _idx) { idx = _idx; }
00081 int getIdx(void) { return idx; }
00082 void setPe(int _pe) { pe = _pe; }
00083 int getPe(void) { return pe; }
00084 void addOutPort(void) { nout++; }
00085 void addInPort(void) { nin++; }
00086 void connectOutPort(void) { ncout++; }
00087 void connectInPort(void) { ncin++; }
00088 int getNumPorts(void) { return nout + nin; }
00089 int getNumConnectedPorts(void) { return ncout + ncin; }
00090 };
00091
00092 #define CHARISMA_IN 1
00093 #define CHARISMA_OUT 2
00094
00095 class Port
00096 {
00097 private:
00098 int inout;
00099 char *name;
00100 Component *comp;
00101 char *type;
00102 Port *peer;
00103 public:
00104 Port(const char *n, Component *c, const char *t, int io)
00105 {
00106 name = new char[strlen(n)+1];
00107 strcpy(name,n);
00108 comp = c;
00109 type = new char[strlen(t)+1];
00110 strcpy(type,t);
00111 inout = io;
00112 peer = 0;
00113 }
00114 void setPeer(Port *p)
00115 {
00116 peer = p;
00117 }
00118 ~Port()
00119 {
00120 delete[] name;
00121 delete[] type;
00122 }
00123 char *getName(void) { return name; }
00124 char *getType(void) { return type; }
00125 Port *getPeer(void) { return peer; }
00126 Component *getComp(void) { return comp; }
00127 };
00128
00129 extern "C"
00130 void METIS_PartGraphRecursive(int* n, int* xadj, int* adjncy, int* vwght,
00131 int* adjwgt, int* wgtflag, int* numflag, int* nparts, int* options,
00132 int* edgecut, int* part);
00133
00134 class CharismaGraph
00135 {
00136 private:
00137 CkHashtableTslow<const char *, Port *> ports;
00138 CkHashtableTslow<const char *, Component *> comps;
00139 Name *curname;
00140 public:
00141 CharismaGraph(void)
00142 {
00143 curname = new Name;
00144 }
00145
00146
00147 void start(const char *name, const char *type)
00148 {
00149 curname->add(name);
00150 CkPrintf("starting registration for %s\n", (char *) curname);
00151 Component *curcomp = new Component((const char *)curname, type);
00152 comps.put((const char *)curname) = curcomp;
00153 }
00154
00155 void end(const char *name)
00156 {
00157 CkPrintf("ending registration for %s\n", (char *) curname);
00158 curname->remove(name);
00159 }
00160
00161 void registerOutPort(const char *name, const char *type)
00162 {
00163 Component *curcomp = comps.get((const char *) curname);
00164 curcomp->addOutPort();
00165 curname->add(name);
00166 CkPrintf("registering outport %s\n", (char *) curname);
00167 ports.put((const char *)curname) = new Port((const char *)curname,
00168 curcomp, type, CHARISMA_OUT);
00169 curname->remove(name);
00170 }
00171
00172 void registerInPort(const char *name, const char *type)
00173 {
00174 Component *curcomp = comps.get((const char *) curname);
00175 curcomp->addInPort();
00176 curname->add(name);
00177 CkPrintf("registering outport %s\n", (char *) curname);
00178 ports.put((const char *)curname) = new Port((const char *) curname,
00179 curcomp, type, CHARISMA_IN);
00180 curname->remove(name);
00181 }
00182
00183 void connect(const char *name1, const char *name2)
00184 {
00185 curname->add(name1);
00186 char *oname = new char[strlen((char*)curname)+1];
00187 strcpy(oname, (char*) curname);
00188 curname->remove(name1);
00189 curname->add(name2);
00190 char *iname = new char[strlen((char*)curname)+1];
00191 strcpy(iname, (char*) curname);
00192 curname->remove(name2);
00193 Port *oport = ports.get(oname);
00194 Port *iport = ports.get(iname);
00195 if(strcmp(oport->getType(), iport->getType())!=0)
00196 CkAbort("Types of connected ports do not match !!!\n");
00197 oport->setPeer(iport);
00198 iport->setPeer(oport);
00199 oport->getComp()->connectOutPort();
00200 iport->getComp()->connectInPort();
00201 delete[] oname;
00202 delete[] iname;
00203 }
00204 void Partition(void)
00205 {
00206 int i;
00207 int n = 0;
00208 CkHashtableIterator *ht = comps.iterator();
00209 CkHashtableIterator *pt = ports.iterator();
00210
00211
00212 ht->seekStart();
00213 while(ht->hasNext()) {
00214 Component *c = (Component *) ht->next();
00215 c->setIdx(n);
00216 n++;
00217 }
00218 int *nconnect = new int[n];
00219 int tadj = 0;
00220 ht->seekStart();
00221 while(ht->hasNext()) {
00222 Component *c = (Component *) ht->next();
00223 nconnect[c->getIdx()] = c->getNumConnectedPorts();
00224 tadj += nconnect[c->getIdx()];
00225 }
00226
00227
00228 int *xadj = new int[n];
00229 int *adjncy = new int[tadj];
00230
00231 xadj[0] = 0;
00232 for(i=1;i<n;i++)
00233 xadj[i] = xadj[i-1] + nconnect[i-1];
00234 for(i=0;i<tadj;i++)
00235 adjncy[i] = (-1);
00236 pt->seekStart();
00237 while(pt->hasNext()) {
00238 Port *p = (Port *) pt->next();
00239 Port *peer = p->getPeer();
00240 if(peer==0)
00241 continue;
00242 Component *comp1 = p->getComp();
00243 Component *comp2 = peer->getComp();
00244 int idx1 = comp1->getIdx();
00245 int idx2 = comp2->getIdx();
00246 int i;
00247 for(i=xadj[idx1];adjncy[i]!=(-1);i++);
00248 adjncy[i] = idx2;
00249 }
00250 int *vwgt = new int[n];
00251 int *adjwgt = new int[tadj];
00252
00253
00254 for(i=0;i<n; i++)
00255 vwgt[i] = 1;
00256
00257
00258 for(i=0;i<tadj; i++)
00259 adjwgt[i] = 1;
00260 int wgtflag = 3;
00261 int numflag = 0;
00262 int nparts = CkNumPes();
00263 int options[5];
00264 options[0] = 0;
00265 int edgecut;
00266 int *part = new int[n];
00267 METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
00268 &numflag, &nparts, options, &edgecut, part);
00269 ht->seekStart();
00270 while(ht->hasNext()) {
00271 Component* c = (Component *) ht->next();
00272 c->setPe(part[c->getIdx()]);
00273 }
00274 }
00275 };
00276
00277 class CkArrayIndexCharisma: public CkArrayIndex
00278 {
00279 int i, j, k;
00280 public:
00281 CkArrayIndexCharisma(int _i) {
00282 i = _i; j = 0; k = 0;
00283 nInts = 1;
00284 dimension = 1;
00285 }
00286 CkArrayIndexCharisma(int _i, int _j) {
00287 i = _i; j= _j; k= 0;
00288 nInts = 2;
00289 dimension = 2;
00290 }
00291 CkArrayIndexCharisma(int _i, int _j, int _k) {
00292 i = _i; j = _j; k= _k;
00293 nInts = 3;
00294 dimension = 3;
00295 }
00296 };
00297
00298 class CharismaInPort
00299 {
00300 public:
00301 virtual ~CharismaInPort() {}
00302 virtual void send(void *msg, int len) = 0;
00303 void _create(const char *name)
00304 {
00305
00306 }
00307 };
00308
00309 class CharismaOutPort
00310 {
00311 protected:
00312 CharismaInPort *inport;
00313 public:
00314 virtual ~CharismaOutPort() {}
00315 virtual void emitData(void *data, int len)
00316 {
00317 inport->send(data, len);
00318 }
00319 void _create(const char *name)
00320 {
00321
00322 }
00323 };
00324
00325 template <class d>
00326 class CkOutPort: public CharismaOutPort
00327 {
00328 public:
00329 CkOutPort(const char *name) { _create(name); }
00330 void emit(d &_d)
00331 {
00332 CharismaOutPort::emitData((void *) &_d, sizeof(d));
00333 }
00334 };
00335
00336 template <class d>
00337 class CkInPort : public CharismaInPort
00338 {
00339 private:
00340 CkCallback cb;
00341 CkInPort() {}
00342 public:
00343 CkInPort(const char *name, int ep,const CkChareID &id)
00344 {
00345 _create(name);
00346 CkCallback _cb(ep,id);
00347 cb = _cb;
00348 }
00349 CkInPort(const char *name, int ep,int onPE,const CkGroupID &id)
00350 {
00351 _create(name);
00352 CkCallback _cb(ep,onPE,id);
00353 cb = _cb;
00354 }
00355 CkInPort(const char *name, int ep,const CkArrayIndex &idx,
00356 const CkArrayID &id)
00357 {
00358 _create(name);
00359 CkCallback _cb(ep,idx,id);
00360 cb = _cb;
00361 }
00362 void send(void *data, int len)
00363 {
00364 send((d&) (*((d*)data)));
00365 }
00366 void send(d &_d)
00367 {
00368 int impl_off=0,impl_arrstart=0;
00369 {
00370 PUP::sizer implP;
00371 implP|_d;
00372 impl_arrstart=CK_ALIGN(implP.size(),16);
00373 impl_off+=impl_arrstart;
00374 }
00375 CkMarshallMsg *impl_msg=new (impl_off,0)CkMarshallMsg;
00376 {
00377 PUP::toMem implP((void *)impl_msg->msgBuf);
00378 implP|_d;
00379 }
00380 CkArrayMessage *impl_amsg=(CkArrayMessage *)impl_msg;
00381 impl_amsg->array_setIfNotThere(CkArray_IfNotThere_buffer);
00382 cb.send(impl_msg);
00383 }
00384 };
00385
00386 class CkOutPortString : public CharismaOutPort
00387 {
00388 public:
00389 CkOutPortString(const char *name) { _create(name); }
00390 void emit(char *str)
00391 {
00392 CharismaOutPort::emitData((void *) str, (int) strlen(str)+1);
00393 }
00394 };
00395
00396 class CkInPortString : public CharismaInPort
00397 {
00398 private:
00399 CkCallback cb;
00400 CkInPortString() {}
00401 public:
00402 CkInPortString(const char *name, int ep,const CkChareID &id)
00403 {
00404 _create(name);
00405 CkCallback _cb(ep,id);
00406 cb = _cb;
00407 }
00408 CkInPortString(const char *name, int ep,int onPE,const CkGroupID &id)
00409 {
00410 _create(name);
00411 CkCallback _cb(ep,onPE,id);
00412 cb = _cb;
00413 }
00414 CkInPortString(const char *name, int ep,const CkArrayIndex &idx,
00415 const CkArrayID &id)
00416 {
00417 _create(name);
00418 CkCallback _cb(ep,idx,id);
00419 cb = _cb;
00420 }
00421 void send(void *data, int len)
00422 {
00423 send((char *) data);
00424 }
00425 void send(char *str)
00426 {
00427 CkMarshallMsg *impl_msg=new ((int)strlen(str)+1,0)CkMarshallMsg;
00428 strcpy((char *)(impl_msg->msgBuf),str);
00429 CkArrayMessage *impl_amsg=(CkArrayMessage *)impl_msg;
00430 impl_amsg->array_setIfNotThere(CkArray_IfNotThere_buffer);
00431 cb.send(impl_msg);
00432 }
00433 };
00434
00435 template <class d>
00436 class CkOutPortArray : public CharismaOutPort
00437 {
00438 public:
00439 CkOutPortArray(const char *name) { _create(name); }
00440 void emit(int n, const d *a)
00441 {
00442 CharismaOutPort::emitData((void *)a, n*sizeof(d));
00443 }
00444 };
00445
00446 template <class d>
00447 class CkInPortArray : public CharismaInPort
00448 {
00449 private:
00450 CkCallback cb;
00451 CkInPortArray() {}
00452 public:
00453 CkInPortArray(const char *name, int ep,const CkChareID &id)
00454 {
00455 _create(name);
00456 CkCallback _cb(ep,id);
00457 cb = _cb;
00458 }
00459 CkInPortArray(const char *name, int ep,int onPE,const CkGroupID &id)
00460 {
00461 _create(name);
00462 CkCallback _cb(ep,onPE,id);
00463 cb = _cb;
00464 }
00465 CkInPortArray(const char *name, int ep,const CkArrayIndex &idx,
00466 const CkArrayID &id)
00467 {
00468 _create(name);
00469 CkCallback _cb(ep,idx,id);
00470 cb = _cb;
00471 }
00472 void send(void *data, int len)
00473 {
00474 send(len/sizeof(d), (const d*) data);
00475 }
00476 void send(int n, const d *a)
00477 {
00478
00479 int impl_off=0,impl_arrstart=0;
00480 int impl_off_a, impl_cnt_a;
00481 impl_off_a=impl_off=CK_ALIGN(impl_off,sizeof(int));
00482 impl_off+=(impl_cnt_a=sizeof(int)*(n));
00483 {
00484 PUP::sizer implP;
00485 implP|n;
00486 implP|impl_off_a;
00487 impl_arrstart=CK_ALIGN(implP.size(),16);
00488 impl_off+=impl_arrstart;
00489 }
00490 CkMarshallMsg *impl_msg=new (impl_off,0)CkMarshallMsg;
00491 {
00492 PUP::toMem implP((void *)impl_msg->msgBuf);
00493 implP|n;
00494 implP|impl_off_a;
00495 }
00496 char *impl_buf=impl_msg->msgBuf+impl_arrstart;
00497 memcpy(impl_buf+impl_off_a,a,impl_cnt_a);
00498 }
00499 };
00500
00501 class CkOutPortVoid : public CharismaOutPort
00502 {
00503 public:
00504 CkOutPortVoid(const char *name) { _create(name); }
00505 void emit(void)
00506 {
00507 CharismaOutPort::emitData((void*) 0, 0);
00508 }
00509 };
00510
00511 class CkInPortVoid : public CharismaInPort
00512 {
00513 private:
00514 CkCallback cb;
00515 CkInPortVoid() {}
00516 public:
00517 CkInPortVoid(const char *name, int ep,const CkChareID &id)
00518 {
00519 _create(name);
00520 CkCallback _cb(ep,id);
00521 cb = _cb;
00522 }
00523 CkInPortVoid(const char *name, int ep,int onPE,const CkGroupID &id)
00524 {
00525 _create(name);
00526 CkCallback _cb(ep,onPE,id);
00527 cb = _cb;
00528 }
00529 CkInPortVoid(const char *name, int ep,const CkArrayIndex &idx,
00530 const CkArrayID &id)
00531 {
00532 _create(name);
00533 CkCallback _cb(ep,idx,id);
00534 cb = _cb;
00535 }
00536 void send(void *data, int len)
00537 {
00538 send();
00539 }
00540 void send(void)
00541 {
00542 void *impl_msg = CkAllocSysMsg();
00543 cb.send(impl_msg);
00544 }
00545 };
00546
00547 template <class d>
00548 class CkOutPortMsg : public CharismaOutPort
00549 {
00550 public:
00551 CkOutPortMsg(const char *name) { _create(name); }
00552 void emit(d *data)
00553 {
00554
00555 CharismaOutPort::emitData((void*) data, sizeof(d));
00556 }
00557 };
00558
00559 template <class d>
00560 class CkInPortMsg : public CharismaInPort
00561 {
00562 private:
00563 CkCallback cb;
00564 CkInPortMsg() {}
00565 public:
00566 CkInPortMsg(const char *name, int ep,const CkChareID &id)
00567 {
00568 _create(name);
00569 CkCallback _cb(ep,id);
00570 cb = _cb;
00571 }
00572 CkInPortMsg(const char *name, int ep,int onPE,const CkGroupID &id)
00573 {
00574 _create(name);
00575 CkCallback _cb(ep,onPE,id);
00576 cb = _cb;
00577 }
00578 CkInPortMsg(const char *name, int ep,const CkArrayIndex &idx,
00579 const CkArrayID &id)
00580 {
00581 _create(name);
00582 CkCallback _cb(ep,idx,id);
00583 cb = _cb;
00584 }
00585 void send(void *data, int len)
00586 {
00587 send((d*) data);
00588 }
00589 void send(d *_d)
00590 {
00591 cb.send(_d);
00592 }
00593 };
00594
00595 class Charisma : public IrrGroup
00596 {
00597 public:
00598 Charisma(void) { }
00599 Charisma(CkMigrateMessage *m) : IrrGroup(m) { }
00600 };
00601
00602 #endif