00001 #include <list>
00002 using std::list;
00003 #include <algorithm>
00004 using std::for_each;
00005 #include <stdlib.h>
00006 #include "xi-symbol.h"
00007 #include <ctype.h>
00008 #include <iostream>
00009 using std::cerr;
00010 using std::cout;
00011 using std::endl;
00012
00013 #if ! CMK_BOOL_DEFINED
00014 typedef enum {false = 0, true = 1} bool;
00015 #endif
00016
00017 #include <fstream>
00018
00019 namespace xi {
00020
00021 int fortranMode;
00022 int internalMode;
00023 const char *cur_file;
00024 const char *python_doc;
00025
00026 const char *Prefix::Proxy="CProxy_";
00027 const char *Prefix::ProxyElement="CProxyElement_";
00028 const char *Prefix::ProxySection="CProxySection_";
00029 const char *Prefix::Message="CMessage_";
00030 const char *Prefix::Index="CkIndex_";
00031 const char *Prefix::Python="CkPython_";
00032
00033
00034
00035 void die(const char *why,int line)
00036 {
00037 if (line==-1)
00038 fprintf(stderr,"%s: Charmxi fatal error> %s\n",cur_file,why);
00039 else
00040 fprintf(stderr,"%s:%d: Charmxi fatal error> %s\n",cur_file,line,why);
00041 exit(1);
00042 }
00043
00044
00045 char* fortranify(const char *s, const char *suff1="", const char *suff2="", const char *suff3="")
00046 {
00047 int i, len1 = strlen(s), len2 = strlen(suff1),
00048 len3 = strlen(suff2), len4 = strlen(suff3);
00049 int c = len1+len2+len3+len4;
00050 char str[1024], strUpper[1024];
00051 strcpy(str, s);
00052 strcat(str, suff1);
00053 strcat(str, suff2);
00054 strcat(str, suff3);
00055 for(i = 0; i < c+1; i++)
00056 str[i] = tolower(str[i]);
00057 for(i = 0; i < c+1; i++)
00058 strUpper[i] = toupper(str[i]);
00059 char *retVal;
00060 retVal = new char[2*c+20];
00061 strcpy(retVal, "FTN_NAME(");
00062 strcat(retVal, strUpper);
00063 strcat(retVal, ",");
00064 strcat(retVal, str);
00065 strcat(retVal, ")");
00066
00067 return retVal;
00068 }
00069
00070 void templateGuardBegin(bool templateOnly, XStr &str) {
00071 if (templateOnly)
00072 str << "#ifdef " << "CK_TEMPLATES_ONLY\n";
00073 else
00074 str << "#ifndef " << "CK_TEMPLATES_ONLY\n";
00075 }
00076 void templateGuardEnd(XStr &str) {
00077 str << "#endif /* CK_TEMPLATES_ONLY */\n";
00078 }
00079
00080 Value::Value(const char *s)
00081 {
00082 factor = 1;
00083 val=s;
00084 if(val == 0 || strlen(val)==0 ) return;
00085 char *v = (char *)malloc(strlen(val)+5);
00086 strcpy(v,val);
00087 int pos = strlen(v)-1;
00088 if(v[pos]=='K' || v[pos]=='k') {
00089 v[pos] = '\0';
00090 factor = 1024;
00091 }
00092 if(v[pos]=='M' || v[pos]=='m') {
00093 v[pos] = '\0';
00094 factor = 1024*1024;
00095 }
00096 val=v;
00097 }
00098
00099
00100 int
00101 Value::getIntVal(void)
00102 {
00103 if(val==0 || strlen(val)==0) return 0;
00104 return (atoi((const char *)val)*factor);
00105 }
00106
00107
00113 template<typename T, typename U, typename A>
00114 class perElemGenC
00115 {
00116 void (U::*fn)(A);
00117 void (*between)(A);
00118 A arg;
00119 public:
00120 perElemGenC(list<T*> &l,
00121 A arg_,
00122 void (U::*fn_)(A),
00123 void (*between_)(A) = NULL)
00124 : fn(fn_), between(between_), arg(arg_)
00125 {
00126 for_each(l.begin(), l.end(), *this);
00127 }
00128 void operator()(T* m)
00129 {
00130 if (m)
00131 {
00132 (m->*fn)(arg);
00133 if (between)
00134 between(arg);
00135 }
00136 }
00137 };
00138
00139 template<typename T, typename U, typename A>
00140 void perElemGen(list<T*> &l, A& arg_, void (U::*fn_)(A&),
00141
00142
00143 void (*between_)(A&))
00144 {
00145 perElemGenC<T, U, A&>(l, arg_, fn_, between_);
00146 }
00147
00148 template<typename T, typename U, typename A>
00149 void perElemGen(list<T*> &l, A& arg_, void (U::*fn_)(A&))
00150 {
00151 perElemGenC<T, U, A&>(l, arg_, fn_, NULL);
00152 }
00153
00154 template<typename T, typename U, typename A>
00155 void perElemGen(list<T*> &l, A* arg_, void (U::*fn_)(A*),
00156
00157
00158 void (*between_)(A*))
00159 {
00160 perElemGenC<T, U, A*>(l, arg_, fn_, between_);
00161 }
00162
00163 template<typename T, typename U, typename A>
00164 void perElemGen(list<T*> &l, A* arg_, void (U::*fn_)(A*))
00165 {
00166 perElemGenC<T, U, A*>(l, arg_, fn_, NULL);
00167 }
00168
00169 void newLine(XStr &str)
00170 {
00171 str << endx;
00172 }
00173
00174 ConstructList::ConstructList(int l, Construct *c, ConstructList *n)
00175 {
00176 constructs.push_back(c);
00177 if (n)
00178 constructs.insert(constructs.end(),
00179 n->constructs.begin(), n->constructs.end());
00180 line = l;
00181 }
00182
00183 void
00184 ConstructList::setExtern(int e)
00185 {
00186 Construct::setExtern(e);
00187 perElemGen(constructs, e, &Construct::setExtern);
00188 }
00189
00190 void
00191 ConstructList::setModule(Module *m)
00192 {
00193 Construct::setModule(m);
00194 perElemGen(constructs, m, &Construct::setModule);
00195 }
00196
00197 void
00198 ConstructList::print(XStr& str)
00199 {
00200 perElemGen(constructs, str, &Construct::print);
00201 }
00202
00203 int ConstructList::genAccels_spe_c_funcBodies(XStr& str) {
00204 int rtn = 0;
00205 for (list<Construct *>::iterator i = constructs.begin();
00206 i != constructs.end(); ++i)
00207 if (*i) rtn += (*i)->genAccels_spe_c_funcBodies(str);
00208 return rtn;
00209 }
00210 void ConstructList::genAccels_spe_c_regFuncs(XStr& str) {
00211 perElemGen(constructs, str, &Construct::genAccels_spe_c_regFuncs);
00212 }
00213 void ConstructList::genAccels_spe_c_callInits(XStr& str) {
00214 perElemGen(constructs, str, &Construct::genAccels_spe_c_callInits);
00215 }
00216 void ConstructList::genAccels_spe_h_includes(XStr& str) {
00217 perElemGen(constructs, str, &Construct::genAccels_spe_h_includes);
00218 }
00219 void ConstructList::genAccels_spe_h_fiCountDefs(XStr& str) {
00220 perElemGen(constructs, str, &Construct::genAccels_spe_h_fiCountDefs);
00221 }
00222 void ConstructList::genAccels_ppe_c_regFuncs(XStr& str) {
00223 perElemGen(constructs, str, &Construct::genAccels_ppe_c_regFuncs);
00224 }
00225
00226
00227 void
00228 TParamList::print(XStr& str)
00229 {
00230 tparam->print(str);
00231 if(next) {
00232 str << ",";
00233 next->print(str);
00234 }
00235 }
00236
00237 std::string TParamList::to_string()
00238 {
00239 XStr s;
00240 print(s);
00241 return s.get_string();
00242 }
00243
00244
00245 void
00246 Type::genProxyName(XStr &str,forWhom forElement)
00247 {
00248 (void)str; (void)forElement;
00249 die("type::genProxyName called (INTERNAL ERROR)");
00250 }
00251 void
00252 Type::genIndexName(XStr &str)
00253 {
00254 (void)str;
00255 die("type::genIndexName called (INTERNAL ERROR)");
00256 }
00257 void
00258 Type::genMsgProxyName(XStr &str)
00259 {
00260 (void)str;
00261 die("type::genMsgProxyName called (INTERNAL ERROR)");
00262 }
00263
00264 void
00265 NamedType::print(XStr& str)
00266 {
00267 if (scope) str << scope;
00268 str << name;
00269 if (tparams) str << "<"<<tparams<<" >";
00270 }
00271
00272 void NamedType::genIndexName(XStr& str) {
00273 if (scope) str << scope;
00274 str << Prefix::Index;
00275 str << name;
00276 if (tparams) str << "<"<<tparams<<" >";
00277 }
00278
00279 void NamedType::genMsgProxyName(XStr& str) {
00280 if (scope) str << scope;
00281 str << Prefix::Message;
00282 str << name;
00283 if (tparams) str << "<"<<tparams<<" >";
00284 }
00285
00286 void
00287 PtrType::print(XStr& str)
00288 {
00289 type->print(str);
00290 for(int i=0;i<numstars;i++)
00291 str << "*";
00292 }
00293
00294 void
00295 TypeList::print(XStr& str)
00296 {
00297 type->print(str);
00298 if(next) {
00299 str << ", ";
00300 next->print(str);
00301 }
00302 }
00303
00304 int TypeList::length(void) const
00305 {
00306 if (next) return next->length()+1;
00307 else return 1;
00308 }
00309
00310 MemberList::MemberList(Member *m, MemberList *n)
00311 {
00312 members.push_back(m);
00313 if (n)
00314 members.insert(members.end(), n->members.begin(), n->members.end());
00315 }
00316
00317
00318 void
00319 MemberList::print(XStr& str)
00320 {
00321 perElemGen(members, str, &Member::print);
00322 }
00323
00324 void
00325 MemberList::appendMember(Member *m)
00326 {
00327 members.push_back(m);
00328 }
00329
00330 int MemberList::genAccels_spe_c_funcBodies(XStr& str) {
00331 int rtn = 0;
00332 for (list<Member*>::iterator i = members.begin(); i != members.end(); ++i)
00333 if (*i)
00334 rtn += (*i)->genAccels_spe_c_funcBodies(str);
00335 return rtn;
00336 }
00337 void MemberList::genAccels_spe_c_regFuncs(XStr& str) {
00338 perElemGen(members, str, &Member::genAccels_spe_c_regFuncs);
00339 }
00340 void MemberList::genAccels_spe_c_callInits(XStr& str) {
00341 perElemGen(members, str, &Member::genAccels_spe_c_callInits);
00342 }
00343 void MemberList::genAccels_spe_h_includes(XStr& str) {
00344 perElemGen(members, str, &Member::genAccels_spe_h_includes);
00345 }
00346 void MemberList::genAccels_spe_h_fiCountDefs(XStr& str) {
00347 perElemGen(members, str, &Member::genAccels_spe_h_fiCountDefs);
00348 }
00349 void MemberList::genAccels_ppe_c_regFuncs(XStr& str) {
00350 perElemGen(members, str, &Member::genAccels_ppe_c_regFuncs);
00351 }
00352
00353
00354 void
00355 Chare::print(XStr& str)
00356 {
00357 if(external)
00358 str << "extern ";
00359 if(templat)
00360 templat->genSpec(str);
00361
00362 str << chareTypeName()<<" "<<type;
00363 if(bases) { str << ": "; bases->print(str); }
00364 if(list) {
00365 str << "{\n"; list->print(str); str << "};\n";
00366 } else {
00367 str << ";\n";
00368 }
00369 }
00370
00371 void
00372 Message::print(XStr& str)
00373 {
00374 if(external)
00375 str << "extern ";
00376 if(templat)
00377 templat->genSpec(str);
00378 str << "message ";
00379 type->print(str);
00380 printVars(str);
00381 str << ";\n";
00382 }
00383
00384 void
00385 TType::print(XStr& str)
00386 {
00387 str << "class ";
00388 type->print(str);
00389 if(init) {
00390 str << "=";
00391 init->print(str);
00392 }
00393 }
00394
00395 void
00396 TName::print(XStr& str)
00397 {
00398 type->print(str);
00399 str << " "<<name;
00400 if(val) {
00401 str << "=";
00402 str << val;
00403 }
00404 }
00405
00406
00407 void
00408 TVarList::print(XStr& str)
00409 {
00410 tvar->print(str);
00411 if(next) {
00412 str << ", ";
00413 next->print(str);
00414 }
00415 }
00416
00417 void
00418 Template::print(XStr& str)
00419 {
00420 if(entity)
00421 entity->print(str);
00422 }
00423
00424 void
00425 Entry::print(XStr& str)
00426 {
00427 if(isThreaded())
00428 str << "threaded ";
00429 if(isSync())
00430 str << "sync ";
00431 if(retType) {
00432 retType->print(str);
00433 str << " ";
00434 }
00435 str << name<<"(";
00436 if(param)
00437 param->print(str);
00438 str << ")";
00439 if(stacksize) {
00440 str << " stacksize = ";
00441 stacksize->print(str);
00442 }
00443 str << ";\n";
00444 }
00445
00446 void
00447 Module::print(XStr& str)
00448 {
00449 if(external)
00450 str << "extern ";
00451 str << "module "<<name;
00452 if(clist) {
00453 str << " {\n";
00454 clist->print(str);
00455 str << "}\n";
00456 } else {
00457 str << ";\n";
00458 }
00459 }
00460
00461 void
00462 Module::generate()
00463 {
00464 using std::ofstream;
00465 XStr declstr, defstr;
00466 XStr pubDeclStr, pubDefStr, pubDefConstr;
00467
00468
00469 #if CMK_CELL != 0
00470 XStr accelstr_spe_c, accelstr_spe_h;
00471 #endif
00472
00473 declstr <<
00474 "#ifndef _DECL_"<<name<<"_H_\n"
00475 "#define _DECL_"<<name<<"_H_\n"
00476 "#include \"charm++.h\"\n";
00477 if (fortranMode) declstr << "#include \"charm-api.h\"\n";
00478 if (clist) clist->genDecls(declstr);
00479 declstr << "extern void _register"<<name<<"(void);\n";
00480 if(isMain()) {
00481 declstr << "extern \"C\" void CkRegisterMainModule(void);\n";
00482 }
00483 declstr << "#endif"<<endx;
00484
00485 int connectPresent = 0;
00486 if (clist) clist->genPub(pubDeclStr, pubDefStr, pubDefConstr, connectPresent);
00487 if (connectPresent == 1) {
00488 pubDeclStr << "};\n\n";
00489 pubDefConstr <<"}\n\n";
00490 }
00491
00492
00493
00494 genDefs(defstr);
00495 templateGuardBegin(false, defstr);
00496 defstr <<
00497 "void _register"<<name<<"(void)\n"
00498 "{\n"
00499 " static int _done = 0; if(_done) return; _done = 1;\n";
00500 if (clist) clist->genReg(defstr);
00501 defstr << "}\n";
00502 if(isMain()) {
00503 if (fortranMode) defstr << "extern void _registerf90main(void);\n";
00504 defstr << "extern \"C\" void CkRegisterMainModule(void) {\n";
00505 if (fortranMode) {
00506 defstr << " // FORTRAN\n";
00507 defstr << " _registerf90main();\n";
00508 }
00509 defstr <<
00510 " _register"<<name<<"();\n"
00511 "}\n";
00512 }
00513 templateGuardEnd(defstr);
00514
00515
00516
00517
00518 #if CMK_CELL != 0
00519
00521 accelstr_spe_c << "#ifndef __ACCEL_" << name << "_C__\n"
00522 << "#define __ACCEL_" << name << "_C__\n\n\n";
00523 int numAccelEntries = genAccels_spe_c_funcBodies(accelstr_spe_c);
00524 accelstr_spe_c << "\n\n#endif //__ACCEL_" << name << "_C__\n";
00525
00527 accelstr_spe_h << "#ifndef __ACCEL_" << name << "_H__\n"
00528 << "#define __ACCEL_" << name << "_H__\n\n\n";
00529 genAccels_spe_h_includes(accelstr_spe_h);
00530 accelstr_spe_h << "\n\n";
00531 accelstr_spe_h << "#define MODULE_" << name << "_FUNC_INDEX_COUNT (" << numAccelEntries;
00532 genAccels_spe_h_fiCountDefs(accelstr_spe_h);
00533 accelstr_spe_h << ")\n\n\n";
00534 accelstr_spe_h << "#endif //__ACCEL_" << name << "_H__\n";
00535
00536 #endif
00537
00538
00539 XStr topname, botname;
00540 topname<<name<<".decl.h";
00541 botname<<name<<".def.h";
00542 ofstream decl(topname.get_string()), def(botname.get_string());
00543 if(!decl || !def) {
00544 cerr<<"Cannot open "<<topname.get_string()<<"or "
00545 <<botname.get_string()<<" for writing!!\n";
00546 die("cannot create output files (check directory permissions)\n");
00547 }
00548 decl<<declstr.get_string();
00549 def<<defstr.get_string();
00550 if (connectPresent == 1) {
00551 decl << pubDeclStr.charstar();
00552 def << pubDefConstr.charstar();
00553 def << pubDefStr.charstar();
00554 }
00555
00556
00557 #if CMK_CELL != 0
00558
00560 XStr accelname_c, accelname_h;
00561 accelname_c << name << ".genSPECode.c";
00562 accelname_h << name << ".genSPECode.h";
00563 ofstream accel_c(accelname_c.get_string()), accel_h(accelname_h.get_string());
00564 if (!accel_c) {
00565 cerr << "Cannot open " << accelname_c.get_string() << " for writing!!\n";
00566 die("Cannot create output files (check directory permissions)\n");
00567 }
00568 if (!accel_h) {
00569 cerr << "Cannot open " << accelname_h.get_string() << " for writing!!\n";
00570 die("Cannot create output files (check directory permissions)\n");
00571 }
00572 accel_c << accelstr_spe_c.get_string();
00573 accel_h << accelstr_spe_h.get_string();
00574
00575
00576 if (isMain()) {
00577
00578 XStr mainAccelStr_c;
00579 mainAccelStr_c << "#include \"main__funcLookup__.genSPECode.h" << "\"\n"
00580 << "#include \"" << name << ".genSPECode.c" << "\"\n";
00581 ofstream mainAccel_c("main__funcLookup__.genSPECode.c");
00582 if (!mainAccel_c) {
00583 cerr << "Cannot open main__funcLookup__.genSPECode.c for writing!!\n";
00584 die("Cannot create output files (check directory permissions)");
00585 }
00586 mainAccel_c << mainAccelStr_c.get_string();
00587
00588 XStr mainAccelStr_h;
00589 mainAccelStr_h << "#ifndef __MAIN_FUNCLOOKUP_H__\n"
00590 << "#define __MAIN_FUNCLOOKUP_H__\n\n"
00591 << "#include <spu_intrinsics.h>\n"
00592 << "#include <stdlib.h>\n"
00593 << "#include <stdio.h>\n"
00594 << "#include \"spert.h\"\n\n"
00595 << "#include \"simd.h\"\n"
00596 << "#include \"" << name << ".genSPECode.h" << "\"\n\n"
00597 << "#endif //__MAIN_FUNCLOOKUP_H__\n";
00598 ofstream mainAccel_h("main__funcLookup__.genSPECode.h");
00599 if (!mainAccel_h) {
00600 cerr << "Cannot open main__funcLookup__.genSPECode.h for writing!!\n";
00601 die("Cannot create output files (check directory permissions)");
00602 }
00603 mainAccel_h << mainAccelStr_h.get_string();
00604
00605 }
00606
00607 #endif
00608 }
00609
00610 void
00611 Module::preprocess()
00612 {
00613 if (clist!=NULL) clist->preprocess();
00614 }
00615
00616 void
00617 Module::genDepend(const char *cifile)
00618 {
00619 cout << name << ".decl.h " << name << ".def.h: "
00620 << cifile << ".stamp" << endl;
00621 }
00622
00623 void
00624 ModuleList::print(XStr& str)
00625 {
00626 perElemGen(modules, str, &Module::print);
00627 }
00628
00629 void
00630 ModuleList::generate()
00631 {
00632 for (list<Module*>::iterator i = modules.begin(); i != modules.end(); ++i)
00633 (*i)->generate();
00634 }
00635
00636 void
00637 ModuleList::preprocess()
00638 {
00639 for (list<Module*>::iterator i = modules.begin(); i != modules.end(); ++i)
00640 (*i)->preprocess();
00641 }
00642
00643 void
00644 ModuleList::genDepends(std::string ciFileBaseName)
00645 {
00646 perElemGen(modules, ciFileBaseName.c_str(), &Module::genDepend);
00647 }
00648
00649 void
00650 Readonly::print(XStr& str)
00651 {
00652 if(external)
00653 str << "extern ";
00654 str << "readonly ";
00655 if(msg)
00656 str << "message ";
00657 type->print(str);
00658 if(msg)
00659 str << " *";
00660 else
00661 str << " ";
00662 str << name;
00663 if(dims)
00664 dims->print(str);
00665 str << ";\n";
00666 }
00667
00668 void
00669 MemberList::setChare(Chare *c)
00670 {
00671 perElemGen(members, c, &Member::setChare);
00672 }
00673
00674 void
00675 ConstructList::genPub(XStr& declstr, XStr& defstr, XStr& defconstr, int& connectPresent)
00676 {
00677 for (list<Construct*>::iterator i = constructs.begin();
00678 i != constructs.end(); ++i)
00679 if (*i) {
00680 (*i)->genPub(declstr, defstr, defconstr, connectPresent);
00681 declstr << endx;
00682 }
00683 }
00684
00685 void
00686 ConstructList::genDecls(XStr& str)
00687 {
00688 perElemGen(constructs, str, &Construct::genDecls, newLine);
00689 }
00690
00691 void
00692 ConstructList::genDefs(XStr& str)
00693 {
00694 perElemGen(constructs, str, &Construct::genDefs, newLine);
00695 }
00696
00697 void
00698 ConstructList::genReg(XStr& str)
00699 {
00700 perElemGen(constructs, str, &Construct::genReg, newLine);
00701 }
00702
00703 void
00704 ConstructList::preprocess()
00705 {
00706 for (list<Construct*>::iterator i = constructs.begin();
00707 i != constructs.end(); ++i)
00708 if (*i)
00709 (*i)->preprocess();
00710 }
00711
00712 XStr Chare::proxyName(int withTemplates)
00713 {
00714 XStr str;
00715 str<<proxyPrefix()<<type;
00716 if (withTemplates) str<<tvars();
00717 return str;
00718 }
00719
00720 XStr Chare::indexName(int withTemplates)
00721 {
00722 XStr str;
00723 str<<Prefix::Index<<type;
00724 if (withTemplates) str<<tvars();
00725 return str;
00726 }
00727
00728 XStr Chare::indexList()
00729 {
00730
00731 XStr str;
00732 if (!isArray()) {
00733 cerr << (char *)baseName() << ": only chare arrays are currently supported\n";
00734 exit(1);
00735 }
00736 XStr dim = ((Array*)this)->dim();
00737 if (dim==(const char*)"1D")
00738 str << "const int *index1";
00739 else if (dim==(const char*)"2D")
00740 str << "const int *index1, const int *index2";
00741 else if (dim==(const char*)"3D")
00742 str << "const int *index1, const int *index2, const int *index3";
00743 else {
00744 cerr << (char *)baseName() << ": only up to 3 dimension chare arrays are currently supported\n";
00745 exit(1);
00746 }
00747 return str;
00748 }
00749
00750 static const char *forWhomStr(forWhom w)
00751 {
00752 switch(w) {
00753 case forAll: return Prefix::Proxy;
00754 case forIndividual: return Prefix::ProxyElement;
00755 case forSection: return Prefix::ProxySection;
00756 case forIndex: return Prefix::Index;
00757 case forPython: return "";
00758 default: return NULL;
00759 };
00760 }
00761
00762 void NamedType::genProxyName(XStr& str,forWhom forElement)
00763 {
00764 const char *prefix=forWhomStr(forElement);
00765 if (prefix==NULL)
00766 die("Unrecognized forElement type passed to NamedType::genProxyName");
00767 if (scope) str << scope;
00768 str << prefix;
00769 str << name;
00770 if (tparams) str << "<"<<tparams<<" >";
00771 }
00772
00773 void TypeList::genProxyNames(XStr& str, const char *prefix, const char *middle,
00774 const char *suffix, const char *sep,forWhom forElement)
00775 {
00776 if(type) {
00777 str << prefix;
00778 type->genProxyName(str,forElement);
00779 if (middle!=NULL) {
00780 str << middle;
00781 type->genProxyName(str,forElement);
00782 }
00783 str << suffix;
00784 }
00785 if(next) {
00786 str << sep;
00787 next->genProxyNames(str, prefix, middle, suffix, sep,forElement);
00788 }
00789 }
00790 void Chare::genProxyNames(XStr& str, const char *prefix,const char *middle,
00791 const char *suffix, const char *sep)
00792 {
00793 bases->genProxyNames(str,prefix,middle,suffix,sep,forElement);
00794 }
00795 void Chare::genIndexNames(XStr& str, const char *prefix,const char *middle,
00796 const char *suffix, const char *sep)
00797 {
00798 bases->genProxyNames(str,prefix,middle,suffix,sep,forIndex);
00799 }
00800 char *Chare::proxyPrefix(void)
00801 {
00802 return (char *)forWhomStr(forElement);
00803 }
00804
00805
00806 void Chare::sharedDisambiguation(XStr &str,const XStr &super)
00807 {
00808 (void)super;
00809 str << "\n void ckDelegate(CkDelegateMgr *dTo,CkDelegateData *dPtr=NULL)"
00810 << "\n { ";
00811 genProxyNames(str," ",NULL,"::ckDelegate(dTo,dPtr); ","");
00812 str << "}"
00813 << "\n void ckUndelegate(void)"
00814 << "\n { ";
00815 genProxyNames(str," ",NULL,"::ckUndelegate(); ","");
00816 str << "}"
00817 << "\n void pup(PUP::er &p)"
00818 << "\n { ";
00819 genProxyNames(str," ",NULL,"::pup(p); ","");
00820 str << "}";
00821 if (isPython()) {
00822 str << "\n void registerPython(const char *str)"
00823 << "\n { CcsRegisterHandler(str, CkCallback("<<Prefix::Index<<type<<"::pyRequest(0), *this)); }";
00824 }
00825 str << "\n";
00826 }
00827
00828
00829 static const char *CIClassStart =
00830 "{\n"
00831 " public:\n"
00832 ;
00833
00834 static const char *CIClassEnd =
00835 "};\n"
00836 ;
00837
00838 Chare::Chare(int ln, attrib_t Nattr, NamedType *t, TypeList *b, MemberList *l)
00839 : attrib(Nattr), type(t), list(l), bases(b)
00840 {
00841 line = ln;
00842 entryCount=1;
00843 hasElement=0;
00844 forElement=forAll;
00845 hasSection=0;
00846 bases_CBase=NULL;
00847 setTemplate(0);
00848 hasSdagEntry=0;
00849 if (list)
00850 {
00851 list->setChare(this);
00852
00853 if(isMigratable()) {
00854 Entry *e=new Entry(ln,SMIGRATE,NULL,
00855 (char *)type->getBaseName(),
00856 new ParamList(new Parameter(line,
00857 new PtrType(new NamedType("CkMigrateMessage")))),0,0,0);
00858 e->setChare(this);
00859 list=new MemberList(e,list);
00860 }
00861 }
00862 if (bases==NULL)
00863 bases = new TypeList(new NamedType("Chare"), NULL);
00864 }
00865
00866 void
00867 Chare::genRegisterMethodDef(XStr& str)
00868 {
00869 if(external || type->isTemplated())
00870 return;
00871 templateGuardBegin(isTemplated(), str);
00872 str << tspec() <<
00873 "void "<<indexName()<<"::__register(const char *s, size_t size) {\n"
00874 " __idx = CkRegisterChare(s, size,";
00875 if (isMainChare()) str << " TypeMainChare";
00876 else if (isGroup()) str << " TypeGroup";
00877 else if (isNodeGroup()) str << " TypeNodeGroup";
00878 else if (isArray()) str << " TypeArray";
00879 else if (isChare()) str << " TypeChare";
00880 else str << " TypeInvalid";
00881 str << ");\n";
00882 if (internalMode) str << " CkRegisterChareInCharm(__idx);\n";
00883
00884 genIndexNames(str, " CkRegisterBase(__idx, ",NULL, "::__idx);\n", "");
00885 genSubRegisterMethodDef(str);
00886 if(list)
00887 list->genReg(str);
00888 if (hasSdagEntry) {
00889 str << " " << baseName() << "::__sdag_register(); \n";
00890 }
00891 str << "}\n";
00892 templateGuardEnd(str);
00893 }
00894
00895 void
00896 Chare::genPub(XStr& declstr, XStr& defstr, XStr& defconstr, int& connectPresent)
00897 {
00898 if(type->isTemplated())
00899 return;
00900 else
00901 {
00902 if(list)
00903 list->genPub(declstr, defstr, defconstr, connectPresent);
00904 }
00905 }
00906
00907 void
00908 Chare::genDecls(XStr& str)
00909 {
00910 if(type->isTemplated())
00911 return;
00912 str << "/* DECLS: "; print(str); str << " */\n";
00913
00914
00915
00916
00917 if (isPython()) {
00918 str << "#include \"PythonCCS.h\"\n";
00919 if (list) {
00920 Entry *etemp = new Entry(0,0,new BuiltinType("void"),"pyRequest",new ParamList(new Parameter(0,new PtrType(new NamedType("CkCcsRequestMsg",0)),"msg")),0,0,0,0);
00921 list->appendMember(etemp);
00922 etemp->setChare(this);
00923
00924
00925
00926 }
00927 }
00928
00929
00930 str << tspec()<<" class "<<type<<";\n";
00931 str << tspec()<<" class "<<Prefix::Index<<type<<";\n";
00932 str << tspec()<<" class "<<Prefix::Proxy<<type<<";\n";
00933 if (hasElement)
00934 str << tspec()<<" class "<<Prefix::ProxyElement<<type<<";\n";
00935 if (hasSection)
00936 str << tspec()<<" class "<<Prefix::ProxySection<<type<<";\n";
00937 if (isPython())
00938 str << tspec()<<" class "<<Prefix::Python<<type<<";\n";
00939
00940
00941 str << "/* --------------- index object ------------------ */\n";
00942 str << tspec()<< "class "<<Prefix::Index<<type;
00943 str << ":";
00944 genProxyNames(str, "public ",NULL, "", ", ");
00945 if(external || type->isTemplated())
00946 {
00947 str << ";";
00948 }
00949 else
00950 {
00951 str << CIClassStart;
00952 genTypedefs(str);
00953 str << " static int __idx;\n";
00954 str << " static void __register(const char *s, size_t size);\n";
00955 if(list)
00956 list->genIndexDecls(str);
00957 str << CIClassEnd;
00958 }
00959 str << "/* --------------- element proxy ------------------ */\n";
00960 genSubDecls(str);
00961 if (hasElement) {
00962 str << "/* ---------------- collective proxy -------------- */\n";
00963 forElement=forAll; genSubDecls(str); forElement=forIndividual;
00964 }
00965 if (hasSection) {
00966 str << "/* ---------------- section proxy -------------- */\n";
00967 forElement=forSection; genSubDecls(str); forElement=forIndividual;
00968 }
00969 if (isPython()) {
00970 str << "/* ---------------- python wrapper -------------- */\n";
00971 genPythonDecls(str);
00972 }
00973
00974 if(list) {
00975
00976 int sdagPresent = 0;
00977 XStr sdagStr;
00978 CParsedFile myParsedFile(this);
00979 list->collectSdagCode(&myParsedFile, sdagPresent);
00980 if(sdagPresent) {
00981 XStr classname;
00982 XStr sdagDecls;
00983 classname << baseName(0);
00984 resetNumbers();
00985 myParsedFile.doProcess(classname, sdagDecls, sdagDefs);
00986 str << sdagDecls;
00987 }
00988 }
00989
00990
00991
00992 TypeList *b=bases_CBase;
00993 if (b==NULL) b=bases;
00994 if (templat) {
00995 templat->genSpec(str);
00996 str << "\nclass CBase_" << type << " : public ";
00997 } else {
00998 str << "typedef ";
00999 }
01000 str << "CBaseT" << b->length() << "<";
01001 if (isPython()) {
01002 str << Prefix::Python << type;
01003 } else {
01004 str << b;
01005 }
01006 str << ", CProxy_" << type;
01007 if (templat) {
01008 templat->genVars(str);
01009 str << " > { };\n";
01010 } else {
01011 str << "> CBase_" << type << ";\n";
01012 }
01013 }
01014
01015 void
01016 Chare::preprocess()
01017 {
01018 if(list) list->preprocess();
01019 }
01020
01021
01022
01023
01024
01025
01026
01027 static void
01028 disambig_proxy(XStr &str, const XStr &super)
01029 {
01030 str << "\n int ckIsDelegated(void) const"
01031 << "\n { return " << super << "::ckIsDelegated(); }"
01032 << "\n inline CkDelegateMgr *ckDelegatedTo(void) const"
01033 << "\n { return " << super << "::ckDelegatedTo(); }"
01034 << "\n inline CkDelegateData *ckDelegatedPtr(void) const"
01035 << "\n { return " << super << "::ckDelegatedPtr(); }"
01036 << "\n CkGroupID ckDelegatedIdx(void) const"
01037 << "\n { return " << super << "::ckDelegatedIdx(); }"
01038 << "\n";
01039 }
01040
01041 void
01042 Chare::genSubDecls(XStr& str)
01043 {
01044 XStr ptype;
01045 ptype<<proxyPrefix()<<type;
01046
01047
01048 str << tspec()<< "class "<<ptype;
01049 if(external || type->isTemplated()) {
01050 str << ";";
01051 return;
01052 }
01053 str << ":";
01054 genProxyNames(str, "public ",NULL, "", ", ");
01055 str << CIClassStart;
01056
01057 genTypedefs(str);
01058
01059
01060 str << " "<<ptype<<"(void) {};\n";
01061
01062 str << " "<<ptype<<"(CkChareID __cid) : ";
01063 genProxyNames(str, "",NULL, "(__cid)", ", ");
01064 str << "{ }\n";
01065
01066 str << " "<<ptype<<"(const Chare *c) : ";
01067 genProxyNames(str, "",NULL, "(c)", ", ");
01068 str << "{ }\n";
01069
01070
01071 XStr super;
01072 bases->getFirst()->genProxyName(super,forElement);
01073 disambig_proxy(str, super);
01074 str << "\n inline void ckCheck(void) const"
01075 << "\n { "<< super << "::ckCheck(); }"
01076 << "\n const CkChareID &ckGetChareID(void) const"
01077 << "\n { return " << super << "::ckGetChareID(); }"
01078 << "\n operator const CkChareID &(void) const"
01079 << "\n { return ckGetChareID(); }"
01080 << "\n";
01081
01082 sharedDisambiguation(str,super);
01083 str << "\n void ckSetChareID(const CkChareID &c)"
01084 << "\n {";
01085 genProxyNames(str," ",NULL,"::ckSetChareID(c); ","");
01086 str << "}"
01087 << "\n "<<type<<tvars()<<" *ckLocal(void) const"
01088 << "\n { return ("<<type<<tvars()<<" *)CkLocalChare(&ckGetChareID()); }"
01089 << "\n";
01090
01091 if(list)
01092 list->genDecls(str);
01093 str << CIClassEnd;
01094 if (!isTemplated()) str << "PUPmarshall("<<ptype<<")\n";
01095 }
01096
01097 void Chare::genPythonDecls(XStr& str) {
01098
01099 XStr ptype;
01100 ptype<<Prefix::Python<<type;
01101
01102
01103 str << tspec()<< "class "<<ptype;
01104 if(external || type->isTemplated()) {
01105 str << ";";
01106 return;
01107 }
01108 str << ":";
01109 TypeList *b=bases_CBase;
01110 if (b==NULL) b=bases;
01111 b->genProxyNames(str,"public ",NULL,"",", ",forPython);
01112 str << ", public PythonObject ";
01113 str << CIClassStart;
01114
01115
01116 str << " "<<ptype<<"(void) {}\n";
01117 str << " "<<ptype<<"(CkMigrateMessage *msg): ";
01118 b->genProxyNames(str,"",NULL,"(msg)",", ",forPython);
01119 str << " {}\n";
01120
01121
01122 str << " void pup(PUP::er &p) {\n";
01123 b->genProxyNames(str," ",NULL,"::pup(p);","\n",forPython);
01124 str << "\n }\n";
01125
01126
01127 str << " static PyMethodDef CkPy_MethodsCustom[];\n";
01128 str << " PyMethodDef *getMethods(void) {return CkPy_MethodsCustom;}\n";
01129 str << " static const char *CkPy_MethodsCustomDoc;\n";
01130 str << " const char *getMethodsDoc(void) {return CkPy_MethodsCustomDoc;}\n";
01131
01132 str << CIClassEnd;
01133
01134
01135 if (list)
01136 list->genPythonDecls(str);
01137 str << "\n";
01138
01139 if (!isTemplated()) str << "PUPmarshall("<<ptype<<")\n";
01140 }
01141
01142 void Chare::genPythonDefs(XStr& str) {
01143
01144 XStr ptype;
01145 ptype<<Prefix::Python<<type;
01146
01147
01148 str << "PyMethodDef "<<ptype<<"::CkPy_MethodsCustom[] = {\n";
01149 if (list)
01150 list->genPythonStaticDefs(str);
01151 str << " {NULL, NULL}\n};\n\n";
01152
01153 str << "const char * "<<ptype<<"::CkPy_MethodsCustomDoc = \"charm.__doc__ = \\\"Available methods for object "<<type<<":\\\\n\"";
01154 if (list)
01155 list->genPythonStaticDocs(str);
01156 str << "\n \"\\\"\";\n\n";
01157
01158 if (list)
01159 list->genPythonDefs(str);
01160
01161 }
01162
01163 Group::Group(int ln, attrib_t Nattr,
01164 NamedType *t, TypeList *b, MemberList *l)
01165 :Chare(ln,Nattr|CGROUP,t,b,l)
01166 {
01167 hasElement=1;
01168 forElement=forIndividual;
01169 hasSection=1;
01170 bases_CBase=NULL;
01171 if (b==NULL) {
01172 delete bases;
01173 if (isNodeGroup())
01174 bases = new TypeList(new NamedType("NodeGroup"), NULL);
01175 else {
01176 bases = new TypeList(new NamedType("IrrGroup"), NULL);
01177 bases_CBase = new TypeList(new NamedType("Group"), NULL);
01178 }
01179 }
01180 }
01181
01182 void Group::genSubRegisterMethodDef(XStr& str) {
01183 if(!isTemplated()){
01184 str << " CkRegisterGroupIrr(__idx,"<<type<<"::isIrreducible());\n";
01185 }else{
01186 str << " CkRegisterGroupIrr(__idx," <<type<<tvars() <<"::isIrreducible());\n";
01187 }
01188 }
01189
01190 static void
01191 disambig_reduction_client(XStr &str, const XStr &super)
01192 {
01193 str << "\n inline void setReductionClient(CkReductionClientFn fn,void *param=NULL) const"
01194 << "\n { " << super << "::setReductionClient(fn,param); }"
01195 << "\n inline void ckSetReductionClient(CkReductionClientFn fn,void *param=NULL) const"
01196 << "\n { " << super << "::ckSetReductionClient(fn,param); }"
01197 << "\n inline void ckSetReductionClient(CkCallback *cb) const"
01198 << "\n { " << super << "::ckSetReductionClient(cb); }"
01199 << "\n";
01200 }
01201
01202 static void
01203 disambig_group(XStr &str, const XStr &super)
01204 {
01205 disambig_proxy(str, super);
01206 str << "inline void ckCheck(void) const {" << super << "::ckCheck();}\n"
01207 << "CkChareID ckGetChareID(void) const\n"
01208 << " {return " << super << "::ckGetChareID();}\n"
01209 << "CkGroupID ckGetGroupID(void) const\n"
01210 << " {return " << super << "::ckGetGroupID();}\n"
01211 << "operator CkGroupID () const { return ckGetGroupID(); }\n";
01212 disambig_reduction_client(str, super);
01213 }
01214
01215 void
01216 Group::genSubDecls(XStr& str)
01217 {
01218 XStr ptype; ptype<<proxyPrefix()<<type;
01219 XStr ttype; ttype<<type<<tvars();
01220 XStr super;
01221 bases->getFirst()->genProxyName(super,forElement);
01222
01223
01224 str << tspec()<< "class "<<ptype;
01225 if(external || type->isTemplated()) {
01226 str << ";";
01227 return;
01228 }
01229 str << ": ";
01230 genProxyNames(str, "public ",NULL, "", ", ");
01231 str << CIClassStart;
01232
01233 genTypedefs(str);
01234
01235
01236 str << " "<<ptype<<"(void) {}\n";
01237 str << " "<<ptype<<"(const IrrGroup *g) : ";
01238 genProxyNames(str, "", NULL,"(g)", ", ");
01239 str << "{ }\n";
01240
01241 if (forElement==forIndividual)
01242 {
01243 str << " "<<ptype<<"(CkGroupID _gid,int _onPE,CK_DELCTOR_PARAM) : ";
01244 genProxyNames(str, "", NULL,"(_gid,_onPE,CK_DELCTOR_ARGS)", ", ");
01245 str << "{ }\n";
01246 str << " "<<ptype<<"(CkGroupID _gid,int _onPE) : ";
01247 genProxyNames(str, "", NULL,"(_gid,_onPE)", ", ");
01248 str << "{ }\n";
01249
01250 disambig_group(str, super);
01251 str << "int ckGetGroupPe(void) const\n"
01252 << "{return " << super << "::ckGetGroupPe();}\n";
01253
01254 }
01255 else if (forElement==forSection)
01256 {
01257 str << " "<<ptype<<"(const CkGroupID &_gid,const int *_pelist,int _npes,CK_DELCTOR_PARAM) : ";
01258 genProxyNames(str, "", NULL,"(_gid,_pelist,_npes,CK_DELCTOR_ARGS)", ", ");
01259 str << "{ }\n";
01260 str << " "<<ptype<<"(const CkGroupID &_gid,const int *_pelist,int _npes) : ";
01261 genProxyNames(str, "", NULL,"(_gid,_pelist,_npes)", ", ");
01262 str << "{ }\n";
01263 str << " "<<ptype<<"(int n,const CkGroupID *_gid, int const * const *_pelist,const int *_npes) : ";
01264 genProxyNames(str, "", NULL,"(n,_gid,_pelist,_npes)", ", ");
01265 str << "{ }\n";
01266 str << " "<<ptype<<"(int n,const CkGroupID *_gid, int const * const *_pelist,const int *_npes,CK_DELCTOR_PARAM) : ";
01267 genProxyNames(str, "", NULL,"(n,_gid,_pelist,_npes,CK_DELCTOR_ARGS)", ", ");
01268 str << "{ }\n";
01269
01270 disambig_group(str, super);
01271 str << "inline int ckGetNumSections() const\n" <<
01272 "{ return " << super << "::ckGetNumSections(); }\n" <<
01273 "inline CkSectionInfo &ckGetSectionInfo()\n" <<
01274 "{ return " << super << "::ckGetSectionInfo(); }\n" <<
01275 "inline CkSectionID *ckGetSectionIDs()\n" <<
01276 "{ return " << super << "::ckGetSectionIDs(); }\n" <<
01277 "inline CkSectionID &ckGetSectionID()\n" <<
01278 "{ return " << super << "::ckGetSectionID(); }\n" <<
01279 "inline CkSectionID &ckGetSectionID(int i)\n" <<
01280 "{ return " << super << "::ckGetSectionID(i); }\n" <<
01281 "inline CkGroupID ckGetGroupIDn(int i) const\n" <<
01282 "{ return " << super << "::ckGetGroupIDn(i); }\n" <<
01283 "inline int *ckGetElements() const\n" <<
01284 "{ return " << super << "::ckGetElements(); }\n" <<
01285 "inline int *ckGetElements(int i) const\n" <<
01286 "{ return " << super << "::ckGetElements(i); }\n" <<
01287 "inline int ckGetNumElements() const\n" <<
01288 "{ return " << super << "::ckGetNumElements(); } \n" <<
01289 "inline int ckGetNumElements(int i) const\n" <<
01290 "{ return " << super << "::ckGetNumElements(i); }\n";
01291 }
01292 else if (forElement==forAll)
01293 {
01294 str << " "<<ptype<<"(CkGroupID _gid,CK_DELCTOR_PARAM) : ";
01295 genProxyNames(str, "", NULL,"(_gid,CK_DELCTOR_ARGS)", ", ");
01296 str << "{ }\n";
01297 str << " "<<ptype<<"(CkGroupID _gid) : ";
01298 genProxyNames(str, "", NULL,"(_gid)", ", ");
01299 str << "{ }\n";
01300
01301
01302 forElement=forIndividual;
01303 str << " "<<proxyName(1)<<" operator[](int onPE) const\n";
01304 str << " {return "<<proxyName(1)<<"(ckGetGroupID(),onPE,CK_DELCTOR_CALL);}\n";
01305 forElement=forAll;
01306
01307 disambig_group(str, super);
01308 }
01309
01310
01311 sharedDisambiguation(str,super);
01312 str<<" void ckSetGroupID(CkGroupID g) {\n";
01313 genProxyNames(str," ",NULL,"::ckSetGroupID(g);\n","");
01314 str<<" }\n";
01315
01316 str << " "<<ttype<<"* ckLocalBranch(void) const {\n";
01317 str << " return ckLocalBranch(ckGetGroupID());\n";
01318 str << " }\n";
01319 str << " static "<<ttype<< "* ckLocalBranch(CkGroupID gID) {\n";
01320 str << " return ("<<ttype<<"*)";
01321 if(isNodeGroup())
01322 str << "CkLocalNodeBranch(gID);\n";
01323 else
01324 str << "CkLocalBranch(gID);\n";
01325 str << " }\n";
01326 if(list)
01327 list->genDecls(str);
01328 str << CIClassEnd;
01329 if (!isTemplated()) str << "PUPmarshall("<<ptype<<")\n";
01330
01331 }
01332
01333 XStr indexSuffix2object(const XStr &indexSuffix) {
01334 if (indexSuffix==(const char*)"1D") return "CkIndex1D";
01335 if (indexSuffix==(const char*)"2D") return "CkIndex2D";
01336 if (indexSuffix==(const char*)"3D") return "CkIndex3D";
01337 if (indexSuffix==(const char*)"4D") return "CkIndex4D";
01338 if (indexSuffix==(const char*)"5D") return "CkIndex5D";
01339 if (indexSuffix==(const char*)"6D") return "CkIndex6D";
01340 if (indexSuffix==(const char*)"Max") return "CkIndexMax";
01341 else return indexSuffix;
01342 }
01343
01344
01345 Array::Array(int ln, attrib_t Nattr, NamedType *index,
01346 NamedType *t, TypeList *b, MemberList *l)
01347 : Chare(ln,Nattr|CARRAY|CMIGRATABLE,t,b,l)
01348 {
01349 hasElement=1;
01350 forElement=forIndividual;
01351 hasSection=1;
01352 index->print(indexSuffix);
01353
01354 if (indexSuffix!=(const char*)"none")
01355 indexType<<"CkArrayIndex"<<indexSuffix;
01356 else indexType<<"CkArrayIndex";
01357
01358 if(b==0) {
01359 delete bases;
01360 if (0==strcmp(type->getBaseName(),"ArrayElement"))
01361
01362 bases = new TypeList(new NamedType("ArrayBase"), NULL);
01363 else {
01364 bases=new TypeList(new NamedType("ArrayElement"),NULL);
01365 XStr indexObject(indexSuffix2object(indexSuffix));
01366 XStr parentClass;
01367 parentClass<<"ArrayElementT<"<<indexObject<<">";
01368 char *parentClassName=strdup(parentClass);
01369 bases_CBase = new TypeList(new NamedType(parentClassName), NULL);
01370 }
01371 }
01372 }
01373
01374 static void
01375 disambig_array(XStr &str, const XStr &super)
01376 {
01377 disambig_proxy(str, super);
01378 str << "\n inline void ckCheck(void) const"
01379 << "\n { " << super << "::ckCheck(); }"
01380 << "\n inline operator CkArrayID () const"
01381 << "\n { return ckGetArrayID(); }"
01382 << "\n inline CkArrayID ckGetArrayID(void) const"
01383 << "\n { return " << super << "::ckGetArrayID(); }"
01384 << "\n inline CkArray *ckLocalBranch(void) const"
01385 << "\n { return " << super << "::ckLocalBranch(); }"
01386 << "\n inline CkLocMgr *ckLocMgr(void) const"
01387 << "\n { return " << super << "::ckLocMgr(); }"
01388 << "\n"
01389 << "\n inline static CkArrayID ckCreateEmptyArray(void)"
01390 << "\n { return " << super << "::ckCreateEmptyArray(); }"
01391 << "\n inline static CkArrayID ckCreateArray(CkArrayMessage *m,int ctor,const CkArrayOptions &opts)"
01392 << "\n { return " << super << "::ckCreateArray(m,ctor,opts); }"
01393 << "\n inline void ckInsertIdx(CkArrayMessage *m,int ctor,int onPe,const CkArrayIndex &idx)"
01394 << "\n { " << super << "::ckInsertIdx(m,ctor,onPe,idx); }"
01395 << "\n inline void doneInserting(void)"
01396 << "\n { " << super << "::doneInserting(); }"
01397 << "\n"
01398 << "\n inline void ckBroadcast(CkArrayMessage *m, int ep, int opts=0) const"
01399 << "\n { " << super << "::ckBroadcast(m,ep,opts); }";
01400 disambig_reduction_client(str, super);
01401 }
01402
01403 void
01404 Array::genSubDecls(XStr& str)
01405 {
01406 XStr ptype; ptype<<proxyPrefix()<<type;
01407
01408
01409 str << tspec()<< " class "<<ptype;
01410 if(external || type->isTemplated()) {
01411 str << ";";
01412 return;
01413 }
01414 str << " : ";
01415 genProxyNames(str, "public ",NULL, "", ", ");
01416 str << CIClassStart;
01417
01418 genTypedefs(str);
01419
01420 str << " "<<ptype<<"(void) {}\n";
01421 if (forElement!=forSection)
01422 {
01423 str << " "<<ptype<<"(const ArrayElement *e) : ";
01424 genProxyNames(str, "", NULL,"(e)", ", ");
01425 str << "{ }\n";
01426 }
01427
01428
01429 XStr super;
01430 bases->getFirst()->genProxyName(super,forElement);
01431 sharedDisambiguation(str,super);
01432
01433 if (forElement==forIndividual)
01434 {
01435 disambig_array(str, super);
01436 str << "\n inline void ckInsert(CkArrayMessage *m,int ctor,int onPe)"
01437 << "\n { " << super << "::ckInsert(m,ctor,onPe); }"
01438 << "\n inline void ckSend(CkArrayMessage *m, int ep, int opts = 0) const"
01439 << "\n { " << super << "::ckSend(m,ep,opts); }"
01440 << "\n inline void *ckSendSync(CkArrayMessage *m, int ep) const"
01441 << "\n { return " << super << "::ckSendSync(m,ep); }"
01442 << "\n inline const CkArrayIndex &ckGetIndex() const"
01443 << "\n { return " << super << "::ckGetIndex(); }"
01444 << "\n"
01445 << "\n " << type << tvars() << " *ckLocal(void) const"
01446 << "\n { return ("<<type<<tvars()<<" *)"<<super<<"::ckLocal(); }"
01447 << "\n";
01448
01449
01450 str << "\n " <<ptype<<"(const CkArrayID &aid,const "<<indexType<<" &idx,CK_DELCTOR_PARAM)"
01451 << "\n :";
01452 genProxyNames(str, "",NULL, "(aid,idx,CK_DELCTOR_ARGS)", ", ");
01453 str << "\n {}"
01454 << "\n " <<ptype<<"(const CkArrayID &aid,const "<<indexType<<" &idx)"
01455 << "\n :";
01456 genProxyNames(str, "",NULL, "(aid,idx)", ", ");
01457 str << "\n {}"
01458 << "\n";
01459
01460 if ((indexType != (const char*)"CkArrayIndex") && (indexType != (const char*)"CkArrayIndexMax"))
01461 {
01462
01463
01464
01465
01466
01467 str << "\n " <<ptype<<"(const CkArrayID &aid,const CkArrayIndex &idx,CK_DELCTOR_PARAM)"
01468 << "\n :";
01469 genProxyNames(str, "",NULL, "(aid,idx,CK_DELCTOR_ARGS)", ", ");
01470 str << "\n {}"
01471 << "\n " << ptype<<"(const CkArrayID &aid,const CkArrayIndex &idx)"
01472 << "\n :";
01473 genProxyNames(str, "",NULL, "(aid,idx)", ", ");
01474 str << "\n {}"
01475 << "\n";
01476 }
01477 }
01478 else if (forElement==forAll)
01479 {
01480 disambig_array(str, super);
01481
01482
01483 str << "\n static CkArrayID ckNew(void) { return ckCreateEmptyArray(); }";
01484
01485 XStr etype; etype<<Prefix::ProxyElement<<type<<tvars();
01486 if (indexSuffix!=(const char*)"none")
01487 {
01488 str << "\n // Generalized array indexing:"
01489 << "\n "<<etype<<" operator [] (const "<<indexType<<" &idx) const"
01490 << "\n { return "<<etype<<"(ckGetArrayID(), idx, CK_DELCTOR_CALL); }"
01491 << "\n "<<etype<<" operator() (const "<<indexType<<" &idx) const"
01492 << "\n { return "<<etype<<"(ckGetArrayID(), idx, CK_DELCTOR_CALL); }"
01493 << "\n";
01494 }
01495
01496
01497 if (indexSuffix==(const char*)"1D")
01498 {
01499 str << " " << etype << " operator [] (int idx) const \n"
01500 << " {return "<< etype <<"(ckGetArrayID(), CkArrayIndex1D(idx), CK_DELCTOR_CALL);}\n"
01501 << " " << etype <<" operator () (int idx) const \n"
01502 << " {return "<< etype <<"(ckGetArrayID(), CkArrayIndex1D(idx), CK_DELCTOR_CALL);}\n";
01503 } else if (indexSuffix==(const char*)"2D") {
01504 str <<
01505 " "<<etype<<" operator () (int i0,int i1) const \n"
01506 " {return "<<etype<<"(ckGetArrayID(), CkArrayIndex2D(i0,i1), CK_DELCTOR_CALL);}\n"
01507 " "<<etype<<" operator () (CkIndex2D idx) const \n"
01508 " {return "<<etype<<"(ckGetArrayID(), CkArrayIndex2D(idx), CK_DELCTOR_CALL);}\n";
01509 } else if (indexSuffix==(const char*)"3D") {
01510 str <<
01511 " "<<etype<<" operator () (int i0,int i1,int i2) const \n"
01512 " {return "<<etype<<"(ckGetArrayID(), CkArrayIndex3D(i0,i1,i2), CK_DELCTOR_CALL);}\n"
01513 " "<<etype<<" operator () (CkIndex3D idx) const \n"
01514 " {return "<<etype<<"(ckGetArrayID(), CkArrayIndex3D(idx), CK_DELCTOR_CALL);}\n";
01515 } else if (indexSuffix==(const char*)"4D") {
01516 str <<
01517 " "<<etype<<" operator () (short int i0,short int i1,short int i2,short int i3) const \n"
01518 " {return "<<etype<<"(ckGetArrayID(), CkArrayIndex4D(i0,i1,i2,i3), CK_DELCTOR_CALL);}\n"
01519 " "<<etype<<" operator () (CkIndex4D idx) const \n"
01520 " {return "<<etype<<"(ckGetArrayID(), CkArrayIndex4D(idx), CK_DELCTOR_CALL);}\n";
01521 } else if (indexSuffix==(const char*)"5D") {
01522 str <<
01523 " "<<etype<<" operator () (short int i0,short int i1,short int i2,short int i3,short int i4) const \n"
01524 " {return "<<etype<<"(ckGetArrayID(), CkArrayIndex5D(i0,i1,i2,i3,i4), CK_DELCTOR_CALL);}\n"
01525 " "<<etype<<" operator () (CkIndex5D idx) const \n"
01526 " {return "<<etype<<"(ckGetArrayID(), CkArrayIndex5D(idx), CK_DELCTOR_CALL);}\n";
01527 } else if (indexSuffix==(const char*)"6D") {
01528 str <<
01529 " "<<etype<<" operator () (short int i0,short int i1,short int i2,short int i3,short int i4,short int i5) const \n"
01530 " {return "<<etype<<"(ckGetArrayID(), CkArrayIndex6D(i0,i1,i2,i3,i4,i5), CK_DELCTOR_CALL);}\n"
01531 " "<<etype<<" operator () (CkIndex6D idx) const \n"
01532 " {return "<<etype<<"(ckGetArrayID(), CkArrayIndex6D(idx), CK_DELCTOR_CALL);}\n";
01533 }
01534 str <<" "<<ptype<<"(const CkArrayID &aid,CK_DELCTOR_PARAM) \n"
01535 " :";genProxyNames(str, "",NULL, "(aid,CK_DELCTOR_ARGS)", ", ");str<<" {}\n";
01536 str <<" "<<ptype<<"(const CkArrayID &aid) \n"
01537 " :";genProxyNames(str, "",NULL, "(aid)", ", ");str<<" {}\n";
01538 }
01539 else if (forElement==forSection)
01540 {
01541 disambig_array(str, super);
01542 str << "\n inline void ckSend(CkArrayMessage *m, int ep, int opts = 0)"
01543 << "\n { " << super << "::ckSend(m,ep,opts); }"
01544 << "\n inline CkSectionInfo &ckGetSectionInfo()"
01545 << "\n { return " << super << "::ckGetSectionInfo(); }"
01546 << "\n inline CkSectionID *ckGetSectionIDs()"
01547 << "\n { return " << super << "::ckGetSectionIDs(); }"
01548 << "\n inline CkSectionID &ckGetSectionID()"
01549 << "\n { return " << super << "::ckGetSectionID(); }"
01550 << "\n inline CkSectionID &ckGetSectionID(int i)"
01551 << "\n { return " << super << "::ckGetSectionID(i); }"
01552 << "\n inline CkArrayID ckGetArrayIDn(int i) const"
01553 << "\n { return " << super << "::ckGetArrayIDn(i); } "
01554 << "\n inline CkArrayIndex *ckGetArrayElements() const"
01555 << "\n { return " << super << "::ckGetArrayElements(); }"
01556 << "\n inline CkArrayIndex *ckGetArrayElements(int i) const"
01557 << "\n { return " << super << "::ckGetArrayElements(i); }"
01558 << "\n inline int ckGetNumElements() const"
01559 << "\n { return " << super << "::ckGetNumElements(); } "
01560 << "\n inline int ckGetNumElements(int i) const"
01561 << "\n { return " << super << "::ckGetNumElements(i); }";
01562
01563 XStr etype; etype<<Prefix::ProxyElement<<type<<tvars();
01564 if (indexSuffix!=(const char*)"none")
01565 {
01566 str <<
01567 " // Generalized array indexing:\n"
01568 " "<<etype<<" operator [] (const "<<indexType<<" &idx) const\n"
01569 " {return "<<etype<<"(ckGetArrayID(), idx, CK_DELCTOR_CALL);}\n"
01570 " "<<etype<<" operator() (const "<<indexType<<" &idx) const\n"
01571 " {return "<<etype<<"(ckGetArrayID(), idx, CK_DELCTOR_CALL);}\n";
01572 }
01573
01574
01575 if (indexSuffix==(const char*)"1D")
01576 {
01577 str <<
01578 " "<<etype<<" operator [] (int idx) const \n"
01579 " {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex1D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
01580 " "<<etype<<" operator () (int idx) const \n"
01581 " {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex1D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
01582 " static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex1D *elems, int nElems) {\n"
01583 " return CkSectionID(aid, elems, nElems);\n"
01584 " } \n"
01585 " static CkSectionID ckNew(const CkArrayID &aid, int l, int u, int s) {\n"
01586 " CkVec<CkArrayIndex1D> al;\n"
01587 " for (int i=l; i<=u; i+=s) al.push_back(CkArrayIndex1D(i));\n"
01588 " return CkSectionID(aid, al.getVec(), al.size());\n"
01589 " } \n";
01590 } else if (indexSuffix==(const char*)"2D") {
01591 str <<
01592 " "<<etype<<" operator () (int idx) const \n"
01593 " {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex2D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
01594 " static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex2D *elems, int nElems) {\n"
01595 " return CkSectionID(aid, elems, nElems);\n"
01596 " } \n"
01597 " static CkSectionID ckNew(const CkArrayID &aid, int l1, int u1, int s1, int l2, int u2, int s2) {\n"
01598 " CkVec<CkArrayIndex2D> al;\n"
01599 " for (int i=l1; i<=u1; i+=s1) \n"
01600 " for (int j=l2; j<=u2; j+=s2) \n"
01601 " al.push_back(CkArrayIndex2D(i, j));\n"
01602 " return CkSectionID(aid, al.getVec(), al.size());\n"
01603 " } \n";
01604 } else if (indexSuffix==(const char*)"3D") {
01605 str <<
01606 " "<<etype<<" operator () (int idx) const \n"
01607 " {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex3D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
01608 " static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex3D *elems, int nElems) {\n"
01609 " return CkSectionID(aid, elems, nElems);\n"
01610 " } \n"
01611 " static CkSectionID ckNew(const CkArrayID &aid, int l1, int u1, int s1, int l2, int u2, int s2, int l3, int u3, int s3) {\n"
01612 " CkVec<CkArrayIndex3D> al;\n"
01613 " for (int i=l1; i<=u1; i+=s1) \n"
01614 " for (int j=l2; j<=u2; j+=s2) \n"
01615 " for (int k=l3; k<=u3; k+=s3) \n"
01616 " al.push_back(CkArrayIndex3D(i, j, k));\n"
01617 " return CkSectionID(aid, al.getVec(), al.size());\n"
01618 " } \n";
01619 } else if (indexSuffix==(const char*)"4D") {
01620 str <<
01621 " "<<etype<<" operator () (int idx) const \n"
01622 " {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex4D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
01623 " static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex4D *elems, int nElems) {\n"
01624 " return CkSectionID(aid, elems, nElems);\n"
01625 " } \n"
01626 " static CkSectionID ckNew(const CkArrayID &aid, int l1, int u1, int s1, int l2, int u2, int s2, int l3, int u3, int s3, int l4, int u4, int s4) {\n"
01627 " CkVec<CkArrayIndex4D> al;\n"
01628 " for (int i=l1; i<=u1; i+=s1) \n"
01629 " for (int j=l2; j<=u2; j+=s2) \n"
01630 " for (int k=l3; k<=u3; k+=s3) \n"
01631 " for (int l=l4; l<=u4; l+=s4) \n"
01632 " al.push_back(CkArrayIndex4D(i, j, k, l));\n"
01633 " return CkSectionID(aid, al.getVec(), al.size());\n"
01634 " } \n";
01635 } else if (indexSuffix==(const char*)"5D") {
01636 str <<
01637 " "<<etype<<" operator () (int idx) const \n"
01638 " {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex5D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
01639 " static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex5D *elems, int nElems) {\n"
01640 " return CkSectionID(aid, elems, nElems);\n"
01641 " } \n"
01642 " static CkSectionID ckNew(const CkArrayID &aid, int l1, int u1, int s1, int l2, int u2, int s2, int l3, int u3, int s3, int l4, int u4, int s4, int l5, int u5, int s5) {\n"
01643 " CkVec<CkArrayIndex5D> al;\n"
01644 " for (int i=l1; i<=u1; i+=s1) \n"
01645 " for (int j=l2; j<=u2; j+=s2) \n"
01646 " for (int k=l3; k<=u3; k+=s3) \n"
01647 " for (int l=l4; l<=u4; l+=s4) \n"
01648 " for (int m=l5; m<=u5; m+=s5) \n"
01649 " al.push_back(CkArrayIndex5D(i, j, k, l, m));\n"
01650 " return CkSectionID(aid, al.getVec(), al.size());\n"
01651 " } \n";
01652 } else if (indexSuffix==(const char*)"6D") {
01653 str <<
01654 " "<<etype<<" operator () (int idx) const \n"
01655 " {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex6D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
01656 " static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex6D *elems, int nElems) {\n"
01657 " return CkSectionID(aid, elems, nElems);\n"
01658 " } \n"
01659 " static CkSectionID ckNew(const CkArrayID &aid, int l1, int u1, int s1, int l2, int u2, int s2, int l3, int u3, int s3, int l4, int u4, int s4, int l5, int u5, int s5, int l6, int u6, int s6) {\n"
01660 " CkVec<CkArrayIndex6D> al;\n"
01661 " for (int i=l1; i<=u1; i+=s1) \n"
01662 " for (int j=l2; j<=u2; j+=s2) \n"
01663 " for (int k=l3; k<=u3; k+=s3) \n"
01664 " for (int l=l4; l<=u4; l+=s4) \n"
01665 " for (int m=l5; m<=u5; m+=s5) \n"
01666 " for (int n=l6; n<=u6; n+=s6) \n"
01667 " al.push_back(CkArrayIndex6D(i, j, k, l, m, n));\n"
01668 " return CkSectionID(aid, al.getVec(), al.size());\n"
01669 " } \n";
01670 }
01671
01672 str <<" "<<ptype<<"(const CkArrayID &aid, CkArrayIndex *elems, int nElems, CK_DELCTOR_PARAM) \n"
01673 " :";genProxyNames(str, "",NULL, "(aid,elems,nElems,CK_DELCTOR_ARGS)", ", ");str << " {}\n";
01674 str <<" "<<ptype<<"(const CkArrayID &aid, CkArrayIndex *elems, int nElems) \n"
01675 " :";genProxyNames(str, "",NULL, "(aid,elems,nElems)", ", ");str<<" {}\n";
01676 str <<" "<<ptype<<"(const CkSectionID &sid)"
01677 " :";genProxyNames(str, "",NULL, "(sid)", ", ");str<< " {}\n";
01678 str <<" "<<ptype<<"(int n, const CkArrayID *aid, CkArrayIndex const * const *elems, const int *nElems, CK_DELCTOR_PARAM) \n"
01679 " :";genProxyNames(str, "",NULL, "(n,aid,elems,nElems,CK_DELCTOR_ARGS)", ", ");str << " {}\n";
01680 str <<" "<<ptype<<"(int n, const CkArrayID *aid, CkArrayIndex const * const *elems, const int *nElems) \n"
01681 " :";genProxyNames(str, "",NULL, "(n,aid,elems,nElems)", ", ");str<<" {}\n";
01682 str <<
01683 " static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex *elems, int nElems) {\n"
01684 " return CkSectionID(aid, elems, nElems);\n"
01685 " } \n";
01686 }
01687
01688 if(list){
01689 list->genDecls(str);
01690 }
01691 str << CIClassEnd;
01692 if (!isTemplated()) str << "PUPmarshall("<<ptype<<")\n";
01693 }
01694
01695 void
01696 Chare::genTypedefs(XStr &str) {
01697 str << " typedef "<<baseName(1)<<" local_t;\n";
01698 str << " typedef "<<Prefix::Index<<baseName(1)<<" index_t;\n";
01699 str << " typedef "<<Prefix::Proxy<<baseName(1)<<" proxy_t;\n";
01700
01701 if (hasElement)
01702 str << " typedef "<<Prefix::ProxyElement<<baseName(1)<<" element_t;\n";
01703 else
01704 str << " typedef "<<Prefix::Proxy<<baseName(1)<<" element_t;\n";
01705
01706 if (hasSection)
01707 str << " typedef "<<Prefix::ProxySection<<baseName(1)<<" section_t;\n";
01708 str << "\n";
01709 }
01710
01711
01712
01713 void
01714 Chare::genDefs(XStr& str)
01715 {
01716 str << "/* DEFS: "; print(str); str << " */\n";
01717 if (fortranMode) {
01718 if (!isArray()) {
01719 cerr << (char *)baseName() << ": only chare arrays are currently supported\n";
01720 exit(1);
01721 }
01722
01723 str << "/* FORTRAN */\n";
01724 str << "extern \"C\" void " << fortranify(baseName(), "_allocate") << "(char **, void *, " << indexList() << ");\n";
01725 str << "extern \"C\" void " << fortranify(baseName(), "_pup") << "(pup_er p, char **, void *);\n";
01726 str << "extern \"C\" void " << fortranify(baseName(), "_resumefromsync") << "(char **, void *, " << indexList() << ");\n";
01727 str << "\n";
01728 XStr dim = ((Array*)this)->dim();
01729 str << "class " << baseName() << " : public ArrayElement" << dim << "\n";
01730 str << "{\n";
01731 str << "public:\n";
01732 str << " char user_data[64];\n";
01733 str << "public:\n";
01734 str << " " << baseName() << "()\n";
01735 str << " {\n";
01736
01737 str << " CkArrayID *aid = &thisArrayID;\n";
01738 if (dim==(const char*)"1D")
01739 str << " " << fortranify(baseName(), "_allocate") << "((char **)&user_data, &aid, &thisIndex);\n";
01740 else if (dim==(const char*)"2D")
01741 str << " " << fortranify(baseName(), "_allocate") << "((char **)&user_data, &aid, &thisIndex.x, &thisIndex.y);\n";
01742 else if (dim==(const char*)"3D")
01743 str << " " << fortranify(baseName(), "_allocate") << "((char **)&user_data, &aid, &thisIndex.x, &thisIndex.y, &thisIndex.z);\n";
01744 str << " usesAtSync = CmiTrue;\n";
01745 str << " }\n";
01746 str << "\n";
01747 str << " " << baseName() << "(CkMigrateMessage *m)\n";
01748 str << " {\n";
01749 str << " /* CkPrintf(\"" << baseName() << " %d migrating\\n\",thisIndex);*/ \n";
01750 str << " }\n";
01751 str << "\n";
01752
01753 str << " virtual void pup(PUP::er &p)\n";
01754 str << " {\n";
01755 str << " ArrayElement" << dim << "::pup(p);\n";
01756 str << " p(user_data, 64);\n";
01757 str << " CkArrayID *aid = &thisArrayID;\n";
01758 str << " ::" << fortranify(baseName(), "_pup") << "(&p, (char **)&user_data, &aid); \n";
01759 str << " }\n";
01760 str << "\n";
01761
01762
01763 str << " void ResumeFromSync()\n";
01764 str << " {\n";
01765 str << " CkArrayID *aid = &thisArrayID;\n";
01766 str << " ::" << fortranify(baseName(), "_resumefromSync");
01767 if (dim == (const char*)"1D") {
01768 str << "((char **)&user_data, &aid, &thisIndex);\n";
01769 }
01770 else if (dim == (const char*)"2D") {
01771 str << "((char **)&user_data, &aid, &thisIndex.x, &thisIndex.y);\n";
01772 }
01773 else if (dim == (const char*)"3D") {
01774 str << "((char **)&user_data, &aid, &thisIndex.x, &thisIndex.y, &thisIndex.z);\n";
01775 }
01776 str << " }\n";
01777
01778 str << "};\n";
01779 str << "\n";
01780 if (dim==(const char*)"1D") {
01781 str << "extern \"C\" void " << fortranify(baseName(), "_cknew") << "(int *numElem, long *aindex)\n";
01782 str << "{\n";
01783 str << " CkArrayID *aid = new CkArrayID;\n";
01784 str << " *aid = CProxy_" << baseName() << "::ckNew(*numElem); \n";
01785 }
01786 else if (dim==(const char*)"2D") {
01787 str << "extern \"C\" void " << fortranify(baseName(), "_cknew") << "(int *numx, int *numy, long *aindex)\n";
01788 str << "{\n";
01789 str << " CkArrayID *aid = new CkArrayID;\n";
01790 str << " *aid = CProxy_" << baseName() << "::ckNew(); \n";
01791 str << " CProxy_" << baseName() << " p(*aid);\n";
01792 str << " for (int i=0; i<*numx; i++) \n";
01793 str << " for (int j=0; j<*numy; j++) \n";
01794 str << " p[CkArrayIndex2D(i, j)].insert(); \n";
01795 str << " p.doneInserting(); \n";
01796 }
01797 else if (dim==(const char*)"3D") {
01798 str << "extern \"C\" void " << fortranify(baseName(), "_cknew") << "(int *numx, int *numy, int *numz, long *aindex)\n";
01799 str << "{\n";
01800 str << " CkArrayID *aid = new CkArrayID;\n";
01801 str << " *aid = CProxy_" << baseName() << "::ckNew(); \n";
01802 str << " CProxy_" << baseName() << " p(*aid);\n";
01803 str << " for (int i=0; i<*numx; i++) \n";
01804 str << " for (int j=0; j<*numy; j++) \n";
01805 str << " for (int k=0; k<*numz; k++) \n";
01806 str << " p[CkArrayIndex3D(i, j, k)].insert(); \n";
01807 str << " p.doneInserting(); \n";
01808 }
01809 str << " *aindex = (long)aid;\n";
01810 str << "}\n";
01811
01812
01813 if (dim == (const char*)"1D") {
01814 str << "extern \"C\" void "
01815 << fortranify(baseName(), "_atsync")
01816 << "(long* aindex, int *index1)\n";
01817 str << "{\n";
01818 str << " CkArrayID *aid = (CkArrayID *)*aindex;\n";
01819 str << "\n";
01820 str << " CProxy_" << baseName() << " h(*aid);\n";
01821 str << " h[*index1].ckLocal()->AtSync();\n";
01822 }
01823 else if (dim == (const char*)"2D") {
01824 str << "extern \"C\" void "
01825 << fortranify(baseName(), "_atsync")
01826 << "(long* aindex, int *index1, int *index2)\n";
01827 str << "{\n";
01828 str << " CkArrayID *aid = (CkArrayID *)*aindex;\n";
01829 str << "\n";
01830 str << " CProxy_" << baseName() << " h(*aid);\n";
01831 str << " h[CkArrayIndex2D(*index1, *index2)].ckLocal()->AtSync();\n";
01832 }
01833 else if (dim == (const char*)"3D") {
01834 str << "extern \"C\" void "
01835 << fortranify(baseName(), "_atsync")
01836 << "(long* aindex, int *index1, int *index2, int *index3)\n";
01837 str << "{\n";
01838 str << " CkArrayID *aid = (CkArrayID *)*aindex;\n";
01839 str << "\n";
01840 str << " CProxy_" << baseName() << " h(*aid);\n";
01841 str << " h[CkArrayIndex3D(*index1, *index2, *index3)].ckLocal()->AtSync();\n";
01842 }
01843 str << "}\n";
01844
01845 }
01846
01847 templateGuardBegin(isTemplated(), str);
01848 if(!type->isTemplated()) {
01849 if(external) str << "extern ";
01850 str << tspec()<<" int "<<indexName()<<"::__idx";
01851 if(!external) str << "=0";
01852 str << ";\n";
01853 }
01854 templateGuardEnd(str);
01855
01856 if(list)
01857 {
01858 list->genDefs(str);
01859 if (hasElement)
01860 {
01861 forElement=forAll;
01862 list->genDefs(str);
01863 if (hasSection) {
01864 forElement=forSection;
01865 list->genDefs(str);
01866 }
01867 forElement=forIndividual;
01868 }
01869 }
01870
01871 templateGuardBegin(isTemplated(), str);
01872
01873 if (isPython()) {
01874 str << "/* ---------------- python wrapper -------------- */\n";
01875
01876
01877 genPythonDefs(str);
01878 }
01879 templateGuardEnd(str);
01880
01881 if(!external && !type->isTemplated())
01882 genRegisterMethodDef(str);
01883 if (hasSdagEntry) {
01884 str << "\n";
01885 str << sdagDefs;
01886 }
01887 }
01888
01889 void
01890 Chare::genReg(XStr& str)
01891 {
01892 str << "/* REG: "; print(str); str << "*/\n";
01893 if(external || templat)
01894 return;
01895 str << " "<<indexName()<<"::__register(\""<<type<<"\", sizeof("<<type<<"));\n";
01896 }
01897
01898 static const char *CIMsgClassAnsi =
01899 "{\n"
01900 " public:\n"
01901 " static int __idx;\n"
01902 " void* operator new(size_t, void*p) { return p; }\n"
01903 " void* operator new(size_t);\n"
01904 " void* operator new(size_t, int*, const int);\n"
01905 " void* operator new(size_t, int*);\n"
01906 "#if CMK_MULTIPLE_DELETE\n"
01907 " void operator delete(void*p, void*){dealloc(p);}\n"
01908 " void operator delete(void*p){dealloc(p);}\n"
01909 " void operator delete(void*p, int*, const int){dealloc(p);}\n"
01910 " void operator delete(void*p, int*){dealloc(p);}\n"
01911 "#endif\n"
01912 " void operator delete(void*p, size_t){dealloc(p);}\n"
01913 " static void* alloc(int,size_t, int*, int);\n"
01914 " static void dealloc(void *p);\n"
01915 ;
01916
01917 void
01918 Message::genAllocDecl(XStr &str)
01919 {
01920 int i, num;
01921 XStr mtype;
01922 mtype << type;
01923 if(templat) templat->genVars(mtype);
01924 str << CIMsgClassAnsi;
01925 str << " CMessage_" << mtype << "();\n";
01926 str << " static void *pack(" << mtype << " *p);\n";
01927 str << " static " << mtype << "* unpack(void* p);\n";
01928 num = numArrays();
01929 if(num>0) {
01930 str << " void *operator new(size_t";
01931 for(i=0;i<num;i++)
01932 str << ", int";
01933 str << ");\n";
01934 }
01935 str << " void *operator new(size_t, ";
01936 for(i=0;i<num;i++)
01937 str << "int, ";
01938 str << "const int);\n";
01939 str << "#if CMK_MULTIPLE_DELETE\n";
01940 if(num>0) {
01941 str << " void operator delete(void *p";
01942 for(i=0;i<num;i++)
01943 str << ", int";
01944 str << "){dealloc(p);}\n";
01945 }
01946 str << " void operator delete(void *p, ";
01947 for(i=0;i<num;i++)
01948 str << "int, ";
01949 str << "const int){dealloc(p);}\n";
01950 str << "#endif\n";
01951 }
01952
01953 void
01954 Message::genDecls(XStr& str)
01955 {
01956 XStr ptype;
01957 ptype<<proxyPrefix()<<type;
01958 if(type->isTemplated())
01959 return;
01960 str << "/* DECLS: "; print(str); str << " */\n";
01961 if(templat)
01962 templat->genSpec(str);
01963 str << "class ";
01964 type->print(str);
01965 str << ";\n";
01966 if(templat)
01967 templat->genSpec(str);
01968 str << "class "<<ptype;
01969 if(external || type->isTemplated()) {
01970 str << ";\n";
01971 return;
01972 }
01973 str << ":public CkMessage";
01974
01975 genAllocDecl(str);
01976
01977 if(!(external||type->isTemplated())) {
01978
01979 str << " static void __register(const char *s, size_t size, CkPackFnPtr pack, CkUnpackFnPtr unpack) {\n";
01980 str << " __idx = CkRegisterMsg(s, pack, unpack, dealloc, size);\n";
01981 str << " }\n";
01982 }
01983 str << "};\n";
01984
01985 if (strncmp(type->getBaseName(), "MarshallMsg_", 12) == 0) {
01986 MsgVarList *ml;
01987 MsgVar *mv;
01988 int i;
01989 str << "class " << type << " : public " << ptype << " {\n";
01990 str << " public:\n";
01991 int num = numVars();
01992 for(i=0, ml=mvlist; i<num; i++, ml=ml->next) {
01993 mv = ml->msg_var;
01994 if (mv->isConditional() || mv->isArray()) {
01995 str << " /* "; mv->print(str); str << " */\n";
01996 str << " " << mv->type << " *" << mv->name << ";\n";
01997 }
01998 }
01999 str <<"};\n";
02000 }
02001 }
02002
02003 void
02004 Message::genDefs(XStr& str)
02005 {
02006 int i, count, num = numVars();
02007 int numArray = numArrays();
02008 MsgVarList *ml;
02009 MsgVar *mv;
02010 XStr ptype, mtype, tspec;
02011 ptype<<proxyPrefix()<<type;
02012 if(templat) templat->genVars(ptype);
02013 mtype << type;
02014 if(templat) templat->genVars(mtype);
02015 if(templat) { templat->genSpec(tspec); tspec << " "; }
02016
02017 str << "/* DEFS: "; print(str); str << " */\n";
02018
02019 templateGuardBegin(templat, str);
02020 if(!(external||type->isTemplated())) {
02021
02022
02023 str << tspec << "void *" << ptype << "::operator new(size_t s){\n";
02024 str << " return " << mtype << "::alloc(__idx, s, 0, 0);\n}\n";
02025
02026 str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz){\n";
02027 str << " return " << mtype << "::alloc(__idx, s, sz, 0);\n}\n";
02028
02029 str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz,";
02030 str << "const int pb){\n";
02031 str << " return " << mtype << "::alloc(__idx, s, sz, pb);\n}\n";
02032
02033 if(numArray>0) {
02034 str << tspec << "void *" << ptype << "::operator new(size_t s";
02035 for(i=0;i<numArray;i++)
02036 str << ", int sz" << i;
02037 str << ") {\n";
02038 str << " int sizes[" << numArray << "];\n";
02039 for(i=0;i<numArray;i++)
02040 str << " sizes[" << i << "] = sz" << i << ";\n";
02041 str << " return " << mtype << "::alloc(__idx, s, sizes, 0);\n";
02042 str << "}\n";
02043 }
02044
02045
02046 str << tspec << "void *"<< ptype << "::operator new(size_t s, ";
02047 for(i=0;i<numArray;i++)
02048 str << "int sz" << i << ", ";
02049 str << "const int p) {\n";
02050 if (numArray>0) str << " int sizes[" << numArray << "];\n";
02051 for(i=0, count=0, ml=mvlist ;i<num; i++, ml=ml->next)
02052 if (ml->msg_var->isArray()) {
02053 str << " sizes[" << count << "] = sz" << count << ";\n";
02054 count ++;
02055 }
02056 str << " return " << mtype << "::alloc(__idx, s, " << (numArray>0?"sizes":"0") << ", p);\n";
02057 str << "}\n";
02058
02059 str << tspec << "void* " << ptype;
02060 str << "::alloc(int msgnum, size_t sz, int *sizes, int pb) {\n";
02061 str << " CkpvAccess(_offsets)[0] = ALIGN8(sz);\n";
02062 for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) {
02063 mv = ml->msg_var;
02064 if (mv->isArray()) {
02065 str << " if(sizes==0)\n";
02066 str << " CkpvAccess(_offsets)[" << count+1 << "] = CkpvAccess(_offsets)[0];\n";
02067 str << " else\n";
02068 str << " CkpvAccess(_offsets)[" << count+1 << "] = CkpvAccess(_offsets)[" << count << "] + ";
02069 str << "ALIGN8(sizeof(" << mv->type << ")*sizes[" << count << "]);\n";
02070 count ++;
02071 }
02072 }
02073 str << " return CkAllocMsg(msgnum, CkpvAccess(_offsets)[" << numArray << "], pb);\n";
02074 str << "}\n";
02075
02076 str << tspec << ptype << "::" << proxyPrefix() << type << "() {\n";
02077 str << mtype << " *newmsg = (" << mtype << " *)this;\n";
02078 for(i=0, count=0, ml=mvlist; i<num; i++,ml=ml->next) {
02079 mv = ml->msg_var;
02080 if (mv->isArray()) {
02081 str << " newmsg->" << mv->name << " = (" << mv->type << " *) ";
02082 str << "((char *)newmsg + CkpvAccess(_offsets)[" << count << "]);\n";
02083 count ++;
02084 }
02085 }
02086 str << "}\n";
02087
02088 int numCond = numConditional();
02089 str << tspec << "void " << ptype << "::dealloc(void *p) {\n";
02090 if (numCond > 0) {
02091 str << " " << mtype << " *msg = (" << mtype << "*) p;\n";
02092 for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) {
02093 mv = ml->msg_var;
02094 if (mv->isConditional()) {
02095 if (mv->type->isPointer()) die("conditional variable cannot be a pointer", line);
02096 str << " CkConditional *cond_" << mv->name << " = static_cast<CkConditional*>(msg->" << mv->name << ");\n";
02097 str << " if (cond_" << mv->name << "!=NULL) cond_" << mv->name << "->deallocate();\n";
02098 }
02099 }
02100 }
02101 str << " CkFreeMsg(p);\n";
02102 str << "}\n";
02103
02104 str << tspec << "void* " << ptype << "::pack(" << mtype << " *msg) {\n";
02105 for(i=0, ml=mvlist; i<num; i++, ml=ml->next) {
02106 mv = ml->msg_var;
02107 if (mv->isArray()) {
02108 str << " msg->" << mv->name << " = (" <<mv->type << " *) ";
02109 str << "((char *)msg->" << mv->name << " - (char *)msg);\n";
02110 }
02111 }
02112 if (numCond > 0) {
02113 str << " int impl_off[" << numCond+1 << "];\n";
02114 str << " impl_off[0] = UsrToEnv(msg)->getUsersize();\n";
02115 for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) {
02116 mv = ml->msg_var;
02117 if (mv->isConditional()) {
02118 str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
02119 mv->type->print(str); str << " " << mv->name << " */\n";
02120 str << " PUP::sizer implP;\n";
02121 str << " implP|*msg->" << mv->name << ";\n";
02122 str << " impl_off[" << count+1 << "] = impl_off[" << count << "] + implP.size();\n";
02123 str << " } else {\n";
02124 str << " impl_off[" << count+1 << "] = impl_off[" << count << "];\n";
02125 str << " }\n";
02126 count ++;
02127 }
02128 }
02129 str << " " << mtype << " *newmsg = (" << mtype << "*) CkAllocMsg(__idx, impl_off["
02130 << numCond << "], UsrToEnv(msg)->getPriobits());\n";
02131 str << " envelope *newenv = UsrToEnv(newmsg);\n";
02132 str << " UInt newSize = newenv->getTotalsize();\n";
02133 str << " CmiMemcpy(newenv, UsrToEnv(msg), impl_off[0]+sizeof(envelope));\n";
02134 str << " newenv->setTotalsize(newSize);\n";
02135 str << " if (UsrToEnv(msg)->getPriobits() > 0) CmiMemcpy(newenv->getPrioPtr(), UsrToEnv(msg)->getPrioPtr(), newenv->getPrioBytes());\n";
02136 for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) {
02137 mv = ml->msg_var;
02138 if (mv->isConditional()) {
02139 str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
02140 mv->type->print(str); str << " " << mv->name << " */\n";
02141 str << " newmsg->" << mv->name << " = ("; mv->type->print(str);
02142 str << "*)(((char*)newmsg)+impl_off[" << count << "]);\n";
02143 str << " PUP::toMem implP((void *)newmsg->" << mv->name << ");\n";
02144 str << " implP|*msg->" << mv->name << ";\n";
02145 str << " newmsg->" << mv->name << " = (" << mv->type << "*) ((char *)newmsg->" << mv->name << " - (char *)newmsg);\n";
02146 str << " }\n";
02147 count++;
02148 }
02149 }
02150 str << " CkFreeMsg(msg);\n";
02151 str << " msg = newmsg;\n";
02152 }
02153 str << " return (void *) msg;\n}\n";
02154
02155 str << tspec << mtype << "* " << ptype << "::unpack(void* buf) {\n";
02156 str << " " << mtype << " *msg = (" << mtype << " *) buf;\n";
02157 for(i=0, ml=mvlist; i<num; i++, ml=ml->next) {
02158 mv = ml->msg_var;
02159 if (mv->isArray()) {
02160 str << " msg->" << mv->name << " = (" <<mv->type << " *) ";
02161 str << "((size_t)msg->" << mv->name << " + (char *)msg);\n";
02162 }
02163 }
02164 if (numCond > 0) {
02165 for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) {
02166 mv = ml->msg_var;
02167 if (mv->isConditional()) {
02168 str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
02169 mv->type->print(str); str << " " << mv->name << " */\n";
02170 str << " PUP::fromMem implP((char*)msg + (size_t)msg->" << mv->name << ");\n";
02171 str << " msg->" << mv->name << " = new " << mv->type << ";\n";
02172 str << " implP|*msg->" << mv->name << ";\n";
02173 str << " }\n";
02174 count ++;
02175 }
02176 }
02177 }
02178 str << " return msg;\n}\n";
02179 }
02180 if(!templat) {
02181 if(!external && !type->isTemplated()) {
02182 str << "int "<< ptype <<"::__idx=0;\n";
02183 }
02184 } else {
02185 str << tspec << "int "<< ptype <<"::__idx=0;\n";
02186 }
02187 templateGuardEnd(str);
02188 }
02189
02190 void
02191 Message::genReg(XStr& str)
02192 {
02193 str << "/* REG: "; print(str); str << "*/\n";
02194 if(!templat && !external) {
02195 XStr ptype, mtype, tspec;
02196 ptype<<proxyPrefix()<<type;
02197 str << ptype << "::__register(\"" << type << "\", sizeof(" << type <<"),";
02198 str << "(CkPackFnPtr) " << type << "::pack,";
02199 str << "(CkUnpackFnPtr) " << type << "::unpack);\n";
02200 }
02201 }
02202
02203 void
02204 Template::setExtern(int e)
02205 {
02206 Construct::setExtern(e);
02207 entity->setExtern(e);
02208 }
02209
02210 void
02211 Template::genVars(XStr& str)
02212 {
02213 str << " < ";
02214 if(tspec)
02215 tspec->genShort(str);
02216 str << " > ";
02217 }
02218
02219 XStr generateTemplateSpec(TVarList* tspec)
02220 {
02221 XStr str;
02222
02223 if(tspec) {
02224 str << "template < ";
02225 tspec->genLong(str);
02226 str << " > ";
02227 }
02228
02229 return str;
02230 }
02231
02232 void
02233 Template::genSpec(XStr& str)
02234 {
02235 str << generateTemplateSpec(tspec);
02236 }
02237
02238 void
02239 Template::genPub(XStr& declstr, XStr& defstr, XStr& defconstr, int& connectPresent)
02240 {
02241 if(!external && entity) {
02242 entity->genPub(declstr, defstr, defconstr, connectPresent);
02243 }
02244 }
02245
02246 void
02247 Template::genDecls(XStr& str)
02248 {
02249 if(!external && entity) {
02250 entity->genDecls(str);
02251 }
02252 }
02253
02254 void
02255 Template::genDefs(XStr& str)
02256 {
02257 if(!external && entity)
02258 entity->genDefs(str);
02259 }
02260
02261 int Template::genAccels_spe_c_funcBodies(XStr& str) {
02262 int rtn = 0;
02263 if (!external && entity) { rtn += entity->genAccels_spe_c_funcBodies(str); }
02264 return rtn;
02265 }
02266
02267 void Template::genAccels_spe_c_regFuncs(XStr& str) {
02268 if (!external && entity) { entity->genAccels_spe_c_regFuncs(str); }
02269 }
02270
02271 void Template::genAccels_spe_c_callInits(XStr& str) {
02272 if (!external && entity) { entity->genAccels_spe_c_callInits(str); }
02273 }
02274
02275 void Template::genAccels_spe_h_includes(XStr& str) {
02276 if (!external && entity) { entity->genAccels_spe_h_includes(str); }
02277 }
02278
02279 void Template::genAccels_spe_h_fiCountDefs(XStr& str) {
02280 if (!external && entity) { entity->genAccels_spe_h_fiCountDefs(str); }
02281 }
02282
02283 void Template::genAccels_ppe_c_regFuncs(XStr& str) {
02284 if (!external && entity) { entity->genAccels_ppe_c_regFuncs(str); }
02285 }
02286
02287 void
02288 TVarList::genLong(XStr& str)
02289 {
02290 if(tvar)
02291 tvar->genLong(str);
02292 if(next) {
02293 str << ", ";
02294 next->genLong(str);
02295 }
02296 }
02297
02298 void
02299 TVarList::genShort(XStr& str)
02300 {
02301 if(tvar)
02302 tvar->genShort(str);
02303 if(next) {
02304 str << ", ";
02305 next->genShort(str);
02306 }
02307 }
02308
02309 void TType::genLong(XStr& str)
02310 {
02311 str << "class ";
02312 if(type)
02313 type->print(str);
02314 if(init) {
02315 str << "=";
02316 init->print(str);
02317 }
02318 }
02319
02320 void TType::genShort(XStr& str)
02321 {
02322 if(type)
02323 type->print(str);
02324 }
02325
02326 void TName::genLong(XStr& str)
02327 {
02328 if(type)
02329 type->print(str);
02330 str << " "<<name;
02331 if(val) {
02332 str << "="<<val;
02333 }
02334 }
02335
02336 void TName::genShort(XStr& str)
02337 {
02338 str << name;
02339 }
02340
02341 void
02342 Module::genPub(XStr& declstr, XStr& defstr, XStr& defconstr, int& connectPresent)
02343 {
02344 if(!external) {
02345 if (clist) clist->genPub(declstr, defstr, defconstr, connectPresent);
02346 }
02347 }
02348
02349
02350 void
02351 Module::genDecls(XStr& str)
02352 {
02353 if(external) {
02354 str << "#include \""<<name<<".decl.h\"\n";
02355 } else {
02356 if (clist) clist->genDecls(str);
02357 }
02358
02359 #if CMK_CELL != 0
02360 str << "extern int register_accel_spe_funcs__module_" << name << "(int curIndex);\n";
02361 if (isMain()) {
02362 str << "extern \"C\" void register_accel_spe_funcs(void);\n";
02363 }
02364 #endif
02365 }
02366
02367 void
02368 Module::genDefs(XStr& str)
02369 {
02370 if(!external)
02371 if (clist)
02372 clist->genDefs(str);
02373
02374
02375 #if CMK_CELL != 0
02376
02377 if (!external) {
02378 templateGuardBegin(false, str);
02379
02380
02381
02382
02383
02384 str << "int register_accel_spe_funcs__module_" << name << "(int curIndex) {\n"
02385 << " static int hasAlreadyRegisteredFlag = 0;\n"
02386 << " if (hasAlreadyRegisteredFlag) { return curIndex; };\n"
02387 << " hasAlreadyRegisteredFlag = 1;\n";
02388 genAccels_ppe_c_regFuncs(str);
02389 str << " return curIndex;\n"
02390 << "}\n";
02391
02392
02393 if (isMain()) {
02394 str << "#include\"spert.h\"\n"
02395 << "extern \"C\" void register_accel_spe_funcs(void) {\n"
02396 << " register_accel_spe_funcs__module_" << name << "(SPE_FUNC_INDEX_USER);\n"
02397 << "}\n";
02398 }
02399
02400 templateGuardEnd(str);
02401 }
02402
02403 #endif
02404 }
02405
02406 void
02407 Module::genReg(XStr& str)
02408 {
02409 if(external) {
02410 str << " _register"<<name<<"();"<<endx;
02411 } else {
02412 if (clist) clist->genDefs(str);
02413 }
02414 }
02415
02416
02417 int Module::genAccels_spe_c_funcBodies(XStr& str) {
02418
02419
02420 if (external) {
02421 str << "#include \"" << name << ".genSPECode.c\"\n";
02422 return 0;
02423 }
02424
02425
02426 if (isMain()) {
02427 str << "typedef void(*AccelFuncPtr)(DMAListEntry*);\n\n"
02428 << "typedef struct __func_lookup_table_entry {\n"
02429 << " int funcIndex;\n"
02430 << " AccelFuncPtr funcPtr;\n"
02431 << "} FuncLookupTableEntry;\n\n"
02432 << "FuncLookupTableEntry funcLookupTable[MODULE_" << name << "_FUNC_INDEX_COUNT];\n\n\n";
02433 }
02434
02435
02436 int rtn = 0;
02437 if (clist) { rtn += clist->genAccels_spe_c_funcBodies(str); }
02438
02439
02440
02441
02442
02443 str << "int register_accel_funcs_" << name << "(int curIndex) {\n"
02444 << " static int hasAlreadyRegisteredFlag = 0;\n"
02445 << " if (hasAlreadyRegisteredFlag) { return curIndex; };\n"
02446 << " hasAlreadyRegisteredFlag = 1;\n";
02447 genAccels_spe_c_regFuncs(str);
02448 str << " return curIndex;\n"
02449 << "}\n\n\n";
02450
02451
02452 if (isMain()) {
02453
02454 str << "\n\n";
02455 str << "#ifdef __cplusplus\n"
02456 << "extern \"C\"\n"
02457 << "#endif\n"
02458 << "void funcLookup(int funcIndex,\n"
02459 << " void* readWritePtr, int readWriteLen,\n"
02460 << " void* readOnlyPtr, int readOnlyLen,\n"
02461 << " void* writeOnlyPtr, int writeOnlyLen,\n"
02462 << " DMAListEntry* dmaList\n"
02463 << " ) {\n\n";
02464
02465 str << " if ((funcIndex >= SPE_FUNC_INDEX_USER) && (funcIndex < (SPE_FUNC_INDEX_USER + MODULE_" << name << "_FUNC_INDEX_COUNT))) {\n"
02466
02467
02468
02469
02470 << " (funcLookupTable[funcIndex - SPE_FUNC_INDEX_USER].funcPtr)(dmaList);\n"
02471 << " } else if (funcIndex == SPE_FUNC_INDEX_INIT) {\n"
02472 << " if (register_accel_funcs_" << name << "(0) != MODULE_" << name << "_FUNC_INDEX_COUNT) {\n"
02473 << " printf(\"ERROR : register_accel_funcs_" << name << "() returned an invalid value.\\n\");\n"
02474 << " };\n";
02475 genAccels_spe_c_callInits(str);
02476 str << " } else if (funcIndex == SPE_FUNC_INDEX_CLOSE) {\n"
02477 << " // NOTE : Do nothing on close, but handle case...\n"
02478 << " } else {\n"
02479 << " printf(\"ERROR : Unknown funcIndex (%d) passed to funcLookup()... ignoring.\\n\", funcIndex);\n"
02480 << " }\n";
02481
02482 str << "}\n";
02483 }
02484
02485 return rtn;
02486 }
02487
02488 void Module::genAccels_spe_c_regFuncs(XStr& str) {
02489 if (external) {
02490 str << " curIndex = register_accel_funcs_" << name << "(curIndex);\n";
02491 } else {
02492 if (clist) { clist->genAccels_spe_c_regFuncs(str); }
02493 }
02494 }
02495
02496 void Module::genAccels_spe_c_callInits(XStr& str) {
02497 if (clist) { clist->genAccels_spe_c_callInits(str); }
02498 }
02499
02500 void Module::genAccels_spe_h_includes(XStr& str) {
02501 if (external) {
02502 str << "#include \"" << name << ".genSPECode.h\"\n";
02503 }
02504 if (clist) { clist->genAccels_spe_h_includes(str); }
02505 }
02506
02507 void Module::genAccels_spe_h_fiCountDefs(XStr& str) {
02508 if (external) {
02509 str << " + MODULE_" << name << "_FUNC_INDEX_COUNT";
02510 }
02511 if (clist) { clist->genAccels_spe_h_fiCountDefs(str); }
02512 }
02513
02514 void Module::genAccels_ppe_c_regFuncs(XStr& str) {
02515 if (external) {
02516 str << " curIndex = register_accel_spe_funcs__module_" << name << "(curIndex);\n";
02517 } else {
02518 if (clist) { clist->genAccels_ppe_c_regFuncs(str); }
02519 }
02520 }
02521
02522 void
02523 Readonly::genDecls(XStr& str)
02524 {
02525 str << "/* DECLS: "; print(str); str << " */\n";
02526 }
02527
02528 void
02529 Readonly::genIndexDecls(XStr& str)
02530 {
02531 str << "/* DECLS: "; print(str); str << " */\n";
02532 }
02533
02534
02535 XStr makeIdent(const XStr &in)
02536 {
02537 XStr ret;
02538 const char *i=in.get_string_const();
02539 while (*i!=0) {
02540
02541 if (*i==':') ret<<"_QColon_";
02542 else if (*i==' ') ret<<"_QSpace_";
02543 else if (*i=='+') ret<<"_QPlus_";
02544 else if (*i=='-') ret<<"_QMinus_";
02545 else if (*i=='*') ret<<"_QTimes_";
02546 else if (*i=='/') ret<<"_QSlash_";
02547 else if (*i=='%') ret<<"_QPercent_";
02548 else if (*i=='&') ret<<"_QAmpersand_";
02549 else if (*i=='.') ret<<"_QDot_";
02550 else if (*i==',') ret<<"_QComma_";
02551 else if (*i=='\'') ret<<"_QSQuote_";
02552 else if (*i=='\"') ret<<"_QQuote_";
02553 else if (*i=='(') ret<<"_QLparen_";
02554 else if (*i==')') ret<<"_QRparen_";
02555 else if (*i=='<') ret<<"_QLess_";
02556 else if (*i=='>') ret<<"_QGreater_";
02557 else if (*i=='{') ret<<"_QLbrace_";
02558 else if (*i=='}') ret<<"_QRbrace_";
02559 else ret << *i;
02560 i++;
02561 }
02562 return ret;
02563 }
02564
02565 void
02566 Readonly::genDefs(XStr& str)
02567 {
02568 str << "/* DEFS: "; print(str); str << " */\n";
02569 if(!container && !strchr(name, ':')) {
02570 str << "extern ";
02571 type->print(str);
02572 if(msg)
02573 str << "*";
02574 str << " "<<name;
02575 if(dims)
02576 dims->print(str);
02577 str << ";\n";
02578 }
02579
02580 if (!msg) {
02581 templateGuardBegin(false, str);
02582 str << "extern \"C\" void __xlater_roPup_"<<makeIdent(qName());
02583 str << "(void *_impl_pup_er) {\n";
02584 str << " PUP::er &_impl_p=*(PUP::er *)_impl_pup_er;\n";
02585 if(dims){
02586 str << " _impl_p("<<qName()<<","; dims->printValue(str); str<<");\n";
02587 }else{
02588 str << " _impl_p|"<<qName()<<";\n";
02589 }
02590 str << "}\n";
02591 templateGuardEnd(str);
02592 }
02593
02594 if (fortranMode) {
02595 str << "extern \"C\" void "
02596 << fortranify("set_", name)
02597 << "(int *n) { " << name << " = *n; }\n";
02598 str << "extern \"C\" void "
02599 << fortranify("get_", name)
02600 << "(int *n) { *n = " << name << "; }\n";
02601 }
02602 }
02603
02604 void
02605 Readonly::genReg(XStr& str)
02606 {
02607 if(external)
02608 return;
02609 if(msg) {
02610 if(dims) die("readonly Message cannot be an array",line);
02611 str << " CkRegisterReadonlyMsg(\""<<qName()<<"\",\""<<type<<"\",";
02612 str << "(void **)&"<<qName()<<");\n";
02613 } else {
02614 str << " CkRegisterReadonly(\""<<qName()<<"\",\""<<type<<"\",";
02615 str << "sizeof("<<qName()<<"),(void *) &"<<qName()<<",";
02616 str << "__xlater_roPup_"<<makeIdent(qName())<<");\n";
02617 }
02618 }
02619
02620 void TParamList::genSpec(XStr& str)
02621 {
02622 if(tparam)
02623 tparam->genSpec(str);
02624 if(next) {
02625 str << ", ";
02626 next->genSpec(str);
02627 }
02628 }
02629
02630 void MemberList::genIndexDecls(XStr& str)
02631 {
02632 perElemGen(members, str, &Member::genIndexDecls, newLine);
02633 }
02634
02635 void MemberList::genPub(XStr& declstr, XStr& defstr, XStr& defconstr, int& connectPresent)
02636 {
02637 for (list<Member*>::iterator i = members.begin(); i != members.end(); ++i)
02638 if (*i) {
02639 (*i)->genPub(declstr, defstr, defconstr, connectPresent);
02640 declstr << endx;
02641 }
02642 }
02643
02644 void MemberList::genDecls(XStr& str)
02645 {
02646 perElemGen(members, str, &Member::genDecls, newLine);
02647 }
02648
02649 void MemberList::collectSdagCode(CParsedFile *pf, int& sdagPresent)
02650 {
02651 for (list<Member*>::iterator i = members.begin(); i != members.end(); ++i)
02652 if (*i)
02653 (*i)->collectSdagCode(pf, sdagPresent);
02654 }
02655
02656 void MemberList::genDefs(XStr& str)
02657 {
02658 perElemGen(members, str, &Member::genDefs, newLine);
02659 }
02660
02661 void MemberList::genReg(XStr& str)
02662 {
02663 perElemGen(members, str, &Member::genReg, newLine);
02664 }
02665
02666 void MemberList::preprocess()
02667 {
02668 for (list<Member*>::iterator i = members.begin(); i != members.end(); ++i)
02669 if (*i)
02670 (*i)->preprocess();
02671 }
02672
02673 void MemberList::lookforCEntry(CEntry *centry)
02674 {
02675 perElemGen(members, centry, &Member::lookforCEntry);
02676 }
02677
02678 void MemberList::genPythonDecls(XStr& str) {
02679 perElemGen(members, str, &Member::genPythonDecls, newLine);
02680 }
02681
02682 void MemberList::genPythonDefs(XStr& str) {
02683 perElemGen(members, str, &Member::genPythonDefs, newLine);
02684 }
02685
02686 void MemberList::genPythonStaticDefs(XStr& str) {
02687 perElemGen(members, str, &Member::genPythonStaticDefs);
02688 }
02689
02690 void MemberList::genPythonStaticDocs(XStr& str) {
02691 perElemGen(members, str, &Member::genPythonStaticDocs);
02692 }
02693
02694 void Entry::lookforCEntry(CEntry *centry)
02695 {
02696
02697 if (strcmp(name, *centry->entry) != 0) return;
02698
02699 if (param && !centry->paramlist) return;
02700 if (!param && centry->paramlist) return;
02701 if (param && !(*param == *centry->paramlist)) return;
02702
02703 isWhenEntry = 1;
02704 centry->decl_entry = this;
02705 }
02706
02707 void Chare::lookforCEntry(CEntry *centry)
02708 {
02709 if(list)
02710 list->lookforCEntry(centry);
02711 if (centry->decl_entry == NULL) {
02712 cerr<<"Function \""<<centry->entry->get_string_const()
02713 <<"\" appears in Sdag When construct, but not defined as an entry function. "
02714 << endl;
02715 die("(FATAL ERROR)");
02716 }
02717 }
02718
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734 XStr *CParsedFile::className = NULL;
02735
02736 void CParsedFile::numberNodes(void)
02737 {
02738 for(Entry *cn=nodeList.begin(); !nodeList.end(); cn=nodeList.next()) {
02739 if (cn->sdagCon != 0) {
02740 cn->sdagCon->numberNodes();
02741 }
02742 }
02743 }
02744
02745 void CParsedFile::labelNodes(void)
02746 {
02747 for(Entry *cn=nodeList.begin(); !nodeList.end(); cn=nodeList.next()) {
02748 if (cn->sdagCon != 0) {
02749 cn->sdagCon->labelNodes();
02750 }
02751 }
02752 }
02753
02754 void CParsedFile::propagateState(void)
02755 {
02756 for(Entry *cn=nodeList.begin(); !nodeList.end(); cn=nodeList.next()) {
02757 cn->sdagCon->propagateState(0);
02758 }
02759 }
02760
02761 void CParsedFile::mapCEntry(void)
02762 {
02763 CEntry *en;
02764 for(en=entryList.begin(); !entryList.end(); en=entryList.next()) {
02765 container->lookforCEntry(en);
02766 }
02767 }
02768
02769 void CParsedFile::generateEntryList(void)
02770 {
02771 for(Entry *cn=nodeList.begin(); !nodeList.end(); cn=nodeList.next()) {
02772 cn->sdagCon->generateEntryList(entryList, 0);
02773 }
02774 }
02775
02776 void CParsedFile::generateConnectEntryList(void)
02777 {
02778 for(Entry *cn=nodeList.begin(); !nodeList.end(); cn=nodeList.next()) {
02779 cn->sdagCon->generateConnectEntryList(connectEntryList);
02780 }
02781 }
02782
02783 void CParsedFile::generateCode(XStr& decls, XStr& defs)
02784 {
02785 for(Entry *cn=nodeList.begin(); !nodeList.end(); cn=nodeList.next()) {
02786 cn->sdagCon->setNext(0,0);
02787 cn->sdagCon->generateCode(decls, defs, cn);
02788 }
02789 }
02790
02791 void CParsedFile::generateEntries(XStr& decls, XStr& defs)
02792 {
02793 CEntry *en;
02794 SdagConstruct *sc;
02795 decls << "public:\n";
02796 for(sc=connectEntryList.begin(); !connectEntryList.end(); sc=connectEntryList.next())
02797 sc->generateConnectEntries(decls);
02798 for(en=entryList.begin(); !entryList.end(); en=entryList.next()) {
02799 en->generateCode(decls, defs);
02800 }
02801 }
02802
02803 void CParsedFile::generateInitFunction(XStr& decls, XStr& defs)
02804 {
02805 decls << "private:\n";
02806 decls << " CDep *__cDep;\n";
02807
02808 XStr name = "__sdag_init";
02809 generateSignature(decls, defs, container, false, "void", &name, false, NULL);
02810 defs << " __cDep = new CDep(" << numEntries << "," << numWhens << ");\n";
02811 CEntry *en;
02812 for(en=entryList.begin(); !entryList.end(); en=entryList.next()) {
02813 en->generateDeps(defs);
02814 }
02815 endMethod(defs);
02816 }
02817
02818
02825 void CParsedFile::generateDependencyMergePoints(XStr& decls)
02826 {
02827 decls << " \n";
02828
02829
02830
02831 for(int i=0;i<numWhens;i++){
02832 decls << " MergeablePathHistory _when_" << i << "_PathMergePoint; /* For Critical Path Detection */ \n";
02833 }
02834
02835
02836
02837 for(int i=0;i<numOlists;i++){
02838 decls << " MergeablePathHistory olist__co" << i << "_PathMergePoint; /* For Critical Path Detection */ \n";
02839 }
02840 }
02841
02842 void CParsedFile::generatePupFunction(XStr& decls)
02843 {
02844 decls << "public:\n";
02845 decls << " void __sdag_pup(PUP::er& p) {\n";
02846 decls << " if (__cDep) { __cDep->pup(p); }\n";
02847 decls << " }\n";
02848 }
02849
02850 void CParsedFile::generateTrace()
02851 {
02852 for(Entry *cn=nodeList.begin(); !nodeList.end(); cn=nodeList.next()) {
02853 if (cn->sdagCon != 0) {
02854 cn->sdagCon->generateTrace();
02855 }
02856 }
02857 }
02858
02859 void CParsedFile::generateRegisterEp(XStr& decls, XStr& defs)
02860 {
02861 XStr name = "__sdag_register";
02862 generateSignature(decls, defs, container, true, "void", &name, false, NULL);
02863
02864 for(Entry *cn=nodeList.begin(); !nodeList.end(); cn=nodeList.next()) {
02865 if (cn->sdagCon != 0) {
02866 cn->sdagCon->generateRegisterEp(defs);
02867 }
02868 }
02869 endMethod(defs);
02870 }
02871
02872 void CParsedFile::generateTraceEp(XStr& decls, XStr& defs)
02873 {
02874 for(Entry *cn=nodeList.begin(); !nodeList.end(); cn=nodeList.next()) {
02875 if (cn->sdagCon != 0) {
02876 cn->sdagCon->generateTraceEp(decls, defs, container);
02877 }
02878 }
02879 }
02880
02882 SdagConstruct::SdagConstruct(EToken t, SdagConstruct *construct1)
02883 {
02884 con1 = 0; con2 = 0; con3 = 0; con4 = 0;
02885 type = t;
02886 traceName=NULL;
02887 publishesList = new TList<SdagConstruct*>();
02888 constructs = new TList<SdagConstruct*>();
02889 constructs->append(construct1);
02890 }
02891
02892 SdagConstruct::SdagConstruct(EToken t, SdagConstruct *construct1, SdagConstruct *aList)
02893 {
02894 con1=0; con2=0; con3=0; con4=0;
02895 type = t;
02896 traceName=NULL;
02897 publishesList = new TList<SdagConstruct*>();
02898 constructs = new TList<SdagConstruct*>();
02899 constructs->append(construct1);
02900 SdagConstruct *sc;
02901 for(sc = aList->constructs->begin(); !aList->constructs->end(); sc=aList->constructs->next())
02902 constructs->append(sc);
02903 }
02904
02905 SdagConstruct::SdagConstruct(EToken t, XStr *txt, SdagConstruct *c1, SdagConstruct *c2, SdagConstruct *c3,
02906 SdagConstruct *c4, SdagConstruct *constructAppend, EntryList *el)
02907 {
02908 text = txt;
02909 type = t;
02910 traceName=NULL;
02911 con1 = c1; con2 = c2; con3 = c3; con4 = c4;
02912 publishesList = new TList<SdagConstruct*>();
02913 constructs = new TList<SdagConstruct*>();
02914 if (constructAppend != 0) {
02915 constructs->append(constructAppend);
02916 }
02917 elist = el;
02918 }
02919
02920 SdagConstruct::SdagConstruct(EToken t, const char *entryStr, const char *codeStr, ParamList *pl)
02921 {
02922 type = t;
02923 traceName=NULL;
02924 text = new XStr(codeStr);
02925 connectEntry = new XStr(entryStr);
02926 con1 = 0; con2 = 0; con3 = 0; con4 =0;
02927 publishesList = new TList<SdagConstruct*>();
02928 constructs = new TList<SdagConstruct*>();
02929 param = pl;
02930
02931 }
02932
02934
02935 void ParamList::checkParamList(){
02936 if(manyPointers){
02937 die("You may pass only a single pointer to a non-local entry method. It should point to a message.", param->line);
02938 abort();
02939 }
02940 }
02941
02942 Entry::Entry(int l, int a, Type *r, const char *n, ParamList *p, Value *sz, SdagConstruct *sc, const char *e, int connect, ParamList *connectPList) :
02943 attribs(a), retType(r), stacksize(sz), sdagCon(sc), name((char *)n), targs(0), intExpr(e), param(p), connectParam(connectPList), isConnect(connect)
02944 {
02945 line=l; container=NULL;
02946 entryCount=-1;
02947 isWhenEntry=0;
02948 if (param && param->isMarshalled() && !isThreaded()) attribs|=SNOKEEP;
02949
02950 if(!isThreaded() && stacksize) die("Non-Threaded methods cannot have stacksize",line);
02951 if(retType && !isSync() && !isIget() && !isLocal() && !retType->isVoid())
02952 die("A remote method normally returns void. To return non-void, you need to declare the method as [sync], which means it has blocking semantics.",line);
02953 if (isPython()) pythonDoc = python_doc;
02954 if(!isLocal() && p){
02955 p->checkParamList();
02956 }
02957
02958 }
02959 void Entry::setChare(Chare *c) {
02960 Member::setChare(c);
02961
02962
02963
02964
02965
02966
02967
02968
02969 if (isConstructor() && container->isMainChare() && param->isVoid()) {
02970
02971 Type *t = new PtrType(new NamedType("CkArgMsg"));
02972 param=new ParamList(new Parameter(line,t));
02973 std::cerr << "Charmxi> " << line << ": Deprecation warning: mainchare constructors should explicitly take CkArgMsg* if that's how they're implemented.\n";
02974 }
02975
02976 entryCount=c->nextEntry();
02977
02978
02979 hasCallMarshall=param->isMarshalled() && !isThreaded() && !isSync() && !isExclusive() && !fortranMode;
02980 if (isSdag()) container->setSdag(1);
02981 }
02982
02983
02984
02985 XStr Entry::paramType(int withDefaultVals,int withEO,int useConst)
02986 {
02987 XStr str;
02988 param->print(str,withDefaultVals,useConst);
02989 if (withEO) str<<eo(withDefaultVals,!param->isVoid());
02990 return str;
02991 }
02992
02993
02994
02995 XStr Entry::paramComma(int withDefaultVals,int withEO)
02996 {
02997 XStr str;
02998 if (!param->isVoid()) {
02999 str << paramType(withDefaultVals,withEO);
03000 str << ", ";
03001 }
03002 return str;
03003 }
03004 XStr Entry::eo(int withDefaultVals,int priorComma) {
03005 XStr str;
03006 if (param->isMarshalled()) {
03007 if (priorComma) str<<", ";
03008 str<<"const CkEntryOptions *impl_e_opts";
03009 if (withDefaultVals) str<<"=NULL";
03010 }
03011 return str;
03012 }
03013
03014 void Entry::collectSdagCode(CParsedFile *pf, int& sdagPresent)
03015 {
03016 if (isSdag()) {
03017 sdagPresent = 1;
03018 pf->nodeList.append(this);
03019 }
03020 }
03021
03022 XStr Entry::marshallMsg(void)
03023 {
03024 XStr ret;
03025 XStr epName = epStr();
03026 param->marshall(ret, epName);
03027 return ret;
03028 }
03029
03030 XStr Entry::epStr(bool isForRedn, bool templateCall)
03031 {
03032 XStr str;
03033 if (isForRedn)
03034 str<<"redn_wrapper_";
03035 str << name << "_";
03036
03037 if (param->isMessage()) {
03038 str<<param->getBaseName();
03039 str.replace(':', '_');
03040 }
03041 else if (param->isVoid())
03042 str<<"void";
03043 else
03044 str<<"marshall"<<entryCount;
03045
03046 if (tspec && templateCall) {
03047 str << "< ";
03048 tspec->genShort(str);
03049 str << " >";
03050 }
03051
03052 return str;
03053 }
03054
03055 XStr Entry::epIdx(int fromProxy, bool isForRedn)
03056 {
03057 XStr str;
03058 if (fromProxy) {
03059 str << indexName()<<"::";
03060
03061 if (tspec)
03062 str << "template ";
03063 }
03064 str << "idx_" << epStr(isForRedn, true) << "()";
03065 return str;
03066 }
03067
03068 XStr Entry::epRegFn(int fromProxy, bool isForRedn)
03069 {
03070 XStr str;
03071 if (fromProxy)
03072 str << indexName() << "::";
03073 str << "reg_" << epStr(isForRedn, true) << "()";
03074 return str;
03075 }
03076
03077 XStr Entry::chareIdx(int fromProxy)
03078 {
03079 XStr str;
03080 if (fromProxy)
03081 str << indexName()<<"::";
03082 str << "__idx";
03083 return str;
03084 }
03085
03086
03087
03088
03089
03090 XStr Member::makeDecl(const XStr &returnType, int forProxy, bool isStatic)
03091 {
03092 XStr str;
03093
03094 if (container->isTemplated())
03095 str << container->tspec() << "\n";
03096 str << generateTemplateSpec(tspec) << "\n";
03097 if (isStatic)
03098 str << "static ";
03099 str << returnType<<" ";
03100 if (forProxy)
03101 str<<container->proxyName();
03102 else
03103 str<<container->indexName();
03104 return str;
03105 }
03106
03107 XStr Entry::syncReturn(void) {
03108 XStr str;
03109 if(retType->isVoid())
03110 str << " CkFreeSysMsg(";
03111 else
03112 str << " return ("<<retType<<") (";
03113 return str;
03114 }
03115
03116
03117
03118 void Entry::genChareDecl(XStr& str)
03119 {
03120 if(isConstructor()) {
03121 genChareStaticConstructorDecl(str);
03122 } else {
03123
03124 str << " " << generateTemplateSpec(tspec) << "\n"
03125 << " " << retType << " " << name << "(" << paramType(1,1) << ");\n";
03126 }
03127 }
03128
03129 void Entry::genChareDefs(XStr& str)
03130 {
03131 if (isImmediate()) {
03132 cerr << (char *)container->baseName() << ": Chare does not allow immediate message.\n";
03133 exit(1);
03134 }
03135 if (isLocal()) {
03136 cerr << (char*)container->baseName() << ": Chare does not allow LOCAL entry methods.\n";
03137 exit(1);
03138 }
03139
03140 if(isConstructor()) {
03141 genChareStaticConstructorDefs(str);
03142 } else {
03143 XStr params; params<<epIdx()<<", impl_msg, &ckGetChareID()";
03144
03145 XStr retStr; retStr<<retType;
03146 str << makeDecl(retStr,1)<<"::"<<name<<"("<<paramType(0,1)<<")\n";
03147 str << "{\n ckCheck();\n"<<marshallMsg();
03148 if(isSync()) {
03149 str << syncReturn() << "CkRemoteCall("<<params<<"));\n";
03150 } else {
03151 str << " if (ckIsDelegated()) {\n";
03152 str << " int destPE=CkChareMsgPrep("<<params<<");\n";
03153 str << " if (destPE!=-1) ckDelegatedTo()->ChareSend(ckDelegatedPtr(),"<<params<<",destPE);\n";
03154 str << " }\n";
03155 XStr opts;
03156 opts << ",0";
03157 if (isSkipscheduler()) opts << "+CK_MSG_EXPEDITED";
03158 if (isInline()) opts << "+CK_MSG_INLINE";
03159 str << " else CkSendMsg("<<params<<opts<<");\n";
03160 }
03161 str << "}\n";
03162 }
03163 }
03164
03165 void Entry::genChareStaticConstructorDecl(XStr& str)
03166 {
03167 str << " static CkChareID ckNew("<<paramComma(1)<<"int onPE=CK_PE_ANY"<<eo(1)<<");\n";
03168 str << " static void ckNew("<<paramComma(1)<<"CkChareID* pcid, int onPE=CK_PE_ANY"<<eo(1)<<");\n";
03169 if (!param->isVoid())
03170 str << " "<<container->proxyName(0)<<"("<<paramComma(1)<<"int onPE=CK_PE_ANY"<<eo(1)<<");\n";
03171 }
03172
03173 void Entry::genChareStaticConstructorDefs(XStr& str)
03174 {
03175 str << makeDecl("CkChareID",1)<<"::ckNew("<<paramComma(0)<<"int impl_onPE"<<eo(0)<<")\n";
03176 str << "{\n"<<marshallMsg();
03177 str << " CkChareID impl_ret;\n";
03178 str << " CkCreateChare("<<chareIdx()<<", "<<epIdx()<<", impl_msg, &impl_ret, impl_onPE);\n";
03179 str << " return impl_ret;\n";
03180 str << "}\n";
03181
03182 str << makeDecl("void",1)<<"::ckNew("<<paramComma(0)<<"CkChareID* pcid, int impl_onPE"<<eo(0)<<")\n";
03183 str << "{\n"<<marshallMsg();
03184 str << " CkCreateChare("<<chareIdx()<<", "<<epIdx()<<", impl_msg, pcid, impl_onPE);\n";
03185 str << "}\n";
03186
03187 if (!param->isVoid()) {
03188 str << makeDecl(" ",1)<<"::"<<container->proxyName(0)<<"("<<paramComma(0)<<"int impl_onPE"<<eo(0)<<")\n";
03189 str << "{\n"<<marshallMsg();
03190 str << " CkChareID impl_ret;\n";
03191 str << " CkCreateChare("<<chareIdx()<<", "<<epIdx()<<", impl_msg, &impl_ret, impl_onPE);\n";
03192 str << " ckSetChareID(impl_ret);\n";
03193 str << "}\n";
03194 }
03195 }
03196
03197
03198
03199 void Entry::genArrayDecl(XStr& str)
03200 {
03201 if(isConstructor()) {
03202 str << " " << generateTemplateSpec(tspec) << "\n";
03203 genArrayStaticConstructorDecl(str);
03204 } else {
03205 if ((isSync() || isLocal()) && !container->isForElement()) return;
03206 str << " " << generateTemplateSpec(tspec) << "\n";
03207 if(isIget())
03208 str << " "<<"CkFutureID"<<" "<<name<<"("<<paramType(1,1)<<") ;\n";
03209 else if(isLocal())
03210 str << " "<<retType<<" "<<name<<"("<<paramType(1,1,0)<<") ;\n";
03211 else
03212 str << " "<<retType<<" "<<name<<"("<<paramType(1,1)<<") ;\n";
03213 }
03214 }
03215
03216 void Entry::genArrayDefs(XStr& str)
03217 {
03218 if(isIget() && !container->isForElement()) return;
03219 if (isImmediate()) {
03220 cerr << (char *)container->baseName() << ": Chare Array does not allow immediate message.\n";
03221 exit(1);
03222 }
03223
03224 if (isConstructor())
03225 genArrayStaticConstructorDefs(str);
03226 else
03227 {
03228 const char *ifNot="CkArray_IfNotThere_buffer";
03229 if (isCreateHere()) ifNot="CkArray_IfNotThere_createhere";
03230 if (isCreateHome()) ifNot="CkArray_IfNotThere_createhome";
03231
03232 if ((isSync() || isLocal()) && !container->isForElement()) return;
03233
03234 XStr retStr; retStr<<retType;
03235 if(isIget())
03236 str << makeDecl("CkFutureID ",1)<<"::"<<name<<"("<<paramType(0,1)<<") \n";
03237 else if(isLocal())
03238 str << makeDecl(retStr,1)<<"::"<<name<<"("<<paramType(0,1,0)<<") \n";
03239 else
03240 str << makeDecl(retStr,1)<<"::"<<name<<"("<<paramType(0,1)<<") \n";
03241 str << "{\n ckCheck();\n";
03242 if (!isLocal()) {
03243 str << marshallMsg();
03244 str << " CkArrayMessage *impl_amsg=(CkArrayMessage *)impl_msg;\n";
03245 str << " impl_amsg->array_setIfNotThere("<<ifNot<<");\n";
03246 } else {
03247 XStr unmarshallStr; param->unmarshall(unmarshallStr);
03248 str << " LDObjHandle objHandle;\n int objstopped=0;\n";
03249 str << " "<<container->baseName()<<" *obj = ckLocal();\n";
03250 str << "#if CMK_ERROR_CHECKING\n";
03251 str << " if (obj==NULL) CkAbort(\"Trying to call a LOCAL entry method on a non-local element\");\n";
03252 str << "#endif\n";
03253 if (!isNoTrace())
03254 str << " _TRACE_BEGIN_EXECUTE_DETAILED(0,ForArrayEltMsg,(" << epIdx()
03255 << "),CkMyPe(), 0, ((CkArrayIndex&)ckGetIndex()).getProjectionID(((CkGroupID)ckGetArrayID()).idx));\n";
03256 str << "#if CMK_LBDB_ON\n objHandle = obj->timingBeforeCall(&objstopped);\n#endif\n";
03257 str << "#if CMK_CHARMDEBUG\n"
03258 " CpdBeforeEp("<<epIdx()<<", obj, NULL);\n"
03259 "#endif\n ";
03260 if (!retType->isVoid()) str << retType<< " retValue = ";
03261 str << "obj->"<<name<<"("<<unmarshallStr<<");\n";
03262 str << "#if CMK_CHARMDEBUG\n"
03263 " CpdAfterEp("<<epIdx()<<");\n"
03264 "#endif\n";
03265 str << "#if CMK_LBDB_ON\n obj->timingAfterCall(objHandle,&objstopped);\n#endif\n";
03266 if (!isNoTrace()) str << " _TRACE_END_EXECUTE();\n";
03267 if (!retType->isVoid()) str << " return retValue;\n";
03268 }
03269 if(isIget()) {
03270 str << " CkFutureID f=CkCreateAttachedFutureSend(impl_amsg,"<<epIdx()<<",ckGetArrayID(),ckGetIndex(),&CProxyElement_ArrayBase::ckSendWrapper);"<<"\n";
03271 }
03272
03273 if(isSync()) {
03274 str << syncReturn() << "ckSendSync(impl_amsg, "<<epIdx()<<"));\n";
03275 }
03276 else if (!isLocal())
03277 {
03278 XStr opts;
03279 opts << ",0";
03280 if (isSkipscheduler()) opts << "+CK_MSG_EXPEDITED";
03281 if (isInline()) opts << "+CK_MSG_INLINE";
03282 if(!isIget()) {
03283 if (container->isForElement() || container->isForSection()) {
03284 str << " ckSend(impl_amsg, "<<epIdx()<<opts<<");\n";
03285 }
03286 else
03287 str << " ckBroadcast(impl_amsg, "<<epIdx()<<opts<<");\n";
03288 }
03289 }
03290 if(isIget()) {
03291 str << " return f;\n";
03292 }
03293 str << "}\n";
03294 }
03295 }
03296
03297 void Entry::genArrayStaticConstructorDecl(XStr& str)
03298 {
03299 if (container->getForWhom()==forIndividual)
03300 str<<
03301 " void insert("<<paramComma(1,0)<<"int onPE=-1"<<eo(1)<<");";
03302 else if (container->getForWhom()==forAll) {
03303 str<<
03304 " static CkArrayID ckNew("<<paramComma(1,0)<<"const CkArrayOptions &opts"<<eo(1)<<");\n";
03305 if (container->isArray()) {
03306 XStr dim = ((Array*)container)->dim();
03307 if (dim==(const char*)"1D") {
03308 str<<" static CkArrayID ckNew("<<paramComma(1,0)<<"const int s1"<<eo(1)<<");\n";
03309 } else if (dim==(const char*)"2D") {
03310 str<<" static CkArrayID ckNew("<<paramComma(1,0)<<"const int s1, const int s2"<<eo(1)<<");\n";
03311 } else if (dim==(const char*)"3D") {
03312 str<<" static CkArrayID ckNew("<<paramComma(1,0)<<"const int s1, const int s2, const int s3"<<eo(1)<<");\n";
03313
03314
03315
03316
03317
03318
03319 }
03320 }
03321 }
03322 else if (container->getForWhom()==forSection) { }
03323 }
03324
03325 void Entry::genArrayStaticConstructorDefs(XStr& str)
03326 {
03327 if (container->getForWhom()==forIndividual)
03328 str<<
03329 makeDecl("void",1)<<"::insert("<<paramComma(0,0)<<"int onPE"<<eo(0)<<")\n"
03330 "{ \n"<<marshallMsg()<<
03331 " ckInsert((CkArrayMessage *)impl_msg,"<<epIdx()<<",onPE);\n}\n";
03332 else if (container->getForWhom()==forAll){
03333 str<<
03334 makeDecl("CkArrayID",1)<<"::ckNew("<<paramComma(0)<<"const CkArrayOptions &opts"<<eo(0)<<")\n"
03335 "{ \n"<<marshallMsg()<<
03336 " return ckCreateArray((CkArrayMessage *)impl_msg,"<<epIdx()<<",opts);\n"
03337 "}\n";
03338 if (container->isArray()) {
03339 XStr dim = ((Array*)container)->dim();
03340 if (dim==(const char*)"1D") {
03341 str<<
03342 makeDecl("CkArrayID",1)<<"::ckNew("<<paramComma(0)<<"const int s1"<<eo(0)<<")\n"
03343 "{ \n"<<marshallMsg()<<
03344 " return ckCreateArray((CkArrayMessage *)impl_msg,"<<epIdx()<<",CkArrayOptions(s1));\n"
03345 "}\n";
03346 } else if (dim==(const char*)"2D") {
03347 str<<
03348 makeDecl("CkArrayID",1)<<"::ckNew("<<paramComma(0)<<"const int s1, const int s2"<<eo(0)<<")\n"
03349 "{ \n"<<marshallMsg()<<
03350 " return ckCreateArray((CkArrayMessage *)impl_msg,"<<epIdx()<<",CkArrayOptions(s1, s2));\n"
03351 "}\n";
03352 } else if (dim==(const char*)"3D") {
03353 str<<
03354 makeDecl("CkArrayID",1)<<"::ckNew("<<paramComma(0)<<"const int s1, const int s2, const int s3"<<eo(0)<<")\n"
03355 "{ \n"<<marshallMsg()<<
03356 " return ckCreateArray((CkArrayMessage *)impl_msg,"<<epIdx()<<",CkArrayOptions(s1, s2, s3));\n"
03357 "}\n";
03358
03359
03360
03361
03362
03363
03364
03365 }
03366 }
03367 }
03368
03369 }
03370
03371
03372
03373
03374 void Entry::genGroupDecl(XStr& str)
03375 {
03376 #if 0
03377 if (isImmediate() && !container->isNodeGroup()) {
03378 cerr << (char *)container->baseName() << ": Group does not allow immediate message.\n";
03379 exit(1);
03380 }
03381 #endif
03382 if (isLocal() && container->isNodeGroup()) {
03383 cerr << (char*)container->baseName() << ": Nodegroup does not allow LOCAL entry methods.\n";
03384 exit(1);
03385 }
03386
03387 if(isConstructor()) {
03388 str << " " << generateTemplateSpec(tspec) << "\n";
03389 genGroupStaticConstructorDecl(str);
03390 } else {
03391 if ((isSync() || isLocal()) && !container->isForElement()) return;
03392 str << " " << generateTemplateSpec(tspec) << "\n";
03393 if (isLocal())
03394 str << " "<<retType<<" "<<name<<"("<<paramType(1,1,0)<<");\n";
03395 else
03396 str << " "<<retType<<" "<<name<<"("<<paramType(1,1)<<");\n";
03397
03398 if(!container->isForElement() && !container->isForSection() && !isSync() && !isLocal() && !container->isNodeGroup()) {
03399 str << " " << generateTemplateSpec(tspec) << "\n";
03400 str << " "<<retType<<" "<<name<<"("<<paramComma(1,0)<<"int npes, int *pes"<<eo(1)<<");\n";
03401 str << " " << generateTemplateSpec(tspec) << "\n";
03402 str << " "<<retType<<" "<<name<<"("<<paramComma(1,0)<<"CmiGroup &grp"<<eo(1)<<");\n";
03403 }
03404 }
03405 }
03406
03407 void Entry::genGroupDefs(XStr& str)
03408 {
03409
03410 char *node = (char *)(container->isNodeGroup()?"Node":"");
03411
03412 if(isConstructor()) {
03413 genGroupStaticConstructorDefs(str);
03414 } else {
03415 int forElement=container->isForElement();
03416 XStr params; params<<epIdx()<<", impl_msg";
03417 XStr paramg; paramg<<epIdx()<<", impl_msg, ckGetGroupID()";
03418 XStr parampg; parampg<<epIdx()<<", impl_msg, ckGetGroupPe(), ckGetGroupID()";
03419
03420 XStr opts; opts<<",0";
03421 if (isImmediate()) opts << "+CK_MSG_IMMEDIATE";
03422 if (isInline()) opts << "+CK_MSG_INLINE";
03423 if (isSkipscheduler()) opts << "+CK_MSG_EXPEDITED";
03424
03425 if ((isSync() || isLocal()) && !container->isForElement()) return;
03426
03427 XStr retStr; retStr<<retType;
03428 XStr msgTypeStr;
03429 if (isLocal())
03430 msgTypeStr<<paramType(0,1,0);
03431 else
03432 msgTypeStr<<paramType(0,1);
03433 str << makeDecl(retStr,1)<<"::"<<name<<"("<<msgTypeStr<<")\n";
03434 str << "{\n ckCheck();\n";
03435 if (!isLocal()) str <<marshallMsg();
03436
03437 if (isLocal()) {
03438 XStr unmarshallStr; param->unmarshall(unmarshallStr);
03439 str << " "<<container->baseName()<<" *obj = ckLocalBranch();\n";
03440 str << " CkAssert(obj);\n";
03441 if (!isNoTrace()) str << " _TRACE_BEGIN_EXECUTE_DETAILED(0,ForBocMsg,("<<epIdx()<<"),CkMyPe(),0,NULL);\n";
03442 str << "#if CMK_LBDB_ON\n"
03443 " // if there is a running obj being measured, stop it temporarily\n"
03444 " LDObjHandle objHandle;\n"
03445 " int objstopped = 0;\n"
03446 " LBDatabase *the_lbdb = (LBDatabase *)CkLocalBranch(_lbdb);\n"
03447 " if (the_lbdb->RunningObject(&objHandle)) {\n"
03448 " objstopped = 1;\n"
03449 " the_lbdb->ObjectStop(objHandle);\n"
03450 " }\n"
03451 "#endif\n";
03452 str << "#if CMK_CHARMDEBUG\n"
03453 " CpdBeforeEp("<<epIdx()<<", obj, NULL);\n"
03454 "#endif\n ";
03455 if (!retType->isVoid()) str << retType << " retValue = ";
03456 str << "obj->"<<name<<"("<<unmarshallStr<<");\n";
03457 str << "#if CMK_CHARMDEBUG\n"
03458 " CpdAfterEp("<<epIdx()<<");\n"
03459 "#endif\n";
03460 str << "#if CMK_LBDB_ON\n"
03461 " if (objstopped) the_lbdb->ObjectStart(objHandle);\n"
03462 "#endif\n";
03463 if (!isNoTrace()) str << " _TRACE_END_EXECUTE();\n";
03464 if (!retType->isVoid()) str << " return retValue;\n";
03465 } else if(isSync()) {
03466 str << syncReturn() <<
03467 "CkRemote"<<node<<"BranchCall("<<paramg<<", ckGetGroupPe()));\n";
03468 }
03469 else
03470 {
03471 if (forElement)
03472 {
03473 str << " if (ckIsDelegated()) {\n";
03474 str << " Ck"<<node<<"GroupMsgPrep("<<paramg<<");\n";
03475 str << " ckDelegatedTo()->"<<node<<"GroupSend(ckDelegatedPtr(),"<<parampg<<");\n";
03476 str << " } else CkSendMsg"<<node<<"Branch"<<"("<<parampg<<opts<<");\n";
03477 }
03478 else if (container->isForSection())
03479 {
03480 str << " if (ckIsDelegated()) {\n";
03481 str << " Ck"<<node<<"GroupMsgPrep("<<paramg<<");\n";
03482 str << " ckDelegatedTo()->"<<node<<"GroupSectionSend(ckDelegatedPtr(),"<<params<<", ckGetNumSections(), ckGetSectionIDs());\n";
03483 str << " } else {\n";
03484 str << " void *impl_msg_tmp = (ckGetNumSections()>1) ? CkCopyMsg((void **) &impl_msg) : impl_msg;\n";
03485 str << " for (int i=0; i<ckGetNumSections(); ++i) {\n";
03486 str << " impl_msg_tmp= (i<ckGetNumSections()-1) ? CkCopyMsg((void **) &impl_msg):impl_msg;\n";
03487 str << " CkSendMsg"<<node<<"BranchMulti("<<epIdx()<<", impl_msg_tmp, ckGetGroupIDn(i), ckGetNumElements(i), ckGetElements(i)"<<opts<<");\n";
03488 str << " }\n";
03489 str << " }\n";
03490 }
03491 else
03492 {
03493 str << " if (ckIsDelegated()) {\n";
03494 str << " Ck"<<node<<"GroupMsgPrep("<<paramg<<");\n";
03495 str << " ckDelegatedTo()->"<<node<<"GroupBroadcast(ckDelegatedPtr(),"<<paramg<<");\n";
03496 str << " } else CkBroadcastMsg"<<node<<"Branch("<<paramg<<opts<<");\n";
03497 }
03498 }
03499 str << "}\n";
03500
03501
03502 if(!forElement && !container->isForSection() && !isSync() && !isLocal() && !container->isNodeGroup()) {
03503 str << ""<<makeDecl(retStr,1)<<"::"<<name<<"("<<paramComma(1,0)<<"int npes, int *pes"<<eo(0)<<") {\n";
03504 str << marshallMsg();
03505 str << " CkSendMsg"<<node<<"BranchMulti("<<paramg<<", npes, pes"<<opts<<");\n";
03506 str << "}\n";
03507 str << ""<<makeDecl(retStr,1)<<"::"<<name<<"("<<paramComma(1,0)<<"CmiGroup &grp"<<eo(0)<<") {\n";
03508 str << marshallMsg();
03509 str << " CkSendMsg"<<node<<"BranchGroup("<<paramg<<", grp"<<opts<<");\n";
03510 str << "}\n";
03511 }
03512 }
03513 }
03514
03515 void Entry::genGroupStaticConstructorDecl(XStr& str)
03516 {
03517 if (container->isForElement()) return;
03518 if (container->isForSection()) return;
03519
03520 str << " static CkGroupID ckNew("<<paramType(1,1)<<");\n";
03521 if (!param->isVoid()) {
03522 str << " "<<container->proxyName(0)<<"("<<paramType(1,1)<<");\n";
03523 }
03524 }
03525
03526 void Entry::genGroupStaticConstructorDefs(XStr& str)
03527 {
03528 if (container->isForElement()) return;
03529 if (container->isForSection()) return;
03530
03531
03532 char *node = (char *)(container->isNodeGroup()?"Node":"");
03533 str << makeDecl("CkGroupID",1)<<"::ckNew("<<paramType(0,1)<<")\n";
03534 str << "{\n"<<marshallMsg();
03535 str << " return CkCreate"<<node<<"Group("<<chareIdx()<<", "<<epIdx()<<", impl_msg);\n";
03536 str << "}\n";
03537
03538 if (!param->isVoid()) {
03539 str << makeDecl(" ",1)<<"::"<<container->proxyName(0)<<"("<<paramType(0,1)<<")\n";
03540 str << "{\n"<<marshallMsg();
03541 str << " ckSetGroupID(CkCreate"<<node<<"Group("<<chareIdx()<<", "<<epIdx()<<", impl_msg));\n";
03542 str << "}\n";
03543 }
03544 }
03545
03546
03547 void Entry::genPythonDecls(XStr& str) {
03548 str <<"/* STATIC DECLS: "; print(str); str << " */\n";
03549 if (isPython()) {
03550
03551 if (!param || param->next || !param->param->getType()->isBuiltin() || !((BuiltinType*)param->param->getType())->isInt()) {
03552 die("A python entry method must accept only one parameter of type `int`");
03553 }
03554
03555 str << "PyObject *_Python_"<<container->baseName()<<"_"<<name<<"(PyObject *self, PyObject *arg);\n";
03556 }
03557 }
03558
03559 void Entry::genPythonDefs(XStr& str) {
03560 str <<"/* DEFS: "; print(str); str << " */\n";
03561 if (isPython()) {
03562
03563 str << "PyObject *_Python_"<<container->baseName()<<"_"<<name<<"(PyObject *self, PyObject *arg) {\n";
03564 str << " PyObject *dict = PyModule_GetDict(PyImport_AddModule(\"__main__\"));\n";
03565 str << " int pyNumber = PyInt_AsLong(PyDict_GetItemString(dict,\"__charmNumber__\"));\n";
03566 str << " PythonObject *pythonObj = (PythonObject *)PyLong_AsVoidPtr(PyDict_GetItemString(dict,\"__charmObject__\"));\n";
03567 str << " "<<container->baseName()<<" *object = static_cast<"<<container->baseName()<<" *>(pythonObj);\n";
03568 str << " object->pyWorkers[pyNumber].arg=arg;\n";
03569 str << " object->pyWorkers[pyNumber].result=&CtvAccess(pythonReturnValue);\n";
03570 str << " object->pyWorkers[pyNumber].pythread=PyThreadState_Get();\n";
03571 str << " CtvAccess(pythonReturnValue) = 0;\n";
03572
03573 str << " //pyWorker->thisProxy."<<name<<"(pyNumber);\n";
03574 str << " object->"<<name<<"(pyNumber);\n";
03575
03576 str << " //CthSuspend();\n";
03577
03578 str << " if (CtvAccess(pythonReturnValue)) {\n";
03579 str << " return CtvAccess(pythonReturnValue);\n";
03580 str << " } else {\n";
03581 str << " Py_INCREF(Py_None); return Py_None;\n";
03582 str << " }\n";
03583 str << "}\n";
03584 }
03585 }
03586
03587 void Entry::genPythonStaticDefs(XStr& str) {
03588 if (isPython()) {
03589 str << " {\""<<name<<"\",_Python_"<<container->baseName()<<"_"<<name<<",METH_VARARGS},\n";
03590 }
03591 }
03592
03593 void Entry::genPythonStaticDocs(XStr& str) {
03594 if (isPython()) {
03595 str << "\n \""<<name<<" -- \"";
03596 if (pythonDoc) str <<(char*)pythonDoc;
03597 str <<"\"\\\\n\"";
03598 }
03599 }
03600
03601
03602
03603
03604 void Entry::genAccelFullParamList(XStr& str, int makeRefs) {
03605
03606 if (!isAccel()) return;
03607
03608 ParamList* curParam = NULL;
03609 int isFirst = 1;
03610
03611
03612 curParam = param;
03613 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
03614 while (curParam != NULL) {
03615
03616 if (!isFirst) { str << ", "; }
03617
03618 Parameter* param = curParam->param;
03619
03620 if (param->isArray()) {
03621 str << param->getType()->getBaseName() << "* " << param->getName();
03622 } else {
03623 str << param->getType()->getBaseName() << " " << param->getName();
03624 }
03625
03626 isFirst = 0;
03627 curParam = curParam->next;
03628 }
03629
03630
03631 curParam = accelParam;
03632 while (curParam != NULL) {
03633
03634 if (!isFirst) { str << ", "; }
03635
03636 Parameter* param = curParam->param;
03637 int bufType = param->getAccelBufferType();
03638 int needWrite = makeRefs && ((bufType == Parameter::ACCEL_BUFFER_TYPE_READWRITE) || (bufType == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY));
03639 if (param->isArray()) {
03640 str << param->getType()->getBaseName() << "* " << param->getName();
03641 } else {
03642 str << param->getType()->getBaseName() << ((needWrite) ? (" &") : (" ")) << param->getName();
03643 }
03644
03645 isFirst = 0;
03646 curParam = curParam->next;
03647 }
03648
03649
03650 if (!isFirst) { str << ", "; }
03651 str << container->baseName() << "* impl_obj";
03652 }
03653
03654 void Entry::genAccelFullCallList(XStr& str) {
03655 if (!isAccel()) return;
03656
03657 int isFirstFlag = 1;
03658
03659
03660 ParamList* curParam = param;
03661 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
03662 while (curParam != NULL) {
03663 if (!isFirstFlag) str << ", ";
03664 isFirstFlag = 0;
03665 str << curParam->param->getName();
03666 curParam = curParam->next;
03667 }
03668
03669
03670 curParam = accelParam;
03671 while (curParam != NULL) {
03672 if (!isFirstFlag) str << ", ";
03673 isFirstFlag = 0;
03674 str << (*(curParam->param->getAccelInstName()));
03675 curParam = curParam->next;
03676 }
03677
03678
03679 if (!isFirstFlag) str << ", ";
03680 isFirstFlag = 0;
03681 str << "impl_obj";
03682 }
03683
03684 void Entry::genAccelIndexWrapperDecl_general(XStr& str) {
03685 str << " static void _accelCall_general_" << epStr() << "(";
03686 genAccelFullParamList(str, 1);
03687 str << ");\n";
03688 }
03689
03690 void Entry::genAccelIndexWrapperDef_general(XStr& str) {
03691 str << makeDecl("void") << "::_accelCall_general_" << epStr() << "(";
03692 genAccelFullParamList(str, 1);
03693 str << ") {\n\n";
03694
03696
03697
03698
03699
03700
03701 str << (*accelCodeBody);
03702
03703 str << "\n\n";
03704 str << " impl_obj->" << (*accelCallbackName) << "();\n";
03705 str << "}\n";
03706 }
03707
03708 void Entry::genAccelIndexWrapperDecl_spe(XStr& str) {
03709
03710
03711 str << " static void _accelCall_spe_" << epStr() << "(";
03712 genAccelFullParamList(str, 0);
03713 str << ");\n";
03714
03715
03716 str << " static void _accelCall_spe_callback_" << epStr() << "(void* userPtr);\n";
03717 }
03718
03719
03720 #if CMK_CELL != 0
03721 #include "spert.h"
03722 #endif
03723
03724 void Entry::genAccelIndexWrapperDef_spe(XStr& str) {
03725
03726 XStr containerType = container->baseName();
03727
03728
03729 str << "\n\n";
03730
03731
03733
03734 str << "typedef struct __spe_callback_struct_" << epStr() << " {\n"
03735 << " " << containerType << "* impl_obj;\n"
03736 << " WRHandle wrHandle;\n"
03737 << " void* scalar_buf_ptr;\n";
03738
03739
03740 ParamList* curParam = param;
03741 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
03742 while (curParam != NULL) {
03743 if (curParam->param->isArray()) {
03744 str << " void* param_buf_ptr_" << curParam->param->getName() << ";\n";
03745 }
03746 curParam = curParam->next;
03747 }
03748 curParam = accelParam;
03749 while (curParam != NULL) {
03750 if (curParam->param->isArray()) {
03751 str << " void* accelParam_buf_ptr_" << curParam->param->getName() << ";\n";
03752 }
03753 curParam = curParam->next;
03754 }
03755
03756 str << "} SpeCallbackStruct_" << epStr() << ";\n\n";
03757
03758
03760
03761 str << "void _accelCall_spe_callback_" << container->baseName() << "_" << epStr() << "(void* userPtr) {\n"
03762 << " " << container->indexName() << "::_accelCall_spe_callback_" << epStr() << "(userPtr);\n"
03763 << "}\n";
03764
03765 str << makeDecl("void") << "::_accelCall_spe_callback_" << epStr() << "(void* userPtr) {\n";
03766 str << " SpeCallbackStruct_" << epStr() << "* cbStruct = (SpeCallbackStruct_" << epStr() << "*)userPtr;\n";
03767 str << " " << containerType << "* impl_obj = cbStruct->impl_obj;\n";
03768
03769
03770
03771 if (accel_numScalars > 0) {
03772
03773
03774 int dmaList_scalarBufIndex = 0;
03775 if (accel_dmaList_scalarNeedsWrite) {
03776 dmaList_scalarBufIndex += accel_dmaList_numReadOnly;
03777 }
03778 str << " char* __scalar_buf_offset = (char*)(cbStruct->scalar_buf_ptr);\n";
03779
03780
03781 curParam = param;
03782 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
03783 while (curParam != NULL) {
03784 if (!(curParam->param->isArray())) {
03785 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
03786 }
03787 curParam = curParam->next;
03788 }
03789
03790
03791 curParam = accelParam;
03792 while (curParam != NULL) {
03793 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READONLY)) {
03794 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
03795 }
03796 curParam = curParam->next;
03797 }
03798
03799
03800 curParam = accelParam;
03801 while (curParam != NULL) {
03802 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READWRITE)) {
03803 str << " " << (*(curParam->param->getAccelInstName())) << " = *((" << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
03804 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
03805 }
03806 curParam = curParam->next;
03807 }
03808
03809
03810 curParam = accelParam;
03811 while (curParam != NULL) {
03812 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY)) {
03813 str << " " << (*(curParam->param->getAccelInstName())) << " = *((" << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
03814 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
03815 }
03816 curParam = curParam->next;
03817 }
03818 }
03819
03820
03821 str << " (cbStruct->impl_obj)->" << (*accelCallbackName) << "();\n";
03822
03823
03824 str << " if (cbStruct->scalar_buf_ptr != NULL) { free_aligned(cbStruct->scalar_buf_ptr); }\n";
03825 curParam = param;
03826 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
03827 while (curParam != NULL) {
03828 if (curParam->param->isArray()) {
03829 str << " if (cbStruct->param_buf_ptr_" << curParam->param->getName() << " != NULL) { "
03830 << "free_aligned(cbStruct->param_buf_ptr_" << curParam->param->getName() << "); "
03831 << "}\n";
03832 }
03833 curParam = curParam->next;
03834 }
03835 str << " delete cbStruct;\n";
03836
03837 str << "}\n\n";
03838
03839
03841
03842 str << makeDecl("void") << "::_accelCall_spe_" << epStr() << "(";
03843 genAccelFullParamList(str, 0);
03844 str << ") {\n\n";
03845
03847
03848
03849
03850
03851
03852
03853 str << " // Allocate a user structure to be passed to the callback function\n"
03854 << " SpeCallbackStruct_" << epStr() << "* cbStruct = new SpeCallbackStruct_" << epStr() << ";\n"
03855 << " cbStruct->impl_obj = impl_obj;\n"
03856 << " cbStruct->wrHandle = INVALID_WRHandle; // NOTE: Set actual value later...\n"
03857 << " cbStruct->scalar_buf_ptr = NULL;\n";
03858
03859 curParam = param;
03860 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
03861 while (curParam != NULL) {
03862 if (curParam->param->isArray()) {
03863 str << " cbStruct->param_buf_ptr_" << curParam->param->getName() << " = NULL;\n";
03864 }
03865 curParam = curParam->next;
03866 }
03867 curParam = accelParam;
03868 while (curParam != NULL) {
03869 if (curParam->param->isArray()) {
03870 str << " cbStruct->accelParam_buf_ptr_" << curParam->param->getName() << " = NULL;\n";
03871 }
03872 curParam = curParam->next;
03873 }
03874 str << "\n";
03875
03876
03877
03878 int dmaList_curIndex = 0;
03879 int numDMAListEntries = accel_numArrays;
03880 if (accel_numScalars > 0) { numDMAListEntries++; }
03881 if (numDMAListEntries <= 0) {
03882 die("Accel entry with no parameters");
03883 }
03884
03885
03886
03887
03888
03889 #if CMK_CELL != 0
03890 if (numDMAListEntries > SPE_DMA_LIST_LENGTH) {
03891 die("Accel entries do not support parameter lists of length > SPE_DMA_LIST_LENGTH yet... fix me...");
03892 }
03893 #endif
03894
03895
03896 if (accel_numScalars > 0) {
03897 str << " // Create a single buffer to hold all the scalar values\n";
03898 str << " int scalar_buf_len = 0;\n";
03899 curParam = param;
03900 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
03901 while (curParam != NULL) {
03902 if (!(curParam->param->isArray())) {
03903 str << " scalar_buf_len += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
03904 }
03905 curParam = curParam->next;
03906 }
03907 curParam = accelParam;
03908 while (curParam != NULL) {
03909 if (!(curParam->param->isArray())) {
03910 str << " scalar_buf_len += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
03911 }
03912 curParam = curParam->next;
03913 }
03914 str << " scalar_buf_len = ROUNDUP_128(scalar_buf_len);\n"
03915 << " cbStruct->scalar_buf_ptr = malloc_aligned(scalar_buf_len, 128);\n"
03916 << " char* scalar_buf_offset = (char*)(cbStruct->scalar_buf_ptr);\n\n";
03917 }
03918
03919
03920
03921 str << " // Declare and populate the DMA list for the work request\n";
03922 str << " DMAListEntry dmaList[" << numDMAListEntries << "];\n\n";
03923
03924
03925
03926 curParam = param;
03927 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
03928 while (curParam != NULL) {
03929
03930
03931 if (accel_numScalars > 0) {
03932 if (((dmaList_curIndex == 0) && (!(accel_dmaList_scalarNeedsWrite))) ||
03933 ((dmaList_curIndex == accel_dmaList_numReadOnly) && (accel_dmaList_scalarNeedsWrite))
03934 ) {
03935
03936 str << " /*** Scalar Buffer ***/\n"
03937 << " dmaList[" << dmaList_curIndex << "].size = scalar_buf_len;\n"
03938 << " dmaList[" << dmaList_curIndex << "].ea = (unsigned int)(cbStruct->scalar_buf_ptr);\n\n";
03939 dmaList_curIndex++;
03940 }
03941 }
03942
03943
03944 str << " /*** Param: '" << curParam->param->getName() << "' ***/\n";
03945 if (curParam->param->isArray()) {
03946 str << " {\n"
03947 << " int bufSize = sizeof(" << curParam->param->getType()->getBaseName() << ") * (" << curParam->param->getArrayLen() << ");\n"
03948 << " bufSize = ROUNDUP_128(bufSize);\n"
03949 << " cbStruct->param_buf_ptr_" << curParam->param->getName() << " = malloc_aligned(bufSize, 128);\n"
03950 << " memcpy(cbStruct->param_buf_ptr_" << curParam->param->getName() << ", " << curParam->param->getName() << ", bufSize);\n"
03951 << " dmaList[" << dmaList_curIndex << "].size = bufSize;\n"
03952 << " dmaList[" << dmaList_curIndex << "].ea = (unsigned int)(cbStruct->param_buf_ptr_" << curParam->param->getName() << ");\n"
03953 << " }\n";
03954 dmaList_curIndex++;
03955 } else {
03956 str << " *((" << curParam->param->getType()->getBaseName() << "*)scalar_buf_offset) = "
03957 << curParam->param->getName() << ";\n"
03958 << " scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
03959 }
03960 curParam = curParam->next;
03961 str << "\n";
03962 }
03963
03964
03965 curParam = accelParam;
03966 while (curParam != NULL) {
03967
03968
03969 if (accel_numScalars > 0) {
03970 if (((dmaList_curIndex == 0) && (!(accel_dmaList_scalarNeedsWrite))) ||
03971 ((dmaList_curIndex == accel_dmaList_numReadOnly) && (accel_dmaList_scalarNeedsWrite))
03972 ) {
03973
03974 str << " /*** Scalar Buffer ***/\n"
03975 << " dmaList[" << dmaList_curIndex << "].size = scalar_buf_len;\n"
03976 << " dmaList[" << dmaList_curIndex << "].ea = (unsigned int)(cbStruct->scalar_buf_ptr);\n\n";
03977 dmaList_curIndex++;
03978 }
03979 }
03980
03981
03982 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READONLY) {
03983 str << " /*** Accel Param: '" << curParam->param->getName() << " ("
03984 << (*(curParam->param->getAccelInstName())) << ")' ***/\n";
03985 if (curParam->param->isArray()) {
03986 str << " dmaList[" << dmaList_curIndex << "].size = ROUNDUP_128("
03987 << "sizeof(" << curParam->param->getType()->getBaseName() << ") * "
03988 << "(" << curParam->param->getArrayLen() << "));\n"
03989 << " dmaList[" << dmaList_curIndex << "].ea = (unsigned int)(" << (*(curParam->param->getAccelInstName())) << ");\n";
03990 dmaList_curIndex++;
03991 } else {
03992 str << " *((" << curParam->param->getType()->getBaseName() << "*)scalar_buf_offset) = "
03993 << (*(curParam->param->getAccelInstName())) << ";\n"
03994 << " scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
03995 }
03996 str << "\n";
03997 }
03998
03999 curParam = curParam->next;
04000 }
04001
04002
04003 curParam = accelParam;
04004 while (curParam != NULL) {
04005
04006
04007 if (accel_numScalars > 0) {
04008 if (((dmaList_curIndex == 0) && (!(accel_dmaList_scalarNeedsWrite))) ||
04009 ((dmaList_curIndex == accel_dmaList_numReadOnly) && (accel_dmaList_scalarNeedsWrite))
04010 ) {
04011
04012 str << " /*** Scalar Buffer ***/\n"
04013 << " dmaList[" << dmaList_curIndex << "].size = scalar_buf_len;\n"
04014 << " dmaList[" << dmaList_curIndex << "].ea = (unsigned int)(cbStruct->scalar_buf_ptr);\n\n";
04015 dmaList_curIndex++;
04016 }
04017 }
04018
04019
04020 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READWRITE) {
04021 str << " /*** Accel Param: '" << curParam->param->getName() << " ("
04022 << (*(curParam->param->getAccelInstName())) << ")' ***/\n";
04023 if (curParam->param->isArray()) {
04024 str << " dmaList[" << dmaList_curIndex << "].size = ROUNDUP_128("
04025 << "sizeof(" << curParam->param->getType()->getBaseName() << ") * "
04026 << "(" << curParam->param->getArrayLen() << "));\n"
04027 << " dmaList[" << dmaList_curIndex << "].ea = (unsigned int)(" << (*(curParam->param->getAccelInstName())) << ");\n";
04028 dmaList_curIndex++;
04029 } else {
04030 str << " *((" << curParam->param->getType()->getBaseName() << "*)scalar_buf_offset) = "
04031 << (*(curParam->param->getAccelInstName())) << ";\n"
04032 << " scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
04033 }
04034 str << "\n";
04035 }
04036
04037 curParam = curParam->next;
04038 }
04039
04040
04041 curParam = accelParam;
04042 while (curParam != NULL) {
04043
04044
04045 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY) {
04046 str << " /*** Accel Param: '" << curParam->param->getName() << " ("
04047 << (*(curParam->param->getAccelInstName())) << ")' ***/\n";
04048 if (curParam->param->isArray()) {
04049 str << " dmaList[" << dmaList_curIndex << "].size = ROUNDUP_128("
04050 << "sizeof(" << curParam->param->getType()->getBaseName() << ") * "
04051 << "(" << curParam->param->getArrayLen() << "));\n"
04052 << " dmaList[" << dmaList_curIndex << "].ea = (unsigned int)(" << (*(curParam->param->getAccelInstName())) << ");\n";
04053 dmaList_curIndex++;
04054 } else {
04055 str << " *((" << curParam->param->getType()->getBaseName() << "*)scalar_buf_offset) = "
04056 << (*(curParam->param->getAccelInstName())) << ";\n"
04057 << " scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
04058 }
04059 str << "\n";
04060 }
04061
04062 curParam = curParam->next;
04063 }
04064
04065 str << " // Issue the work request\n";
04066 str << " cbStruct->wrHandle = sendWorkRequest_list(accel_spe_func_index__" << epStr() << ",\n"
04067 << " 0,\n"
04068 << " dmaList,\n"
04069 << " " << accel_dmaList_numReadOnly << ",\n"
04070 << " " << accel_dmaList_numReadWrite << ",\n"
04071 << " " << accel_dmaList_numWriteOnly << ",\n"
04072 << " cbStruct,\n"
04073 << " WORK_REQUEST_FLAGS_NONE,\n"
04074 << " _accelCall_spe_callback_" << container->baseName() << "_" << epStr() << "\n"
04075 << " );\n";
04076
04077 str << "}\n\n";
04078
04079
04080
04081 str << "\n";
04082 }
04083
04084 int Entry::genAccels_spe_c_funcBodies(XStr& str) {
04085
04086
04087 if (!isAccel()) { return 0; }
04088
04089
04090 str << "void __speFunc__" << indexName() << "__" << epStr() << "(DMAListEntry* dmaList) {\n";
04091
04092 ParamList* curParam = NULL;
04093 int dmaList_curIndex = 0;
04094
04095
04096 if (accel_numScalars > 0) {
04097 if (accel_dmaList_scalarNeedsWrite) {
04098 str << " void* __scalar_buf_ptr = (void*)(dmaList[" << accel_dmaList_numReadOnly << "].ea);\n";
04099 } else {
04100 str << " void* __scalar_buf_ptr = (void*)(dmaList[0].ea);\n";
04101 dmaList_curIndex++;
04102 }
04103 str << " char* __scalar_buf_offset = (char*)(__scalar_buf_ptr);\n";
04104 }
04105
04106
04107 curParam = param;
04108 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
04109 while (curParam != NULL) {
04110 if (curParam->param->isArray()) {
04111 str << " " << curParam->param->getType()->getBaseName() << "* " << curParam->param->getName() << " = (" << curParam->param->getType()->getBaseName() << "*)(dmaList[" << dmaList_curIndex << "].ea);\n";
04112 dmaList_curIndex++;
04113 } else {
04114 str << " " << curParam->param->getType()->getBaseName() << " " << curParam->param->getName() << " = *((" << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
04115 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
04116 }
04117 curParam = curParam->next;
04118 }
04119
04120
04121 curParam = accelParam;
04122 while (curParam != NULL) {
04123 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READONLY) {
04124 if (curParam->param->isArray()) {
04125 str << " " << curParam->param->getType()->getBaseName() << "* " << curParam->param->getName() << " = (" << curParam->param->getType()->getBaseName() << "*)(dmaList[" << dmaList_curIndex << "].ea);\n";
04126 dmaList_curIndex++;
04127 } else {
04128 str << " " << curParam->param->getType()->getBaseName() << " " << curParam->param->getName() << " = *((" << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
04129 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
04130 }
04131 }
04132 curParam = curParam->next;
04133 }
04134
04135
04136 dmaList_curIndex = accel_dmaList_numReadOnly;
04137 if ((accel_numScalars > 0) && (accel_dmaList_scalarNeedsWrite)) {
04138 dmaList_curIndex++;
04139 }
04140
04141
04142 curParam = accelParam;
04143 while (curParam != NULL) {
04144 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READWRITE) {
04145 if (curParam->param->isArray()) {
04146 str << " " << curParam->param->getType()->getBaseName() << "* " << curParam->param->getName() << " = (" << curParam->param->getType()->getBaseName() << "*)(dmaList[" << dmaList_curIndex << "].ea);\n";
04147 dmaList_curIndex++;
04148 } else {
04149 str << " " << curParam->param->getType()->getBaseName() << " " << curParam->param->getName() << " = *((" << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
04150 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
04151 }
04152 }
04153 curParam = curParam->next;
04154 }
04155
04156
04157 curParam = accelParam;
04158 while (curParam != NULL) {
04159 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY) {
04160 if (curParam->param->isArray()) {
04161 str << " " << curParam->param->getType()->getBaseName() << "* " << curParam->param->getName() << " = (" << curParam->param->getType()->getBaseName() << "*)(dmaList[" << dmaList_curIndex << "].ea);\n";
04162 dmaList_curIndex++;
04163 } else {
04164 str << " " << curParam->param->getType()->getBaseName() << " " << curParam->param->getName() << " = *((" << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
04165 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
04166 }
04167 }
04168 curParam = curParam->next;
04169 }
04170
04171
04172
04173 str << " {\n " << (*accelCodeBody) << "\n }\n";
04174
04175
04176
04177 if ((accel_numScalars > 0) && (accel_dmaList_scalarNeedsWrite)) {
04178
04179 str << " __scalar_buf_offset = (char*)(__scalar_buf_ptr);\n";
04180
04181
04182 curParam = param;
04183 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
04184 while (curParam != NULL) {
04185 if (!(curParam->param->isArray())) {
04186 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
04187 }
04188 curParam = curParam->next;
04189 }
04190
04191
04192 curParam = accelParam;
04193 while (curParam != NULL) {
04194 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READONLY)) {
04195 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
04196 }
04197 curParam = curParam->next;
04198 }
04199
04200
04201 curParam = accelParam;
04202 while (curParam != NULL) {
04203 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READWRITE)) {
04204 str << " *((" << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset) = " << curParam->param->getName() << ";\n";
04205 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
04206 }
04207 curParam = curParam->next;
04208 }
04209
04210
04211 curParam = accelParam;
04212 while (curParam != NULL) {
04213 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY)) {
04214 str << " *((" << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset) = " << curParam->param->getName() << ";\n";
04215 str << " __scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName() << ");\n";
04216 }
04217 curParam = curParam->next;
04218 }
04219
04220 }
04221
04222 str << "}\n\n\n";
04223
04224 return 1;
04225 }
04226
04227 void Entry::genAccels_spe_c_regFuncs(XStr& str) {
04228 if (isAccel()) {
04229 str << " funcLookupTable[curIndex ].funcIndex = curIndex;\n"
04230 << " funcLookupTable[curIndex++].funcPtr = __speFunc__" << indexName() << "__" << epStr() << ";\n";
04231 }
04232 }
04233
04234 void Entry::genAccels_ppe_c_regFuncs(XStr& str) {
04235 if (isAccel()) {
04236 str << " " << indexName() << "::accel_spe_func_index__" << epStr() << " = curIndex++;\n";
04237 }
04238 }
04239
04240
04241
04242 void Entry::genIndexDecls(XStr& str)
04243 {
04244 str << " /* DECLS: "; print(str); str << " */";
04245
04246 XStr templateSpecLine;
04247 templateSpecLine << "\n " << generateTemplateSpec(tspec);
04248
04249
04250 str << "\n // Entry point registration at startup"
04251 << templateSpecLine
04252 << "\n static int reg_" << epStr() << "();"
04253 << "\n // Entry point index lookup"
04254 << templateSpecLine
04255 << "\n inline static int idx_" << epStr() << "() {"
04256 << "\n static int epidx = " << epRegFn(0) << ";"
04257 << "\n return epidx;"
04258 << "\n }\n";
04259
04260 if (!isConstructor()) {
04261 str << templateSpecLine
04262 << "\n inline static int idx_" << name << "("
04263 << retType
04264 << " (" << container->baseName() << "::*)(";
04265 if (param)
04266 param->print(str);
04267 str << ") ) {"
04268 << "\n return " << epIdx(0) << ";"
04269 << "\n }\n\n";
04270 }
04271
04272
04273 #if CMK_CELL != 0
04274 if (isAccel()) {
04275 str << " static int accel_spe_func_index__" << epStr() << ";\n";
04276 }
04277 #endif
04278
04279
04280 str << templateSpecLine
04281 << "\n static int ";
04282 if (isConstructor()) str <<"ckNew";
04283 else str <<name;
04284 str << "("<<paramType(1,0)<<") { return "<<epIdx(0)<<"; }";
04285
04286
04287 if (isAccel()) {
04288 genAccelIndexWrapperDecl_general(str);
04289 #if CMK_CELL != 0
04290 genAccelIndexWrapperDecl_spe(str);
04291 #endif
04292 }
04293
04294 if (isReductionTarget()) {
04295 str << "\n // Entry point registration at startup"
04296 << templateSpecLine
04297 << "\n static int reg_"<< epStr(true) <<"();"
04298 << "\n // Entry point index lookup"
04299 << templateSpecLine
04300 << "\n inline static int idx_" << epStr(true) << "() {"
04301 << "\n static int epidx = "<< epRegFn(0, true) <<";"
04302 << "\n return epidx;"
04303 << "\n }"
04304 << templateSpecLine
04305 << "\n static int " << "redn_wrapper_" << name
04306 << "(CkReductionMsg* impl_msg) { return " << epIdx(0, true) << "; }"
04307 << templateSpecLine
04308 << "\n static void _call_" << epStr(true) << "(void* impl_msg, void* impl_obj_void);";
04309 }
04310
04311
04312 str << templateSpecLine
04313 << "\n static void _call_" << epStr() << "(void* impl_msg, void* impl_obj);";
04314 if(isThreaded()) {
04315 str << templateSpecLine
04316 << "\n static void _callthr_"<<epStr()<<"(CkThrCallArg *);";
04317 }
04318 if (hasCallMarshall) {
04319 str << templateSpecLine
04320 << "\n static int _callmarshall_" << epStr()
04321 << "(char* impl_buf, void* impl_obj_void);";
04322 }
04323 if (param->isMarshalled()) {
04324 str << templateSpecLine
04325 << "\n static void _marshallmessagepup_"<<epStr()<<"(PUP::er &p,void *msg);";
04326 }
04327 }
04328
04329 void Entry::genDecls(XStr& str)
04330 {
04331 if (external)
04332 return;
04333
04334 if(isConstructor() && retType && !retType->isVoid())
04335 die("Constructors cannot return a value",line);
04336
04337 str << "/* DECLS: "; print(str); str << " */\n";
04338 if(retType==0 && !isConstructor())
04339 die("Entry methods must specify a return type-- \n"
04340 "use void if necessary",line);
04341
04342 if (attribs&SMIGRATE)
04343 {}
04344 else if(container->isGroup()) {
04345 genGroupDecl(str);
04346 } else if(container->isArray()) {
04347 if(!isIget())
04348 genArrayDecl(str);
04349 else if(container->isForElement())
04350 genArrayDecl(str);
04351 } else {
04352 genChareDecl(str);
04353 }
04354 }
04355
04356
04357 void Entry::genPub(XStr &declstr, XStr& defstr, XStr& defconstr, int& connectPresent)
04358 {
04359
04360
04361
04362
04363
04364 if ((isConnect == 1) && (connectPresent == 0)) {
04365 connectPresent = 1;
04366 declstr << "class publish\n";
04367 declstr << "{\n";
04368 declstr << " public:\n";
04369 declstr << " publish();\n";
04370 defconstr << "publish::publish()\n" << "{\n";
04371 }
04372 if (isConnect == 1) {
04373 defconstr << " publishflag_" <<getEntryName() << " = 0;\n";
04374 defconstr << " getflag_" <<getEntryName() << " = 0;\n";
04375 declstr << " void " <<getEntryName() <<"(";
04376 defstr << "void publish::" << getEntryName() <<"(";
04377 ParamList *pl = connectParam;
04378 XStr *parameters = new XStr("");
04379 int count = 0;
04380 int i, numStars;
04381 if (pl->isVoid() == 1) {
04382 declstr << "void);\n";
04383 defstr << "void);\n";
04384 }
04385 else if (pl->isMessage() == 1){
04386 declstr << pl->getBaseName() <<"* " << pl->getGivenName() <<");\n";
04387 defstr << pl->getBaseName() <<"* " << pl->getGivenName() <<");\n";
04388 defconstr << " " << pl->getGivenName() <<" = new " << pl->getBaseName() <<"();\n";
04389 parameters->append(" ");
04390 parameters->append(pl->getBaseName());
04391 parameters->append("* ");
04392 parameters->append(pl->getGivenName());
04393 parameters->append("_msg;\n ");
04394 }
04395 else {
04396 defconstr << " " << getEntryName() <<"_msg = new CkMarshallMsg();\n";
04397 parameters->append(" CkMarshallMsg *");
04398 parameters->append(getEntryName());
04399 parameters->append("_msg;\n");
04400 while(pl != NULL) {
04401 if (count > 0) {
04402 declstr << ", ";
04403 defstr << ", ";
04404 }
04405 if (pl->isPointer() == 1) {
04406
04407 declstr << pl->getBaseName();
04408 defstr << pl->getBaseName();
04409 numStars = pl->getNumStars();
04410 for(i=0; i< numStars; i++) {
04411 declstr << "*";
04412 defstr << "*";
04413 }
04414 declstr << " " << pl->getGivenName();
04415 defstr << " " << pl->getGivenName();
04416 }
04417 else if (pl->isReference() == 1) {
04418 declstr << pl->getBaseName() <<"& " <<pl->getGivenName();
04419 defstr << pl->getBaseName() <<"& " <<pl->getGivenName();
04420 }
04421 else if (pl->isArray() == 1){
04422 declstr << pl->getBaseName() <<"* " <<pl->getGivenName();
04423 defstr << pl->getBaseName() <<"* " <<pl->getGivenName();
04424 }
04425 else if ((pl->isBuiltin() == 1) || (pl->isNamed() == 1)) {
04426 declstr << pl->getBaseName() <<" " <<pl->getGivenName();
04427 defstr << pl->getBaseName() <<" " <<pl->getGivenName();
04428 }
04429 pl = pl->next;
04430 count++;
04431 }
04432 declstr << "); \n";
04433 defstr << ") { \n";
04434 }
04435 declstr << " void get_" << getEntryName() << "(CkCallback cb);\n";
04436 declstr << " int publishflag_" << getEntryName() << ";\n";
04437 declstr << " int getflag_" << getEntryName() << ";\n";
04438 declstr << " CkCallback " << getEntryName() << "_cb;\n";
04439 declstr << parameters->charstar();
04440
04441
04442
04443
04444 defstr <<" const CkEntryOptions *impl_e_opts = NULL;\n";
04445 XStr epName = epStr();
04446 connectParam->marshall(defstr, epName);
04447 defstr << " " << getEntryName() << "_msg = impl_msg;\n";
04448 defstr << " " << "if (getflag_" << getEntryName() <<" == 1) {\n";
04449
04450 defstr << " " << getEntryName() << "_cb.send(" << getEntryName() <<"_msg);\n";
04451 defstr << " }\n";
04452 defstr << " else\n";
04453 defstr << " publishflag_" << getEntryName() << " = 1;\n";
04454 defstr << "}\n\n";
04455
04456
04457
04458 defstr << "void publish::get_" << getEntryName() << "(CkCallback cb) {\n";
04459 defstr << " " << getEntryName() << "_cb = cb;\n";
04460 defstr << " if (publishflag_" << getEntryName() << " == 1) {\n";
04461 defstr << " cb.send(" << getEntryName() << "_msg);\n";
04462 defstr << " publishflag_" << getEntryName() << " = 0 ;\n";
04463 defstr << " }\n";
04464 defstr << " else\n";
04465 defstr << " getflag_" << getEntryName() << " = 1;\n";
04466 defstr << "}\n";
04467 }
04468 }
04469
04470
04471
04472
04473
04474 XStr Entry::callThread(const XStr &procName,int prependEntryName)
04475 {
04476 XStr str,procFull;
04477 procFull<<"_callthr_";
04478 if(prependEntryName) procFull<<name<<"_";
04479 procFull<<procName;
04480
04481 str << " CthThread tid = CthCreate((CthVoidFn)"<<procFull
04482 <<", new CkThrCallArg(impl_msg,impl_obj), "<<getStackSize()<<");\n";
04483 str << " ((Chare *)impl_obj)->CkAddThreadListeners(tid,impl_msg);\n";
04484
04485 #if CMK_BIGSIM_CHARM
04486 str << " BgAttach(tid);\n";
04487 #endif
04488 str << " CthAwaken(tid);\n";
04489 str << "}\n";
04490
04491
04492
04493 str << makeDecl("void")<<"::"<<procFull<<"(CkThrCallArg *impl_arg)\n";
04494 str << "{\n";\
04495 str << " void *impl_msg = impl_arg->msg;\n";
04496 str << " "<<container->baseName()<<" *impl_obj = ("<<container->baseName()<<" *) impl_arg->obj;\n";
04497 str << " delete impl_arg;\n";
04498 return str;
04499 }
04500
04501
04502
04503
04504
04505 void Entry::genCall(XStr& str, const XStr &preCall, bool redn_wrapper)
04506 {
04507 bool isArgcArgv=false;
04508 bool isMigMain=false;
04509
04510 if (param->isCkArgMsgPtr() && (!isConstructor() || !container->isMainChare()))
04511 die("CkArgMsg can only be used in mainchare's constructor.\n");
04512
04513 if (isConstructor() && container->isMainChare() &&
04514 (!param->isVoid()) && (!param->isCkArgMsgPtr())){
04515 if(param->isCkMigMsgPtr()) isMigMain = true;
04516 else isArgcArgv = true;
04517 } else {
04518
04519 if (redn_wrapper) param->beginRednWrapperUnmarshall(str);
04520 else param->beginUnmarshall(str);
04521 }
04522
04523 str << preCall;
04524 if (!isConstructor() && fortranMode) {
04525 if (!container->isArray()) {
04526 cerr << (char *)container->baseName() << ": only chare arrays are currently supported\n";
04527 exit(1);
04528 }
04529 str << "/* FORTRAN */\n";
04530 XStr dim; dim << ((Array*)container)->dim();
04531 if (dim==(const char*)"1D")
04532 str << " int index1 = impl_obj->thisIndex;\n";
04533 else if (dim==(const char*)"2D") {
04534 str << " int index1 = impl_obj->thisIndex.x;\n";
04535 str << " int index2 = impl_obj->thisIndex.y;\n";
04536 }
04537 else if (dim==(const char*)"3D") {
04538 str << " int index1 = impl_obj->thisIndex.x;\n";
04539 str << " int index2 = impl_obj->thisIndex.y;\n";
04540 str << " int index3 = impl_obj->thisIndex.z;\n";
04541 }
04542 str << " ::" << fortranify(name)
04543 << "((char **)(impl_obj->user_data), &index1";
04544 if (dim==(const char*)"2D" || dim==(const char*)"3D")
04545 str << ", &index2";
04546 if (dim==(const char*)"3D")
04547 str << ", &index3";
04548 if (!param->isVoid()) { str << ", "; param->unmarshallAddress(str); }
04549 str<<");\n";
04550 str << "/* FORTRAN END */\n";
04551 }
04552
04553
04554 else if (isAccel()) {
04555
04556 #if CMK_CELL != 0
04557 str << " if (1) { // DMK : TODO : For now, hardcode the condition (i.e. for now, do not dynamically load-balance between host and accelerator)\n";
04558 str << " _accelCall_spe_" << epStr() << "(";
04559 genAccelFullCallList(str);
04560 str << ");\n";
04561 str << " } else {\n ";
04562 #endif
04563
04564 str << " _accelCall_general_" << epStr() << "(";
04565 genAccelFullCallList(str);
04566 str << ");\n";
04567
04568 #if CMK_CELL != 0
04569 str << " }\n";
04570 #endif
04571
04572 }
04573
04574 else {
04575 if (isArgcArgv) str<<" CkArgMsg *m=(CkArgMsg *)impl_msg;\n";
04576
04577 if(isConstructor()) {
04578 str << " new (impl_obj) "<<container->baseName();
04579 } else {
04580 str << " impl_obj->" << (tspec ? "template " : "") << name;
04581 if (tspec) {
04582 str << "< ";
04583 tspec->genShort(str);
04584 str << " >";
04585 }
04586 }
04587
04588 if (isArgcArgv) {
04589 str<<"(m->argc,m->argv);\n";
04590 str<<" delete m;\n";
04591 }else if(isMigMain){
04592 str<<"((CkMigrateMessage*)impl_msg);\n";
04593 }
04594 else {
04595 str<<"("; param->unmarshall(str); str<<");\n";
04596 }
04597 }
04598 }
04599
04600 void Entry::genDefs(XStr& str)
04601 {
04602 if (external)
04603 return;
04604 XStr containerType=container->baseName();
04605 XStr preMarshall,preCall,postCall;
04606
04607 templateGuardBegin(tspec || container->isTemplated(), str);
04608 str << "/* DEFS: "; print(str); str << " */\n";
04609
04610 if (attribs&SMIGRATE)
04611 {}
04612 else if(container->isGroup()){
04613 genGroupDefs(str);
04614 } else if(container->isArray()) {
04615 genArrayDefs(str);
04616 } else
04617 genChareDefs(str);
04618
04619 if (container->isMainChare() || container->isChare() || container->isForElement()) {
04620 if (isReductionTarget()) {
04621 XStr retStr; retStr<<retType;
04622 str << makeDecl(retStr);
04623
04624 str << "::_call_" << epStr(true) << "(void* impl_msg, void* impl_obj_void)"
04625 << "\n{"
04626 << "\n " << container->baseName() << "* impl_obj = static_cast<"
04627 << container->baseName() << "*> (impl_obj_void);\n"
04628 << " char* impl_buf = (char*)((CkReductionMsg*)impl_msg)->getData();\n";
04629 XStr precall;
04630 genCall(str, precall, true);
04631 str << " delete (CkReductionMsg*)impl_msg;\n}\n\n";
04632 }
04633 }
04634
04635
04636
04637 if (container->getForWhom()!=forAll) {
04638 templateGuardEnd(str);
04639 return;
04640 }
04641
04642
04643 str << "\n// Entry point registration function"
04644 << "\n" << makeDecl("int") << "::reg_" << epStr() << "() {"
04645 << "\n int epidx = " << genRegEp() << ";";
04646 if (hasCallMarshall)
04647 str << "\n CkRegisterMarshallUnpackFn(epidx, "
04648 << "_callmarshall_" << epStr(false, true) << ");";
04649 if (param->isMarshalled()) {
04650 str << "\n CkRegisterMessagePupFn(epidx, "
04651 << "_marshallmessagepup_" << epStr(false, true) << ");\n";
04652 }
04653 else if (param->isMessage() && !attribs&SMIGRATE) {
04654 str << "\n CkRegisterMessagePupFn(epidx, (CkMessagePupFn)"
04655 << param->param->getType()->getBaseName() << "::ckDebugPup);";
04656 }
04657 str << "\n return epidx;"
04658 << "\n}\n\n";
04659
04660 if (isReductionTarget())
04661 {
04662 str << "\n// Redn wrapper registration function"
04663 << "\n" << makeDecl("int") << "::reg_"<< epStr(true) <<"() {"
04664 << "\n return " << genRegEp(true) << ";"
04665 << "\n}\n\n";
04666 }
04667
04668
04669 #if CMK_CELL != 0
04670 if (isAccel()) {
04671 str << "int " << indexName() << "::" << "accel_spe_func_index__" << epStr() << "=0;\n";
04672 }
04673 #endif
04674
04675
04676 if(isSync() || isIget()) {
04677
04678
04679 if(isConstructor()) die("Constructors cannot be [sync]",line);
04680 preMarshall<< " int impl_ref = CkGetRefNum(impl_msg), impl_src = CkGetSrcPe(impl_msg);\n";
04681 preCall<< " void *impl_retMsg=";
04682 if(retType->isVoid()) {
04683 preCall << "CkAllocSysMsg();\n ";
04684 } else {
04685 preCall << "(void *) ";
04686 }
04687
04688 postCall << " CkSendToFutureID(impl_ref, impl_retMsg, impl_src);\n";
04689 } else if(isExclusive()) {
04690
04691 if(!container->isNodeGroup()) die("only nodegroup methods can be exclusive",line);
04692 if(isConstructor()) die("Constructors cannot be [exclusive]",line);
04693 preMarshall << " if(CmiTryLock(impl_obj->__nodelock)) {\n";
04694
04695 if (param->isMarshalled()) {
04696 preMarshall << " impl_msg = CkCopyMsg(&impl_msg);\n";
04697 }
04698 preMarshall << " CkSendMsgNodeBranch("<<epIdx()<<",impl_msg,CkMyNode(),impl_obj->CkGetNodeGroupID());\n";
04699 preMarshall << " return;\n";
04700 preMarshall << " }\n";
04701
04702 postCall << " CmiUnlock(impl_obj->__nodelock);\n";
04703 }
04704
04705 if (!isConstructor() && fortranMode) {
04706 str << "/* FORTRAN SECTION */\n";
04707
04708 XStr dim; dim << ((Array*)container)->dim();
04709
04710
04711 str << "extern \"C\" void " << fortranify(name) << "(char **, " << container->indexList();
04712 if (!param->isVoid()) { str << ", "; param->printAddress(str); }
04713 str << ");\n";
04714
04715
04716
04717 str << "extern \"C\" void "
04718
04719 << fortranify("SendTo_", container->baseName(), "_", name)
04720 << "(long* aindex, " << container->indexList();
04721 if (!param->isVoid()) { str << ", "; param->printAddress(str); }
04722 str << ")\n";
04723 str << "{\n";
04724 str << " CkArrayID *aid = (CkArrayID *)*aindex;\n";
04725 str << "\n";
04726 str << " " << container->proxyName() << " h(*aid);\n";
04727 str << " if (*index1 == -1) \n";
04728 str << " h." << name << "(";
04729 if (!param->isVoid()) param->printValue(str);
04730 str << ");\n";
04731 str << " else\n";
04732 if (dim==(const char*)"1D")
04733 str << " h[*index1]." << name << "(";
04734 else if (dim==(const char*)"2D")
04735 str << " h[CkArrayIndex2D(*index1, *index2)]." << name << "(";
04736 else if (dim==(const char*)"3D")
04737 str << " h[CkArrayIndex3D(*index1, *index2, *index3)]." << name << "(";
04738 if (!param->isVoid()) param->printValue(str);
04739 str << ");\n";
04740 str << "}\n";
04741 str << "/* FORTRAN SECTION END */\n";
04742 }
04743
04744
04745
04746
04747 if (isAccel()) {
04748 genAccelIndexWrapperDef_general(str);
04749 #if CMK_CELL != 0
04750 genAccelIndexWrapperDef_spe(str);
04751 #endif
04752 }
04753
04754
04755 str << makeDecl("void")<<"::_call_"<<epStr()<<"(void* impl_msg, void* impl_obj_void)\n";
04756 str << "{\n"
04757 << " " << container->baseName() << "* impl_obj = static_cast<"
04758 << container->baseName() << " *>(impl_obj_void);\n";
04759 if (!isLocal()) {
04760 if(isThreaded()) str << callThread(epStr());
04761 str << preMarshall;
04762 if (param->isMarshalled()) {
04763 if (param->hasConditional()) str << " MarshallMsg_"<<epStr()<<" *impl_msg_typed=(MarshallMsg_"<<epStr()<<" *)impl_msg;\n";
04764 else str << " CkMarshallMsg *impl_msg_typed=(CkMarshallMsg *)impl_msg;\n";
04765 str << " char *impl_buf=impl_msg_typed->msgBuf;\n";
04766 }
04767 genCall(str,preCall);
04768 param->endUnmarshall(str);
04769 str << postCall;
04770 if(isThreaded() && param->isMarshalled()) str << " delete impl_msg_typed;\n";
04771 } else {
04772 str << " CkAbort(\"This method should never be called as it refers to a LOCAL entry method!\");\n";
04773 }
04774 str << "}\n";
04775
04776 if (hasCallMarshall) {
04777 str << makeDecl("int") << "::_callmarshall_" << epStr()
04778 <<"(char* impl_buf, void* impl_obj_void) {\n";
04779 str << " " << containerType << "* impl_obj = static_cast< " << containerType << " *>(impl_obj_void);\n";
04780 if (!isLocal()) {
04781 if (!param->hasConditional()) {
04782 genCall(str,preCall);
04783
04784
04785
04786 str << " return implP.size();\n";
04787 } else {
04788 str << " CkAbort(\"This method is not implemented for EPs using conditional packing\");\n";
04789 str << " return 0;\n";
04790 }
04791 } else {
04792 str << " CkAbort(\"This method should never be called as it refers to a LOCAL entry method!\");\n";
04793 str << " return 0;\n";
04794 }
04795 str << "}\n";
04796 }
04797 if (param->isMarshalled()) {
04798 str << makeDecl("void")<<"::_marshallmessagepup_"<<epStr()<<"(PUP::er &implDestP,void *impl_msg) {\n";
04799 if (!isLocal()) {
04800 if (param->hasConditional()) str << " MarshallMsg_"<<epStr()<<" *impl_msg_typed=(MarshallMsg_"<<epStr()<<" *)impl_msg;\n";
04801 else str << " CkMarshallMsg *impl_msg_typed=(CkMarshallMsg *)impl_msg;\n";
04802 str << " char *impl_buf=impl_msg_typed->msgBuf;\n";
04803 param->beginUnmarshall(str);
04804 param->pupAllValues(str);
04805 } else {
04806 str << " /*Fake pupping since we don't really have a message */\n";
04807 str << " int n=0;\n";
04808 str << " if (implDestP.hasComments()) implDestP.comment(\"LOCAL message\");\n";
04809 str << " implDestP|n;\n";
04810 }
04811 str << "}\n";
04812 }
04813 templateGuardEnd(str);
04814 }
04815
04816 XStr Entry::genRegEp(bool isForRedn)
04817 {
04818 XStr str;
04819 str << "CkRegisterEp(\"";
04820 if (isForRedn)
04821 str << "redn_wrapper_" << name << "(CkReductionMsg *impl_msg)\",\n";
04822 else
04823 str << name << "("<<paramType(0)<<")\",\n";
04824 str << " _call_" << epStr(isForRedn, true);
04825 str << ", ";
04826
04827 if (param->isMarshalled()) {
04828 if (param->hasConditional()) str<<"MarshallMsg_"<<epStr()<<"::__idx";
04829 else str<<"CkMarshallMsg::__idx";
04830 } else if(!param->isVoid() && !(attribs&SMIGRATE)) {
04831 param->genMsgProxyName(str);
04832 str <<"::__idx";
04833 } else if (isForRedn) {
04834 str << "CMessage_CkReductionMsg::__idx";
04835 } else {
04836 str << "0";
04837 }
04838
04839 str << ", __idx";
04840
04841 str << ", 0";
04842
04843
04844
04845
04846 if ( !isForRedn && (attribs & SNOKEEP) ) str << "+CK_EP_NOKEEP";
04847 if (attribs & SNOTRACE) str << "+CK_EP_TRACEDISABLE";
04848 if (attribs & SIMMEDIATE) str << "+CK_EP_TRACEDISABLE";
04849
04850
04851 if (attribs & SMEM) str << "+CK_EP_MEMCRITICAL";
04852
04853 if (internalMode) str << "+CK_EP_INTRINSIC";
04854 str << ")";
04855 return str;
04856 }
04857
04858 void Entry::genReg(XStr& str)
04859 {
04860 if (tspec)
04861 return;
04862
04863 if (external) {
04864 str << " CkIndex_" << label << "::idx_" << name;
04865 if (targs)
04866 str << "< " << targs << " >";
04867 str << "( static_cast< "
04868 << retType << " (" << label << "::*)(" << paramType(0,0) << ") >(NULL) );\n";
04869 return;
04870 }
04871
04872 str << " // REG: "<<*this;
04873 str << " " << epIdx(0) << ";\n";
04874 if (isReductionTarget())
04875 str << " " << epIdx(0, true) << ";\n";
04876 if (isConstructor()) {
04877 if(container->isMainChare()&&!(attribs&SMIGRATE))
04878 str << " CkRegisterMainChare(__idx, "<<epIdx(0)<<");\n";
04879 if(param->isVoid())
04880 str << " CkRegisterDefaultCtor(__idx, "<<epIdx(0)<<");\n";
04881 if(attribs&SMIGRATE)
04882 str << " CkRegisterMigCtor(__idx, "<<epIdx(0)<<");\n";
04883 }
04884 }
04885
04886 void Entry::preprocess() {
04887 ParamList *pl = param;
04888 if (pl != NULL && pl->hasConditional()) {
04889 XStr str;
04890 str << "MarshallMsg_" << epStr();
04891 NamedType *nt = new NamedType(strdup(str));
04892 MsgVar *var = new MsgVar(new BuiltinType("char"), "msgBuf", 0, 1);
04893 MsgVarList *list = new MsgVarList(var);
04894 do {
04895 if (pl->param->isConditional()) {
04896 var = new MsgVar(pl->param->getType(), pl->param->getName(), 1, 0);
04897 list = new MsgVarList(var, list);
04898 }
04899 } while (NULL!=(pl=pl->next));
04900 Message *m = new Message(-1, nt, list);
04901 m->setModule(container->containerModule);
04902 container->containerModule->prependConstruct(m);
04903 }
04904
04905
04906
04907 accel_numScalars = 0;
04908 accel_numArrays = 0;
04909 accel_dmaList_numReadOnly = 0;
04910 accel_dmaList_numReadWrite = 0;
04911 accel_dmaList_numWriteOnly = 0;
04912 accel_dmaList_scalarNeedsWrite = 0;
04913 if (isAccel()) {
04914 ParamList* curParam = param;
04915 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
04916 while (curParam != NULL) {
04917 if (curParam->param->isArray()) {
04918 accel_numArrays++;
04919 accel_dmaList_numReadOnly++;
04920 } else {
04921 accel_numScalars++;
04922 }
04923 curParam = curParam->next;
04924 }
04925 curParam = accelParam;
04926 while (curParam != NULL) {
04927 if (curParam->param->isArray()) {
04928 accel_numArrays++;
04929 switch (curParam->param->getAccelBufferType()) {
04930 case Parameter::ACCEL_BUFFER_TYPE_READWRITE: accel_dmaList_numReadWrite++; break;
04931 case Parameter::ACCEL_BUFFER_TYPE_READONLY: accel_dmaList_numReadOnly++; break;
04932 case Parameter::ACCEL_BUFFER_TYPE_WRITEONLY: accel_dmaList_numWriteOnly++; break;
04933 default: die("Unknown accel param type"); break;
04934 }
04935 } else {
04936 accel_numScalars++;
04937 switch (curParam->param->getAccelBufferType()) {
04938 case Parameter::ACCEL_BUFFER_TYPE_READWRITE: accel_dmaList_scalarNeedsWrite++; break;
04939 case Parameter::ACCEL_BUFFER_TYPE_READONLY: break;
04940 case Parameter::ACCEL_BUFFER_TYPE_WRITEONLY: accel_dmaList_scalarNeedsWrite++; break;
04941 default: die("Unknown accel param type"); break;
04942 }
04943 }
04944 curParam = curParam->next;
04945 }
04946 if (accel_numScalars > 0) {
04947 if (accel_dmaList_scalarNeedsWrite) {
04948 accel_dmaList_numReadWrite++;
04949 } else {
04950 accel_dmaList_numReadOnly++;
04951 }
04952 }
04953 }
04954
04955 }
04956
04957
04958
04959
04960
04961
04962
04963
04964
04965
04966
04967
04968
04969
04970
04971
04972
04973
04974
04975
04976
04977
04978
04979
04980
04981
04982
04983
04984
04985
04986
04987
04988
04989
04990
04991
04992
04993
04994
04995
04996
04997 Parameter::Parameter(int Nline,Type *Ntype,const char *Nname,
04998 const char *NarrLen,Value *Nvalue)
04999 :type(Ntype), name(Nname), arrLen(NarrLen), val(Nvalue),line(Nline)
05000 {
05001 conditional=0;
05002 given_name = Nname;
05003 if (isMessage()) {
05004 name="impl_msg";
05005 }
05006 if (name==NULL && !isVoid())
05007 {
05008 static int unnamedCount=0;
05009 name=new char[50];
05010 sprintf((char *)name,"impl_noname_%x",unnamedCount++);
05011 }
05012 byReference=false;
05013 if ((arrLen==NULL)&&(val==NULL))
05014 {
05015 if (type->isNamed())
05016 {
05017 byReference=true;
05018 }
05019 if (type->isReference()) {
05020 byReference=true;
05021
05022
05023 type=type->deref();
05024 }
05025 }
05026 }
05027
05028 void ParamList::print(XStr &str,int withDefaultValues,int useConst)
05029 {
05030 param->print(str,withDefaultValues,useConst);
05031 if (next) {
05032 str<<", ";
05033 next->print(str,withDefaultValues,useConst);
05034 }
05035 }
05036 void Parameter::print(XStr &str,int withDefaultValues,int useConst)
05037 {
05038 if (arrLen!=NULL)
05039 {
05040 if (useConst) str<<"const ";
05041 str<<type<<" *";
05042 if (name!=NULL) str<<name;
05043 }
05044 else {
05045 if (conditional) {
05046 str<<type<<" *"<<name;
05047 }
05048 else if (byReference)
05049 {
05050 if (useConst) str<<"const ";
05051 str<<type<<" &";
05052 if (name!=NULL) str<<name;
05053 }
05054 else
05055 {
05056 str<<type;
05057 if (name!=NULL) str<<" "<<name;
05058 if (withDefaultValues && val!=NULL)
05059 {str<<" = ";val->print(str);}
05060 }
05061 }
05062 }
05063
05064 void ParamList::printAddress(XStr &str)
05065 {
05066 param->printAddress(str);
05067 if (next) {
05068 str<<", ";
05069 next->printAddress(str);
05070 }
05071 }
05072
05073 void Parameter::printAddress(XStr &str)
05074 {
05075 type->print(str);
05076 str<<"*";
05077 if (name!=NULL)
05078 str<<" "<<name;
05079 }
05080
05081 void ParamList::printValue(XStr &str)
05082 {
05083 param->printValue(str);
05084 if (next) {
05085 str<<", ";
05086 next->printValue(str);
05087 }
05088 }
05089
05090 void Parameter::printValue(XStr &str)
05091 {
05092 if (arrLen==NULL)
05093 str<<"*";
05094 if (name!=NULL)
05095 str<<name;
05096 }
05097
05098 int ParamList::orEach(pred_t f)
05099 {
05100 ParamList *cur=this;
05101 int ret=0;
05102 do {
05103 ret|=((cur->param)->*f)();
05104 } while (NULL!=(cur=cur->next));
05105 return ret;
05106 }
05107
05108 void ParamList::callEach(fn_t f,XStr &str)
05109 {
05110 ParamList *cur=this;
05111 do {
05112 ((cur->param)->*f)(str);
05113 } while (NULL!=(cur=cur->next));
05114 }
05115
05116 int ParamList::hasConditional() {
05117 return orEach(&Parameter::isConditional);
05118 }
05119
05121 void ParamList::marshall(XStr &str, XStr &entry)
05122 {
05123 if (isVoid())
05124 str<<" void *impl_msg = CkAllocSysMsg();\n";
05125 else if (isMarshalled())
05126 {
05127 str<<" //Marshall: ";print(str,0);str<<"\n";
05128
05129 str<<" int impl_off=0;\n";
05130 int hasArrays=orEach(&Parameter::isArray);
05131 if (hasArrays) {
05132 str<<" int impl_arrstart=0;\n";
05133 callEach(&Parameter::marshallArraySizes,str);
05134 }
05135 str<<" { //Find the size of the PUP'd data\n";
05136 str<<" PUP::sizer implP;\n";
05137 callEach(&Parameter::pup,str);
05138 if (hasArrays)
05139 {
05140 str<<" impl_arrstart=CK_ALIGN(implP.size(),16);\n";
05141 str<<" impl_off+=impl_arrstart;\n";
05142 }
05143 else
05144 str<<" impl_off+=implP.size();\n";
05145 str<<" }\n";
05146
05147 if (hasConditional()) str<<" MarshallMsg_"<<entry<<" *impl_msg=CkAllocateMarshallMsgT<MarshallMsg_"<<entry<<" >(impl_off,impl_e_opts);\n";
05148 else str<<" CkMarshallMsg *impl_msg=CkAllocateMarshallMsg(impl_off,impl_e_opts);\n";
05149
05150 str<<" { //Copy over the PUP'd data\n";
05151 str<<" PUP::toMem implP((void *)impl_msg->msgBuf);\n";
05152 callEach(&Parameter::pup,str);
05153 callEach(&Parameter::copyPtr,str);
05154 str<<" }\n";
05155 if (hasArrays)
05156 {
05157 str<<" char *impl_buf=impl_msg->msgBuf+impl_arrstart;\n";
05158 callEach(&Parameter::marshallArrayData,str);
05159 }
05160 }
05161 }
05162 void Parameter::marshallArraySizes(XStr &str)
05163 {
05164 Type *dt=type->deref();
05165 if (dt->isPointer())
05166 die("can't pass pointers across processors--\n"
05167 "Indicate the array length with []'s, or pass a reference",line);
05168 if (isArray()) {
05169 str<<" int impl_off_"<<name<<", impl_cnt_"<<name<<";\n";
05170 str<<" impl_off_"<<name<<"=impl_off=CK_ALIGN(impl_off,sizeof("<<dt<<"));\n";
05171 str<<" impl_off+=(impl_cnt_"<<name<<"=sizeof("<<dt<<")*("<<arrLen<<"));\n";
05172 }
05173 }
05174 void Parameter::pup(XStr &str) {
05175 if (isArray()) {
05176 str<<" implP|impl_off_"<<name<<";\n";
05177 str<<" implP|impl_cnt_"<<name<<";\n";
05178 }
05179 else if (!conditional) {
05180 if (byReference) {
05181 str<<" //Have to cast away const-ness to get pup routine\n";
05182 str<<" implP|("<<type<<" &)"<<name<<";\n";
05183 }
05184 else
05185 str<<" implP|"<<name<<";\n";
05186 }
05187 }
05188 void Parameter::marshallArrayData(XStr &str)
05189 {
05190 if (isArray())
05191 str<<" memcpy(impl_buf+impl_off_"<<name<<
05192 ","<<name<<",impl_cnt_"<<name<<");\n";
05193 }
05194 void Parameter::copyPtr(XStr &str)
05195 {
05196 if (isConditional()) {
05197 str<<" impl_msg->"<<name<<"="<<name<<";\n";
05198 }
05199 }
05200
05201 void ParamList::beginRednWrapperUnmarshall(XStr &str)
05202 {
05203 if (isMarshalled())
05204 {
05205 str<<" /*Unmarshall pup'd fields: ";print(str,0);str<<"*/\n";
05206 str<<" PUP::fromMem implP(impl_buf);\n";
05207 if (next != NULL && next->next == NULL) {
05208 if (isArray()) {
05209 Type* dt = next->param->type->deref();
05210 str << " " << dt << " " << next->param->name << "; "
05211 << next->param->name << " = "
05212 << "((CkReductionMsg*)impl_msg)->getLength() / sizeof("
05213 << param->type->deref() << ");\n";
05214 dt = param->type->deref();
05215 str << " " << dt << "* " << param->name << "; "
05216 << param->name << " = (" << dt << "*)impl_buf;\n";
05217 } else if (next->isArray()) {
05218 Type* dt = param->type->deref();
05219 str << " " << dt << " " << param->name << "; "
05220 << param->name << " = "
05221 << "((CkReductionMsg*)impl_msg)->getLength() / sizeof("
05222 << next->param->type->deref() << ");\n";
05223 dt = next->param->type->deref();
05224 str << " " << dt << "* " << next->param->name << "; "
05225 << next->param->name << " = (" << dt << "*)impl_buf;\n";
05226 } else {
05227 callEach(&Parameter::beginUnmarshall,str);
05228 }
05229 } else {
05230 str << " /* non two-param case */\n";
05231 callEach(&Parameter::beginUnmarshall,str);
05232 str<<" impl_buf+=CK_ALIGN(implP.size(),16);\n";
05233 str<<" /*Unmarshall arrays:*/\n";
05234 callEach(&Parameter::unmarshallArrayData,str);
05235 }
05236 }
05237 }
05238
05240 void ParamList::beginUnmarshall(XStr &str)
05241 {
05242 if (isMarshalled())
05243 {
05244 str<<" /*Unmarshall pup'd fields: ";print(str,0);str<<"*/\n";
05245 str<<" PUP::fromMem implP(impl_buf);\n";
05246 callEach(&Parameter::beginUnmarshall,str);
05247 str<<" impl_buf+=CK_ALIGN(implP.size(),16);\n";
05248 str<<" /*Unmarshall arrays:*/\n";
05249 callEach(&Parameter::unmarshallArrayData,str);
05250 }
05251 else if (isVoid()) {str<<" CkFreeSysMsg(impl_msg);\n";}
05252 }
05253 void Parameter::beginUnmarshall(XStr &str)
05254 {
05255 Type *dt=type->deref();
05256 if (isArray()) {
05257 str<<" int impl_off_"<<name<<", impl_cnt_"<<name<<"; \n";
05258 str<<" implP|impl_off_"<<name<<";\n";
05259 str<<" implP|impl_cnt_"<<name<<";\n";
05260 }
05261 else if (isConditional())
05262 str<<" "<<dt<<" *"<<name<<"=impl_msg_typed->"<<name<<";\n";
05263 else
05264 str<<" "<<dt<<" "<<name<<"; implP|"<<name<<";\n";
05265 }
05266 void Parameter::unmarshallArrayData(XStr &str)
05267 {
05268 if (isArray()) {
05269 Type *dt=type->deref();
05270 str<<" "<<dt<<" *"<<name<<"=("<<dt<<" *)(impl_buf+impl_off_"<<name<<");\n";
05271 }
05272 }
05273 void ParamList::unmarshall(XStr &str, int isFirst)
05274 {
05275 if (isFirst && isMessage()) str<<"("<<param->type<<")impl_msg";
05276 else if (!isVoid()) {
05277 str<<param->getName();
05278 if (next) {
05279 str<<", ";
05280 next->unmarshall(str, 0);
05281 }
05282 }
05283 }
05284 void ParamList::unmarshallAddress(XStr &str, int isFirst)
05285 {
05286 if (isFirst && isMessage()) str<<"("<<param->type<<")impl_msg";
05287 else if (!isVoid()) {
05288 if (param->isArray()) str<<param->getName();
05289 else str<<"& "<<param->getName();
05290 if (next) {
05291 str<<", ";
05292 next->unmarshallAddress(str, 0);
05293 }
05294 }
05295 }
05296 void ParamList::pupAllValues(XStr &str) {
05297 if (isMarshalled())
05298 callEach(&Parameter::pupAllValues,str);
05299 }
05300 void Parameter::pupAllValues(XStr &str) {
05301 str<<" if (implDestP.hasComments()) implDestP.comment(\""<<name<<"\");\n";
05302 if (isArray()) {
05303 str<<
05304 " implDestP.synchronize(PUP::sync_begin_array);\n"
05305 " { for (int impl_i=0;impl_i*(sizeof(*"<<name<<"))<impl_cnt_"<<name<<";impl_i++) { \n"
05306 " implDestP.synchronize(PUP::sync_item);\n"
05307 " implDestP|"<<name<<"[impl_i];\n"
05308 " } } \n"
05309 " implDestP.synchronize(PUP::sync_end_array);\n"
05310 ;
05311 }
05312 else {
05313 if (isConditional()) str<<" pup_pointer(&implDestP, (void**)&"<<name<<");\n";
05314 else str<<" implDestP|"<<name<<";\n";
05315 }
05316 }
05317 void ParamList::endUnmarshall(XStr &)
05318 {
05319
05320
05321
05322
05323
05324 }
05325
05326
05327 InitCall::InitCall(int l, const char *n, int nodeCall)
05328 : name(n)
05329 {
05330 line=l; setChare(0); isNodeCall=nodeCall;
05331
05332
05333 isAccelFlag = 0;
05334 }
05335 void InitCall::print(XStr& str)
05336 {
05337 str<<" initcall void "<<name<<"(void);\n";
05338 }
05339 void InitCall::genReg(XStr& str)
05340 {
05341 str<<" _registerInitCall(";
05342 if (container)
05343 str<<container->baseName()<<"::";
05344 str<<name;
05345 str<<","<<isNodeCall<<");\n";
05346 }
05347
05348 void InitCall::genAccels_spe_c_callInits(XStr& str) {
05349 if (isAccel()) {
05350 str << " " << name << "();\n";
05351 }
05352 }
05353
05354
05355
05356 PUPableClass::PUPableClass(int l, NamedType* type_,PUPableClass *next_)
05357 : type(type_), next(next_)
05358 {
05359 line=l; setChare(0);
05360 }
05361 void PUPableClass::print(XStr& str)
05362 {
05363 str << " PUPable " << type <<";\n";
05364 if (next) next->print(str);
05365 }
05366 void PUPableClass::genDefs(XStr& str)
05367 {
05368 if (type->isTemplated()) {
05369 templateGuardBegin(true, str);
05370 str << " #define _CHARMXI_CLASS_NAME " << type << "\n";
05371 str << " PUPable_def_template(_CHARMXI_CLASS_NAME)\n";
05372 str << " #undef _CHARMXI_CLASS_NAME\n";
05373 templateGuardEnd(str);
05374 } else {
05375 str<<" PUPable_def(" << type << ")\n";
05376 }
05377 if (next) next->genDefs(str);
05378 }
05379 void PUPableClass::genReg(XStr& str)
05380 {
05381 if (type->isTemplated()) {
05382 str<<" #define _CHARMXI_CLASS_NAME " << type << "\n";
05383 str<<" PUPable_reg2(_CHARMXI_CLASS_NAME,\"" << type << "\");\n";
05384 str<<" #undef _CHARMXI_CLASS_NAME\n";
05385 } else {
05386 str<<" PUPable_reg(" << type << ");\n";
05387 }
05388 if (next) next->genReg(str);
05389 }
05390
05391
05392
05393 IncludeFile::IncludeFile(int l, const char *n)
05394 : name(n)
05395 {
05396 line=l; setChare(0);
05397 }
05398 void IncludeFile::print(XStr& str)
05399 {
05400 str<<" include "<<name<<";\n";
05401 }
05402 void IncludeFile::genDecls(XStr& str) {
05403 str<<"#include "<<name<<"\n";
05404 }
05405
05406
05407
05408 ClassDeclaration::ClassDeclaration(int l, const char *n)
05409 : name(n)
05410 {
05411 line=l; setChare(0);
05412 }
05413 void ClassDeclaration::print(XStr& str)
05414 {
05415 str<<" class "<<name<<";\n";
05416 }
05417 void ClassDeclaration::genDecls(XStr& str) {
05418 str<<"class "<<name<<";\n";
05419 }
05420
05421
05422
05423
05424 }