00001 #include "xi-Chare.h"
00002 #include "xi-Entry.h"
00003 #include "xi-Parameter.h"
00004 #include "xi-SdagCollection.h"
00005 #include "xi-Value.h"
00006
00007 #include "sdag/constructs/When.h"
00008
00009 #include <list>
00010 using std::list;
00011
00012 namespace xi {
00013
00014 extern int fortranMode;
00015 extern int internalMode;
00016 const char* python_doc;
00017
00018 XStr Entry::proxyName(void) { return container->proxyName(); }
00019 XStr Entry::indexName(void) { return container->indexName(); }
00020
00021 void Entry::print(XStr& str) {
00022 if (isThreaded()) str << "threaded ";
00023 if (isSync()) str << "sync ";
00024 if (retType) {
00025 retType->print(str);
00026 str << " ";
00027 }
00028 str << name << "(";
00029 if (param) param->print(str);
00030 str << ")";
00031 if (stacksize) {
00032 str << " stacksize = ";
00033 stacksize->print(str);
00034 }
00035 str << ";\n";
00036 }
00037
00038 void Entry::check() {
00039 if (!external) {
00040 if (isConstructor() && retType && !retType->isVoid())
00041 XLAT_ERROR_NOCOL("constructors cannot return a value", first_line_);
00042
00043 if (!isConstructor() && !retType)
00044 XLAT_ERROR_NOCOL(
00045 "non-constructor entry methods must specify a return type (probably void)",
00046 first_line_);
00047
00048 if (isConstructor() && (isSync() || isIget())) {
00049 XLAT_ERROR_NOCOL("constructors cannot have the 'sync' attribute", first_line_);
00050 attribs ^= SSYNC;
00051 }
00052
00053 if (param->isCkArgMsgPtr() && (!isConstructor() || !container->isMainChare()))
00054 XLAT_ERROR_NOCOL("CkArgMsg can only be used in mainchare's constructor",
00055 first_line_);
00056
00057 if (isExclusive() && isConstructor())
00058 XLAT_ERROR_NOCOL("constructors cannot be 'exclusive'", first_line_);
00059
00060 if (isImmediate() && !container->isNodeGroup())
00061 XLAT_ERROR_NOCOL("[immediate] entry methods are only allowed on 'nodegroup' types",
00062 first_line_);
00063
00064 if (isLocal() && (container->isChare() || container->isNodeGroup()))
00065 XLAT_ERROR_NOCOL(
00066 "[local] entry methods are only allowed on 'array' and 'group' types",
00067 first_line_);
00068 }
00069
00070 if (!isThreaded() && stacksize)
00071 XLAT_ERROR_NOCOL(
00072 "the 'stacksize' attribute is only applicable to methods declared 'threaded'",
00073 first_line_);
00074
00075 if (retType && !isSync() && !isIget() && !isLocal() && !retType->isVoid())
00076 XLAT_ERROR_NOCOL(
00077 "non-void return type in a non-sync/non-local entry method\n"
00078 "To return non-void, you need to declare the method as [sync], which means it "
00079 "has blocking semantics,"
00080 " or [local].",
00081 first_line_);
00082
00083 if (!isLocal() && param) param->checkParamList();
00084
00085 if (isPython() && !container->isPython())
00086 XLAT_ERROR_NOCOL("python entry method declared in non-python chare", first_line_);
00087
00088
00089 if (isPython() && (!param || param->next || !param->param->getType()->isBuiltin() ||
00090 !((BuiltinType*)param->param->getType())->isInt()))
00091 XLAT_ERROR_NOCOL(
00092 "python entry methods take only one parameter, which is of type 'int'",
00093 first_line_);
00094
00095 if (isExclusive() && !container->isNodeGroup())
00096 XLAT_ERROR_NOCOL("only nodegroup methods can be 'exclusive'", first_line_);
00097
00098
00099
00100 if (isSdag()) {
00101 list<CEntry*> whenEntryList;
00102 sdagCon->generateEntryList(whenEntryList, NULL);
00103
00104 containsWhenConstruct = !whenEntryList.empty();
00105
00106 for (list<CEntry*>::iterator en = whenEntryList.begin(); en != whenEntryList.end();
00107 ++en) {
00108 container->lookforCEntry(*en);
00109 (*en)->check();
00110 }
00111 }
00112
00113 if (isTramTarget()) {
00114 if (param && (!param->isMarshalled() || param->isVoid() || param->next != NULL))
00115 XLAT_ERROR_NOCOL(
00116 "'aggregate' entry methods must be parameter-marshalled "
00117 "and take a single argument",
00118 first_line_);
00119
00120 if (!external && !((container->isGroup() && !container->isNodeGroup()) || container->isArray()))
00121 XLAT_ERROR_NOCOL(
00122 "'aggregate' entry methods can only be used in regular groups and chare arrays",
00123 first_line_);
00124 }
00125 }
00126
00127 void Entry::lookforCEntry(CEntry* centry) {
00128
00129 if (strcmp(name, *centry->entry) != 0) return;
00130
00131 centry->addCandidate(this);
00132
00133
00134 if (param && !centry->paramlist) return;
00135 if (!param && centry->paramlist) return;
00136 if (param && !(*param == *centry->paramlist)) return;
00137
00138 isWhenEntry = 1;
00139 centry->decl_entry = this;
00140 }
00141
00142 Entry::Entry(int l, int a, Type* r, const char* n, ParamList* p, Value* sz,
00143 SdagConstruct* sc, const char* e, int fl, int ll)
00144 : attribs(a),
00145 retType(r),
00146 stacksize(sz),
00147 sdagCon(sc),
00148 name((char*)n),
00149 targs(0),
00150 intExpr(e),
00151 param(p),
00152 genClosureTypeName(0),
00153 genClosureTypeNameProxy(0),
00154 genClosureTypeNameProxyTemp(0),
00155 entryPtr(0),
00156 first_line_(fl),
00157 last_line_(ll),
00158 numRdmaSendParams(0),
00159 numRdmaRecvParams(0) {
00160 line = l;
00161 container = NULL;
00162 entryCount = -1;
00163 isWhenEntry = 0;
00164 containsWhenConstruct = false;
00165 if (param && param->isMarshalled() && !isThreaded()) attribs |= SNOKEEP;
00166
00167 if (isPython()) pythonDoc = python_doc;
00168 ParamList* plist = p;
00169 while (plist != NULL) {
00170 plist->entry = this;
00171 if (plist->param) {
00172 plist->param->entry = this;
00173 if (plist->param->getRdma() == CMK_ZC_P2P_SEND_MSG)
00174 numRdmaSendParams++;
00175 if (plist->param->getRdma() == CMK_ZC_P2P_RECV_MSG)
00176 numRdmaRecvParams++;
00177 }
00178 plist = plist->next;
00179 }
00180 }
00181
00182 void Entry::setChare(Chare* c) {
00183 Member::setChare(c);
00184
00185
00186
00187
00188
00189
00190
00191
00192 if (isConstructor() && param->isVoid()) {
00193 if (container->isMainChare()) {
00194
00195 Type* t = new PtrType(new NamedType("CkArgMsg"));
00196 param = new ParamList(new Parameter(line, t));
00197 std::cerr << "Charmxi> " << line
00198 << ": Deprecation warning: mainchare constructors should explicitly take "
00199 "CkArgMsg* if that's how they're implemented.\n";
00200 }
00201 if (container->isArray()) {
00202 Array* a = dynamic_cast<Array*>(c);
00203 a->hasVoidConstructor = true;
00204 }
00205 }
00206
00207 entryCount = c->nextEntry();
00208
00209
00210 hasCallMarshall = param->isMarshalled() && !isThreaded() && !isSync() &&
00211 !isExclusive() && !fortranMode;
00212 if (isSdag()) {
00213 container->setSdag(1);
00214
00215 list<CEntry*> whenEntryList;
00216 sdagCon->generateEntryList(whenEntryList, NULL);
00217
00218 for (list<CEntry*>::iterator i = whenEntryList.begin(); i != whenEntryList.end();
00219 ++i) {
00220 container->lookforCEntry(*i);
00221 }
00222 }
00223 }
00224
00225 void Entry::preprocessSDAG() {
00226 if (isSdag() || isWhenEntry) {
00227 if (container->isNodeGroup()) {
00228 attribs |= SLOCKED;
00229
00230 }
00231 }
00232 }
00233
00234
00235
00236 XStr Entry::paramType(int withDefaultVals, int withEO, int useConst, int rValue) {
00237 XStr str;
00238 param->print(str, withDefaultVals, useConst, rValue);
00239 if (withEO) str << eo(withDefaultVals, !param->isVoid());
00240 return str;
00241 }
00242
00243
00244
00245 XStr Entry::paramComma(int withDefaultVals, int withEO) {
00246 XStr str;
00247 if (!param->isVoid()) {
00248 str << paramType(withDefaultVals, withEO);
00249 str << ", ";
00250 }
00251 return str;
00252 }
00253 XStr Entry::eo(int withDefaultVals, int priorComma) {
00254 XStr str;
00255
00256
00257 if (!param->isMessage()) {
00258 if (priorComma) str << ", ";
00259 str << "const CkEntryOptions *impl_e_opts";
00260 if (withDefaultVals) str << "=NULL";
00261 }
00262 return str;
00263 }
00264
00265 void Entry::collectSdagCode(SdagCollection* sc) {
00266 if (isSdag()) {
00267 sc->addNode(this);
00268 }
00269 }
00270
00271 XStr Entry::marshallMsg(void) {
00272 XStr ret;
00273 XStr epName = epStr();
00274 param->marshall(ret, epName);
00275 return ret;
00276 }
00277
00278 XStr Entry::epStr(bool isForRedn, bool templateCall) {
00279 XStr str;
00280 if (isForRedn) str << "redn_wrapper_";
00281 str << name << "_";
00282
00283 if (param->isMessage()) {
00284 str << param->getBaseName();
00285 str.replace(':', '_');
00286 } else if (param->isVoid())
00287 str << "void";
00288 else
00289 str << "marshall" << entryCount;
00290
00291 if (tspec && templateCall) {
00292 str << "<";
00293 tspec->genShort(str);
00294 str << ">";
00295 }
00296
00297 return str;
00298 }
00299
00300 XStr Entry::epIdx(int fromProxy, bool isForRedn) {
00301 XStr str;
00302 if (fromProxy) {
00303 str << indexName() << "::";
00304
00305 if (tspec) str << "template ";
00306 }
00307 str << "idx_" << epStr(isForRedn, true) << "()";
00308 return str;
00309 }
00310
00311 XStr Entry::epRegFn(int fromProxy, bool isForRedn) {
00312 XStr str;
00313 if (fromProxy) str << indexName() << "::";
00314 str << "reg_" << epStr(isForRedn, true) << "()";
00315 return str;
00316 }
00317
00318 XStr Entry::chareIdx(int fromProxy) {
00319 XStr str;
00320 if (fromProxy) str << indexName() << "::";
00321 str << "__idx";
00322 return str;
00323 }
00324
00325 XStr Entry::syncPreCall(void) {
00326 XStr str;
00327 if (retType->isVoid())
00328 str << " void *impl_msg_typed_ret = ";
00329 else if (retType->isMessage())
00330 str << " " << retType << " impl_msg_typed_ret = (" << retType << ")";
00331 else
00332 str << " CkMarshallMsg *impl_msg_typed_ret = (CkMarshallMsg *)";
00333 return str;
00334 }
00335
00336 XStr Entry::syncPostCall(void) {
00337 XStr str;
00338 if (retType->isVoid())
00339 str << " CkFreeSysMsg(impl_msg_typed_ret); \n";
00340 else if (!retType->isMessage()) {
00341 str << " char *impl_buf_ret=impl_msg_typed_ret->msgBuf; \n";
00342 str << " PUP::fromMem implPS(impl_buf_ret); \n";
00343 str << " " << retType << " retval; implPS|retval; \n";
00344 str << " CkFreeMsg(impl_msg_typed_ret); \n";
00345 str << " return retval; \n";
00346 } else {
00347 str << " return impl_msg_typed_ret;\n";
00348 }
00349 return str;
00350 }
00351
00352
00353
00354 void Entry::genChareDecl(XStr& str) {
00355 if (isConstructor()) {
00356 genChareStaticConstructorDecl(str);
00357 } else {
00358
00359 str << " " << generateTemplateSpec(tspec) << "\n"
00360 << " " << retType << " " << name << "(" << paramType(1, 1) << ");\n";
00361 }
00362 }
00363
00364 void Entry::genChareDefs(XStr& str) {
00365 if (isConstructor()) {
00366 genChareStaticConstructorDefs(str);
00367 } else {
00368 XStr params;
00369 params << epIdx() << ", impl_msg, &ckGetChareID()";
00370
00371 XStr retStr;
00372 retStr << retType;
00373 str << makeDecl(retStr, 1) << "::" << name << "(" << paramType(0, 1) << ")\n";
00374 str << "{\n ckCheck();\n";
00375 str << marshallMsg();
00376 if (isSync()) {
00377 str << syncPreCall() << "CkRemoteCall(" << params << ");\n";
00378 str << syncPostCall();
00379 } else {
00380 str << " if (ckIsDelegated()) {\n";
00381 if (param->hasRdma()) {
00382 str << " CkAbort(\"Entry methods with nocopy parameters not supported when "
00383 "called with delegation managers\");\n";
00384 } else {
00385 str << " int destPE=CkChareMsgPrep(" << params << ");\n";
00386 str << " if (destPE!=-1) ckDelegatedTo()->ChareSend(ckDelegatedPtr(),"
00387 << params << ",destPE);\n";
00388 }
00389 str << " } else {\n";
00390 XStr opts;
00391 opts << ",0";
00392 if (isSkipscheduler()) opts << "+CK_MSG_EXPEDITED";
00393 if (isInline()) opts << "+CK_MSG_INLINE";
00394 str << " CkSendMsg(" << params << opts << ");\n";
00395 str << " }\n";
00396 }
00397 str << "}\n";
00398 }
00399 }
00400
00401 void Entry::genChareStaticConstructorDecl(XStr& str) {
00402 str << " static CkChareID ckNew(" << paramComma(1) << "int onPE=CK_PE_ANY" << eo(1)
00403 << ");\n";
00404 str << " static void ckNew(" << paramComma(1)
00405 << "CkChareID* pcid, int onPE=CK_PE_ANY" << eo(1) << ");\n";
00406 if (!param->isVoid())
00407 str << " " << container->proxyName(0) << "(" << paramComma(1)
00408 << "int onPE=CK_PE_ANY" << eo(1) << ");\n";
00409 }
00410
00411 void Entry::genChareStaticConstructorDefs(XStr& str) {
00412 str << makeDecl("CkChareID", 1) << "::ckNew(" << paramComma(0) << "int impl_onPE"
00413 << eo(0) << ")\n";
00414 str << "{\n";
00415 str << marshallMsg();
00416 str << " CkChareID impl_ret;\n";
00417 str << " CkCreateChare(" << chareIdx() << ", " << epIdx()
00418 << ", impl_msg, &impl_ret, impl_onPE);\n";
00419 str << " return impl_ret;\n";
00420 str << "}\n";
00421
00422 str << makeDecl("void", 1) << "::ckNew(" << paramComma(0)
00423 << "CkChareID* pcid, int impl_onPE" << eo(0) << ")\n";
00424 str << "{\n";
00425 str << marshallMsg();
00426 str << " CkCreateChare(" << chareIdx() << ", " << epIdx()
00427 << ", impl_msg, pcid, impl_onPE);\n";
00428 str << "}\n";
00429
00430 if (!param->isVoid()) {
00431 str << makeDecl(" ", 1) << "::" << container->proxyName(0) << "(" << paramComma(0)
00432 << "int impl_onPE" << eo(0) << ")\n";
00433 str << "{\n";
00434 str << marshallMsg();
00435 str << " CkChareID impl_ret;\n";
00436 str << " CkCreateChare(" << chareIdx() << ", " << epIdx()
00437 << ", impl_msg, &impl_ret, impl_onPE);\n";
00438 str << " ckSetChareID(impl_ret);\n";
00439 str << "}\n";
00440 }
00441 }
00442
00443
00444
00445 void Entry::genArrayDecl(XStr& str) {
00446 if (isConstructor()) {
00447 str << " " << generateTemplateSpec(tspec) << "\n";
00448 genArrayStaticConstructorDecl(str);
00449 } else {
00450 if ((isSync() || isLocal()) && !container->isForElement())
00451 return;
00452 if (isIget()) {
00453 str << " " << generateTemplateSpec(tspec) << "\n";
00454 str << " "
00455 << "CkFutureID"
00456 << " " << name << "(" << paramType(1, 1) << ") ;\n";
00457 } else if ((isLocal() || isInline()) && container->isForElement()) {
00458 XStr fwdStr;
00459 int fwdNum = 1;
00460 ParamList *pl = param;
00461 while (pl) {
00462 Parameter *p = pl->param;
00463 if (!p->isRdma() && p->arrLen == NULL && !p->conditional && p->byReference) {
00464 if (fwdNum > 1)
00465 fwdStr << ", ";
00466 fwdStr << "typename Fwd" << fwdNum++ << " = " << p->type;
00467 }
00468 pl = pl->next;
00469 }
00470 const bool doFwd = fwdNum > 1;
00471 if (tspec || doFwd) {
00472 str << " template <";
00473 if (tspec) {
00474 tspec->genLong(str);
00475 if (doFwd)
00476 str << ", ";
00477 }
00478 if (doFwd)
00479 str << fwdStr;
00480 str << ">\n";
00481 }
00482 str << " " << retType << " " << name << "(" << paramType(1, 1, 0, 1) << ") ;\n";
00483 } else if (isLocal()) {
00484 str << " " << generateTemplateSpec(tspec) << "\n";
00485 str << " " << retType << " " << name << "(" << paramType(1, 1, 0) << ") ;\n";
00486 } else if (isTramTarget() && container->isForElement()) {
00487 str << " " << generateTemplateSpec(tspec) << "\n";
00488 str << " " << retType << " " << name << "(" << paramType(0, 1) << ") = delete;\n";
00489 str << " " << retType << " " << name << "(" << paramType(1, 0) << ") ;\n";
00490 } else {
00491 str << " " << generateTemplateSpec(tspec) << "\n";
00492 str << " " << retType << " " << name << "(" << paramType(1, 1)
00493 << ") ;\n";
00494 }
00495 }
00496 }
00497
00498 void Entry::genArrayDefs(XStr& str) {
00499 if (isIget() && !container->isForElement()) return;
00500
00501 if (isConstructor())
00502 genArrayStaticConstructorDefs(str);
00503 else {
00504 const char* ifNot = "CkArray_IfNotThere_buffer";
00505 if (isCreateHere()) ifNot = "CkArray_IfNotThere_createhere";
00506 if (isCreateHome()) ifNot = "CkArray_IfNotThere_createhome";
00507
00508 if ((isSync() || isLocal()) && !container->isForElement())
00509 return;
00510
00511 XStr retStr;
00512 retStr << retType;
00513 if (isIget())
00514 str << makeDecl("CkFutureID ", 1) << "::" << name << "(" << paramType(0, 1)
00515 << ") \n";
00516 else if ((isLocal() || isInline()) && container->isForElement()) {
00517 XStr fwdStr;
00518 int fwdNum = 1;
00519 ParamList *pl = param;
00520 while (pl) {
00521 Parameter *p = pl->param;
00522 if (!p->isRdma() && p->arrLen == NULL && !p->conditional && p->byReference) {
00523 if (fwdNum > 1)
00524 fwdStr << ", ";
00525 fwdStr << "typename Fwd" << fwdNum++;
00526 }
00527 pl = pl->next;
00528 }
00529 str << makeDecl(retStr, 1, false, fwdStr) << "::" << name << "(" << paramType(0, 1, 0, 1) << ") \n";
00530 } else if (isLocal())
00531 str << makeDecl(retStr, 1) << "::" << name << "(" << paramType(0, 1, 0) << ") \n";
00532 else
00533 str << makeDecl(retStr, 1) << "::" << name << "(" << paramType(0, 1)
00534 << ") \n";
00535 str << "{\n";
00536
00537 str << " ckCheck();\n";
00538 XStr inlineCall;
00539 if (!isNoTrace())
00540 inlineCall
00541 << " _TRACE_BEGIN_EXECUTE_DETAILED(0,ForArrayEltMsg,(" << epIdx()
00542 << "),CkMyPe(), 0, ((CkArrayIndex&)ckGetIndex()).getProjectionID(), obj);\n";
00543 if (isAppWork()) inlineCall << " _TRACE_BEGIN_APPWORK();\n";
00544 inlineCall << "#if CMK_LBDB_ON\n"
00545 << " LDObjHandle objHandle;\n"
00546 << " int objstopped=0;\n"
00547 << " objHandle = obj->timingBeforeCall(&objstopped);\n"
00548 << "#endif\n";
00549 inlineCall << "#if CMK_CHARMDEBUG\n"
00550 " CpdBeforeEp("
00551 << epIdx()
00552 << ", obj, NULL);\n"
00553 "#endif\n";
00554 inlineCall << " ";
00555 if (!retType->isVoid()) inlineCall << retType << " retValue = ";
00556 inlineCall << "obj->" << (tspec ? "template " : "") << name;
00557 if (tspec) {
00558 inlineCall << "<";
00559 tspec->genShort(inlineCall);
00560 inlineCall << ">";
00561 }
00562 inlineCall << "(";
00563 param->unmarshallForward(inlineCall, true);
00564 inlineCall << ");\n";
00565 inlineCall << "#if CMK_CHARMDEBUG\n"
00566 " CpdAfterEp("
00567 << epIdx()
00568 << ");\n"
00569 "#endif\n";
00570 inlineCall << "#if CMK_LBDB_ON\n "
00571 "obj->timingAfterCall(objHandle,&objstopped);\n#endif\n";
00572 if (isAppWork()) inlineCall << " _TRACE_END_APPWORK();\n";
00573 if (!isNoTrace()) inlineCall << " _TRACE_END_EXECUTE();\n";
00574 if (!retType->isVoid()) {
00575 inlineCall << " return retValue;\n";
00576 } else {
00577 inlineCall << " return;\n";
00578 }
00579
00580 XStr prepareMsg;
00581 prepareMsg << marshallMsg();
00582 prepareMsg << " UsrToEnv(impl_msg)->setMsgtype(ForArrayEltMsg);\n";
00583 prepareMsg << " CkArrayMessage *impl_amsg=(CkArrayMessage *)impl_msg;\n";
00584 prepareMsg << " impl_amsg->array_setIfNotThere(" << ifNot << ");\n";
00585
00586 if (!isLocal()) {
00587 if (isInline() && container->isForElement()) {
00588 str << " " << container->baseName() << " *obj = ckLocal();\n";
00589 str << " if (obj) {\n" << inlineCall << " }\n";
00590 }
00591 str << prepareMsg;
00592 } else {
00593 str << " " << container->baseName() << " *obj = ckLocal();\n";
00594 str << "#if CMK_ERROR_CHECKING\n";
00595 str << " if (obj==NULL) CkAbort(\"Trying to call a LOCAL entry method on a "
00596 "non-local element\");\n";
00597 str << "#endif\n";
00598 str << inlineCall;
00599 }
00600 if (isIget()) {
00601 str << " CkFutureID f=CkCreateAttachedFutureSend(impl_amsg," << epIdx()
00602 << ",ckGetArrayID(),ckGetIndex(),&CProxyElement_ArrayBase::ckSendWrapper);"
00603 << "\n";
00604 }
00605
00606 if (isSync()) {
00607 str << syncPreCall() << "ckSendSync(impl_amsg, " << epIdx() << ");\n";
00608 str << syncPostCall();
00609 } else if (!isLocal()) {
00610 XStr opts;
00611 opts << ",0";
00612 if (isSkipscheduler()) opts << "+CK_MSG_EXPEDITED";
00613 if (isInline()) opts << "+CK_MSG_INLINE";
00614 if (!isIget()) {
00615 if (container->isForElement() || container->isForSection()) {
00616 str << " ckSend(impl_amsg, " << epIdx() << opts << ");\n";
00617 } else
00618 str << " ckBroadcast(impl_amsg, " << epIdx() << opts << ");\n";
00619 }
00620 }
00621 if (isIget()) {
00622 str << " return f;\n";
00623 }
00624 str << "}\n";
00625
00626 if (!tspec && !container->isTemplated() && !isIget() && (isLocal() || isInline()) && container->isForElement()) {
00627 XStr fwdStr;
00628 int fwdNum = 1;
00629 ParamList *pl = param;
00630 while (pl) {
00631 Parameter *p = pl->param;
00632 if (!p->isRdma() && p->arrLen == NULL && !p->conditional && p->byReference) {
00633 if (fwdNum > 1)
00634 fwdStr << ", ";
00635 ++fwdNum;
00636 if (p->byConst) fwdStr << "const ";
00637 fwdStr << p->type << " &";
00638 }
00639 pl = pl->next;
00640 }
00641 const bool doFwd = fwdNum > 1;
00642 if (doFwd) {
00643 str << "// explicit instantiation for compatibility\n";
00644 str << "template " << makeDecl(retStr, 1) << "::" << name << "<" << fwdStr << ">(" << paramType(0, 1, 0) << ");\n";
00645 }
00646 }
00647 }
00648 }
00649
00650 void Entry::genArrayStaticConstructorDecl(XStr& str) {
00651 if (!container->isArray())
00652 die("Internal error - array declarations called for on non-array Chare type");
00653
00654 if (container->getForWhom() == forIndividual)
00655 str <<
00656 " void insert(" << paramComma(1, 0) << "int onPE=-1" << eo(1) << ");";
00657 else if (container->getForWhom() == forAll) {
00658
00659
00660 str << " static CkArrayID ckNew(" << paramComma(1, 0)
00661 << "const CkArrayOptions &opts = CkArrayOptions()" << eo(1) << ");\n";
00662 str << " static void ckNew(" << paramComma(1, 0)
00663 << "const CkArrayOptions &opts, CkCallback _ck_array_creation_cb" << eo(1)
00664 << ");\n";
00665
00666 XStr dim = ((Array*)container)->dim();
00667 if (dim == (const char*)"1D") {
00668 str << " static CkArrayID ckNew(" << paramComma(1, 0) << "const int s1" << eo(1)
00669 << ");\n";
00670 str << " static void ckNew(" << paramComma(1, 0)
00671 << "const int s1, CkCallback _ck_array_creation_cb" << eo(1) << ");\n";
00672 } else if (dim == (const char*)"2D") {
00673 str << " static CkArrayID ckNew(" << paramComma(1, 0)
00674 << "const int s1, const int s2" << eo(1) << ");\n";
00675 str << " static void ckNew(" << paramComma(1, 0)
00676 << "const int s1, const int s2, CkCallback _ck_array_creation_cb" << eo(1)
00677 << ");\n";
00678 } else if (dim == (const char*)"3D") {
00679 str << " static CkArrayID ckNew(" << paramComma(1, 0)
00680 << "const int s1, const int s2, const int s3" << eo(1) << ");\n";
00681 str << " static void ckNew(" << paramComma(1, 0)
00682 << "const int s1, const int s2, const int s3, CkCallback _ck_array_creation_cb"
00683 << eo(1) << ");\n";
00684
00685
00686
00687
00688
00689
00690
00691
00692 }
00693 } else if (container->getForWhom() == forSection) {
00694 }
00695 }
00696
00697 void Entry::genArrayStaticConstructorDefs(XStr& str) {
00698 if (!container->isArray())
00699 die("Internal error - array definitions called for on non-array Chare type");
00700
00701 if (container->getForWhom() == forIndividual)
00702 str << makeDecl("void", 1) << "::insert(" << paramComma(0, 0) << "int onPE" << eo(0)
00703 << ")\n"
00704 "{ \n "
00705 << marshallMsg()
00706 << " UsrToEnv(impl_msg)->setMsgtype(ArrayEltInitMsg);\n"
00707 " ckInsert((CkArrayMessage *)impl_msg,"
00708 << epIdx() << ",onPE);\n}\n";
00709 else if (container->getForWhom() == forAll) {
00710 XStr syncPrototype, asyncPrototype, head, syncTail, asyncTail;
00711 syncPrototype << makeDecl("CkArrayID", 1) << "::ckNew";
00712 asyncPrototype << makeDecl("void", 1) << "::ckNew";
00713
00714 head << "{\n" << marshallMsg();
00715
00716 syncTail << " UsrToEnv(impl_msg)->setMsgtype(ArrayEltInitMsg);\n"
00717 << " CkArrayID gId = ckCreateArray((CkArrayMessage *)impl_msg, " << epIdx()
00718 << ", opts);\n";
00719
00720 genTramInstantiation(syncTail);
00721 syncTail << " return gId;\n}\n";
00722
00723 asyncTail << " UsrToEnv(impl_msg)->setMsgtype(ArrayEltInitMsg);\n"
00724 << " CkSendAsyncCreateArray(" << epIdx()
00725 << ", _ck_array_creation_cb, opts, impl_msg);\n"
00726 << "}\n";
00727
00728 str << syncPrototype << "(" << paramComma(0) << "const CkArrayOptions &opts" << eo(0)
00729 << ")\n"
00730 << head << syncTail;
00731 str << asyncPrototype << "(" << paramComma(0)
00732 << "const CkArrayOptions &opts, CkCallback _ck_array_creation_cb" << eo(0)
00733 << ")\n"
00734 << head << asyncTail;
00735
00736 XStr dim = ((Array*)container)->dim();
00737 XStr sizeParams, sizeArgs;
00738 bool emit = true;
00739
00740 if (dim == (const char*)"1D") {
00741 sizeParams << "const int s1";
00742 sizeArgs << "s1";
00743 } else if (dim == (const char*)"2D") {
00744 sizeParams << "const int s1, const int s2";
00745 sizeArgs << "s1, s2";
00746 } else if (dim == (const char*)"3D") {
00747 sizeParams << "const int s1, const int s2, const int s3";
00748 sizeArgs << "s1, s2, s3";
00749 }
00750 #if 0
00751 else if (dim==(const char*)"4D") {
00752 sizeParams << "const short s1, const short s2, const short s3, const short s4";
00753 sizeArgs << "s1, s2, s3, s4";
00754 } else if (dim==(const char*)"5D") {
00755 sizeParams << "const short s1, const short s2, const short s3, const short s4, "
00756 << "const short s5";
00757 sizeArgs << "s1, s2, s3, s4, s5";
00758 } else if (dim==(const char*)"6D") {
00759 sizeParams << "const short s1, const short s2, const short s3, const short s4, "
00760 << "const short s5, const short s6";
00761 sizeArgs << "s1, s2, s3, s4, s5, s6";
00762 }
00763 #endif
00764 else {
00765 emit = false;
00766 }
00767
00768 if (emit) {
00769 str << syncPrototype << "(" << paramComma(0) << sizeParams << eo(0) << ")\n"
00770 << head << " CkArrayOptions opts(" << sizeArgs << ");\n"
00771 << syncTail;
00772 str << asyncPrototype << "(" << paramComma(0) << sizeParams
00773 << ", CkCallback _ck_array_creation_cb" << eo(0) << ")\n"
00774 << head << " CkArrayOptions opts(" << sizeArgs << ");\n"
00775 << asyncTail;
00776 }
00777 }
00778 }
00779
00780
00781
00782 void Entry::genGroupDecl(XStr& str) {
00783 if (isConstructor()) {
00784 str << " " << generateTemplateSpec(tspec) << "\n";
00785 genGroupStaticConstructorDecl(str);
00786 } else {
00787 if ((isSync() || isLocal()) && !container->isForElement())
00788 return;
00789 str << " " << generateTemplateSpec(tspec) << "\n";
00790 if (isLocal()) {
00791 str << " " << retType << " " << name << "(" << paramType(1, 1, 0) << ");\n";
00792 } else if (isTramTarget() && container->isForElement()) {
00793 str << " " << retType << " " << name << "(" << paramType(0, 1) << ") = delete;\n";
00794 str << " " << retType << " " << name << "(" << paramType(1, 0) << ");\n";
00795 } else {
00796 str << " " << retType << " " << name << "(" << paramType(1, 1) << ");\n";
00797 }
00798
00799 if (!container->isForElement() && !container->isForSection() && !isSync() &&
00800 !isLocal() && !container->isNodeGroup()) {
00801 str << " " << generateTemplateSpec(tspec) << "\n";
00802 str << " " << retType << " " << name << "(" << paramComma(0, 0)
00803 << "int npes, int *pes" << eo(1) << ");\n";
00804 str << " " << generateTemplateSpec(tspec) << "\n";
00805 str << " " << retType << " " << name << "(" << paramComma(0, 0)
00806 << "CmiGroup &grp" << eo(1) << ");\n";
00807 }
00808 }
00809 }
00810
00811 void Entry::genGroupDefs(XStr& str) {
00812 if(isConstructor()) {
00813 genGroupStaticConstructorDefs(str);
00814 return;
00815 }
00816
00817
00818 char* node = (char*)(container->isNodeGroup() ? "Node" : "");
00819
00820 int forElement = container->isForElement();
00821 XStr params;
00822 params << epIdx() << ", impl_msg";
00823 XStr paramg;
00824 paramg << epIdx() << ", impl_msg, ckGetGroupID()";
00825 XStr parampg;
00826 parampg << epIdx() << ", impl_msg, ckGetGroupPe(), ckGetGroupID()";
00827
00828 XStr opts;
00829 opts << ",0";
00830 if (isImmediate()) opts << "+CK_MSG_IMMEDIATE";
00831 if (isInline()) opts << "+CK_MSG_INLINE";
00832 if (isSkipscheduler()) opts << "+CK_MSG_EXPEDITED";
00833
00834 if ((isSync() || isLocal()) && !container->isForElement())
00835 return;
00836
00837 XStr retStr;
00838 retStr << retType;
00839 XStr msgTypeStr;
00840 if (isLocal())
00841 msgTypeStr << paramType(0, 1, 0);
00842 else
00843 msgTypeStr << paramType(0, 1);
00844 str << makeDecl(retStr, 1) << "::" << name << "(" << msgTypeStr << ")\n";
00845 str << "{\n";
00846
00847 str << " ckCheck();\n";
00848 if (!isLocal()) str << marshallMsg();
00849
00850 if (isLocal()) {
00851 XStr unmarshallStr;
00852 param->unmarshall(unmarshallStr, true);
00853 str << " " << container->baseName() << " *obj = ckLocalBranch();\n";
00854 str << " CkAssert(obj);\n";
00855 if (!isNoTrace())
00856
00857
00858 str << " envelope env;\n"
00859 << " env.setMsgtype(ForBocMsg);\n"
00860 << " env.setTotalsize(0);\n"
00861 << " _TRACE_CREATION_DETAILED(&env, " << epIdx() << ");\n"
00862 << " _TRACE_CREATION_DONE(1);\n"
00863 << " _TRACE_BEGIN_EXECUTE_DETAILED(CpvAccess(curPeEvent),ForBocMsg,(" << epIdx()
00864 << "),CkMyPe(),0,NULL, NULL);\n";
00865 if (isAppWork()) str << " _TRACE_BEGIN_APPWORK();\n";
00866 str << "#if CMK_LBDB_ON\n"
00867 " // if there is a running obj being measured, stop it temporarily\n"
00868 " LDObjHandle objHandle;\n"
00869 " int objstopped = 0;\n"
00870 " LBDatabase *the_lbdb = (LBDatabase *)CkLocalBranch(_lbdb);\n"
00871 " if (the_lbdb->RunningObject(&objHandle)) {\n"
00872 " objstopped = 1;\n"
00873 " the_lbdb->ObjectStop(objHandle);\n"
00874 " }\n"
00875 "#endif\n";
00876 str << "#if CMK_CHARMDEBUG\n"
00877 " CpdBeforeEp("
00878 << epIdx()
00879 << ", obj, NULL);\n"
00880 "#endif\n ";
00881 if (!retType->isVoid()) str << retType << " retValue = ";
00882 str << "obj->" << name << "(" << unmarshallStr << ");\n";
00883 str << "#if CMK_CHARMDEBUG\n"
00884 " CpdAfterEp("
00885 << epIdx()
00886 << ");\n"
00887 "#endif\n";
00888 str << "#if CMK_LBDB_ON\n"
00889 " if (objstopped) the_lbdb->ObjectStart(objHandle);\n"
00890 "#endif\n";
00891 if (isAppWork()) str << " _TRACE_END_APPWORK();\n";
00892 if (!isNoTrace()) str << " _TRACE_END_EXECUTE();\n";
00893 if (!retType->isVoid()) str << " return retValue;\n";
00894 } else if (isSync()) {
00895 str << syncPreCall() << "CkRemote" << node << "BranchCall(" << paramg
00896 << ", ckGetGroupPe());\n";
00897 str << syncPostCall();
00898 } else {
00899 if (forElement) {
00900 str << " if (ckIsDelegated()) {\n";
00901 if (param->hasRdma()) {
00902 str << " CkAbort(\"Entry methods with nocopy parameters not supported "
00903 "when called with delegation managers\");\n";
00904 } else {
00905 str << " Ck" << node << "GroupMsgPrep(" << paramg << ");\n";
00906 str << " ckDelegatedTo()->" << node << "GroupSend(ckDelegatedPtr(),"
00907 << parampg << ");\n";
00908 }
00909 str << " } else {\n";
00910 str << " CkSendMsg" << node << "Branch"
00911 << "(" << parampg << opts << ");\n";
00912 str << " }\n";
00913 } else if (container->isForSection()) {
00914 str << " if (ckIsDelegated()) {\n";
00915 str << " ckDelegatedTo()->" << node << "GroupSectionSend(ckDelegatedPtr(),"
00916 << params << ", ckGetNumSections(), ckGetSectionIDs());\n";
00917 str << " } else {\n";
00918 str << " void *impl_msg_tmp;\n";
00919 str << " for (int i=0; i<ckGetNumSections(); ++i) {\n";
00920 str << " impl_msg_tmp= (i<ckGetNumSections()-1) ? CkCopyMsg((void **) "
00921 "&impl_msg):impl_msg;\n";
00922 str << " CkSendMsg" << node << "BranchMulti(" << epIdx()
00923 << ", impl_msg_tmp, ckGetGroupIDn(i), ckGetNumElements(i), ckGetElements(i)"
00924 << opts << ");\n";
00925 str << " }\n";
00926 str << " }\n";
00927 } else {
00928 str << " if (ckIsDelegated()) {\n";
00929 str << " Ck" << node << "GroupMsgPrep(" << paramg << ");\n";
00930 str << " ckDelegatedTo()->" << node << "GroupBroadcast(ckDelegatedPtr(),"
00931 << paramg << ");\n";
00932 str << " } else CkBroadcastMsg" << node << "Branch(" << paramg << opts
00933 << ");\n";
00934 }
00935 }
00936 str << "}\n";
00937
00938
00939 if (!forElement && !container->isForSection() && !isSync() && !isLocal() &&
00940 !container->isNodeGroup()) {
00941 str << "" << makeDecl(retStr, 1) << "::" << name << "(" << paramComma(0, 0)
00942 << "int npes, int *pes" << eo(0) << ") {\n";
00943 str << marshallMsg();
00944 str << " CkSendMsg" << node << "BranchMulti(" << paramg << ", npes, pes" << opts
00945 << ");\n";
00946 str << "}\n";
00947 str << "" << makeDecl(retStr, 1) << "::" << name << "(" << paramComma(0, 0)
00948 << "CmiGroup &grp" << eo(0) << ") {\n";
00949 str << marshallMsg();
00950 str << " CkSendMsg" << node << "BranchGroup(" << paramg << ", grp" << opts
00951 << ");\n";
00952 str << "}\n";
00953 }
00954 }
00955
00956 XStr Entry::aggregatorIndexType() {
00957 XStr indexType;
00958 if (container->isGroup()) {
00959 indexType << "int";
00960 } else if (container->isArray()) {
00961 XStr dim, arrayIndexType;
00962 dim << ((Array*)container)->dim();
00963 indexType << "CkArrayIndex";
00964 }
00965 return indexType;
00966 }
00967
00968 XStr Entry::dataItemType() {
00969 XStr itemType;
00970 if (container->isGroup()) {
00971 itemType << param->param->type;
00972 } else if (container->isArray()) {
00973 itemType << "ArrayDataItem<" << param->param->type << ", " << aggregatorIndexType()
00974 << ">";
00975 }
00976 return itemType;
00977 }
00978
00979 XStr Entry::aggregatorType() {
00980 XStr groupType;
00981 if (container->isGroup()) {
00982 groupType << "GroupMeshStreamer<" << param->param->type << ", "
00983 << container->baseName() << ", SimpleMeshRouter"
00984 << ", " << container->indexName() << "::_callmarshall_" << epStr() << ">";
00985 } else if (container->isArray()) {
00986 groupType << "ArrayMeshStreamer<" << param->param->type << ", "
00987 << aggregatorIndexType() << ", " << container->baseName() << ", "
00988 << "SimpleMeshRouter, " << container->indexName() << "::_callmarshall_"
00989 << epStr() << ">";
00990 }
00991 return groupType;
00992 }
00993
00994 XStr Entry::aggregatorGlobalType(XStr& scope) {
00995 XStr groupType;
00996 if (container->isGroup()) {
00997 groupType << "GroupMeshStreamer<" << param->param->type << ", " << scope
00998 << container->baseName() << ", SimpleMeshRouter"
00999 << ", " << scope << container->indexName() << "::_callmarshall_" << epStr()
01000 << ">";
01001 } else if (container->isArray()) {
01002 groupType << "ArrayMeshStreamer<" << param->param->type << ", "
01003 << aggregatorIndexType() << ", " << scope << container->baseName() << ", "
01004 << "SimpleMeshRouter, " << scope << container->indexName()
01005 << "::_callmarshall_" << epStr() << ">";
01006 }
01007 return groupType;
01008 }
01009
01010 XStr Entry::aggregatorName() {
01011 XStr aggregatorName;
01012 aggregatorName << epStr() << "TramAggregator";
01013 return aggregatorName;
01014 }
01015
01016 void Entry::genTramTypes() {
01017 if (isTramTarget()) {
01018 XStr typeString, nameString, itemTypeString;
01019 typeString << aggregatorType();
01020 nameString << aggregatorName();
01021 itemTypeString << dataItemType();
01022 #if __cplusplus >= 201103L
01023 container->tramInstances.emplace_back(
01024 typeString.get_string(), nameString.get_string(), itemTypeString.get_string());
01025 #else
01026 container->tramInstances.push_back(TramInfo(
01027 typeString.get_string(), nameString.get_string(), itemTypeString.get_string()));
01028 #endif
01029 tramInstanceIndex = container->tramInstances.size();
01030 }
01031 }
01032
01033 void Entry::genTramDefs(XStr& str) {
01034 XStr retStr;
01035 retStr << retType;
01036 XStr msgTypeStr;
01037
01038 if (isLocal())
01039 msgTypeStr << paramType(0, 0, 0);
01040 else
01041 msgTypeStr << paramType(0, 0);
01042 str << makeDecl(retStr, 1) << "::" << name << "(" << msgTypeStr << ") {\n"
01043 << " if (" << aggregatorName() << " == NULL) {\n";
01044
01045 if (container->isGroup()) {
01046 str << " CkGroupID gId = ckGetGroupID();\n";
01047 } else if (container->isArray()) {
01048 str << " CkArray *aMgr = ckLocalBranch();\n"
01049 << " CkGroupID gId = aMgr->getGroupID();\n";
01050 }
01051
01052 str << " CkGroupID tramGid;\n"
01053 << " tramGid.idx = gId.idx + " << tramInstanceIndex << ";\n"
01054 << " " << aggregatorName() << " = (" << aggregatorType() << "*)"
01055 << " CkLocalBranch(tramGid);\n }\n";
01056
01057 if (container->isGroup()) {
01058 str << " " << aggregatorName() << "->insertData(" << param->param->name << ", "
01059 << "ckGetGroupPe());\n}\n";
01060 } else if (container->isArray()) {
01061 XStr dim;
01062 dim << ((Array*)container)->dim();
01063 str << " const CkArrayIndex &myIndex = ckGetIndex();\n"
01064 << " " << aggregatorName() << "->insertData<" << (isInline() ? "true" : "false")
01065 << ">(" << param->param->name;
01066 str << ", " << "myIndex);\n}\n";
01067 }
01068 }
01069
01070
01071 const static int tramBufferSize = 16384;
01072
01073 void Entry::genTramInstantiation(XStr& str) {
01074 if (!container->tramInstances.empty()) {
01075 str << " int pesPerNode = CkMyNodeSize();\n"
01076 << " if (pesPerNode == 1) {\n"
01077 << " pesPerNode = CmiNumCores();\n"
01078 << " }\n"
01079 << " const int nDims = 2;\n"
01080 << " int dims[nDims];\n"
01081 << " dims[0] = CkNumPes() / pesPerNode;\n"
01082 << " dims[1] = pesPerNode;\n"
01083 << " if (dims[0] * dims[1] != CkNumPes()) {\n"
01084 << " dims[0] = CkNumPes();\n"
01085 << " dims[1] = 1;\n"
01086 << " }\n"
01087 << " int tramBufferSize = " << tramBufferSize << ";\n";
01088 for (int i = 0; i < container->tramInstances.size(); i++) {
01089 str << " {\n"
01090 << " int itemsPerBuffer = tramBufferSize / sizeof("
01091 << container->tramInstances[i].itemType.c_str() << ");\n"
01092 << " if (itemsPerBuffer == 0) {\n"
01093 << " itemsPerBuffer = 1;\n"
01094 << " }\n"
01095 << " CProxy_" << container->tramInstances[i].type.c_str() << " tramProxy =\n"
01096 << " CProxy_" << container->tramInstances[i].type.c_str()
01097 << "::ckNew(2, dims, gId, itemsPerBuffer, false, 10.0);\n"
01098 << " tramProxy.enablePeriodicFlushing();\n"
01099 << " }\n";
01100 }
01101 }
01102 }
01103
01104 XStr Entry::tramBaseType() {
01105 XStr baseTypeString;
01106 baseTypeString << "MeshStreamer<" << dataItemType() << ", SimpleMeshRouter>";
01107
01108 return baseTypeString;
01109 }
01110
01111 void Entry::genTramRegs(XStr& str) {
01112 if (isTramTarget()) {
01113 XStr messageTypeString;
01114 messageTypeString << "MeshStreamerMessage<" << dataItemType() << ">";
01115
01116 XStr baseTypeString = tramBaseType();
01117
01118 NamedType messageType(messageTypeString.get_string());
01119 Message helper(-1, &messageType);
01120 helper.genReg(str);
01121
01122 str << "\n /* REG: group " << aggregatorType() << ": IrrGroup;\n */\n"
01123 << " CkIndex_" << aggregatorType() << "::__register(\"" << aggregatorType()
01124 << "\", sizeof(" << aggregatorType() << "));\n"
01125 << " /* REG: group " << baseTypeString << ": IrrGroup;\n */\n"
01126 << " CkIndex_" << baseTypeString << "::__register(\"" << baseTypeString
01127 << "\", sizeof(" << baseTypeString << "));\n";
01128 }
01129 }
01130
01131 void Entry::genTramPups(XStr& scope, XStr& decls, XStr& defs) {
01132 if (isTramTarget()) {
01133 XStr aggregatorTypeString = aggregatorGlobalType(scope);
01134 container->genRecursivePup(aggregatorTypeString, "template <>\n", decls, defs);
01135 }
01136 }
01137
01138 void Entry::genGroupStaticConstructorDecl(XStr& str) {
01139 if (container->isForElement()) return;
01140 if (container->isForSection()) return;
01141
01142 str << " static CkGroupID ckNew(" << paramType(1, 1) << ");\n";
01143 if (!param->isVoid()) {
01144 str << " " << container->proxyName(0) << "(" << paramType(1, 1) << ");\n";
01145 }
01146 }
01147
01148 void Entry::genGroupStaticConstructorDefs(XStr& str) {
01149 if (container->isForElement()) return;
01150 if (container->isForSection()) return;
01151
01152
01153 char* node = (char*)(container->isNodeGroup() ? "Node" : "");
01154 str << makeDecl("CkGroupID", 1) << "::ckNew(" << paramType(0, 1) << ")\n";
01155 str << "{\n";
01156 str << marshallMsg();
01157 str << " UsrToEnv(impl_msg)->setMsgtype(" << node << "BocInitMsg);\n";
01158 str << " CkGroupID gId = CkCreate" << node << "Group(" << chareIdx() << ", " << epIdx()
01159 << ", impl_msg);\n";
01160
01161 genTramInstantiation(str);
01162
01163 str << " return gId;\n";
01164 str << "}\n";
01165
01166 if (!param->isVoid()) {
01167 str << makeDecl(" ", 1) << "::" << container->proxyName(0) << "(" << paramType(0, 1)
01168 << ")\n";
01169 str << "{\n";
01170 str << marshallMsg();
01171 str << " UsrToEnv(impl_msg)->setMsgtype(" << node << "BocInitMsg);\n";
01172 str << " ckSetGroupID(CkCreate" << node << "Group(" << chareIdx() << ", " << epIdx()
01173 << ", impl_msg));\n";
01174 str << "}\n";
01175 }
01176 }
01177
01178
01179 void Entry::genPythonDecls(XStr& str) {
01180 str << "/* STATIC DECLS: ";
01181 print(str);
01182 str << " */\n";
01183 if (isPython()) {
01184 str << "PyObject *_Python_" << container->baseName() << "_" << name
01185 << "(PyObject *self, PyObject *arg);\n";
01186 }
01187 }
01188
01189 void Entry::genPythonDefs(XStr& str) {
01190 str << "/* DEFS: ";
01191 print(str);
01192 str << " */\n";
01193 if (isPython()) {
01194 str << "PyObject *_Python_" << container->baseName() << "_" << name
01195 << "(PyObject *self, PyObject *arg) {\n";
01196 str << " PyObject *dict = PyModule_GetDict(PyImport_AddModule(\"__main__\"));\n";
01197 str << " int pyNumber = "
01198 "PyInt_AsLong(PyDict_GetItemString(dict,\"__charmNumber__\"));\n";
01199 str << " PythonObject *pythonObj = (PythonObject "
01200 "*)PyLong_AsVoidPtr(PyDict_GetItemString(dict,\"__charmObject__\"));\n";
01201 str << " " << container->baseName() << " *object = static_cast<"
01202 << container->baseName() << "*>(pythonObj);\n";
01203 str << " object->pyWorkers[pyNumber].arg=arg;\n";
01204 str << " object->pyWorkers[pyNumber].result=&CtvAccess(pythonReturnValue);\n";
01205 str << " object->pyWorkers[pyNumber].pythread=PyThreadState_Get();\n";
01206 str << " CtvAccess(pythonReturnValue) = 0;\n";
01207
01208 str << " //pyWorker->thisProxy." << name << "(pyNumber);\n";
01209 str << " object->" << name << "(pyNumber);\n";
01210
01211 str << " //CthSuspend();\n";
01212
01213 str << " if (CtvAccess(pythonReturnValue)) {\n";
01214 str << " return CtvAccess(pythonReturnValue);\n";
01215 str << " } else {\n";
01216 str << " Py_INCREF(Py_None); return Py_None;\n";
01217 str << " }\n";
01218 str << "}\n";
01219 }
01220 }
01221
01222 void Entry::genPythonStaticDefs(XStr& str) {
01223 if (isPython()) {
01224 str << " {\"" << name << "\",_Python_" << container->baseName() << "_" << name
01225 << ",METH_VARARGS},\n";
01226 }
01227 }
01228
01229 void Entry::genPythonStaticDocs(XStr& str) {
01230 if (isPython()) {
01231 str << "\n \"" << name << " -- \"";
01232 if (pythonDoc) str << (char*)pythonDoc;
01233 str << "\"\\\\n\"";
01234 }
01235 }
01236
01237
01238
01239 void Entry::genAccelFullParamList(XStr& str, int makeRefs) {
01240 if (!isAccel()) return;
01241
01242 ParamList* curParam = NULL;
01243 int isFirst = 1;
01244
01245
01246 curParam = param;
01247 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01248 curParam = curParam->next;
01249 }
01250 while (curParam != NULL) {
01251 if (!isFirst) {
01252 str << ", ";
01253 }
01254
01255 Parameter* param = curParam->param;
01256
01257 if (param->isArray()) {
01258 str << param->getType()->getBaseName() << "* " << param->getName();
01259 } else {
01260 str << param->getType()->getBaseName() << " " << param->getName();
01261 }
01262
01263 isFirst = 0;
01264 curParam = curParam->next;
01265 }
01266
01267
01268 curParam = accelParam;
01269 while (curParam != NULL) {
01270 if (!isFirst) {
01271 str << ", ";
01272 }
01273
01274 Parameter* param = curParam->param;
01275 int bufType = param->getAccelBufferType();
01276 int needWrite = makeRefs && ((bufType == Parameter::ACCEL_BUFFER_TYPE_READWRITE) ||
01277 (bufType == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY));
01278 if (param->isArray()) {
01279 str << param->getType()->getBaseName() << "* " << param->getName();
01280 } else {
01281 str << param->getType()->getBaseName() << ((needWrite) ? (" &") : (" "))
01282 << param->getName();
01283 }
01284
01285 isFirst = 0;
01286 curParam = curParam->next;
01287 }
01288
01289
01290 if (!isFirst) {
01291 str << ", ";
01292 }
01293 str << container->baseName() << "* impl_obj";
01294 }
01295
01296 void Entry::genAccelFullCallList(XStr& str) {
01297 if (!isAccel()) return;
01298
01299 int isFirstFlag = 1;
01300
01301
01302 ParamList* curParam = param;
01303 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01304 curParam = curParam->next;
01305 }
01306 while (curParam != NULL) {
01307 if (!isFirstFlag) str << ", ";
01308 isFirstFlag = 0;
01309 str << curParam->param->getName();
01310 curParam = curParam->next;
01311 }
01312
01313
01314
01315 curParam = accelParam;
01316 while (curParam != NULL) {
01317 if (!isFirstFlag) str << ", ";
01318 isFirstFlag = 0;
01319 str << (*(curParam->param->getAccelInstName()));
01320 curParam = curParam->next;
01321 }
01322
01323
01324 if (!isFirstFlag) str << ", ";
01325 isFirstFlag = 0;
01326 str << "impl_obj";
01327 }
01328
01329 void Entry::genAccelIndexWrapperDecl_general(XStr& str) {
01330 str << " static void _accelCall_general_" << epStr() << "(";
01331 genAccelFullParamList(str, 1);
01332 str << ");\n";
01333 }
01334
01335 void Entry::genAccelIndexWrapperDef_general(XStr& str) {
01336 str << makeDecl("void") << "::_accelCall_general_" << epStr() << "(";
01337 genAccelFullParamList(str, 1);
01338 str << ") {\n\n";
01339
01341
01342
01343
01344
01345
01346 str << (*accelCodeBody);
01347
01348 str << "\n\n";
01349 str << " impl_obj->" << (*accelCallbackName) << "();\n";
01350 str << "}\n";
01351 }
01352
01353 void Entry::genAccelIndexWrapperDecl_spe(XStr& str) {
01354
01355 str << " static void _accelCall_spe_" << epStr() << "(";
01356 genAccelFullParamList(str, 0);
01357 str << ");\n";
01358
01359
01360 str << " static void _accelCall_spe_callback_" << epStr() << "(void* userPtr);\n";
01361 }
01362
01363
01364 #if CMK_CELL != 0
01365 #include "spert.h"
01366 #endif
01367
01368 void Entry::genAccelIndexWrapperDef_spe(XStr& str) {
01369 XStr containerType = container->baseName();
01370
01371
01372 str << "\n\n";
01373
01375
01376 str << "typedef struct __spe_callback_struct_" << epStr() << " {\n"
01377 << " " << containerType << "* impl_obj;\n"
01378 << " WRHandle wrHandle;\n"
01379 << " void* scalar_buf_ptr;\n";
01380
01381
01382 ParamList* curParam = param;
01383 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01384 curParam = curParam->next;
01385 }
01386 while (curParam != NULL) {
01387 if (curParam->param->isArray()) {
01388 str << " void* param_buf_ptr_" << curParam->param->getName() << ";\n";
01389 }
01390 curParam = curParam->next;
01391 }
01392 curParam = accelParam;
01393 while (curParam != NULL) {
01394 if (curParam->param->isArray()) {
01395 str << " void* accelParam_buf_ptr_" << curParam->param->getName() << ";\n";
01396 }
01397 curParam = curParam->next;
01398 }
01399
01400 str << "} SpeCallbackStruct_" << epStr() << ";\n\n";
01401
01403
01404 str << "void _accelCall_spe_callback_" << container->baseName() << "_" << epStr()
01405 << "(void* userPtr) {\n"
01406 << " " << container->indexName() << "::_accelCall_spe_callback_" << epStr()
01407 << "(userPtr);\n"
01408 << "}\n";
01409
01410 str << makeDecl("void") << "::_accelCall_spe_callback_" << epStr()
01411 << "(void* userPtr) {\n";
01412 str << " SpeCallbackStruct_" << epStr() << "* cbStruct = (SpeCallbackStruct_"
01413 << epStr() << "*)userPtr;\n";
01414 str << " " << containerType << "* impl_obj = cbStruct->impl_obj;\n";
01415
01416
01417
01418 if (accel_numScalars > 0) {
01419
01420 int dmaList_scalarBufIndex = 0;
01421 if (accel_dmaList_scalarNeedsWrite) {
01422 dmaList_scalarBufIndex += accel_dmaList_numReadOnly;
01423 }
01424 str << " char* __scalar_buf_offset = (char*)(cbStruct->scalar_buf_ptr);\n";
01425
01426
01427 curParam = param;
01428 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01429 curParam = curParam->next;
01430 }
01431 while (curParam != NULL) {
01432 if (!(curParam->param->isArray())) {
01433 str << " __scalar_buf_offset += sizeof("
01434 << curParam->param->getType()->getBaseName() << ");\n";
01435 }
01436 curParam = curParam->next;
01437 }
01438
01439
01440 curParam = accelParam;
01441 while (curParam != NULL) {
01442 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01443 Parameter::ACCEL_BUFFER_TYPE_READONLY)) {
01444 str << " __scalar_buf_offset += sizeof("
01445 << curParam->param->getType()->getBaseName() << ");\n";
01446 }
01447 curParam = curParam->next;
01448 }
01449
01450
01451 curParam = accelParam;
01452 while (curParam != NULL) {
01453 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01454 Parameter::ACCEL_BUFFER_TYPE_READWRITE)) {
01455 str << " " << (*(curParam->param->getAccelInstName())) << " = *(("
01456 << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01457 str << " __scalar_buf_offset += sizeof("
01458 << curParam->param->getType()->getBaseName() << ");\n";
01459 }
01460 curParam = curParam->next;
01461 }
01462
01463
01464 curParam = accelParam;
01465 while (curParam != NULL) {
01466 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01467 Parameter::ACCEL_BUFFER_TYPE_WRITEONLY)) {
01468 str << " " << (*(curParam->param->getAccelInstName())) << " = *(("
01469 << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01470 str << " __scalar_buf_offset += sizeof("
01471 << curParam->param->getType()->getBaseName() << ");\n";
01472 }
01473 curParam = curParam->next;
01474 }
01475 }
01476
01477
01478 str << " (cbStruct->impl_obj)->" << (*accelCallbackName) << "();\n";
01479
01480
01481 str << " if (cbStruct->scalar_buf_ptr != NULL) { "
01482 "free_aligned(cbStruct->scalar_buf_ptr); }\n";
01483 curParam = param;
01484 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01485 curParam = curParam->next;
01486 }
01487 while (curParam != NULL) {
01488 if (curParam->param->isArray()) {
01489 str << " if (cbStruct->param_buf_ptr_" << curParam->param->getName()
01490 << " != NULL) { "
01491 << "free_aligned(cbStruct->param_buf_ptr_" << curParam->param->getName()
01492 << "); "
01493 << "}\n";
01494 }
01495 curParam = curParam->next;
01496 }
01497 str << " delete cbStruct;\n";
01498
01499 str << "}\n\n";
01500
01502
01503 str << makeDecl("void") << "::_accelCall_spe_" << epStr() << "(";
01504 genAccelFullParamList(str, 0);
01505 str << ") {\n\n";
01506
01508
01509
01510
01511
01512
01513
01514 str << " // Allocate a user structure to be passed to the callback function\n"
01515 << " SpeCallbackStruct_" << epStr() << "* cbStruct = new SpeCallbackStruct_"
01516 << epStr() << ";\n"
01517 << " cbStruct->impl_obj = impl_obj;\n"
01518 << " cbStruct->wrHandle = INVALID_WRHandle; // NOTE: Set actual value later...\n"
01519 << " cbStruct->scalar_buf_ptr = NULL;\n";
01520
01521 curParam = param;
01522 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01523 curParam = curParam->next;
01524 }
01525 while (curParam != NULL) {
01526 if (curParam->param->isArray()) {
01527 str << " cbStruct->param_buf_ptr_" << curParam->param->getName() << " = NULL;\n";
01528 }
01529 curParam = curParam->next;
01530 }
01531 curParam = accelParam;
01532 while (curParam != NULL) {
01533 if (curParam->param->isArray()) {
01534 str << " cbStruct->accelParam_buf_ptr_" << curParam->param->getName()
01535 << " = NULL;\n";
01536 }
01537 curParam = curParam->next;
01538 }
01539 str << "\n";
01540
01541
01542 int dmaList_curIndex = 0;
01543 int numDMAListEntries = accel_numArrays;
01544 if (accel_numScalars > 0) {
01545 numDMAListEntries++;
01546 }
01547 if (numDMAListEntries <= 0) {
01548 XLAT_ERROR_NOCOL("accel entry with no parameters", first_line_);
01549 }
01550
01551
01552
01553
01554
01555
01556 #if CMK_CELL != 0
01557 if (numDMAListEntries > SPE_DMA_LIST_LENGTH) {
01558 die("Accel entries do not support parameter lists of length > SPE_DMA_LIST_LENGTH "
01559 "yet... fix me...");
01560 }
01561 #endif
01562
01563
01564 if (accel_numScalars > 0) {
01565 str << " // Create a single buffer to hold all the scalar values\n";
01566 str << " int scalar_buf_len = 0;\n";
01567 curParam = param;
01568 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01569 curParam = curParam->next;
01570 }
01571 while (curParam != NULL) {
01572 if (!(curParam->param->isArray())) {
01573 str << " scalar_buf_len += sizeof(" << curParam->param->getType()->getBaseName()
01574 << ");\n";
01575 }
01576 curParam = curParam->next;
01577 }
01578 curParam = accelParam;
01579 while (curParam != NULL) {
01580 if (!(curParam->param->isArray())) {
01581 str << " scalar_buf_len += sizeof(" << curParam->param->getType()->getBaseName()
01582 << ");\n";
01583 }
01584 curParam = curParam->next;
01585 }
01586 str << " scalar_buf_len = ROUNDUP_128(scalar_buf_len);\n"
01587 << " cbStruct->scalar_buf_ptr = malloc_aligned(scalar_buf_len, 128);\n"
01588 << " char* scalar_buf_offset = (char*)(cbStruct->scalar_buf_ptr);\n\n";
01589 }
01590
01591
01592 str << " // Declare and populate the DMA list for the work request\n";
01593 str << " DMAListEntry dmaList[" << numDMAListEntries << "];\n\n";
01594
01595
01596
01597 curParam = param;
01598 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01599 curParam = curParam->next;
01600 }
01601 while (curParam != NULL) {
01602
01603 if (accel_numScalars > 0) {
01604 if (((dmaList_curIndex == 0) && (!(accel_dmaList_scalarNeedsWrite))) ||
01605 ((dmaList_curIndex == accel_dmaList_numReadOnly) &&
01606 (accel_dmaList_scalarNeedsWrite))) {
01607 str << " /*** Scalar Buffer ***/\n"
01608 << " dmaList[" << dmaList_curIndex << "].size = scalar_buf_len;\n"
01609 << " dmaList[" << dmaList_curIndex
01610 << "].ea = (unsigned int)(cbStruct->scalar_buf_ptr);\n\n";
01611 dmaList_curIndex++;
01612 }
01613 }
01614
01615
01616 str << " /*** Param: '" << curParam->param->getName() << "' ***/\n";
01617 if (curParam->param->isArray()) {
01618 str << " {\n"
01619 << " int bufSize = sizeof(" << curParam->param->getType()->getBaseName()
01620 << ") * (" << curParam->param->getArrayLen() << ");\n"
01621 << " bufSize = ROUNDUP_128(bufSize);\n"
01622 << " cbStruct->param_buf_ptr_" << curParam->param->getName()
01623 << " = malloc_aligned(bufSize, 128);\n"
01624 << " memcpy(cbStruct->param_buf_ptr_" << curParam->param->getName() << ", "
01625 << curParam->param->getName() << ", bufSize);\n"
01626 << " dmaList[" << dmaList_curIndex << "].size = bufSize;\n"
01627 << " dmaList[" << dmaList_curIndex
01628 << "].ea = (unsigned int)(cbStruct->param_buf_ptr_"
01629 << curParam->param->getName() << ");\n"
01630 << " }\n";
01631 dmaList_curIndex++;
01632 } else {
01633 str << " *((" << curParam->param->getType()->getBaseName()
01634 << "*)scalar_buf_offset) = " << curParam->param->getName() << ";\n"
01635 << " scalar_buf_offset += sizeof(" << curParam->param->getType()->getBaseName()
01636 << ");\n";
01637 }
01638 curParam = curParam->next;
01639 str << "\n";
01640 }
01641
01642
01643 curParam = accelParam;
01644 while (curParam != NULL) {
01645
01646 if (accel_numScalars > 0) {
01647 if (((dmaList_curIndex == 0) && (!(accel_dmaList_scalarNeedsWrite))) ||
01648 ((dmaList_curIndex == accel_dmaList_numReadOnly) &&
01649 (accel_dmaList_scalarNeedsWrite))) {
01650 str << " /*** Scalar Buffer ***/\n"
01651 << " dmaList[" << dmaList_curIndex << "].size = scalar_buf_len;\n"
01652 << " dmaList[" << dmaList_curIndex
01653 << "].ea = (unsigned int)(cbStruct->scalar_buf_ptr);\n\n";
01654 dmaList_curIndex++;
01655 }
01656 }
01657
01658
01659 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READONLY) {
01660 str << " /*** Accel Param: '" << curParam->param->getName() << " ("
01661 << (*(curParam->param->getAccelInstName())) << ")' ***/\n";
01662 if (curParam->param->isArray()) {
01663 str << " dmaList[" << dmaList_curIndex << "].size = ROUNDUP_128("
01664 << "sizeof(" << curParam->param->getType()->getBaseName() << ") * "
01665 << "(" << curParam->param->getArrayLen() << "));\n"
01666 << " dmaList[" << dmaList_curIndex << "].ea = (unsigned int)("
01667 << (*(curParam->param->getAccelInstName())) << ");\n";
01668 dmaList_curIndex++;
01669 } else {
01670 str << " *((" << curParam->param->getType()->getBaseName()
01671 << "*)scalar_buf_offset) = " << (*(curParam->param->getAccelInstName()))
01672 << ";\n"
01673 << " scalar_buf_offset += sizeof("
01674 << curParam->param->getType()->getBaseName() << ");\n";
01675 }
01676 str << "\n";
01677 }
01678
01679 curParam = curParam->next;
01680 }
01681
01682
01683 curParam = accelParam;
01684 while (curParam != NULL) {
01685
01686 if (accel_numScalars > 0) {
01687 if (((dmaList_curIndex == 0) && (!(accel_dmaList_scalarNeedsWrite))) ||
01688 ((dmaList_curIndex == accel_dmaList_numReadOnly) &&
01689 (accel_dmaList_scalarNeedsWrite))) {
01690 str << " /*** Scalar Buffer ***/\n"
01691 << " dmaList[" << dmaList_curIndex << "].size = scalar_buf_len;\n"
01692 << " dmaList[" << dmaList_curIndex
01693 << "].ea = (unsigned int)(cbStruct->scalar_buf_ptr);\n\n";
01694 dmaList_curIndex++;
01695 }
01696 }
01697
01698
01699 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READWRITE) {
01700 str << " /*** Accel Param: '" << curParam->param->getName() << " ("
01701 << (*(curParam->param->getAccelInstName())) << ")' ***/\n";
01702 if (curParam->param->isArray()) {
01703 str << " dmaList[" << dmaList_curIndex << "].size = ROUNDUP_128("
01704 << "sizeof(" << curParam->param->getType()->getBaseName() << ") * "
01705 << "(" << curParam->param->getArrayLen() << "));\n"
01706 << " dmaList[" << dmaList_curIndex << "].ea = (unsigned int)("
01707 << (*(curParam->param->getAccelInstName())) << ");\n";
01708 dmaList_curIndex++;
01709 } else {
01710 str << " *((" << curParam->param->getType()->getBaseName()
01711 << "*)scalar_buf_offset) = " << (*(curParam->param->getAccelInstName()))
01712 << ";\n"
01713 << " scalar_buf_offset += sizeof("
01714 << curParam->param->getType()->getBaseName() << ");\n";
01715 }
01716 str << "\n";
01717 }
01718
01719 curParam = curParam->next;
01720 }
01721
01722
01723 curParam = accelParam;
01724 while (curParam != NULL) {
01725
01726 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY) {
01727 str << " /*** Accel Param: '" << curParam->param->getName() << " ("
01728 << (*(curParam->param->getAccelInstName())) << ")' ***/\n";
01729 if (curParam->param->isArray()) {
01730 str << " dmaList[" << dmaList_curIndex << "].size = ROUNDUP_128("
01731 << "sizeof(" << curParam->param->getType()->getBaseName() << ") * "
01732 << "(" << curParam->param->getArrayLen() << "));\n"
01733 << " dmaList[" << dmaList_curIndex << "].ea = (unsigned int)("
01734 << (*(curParam->param->getAccelInstName())) << ");\n";
01735 dmaList_curIndex++;
01736 } else {
01737 str << " *((" << curParam->param->getType()->getBaseName()
01738 << "*)scalar_buf_offset) = " << (*(curParam->param->getAccelInstName()))
01739 << ";\n"
01740 << " scalar_buf_offset += sizeof("
01741 << curParam->param->getType()->getBaseName() << ");\n";
01742 }
01743 str << "\n";
01744 }
01745
01746 curParam = curParam->next;
01747 }
01748
01749 str << " // Issue the work request\n";
01750 str << " cbStruct->wrHandle = sendWorkRequest_list(accel_spe_func_index__" << epStr()
01751 << ",\n"
01752 << " 0,\n"
01753 << " dmaList,\n"
01754 << " " << accel_dmaList_numReadOnly
01755 << ",\n"
01756 << " " << accel_dmaList_numReadWrite
01757 << ",\n"
01758 << " " << accel_dmaList_numWriteOnly
01759 << ",\n"
01760 << " cbStruct,\n"
01761 << " WORK_REQUEST_FLAGS_NONE,\n"
01762 << " _accelCall_spe_callback_"
01763 << container->baseName() << "_" << epStr() << "\n"
01764 << " );\n";
01765
01766 str << "}\n\n";
01767
01768
01769 str << "\n";
01770 }
01771
01772 int Entry::genAccels_spe_c_funcBodies(XStr& str) {
01773
01774 if (!isAccel()) {
01775 return 0;
01776 }
01777
01778
01779 str << "void __speFunc__" << indexName() << "__" << epStr()
01780 << "(DMAListEntry* dmaList) {\n";
01781
01782 ParamList* curParam = NULL;
01783 int dmaList_curIndex = 0;
01784
01785
01786 if (accel_numScalars > 0) {
01787 if (accel_dmaList_scalarNeedsWrite) {
01788 str << " void* __scalar_buf_ptr = (void*)(dmaList[" << accel_dmaList_numReadOnly
01789 << "].ea);\n";
01790 } else {
01791 str << " void* __scalar_buf_ptr = (void*)(dmaList[0].ea);\n";
01792 dmaList_curIndex++;
01793 }
01794 str << " char* __scalar_buf_offset = (char*)(__scalar_buf_ptr);\n";
01795 }
01796
01797
01798 curParam = param;
01799 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01800 curParam = curParam->next;
01801 }
01802 while (curParam != NULL) {
01803 if (curParam->param->isArray()) {
01804 str << " " << curParam->param->getType()->getBaseName() << "* "
01805 << curParam->param->getName() << " = ("
01806 << curParam->param->getType()->getBaseName() << "*)(dmaList["
01807 << dmaList_curIndex << "].ea);\n";
01808 dmaList_curIndex++;
01809 } else {
01810 str << " " << curParam->param->getType()->getBaseName() << " "
01811 << curParam->param->getName() << " = *(("
01812 << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01813 str << " __scalar_buf_offset += sizeof("
01814 << curParam->param->getType()->getBaseName() << ");\n";
01815 }
01816 curParam = curParam->next;
01817 }
01818
01819
01820 curParam = accelParam;
01821 while (curParam != NULL) {
01822 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READONLY) {
01823 if (curParam->param->isArray()) {
01824 str << " " << curParam->param->getType()->getBaseName() << "* "
01825 << curParam->param->getName() << " = ("
01826 << curParam->param->getType()->getBaseName() << "*)(dmaList["
01827 << dmaList_curIndex << "].ea);\n";
01828 dmaList_curIndex++;
01829 } else {
01830 str << " " << curParam->param->getType()->getBaseName() << " "
01831 << curParam->param->getName() << " = *(("
01832 << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01833 str << " __scalar_buf_offset += sizeof("
01834 << curParam->param->getType()->getBaseName() << ");\n";
01835 }
01836 }
01837 curParam = curParam->next;
01838 }
01839
01840
01841 dmaList_curIndex = accel_dmaList_numReadOnly;
01842 if ((accel_numScalars > 0) && (accel_dmaList_scalarNeedsWrite)) {
01843 dmaList_curIndex++;
01844 }
01845
01846
01847 curParam = accelParam;
01848 while (curParam != NULL) {
01849 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_READWRITE) {
01850 if (curParam->param->isArray()) {
01851 str << " " << curParam->param->getType()->getBaseName() << "* "
01852 << curParam->param->getName() << " = ("
01853 << curParam->param->getType()->getBaseName() << "*)(dmaList["
01854 << dmaList_curIndex << "].ea);\n";
01855 dmaList_curIndex++;
01856 } else {
01857 str << " " << curParam->param->getType()->getBaseName() << " "
01858 << curParam->param->getName() << " = *(("
01859 << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01860 str << " __scalar_buf_offset += sizeof("
01861 << curParam->param->getType()->getBaseName() << ");\n";
01862 }
01863 }
01864 curParam = curParam->next;
01865 }
01866
01867
01868 curParam = accelParam;
01869 while (curParam != NULL) {
01870 if (curParam->param->getAccelBufferType() == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY) {
01871 if (curParam->param->isArray()) {
01872 str << " " << curParam->param->getType()->getBaseName() << "* "
01873 << curParam->param->getName() << " = ("
01874 << curParam->param->getType()->getBaseName() << "*)(dmaList["
01875 << dmaList_curIndex << "].ea);\n";
01876 dmaList_curIndex++;
01877 } else {
01878 str << " " << curParam->param->getType()->getBaseName() << " "
01879 << curParam->param->getName() << " = *(("
01880 << curParam->param->getType()->getBaseName() << "*)__scalar_buf_offset);\n";
01881 str << " __scalar_buf_offset += sizeof("
01882 << curParam->param->getType()->getBaseName() << ");\n";
01883 }
01884 }
01885 curParam = curParam->next;
01886 }
01887
01888
01889 str << " {\n " << (*accelCodeBody) << "\n }\n";
01890
01891
01892 if ((accel_numScalars > 0) && (accel_dmaList_scalarNeedsWrite)) {
01893 str << " __scalar_buf_offset = (char*)(__scalar_buf_ptr);\n";
01894
01895
01896 curParam = param;
01897 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
01898 curParam = curParam->next;
01899 }
01900 while (curParam != NULL) {
01901 if (!(curParam->param->isArray())) {
01902 str << " __scalar_buf_offset += sizeof("
01903 << curParam->param->getType()->getBaseName() << ");\n";
01904 }
01905 curParam = curParam->next;
01906 }
01907
01908
01909 curParam = accelParam;
01910 while (curParam != NULL) {
01911 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01912 Parameter::ACCEL_BUFFER_TYPE_READONLY)) {
01913 str << " __scalar_buf_offset += sizeof("
01914 << curParam->param->getType()->getBaseName() << ");\n";
01915 }
01916 curParam = curParam->next;
01917 }
01918
01919
01920 curParam = accelParam;
01921 while (curParam != NULL) {
01922 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01923 Parameter::ACCEL_BUFFER_TYPE_READWRITE)) {
01924 str << " *((" << curParam->param->getType()->getBaseName()
01925 << "*)__scalar_buf_offset) = " << curParam->param->getName() << ";\n";
01926 str << " __scalar_buf_offset += sizeof("
01927 << curParam->param->getType()->getBaseName() << ");\n";
01928 }
01929 curParam = curParam->next;
01930 }
01931
01932
01933 curParam = accelParam;
01934 while (curParam != NULL) {
01935 if ((!(curParam->param->isArray())) && (curParam->param->getAccelBufferType() ==
01936 Parameter::ACCEL_BUFFER_TYPE_WRITEONLY)) {
01937 str << " *((" << curParam->param->getType()->getBaseName()
01938 << "*)__scalar_buf_offset) = " << curParam->param->getName() << ";\n";
01939 str << " __scalar_buf_offset += sizeof("
01940 << curParam->param->getType()->getBaseName() << ");\n";
01941 }
01942 curParam = curParam->next;
01943 }
01944 }
01945
01946 str << "}\n\n\n";
01947
01948 return 1;
01949 }
01950
01951 void Entry::genAccels_spe_c_regFuncs(XStr& str) {
01952 if (isAccel()) {
01953 str << " funcLookupTable[curIndex ].funcIndex = curIndex;\n"
01954 << " funcLookupTable[curIndex++].funcPtr = __speFunc__" << indexName() << "__"
01955 << epStr() << ";\n";
01956 }
01957 }
01958
01959 void Entry::genAccels_ppe_c_regFuncs(XStr& str) {
01960 if (isAccel()) {
01961 str << " " << indexName() << "::accel_spe_func_index__" << epStr()
01962 << " = curIndex++;\n";
01963 }
01964 }
01965
01966
01967 void Entry::genIndexDecls(XStr& str) {
01968 str << " /* DECLS: ";
01969 print(str);
01970 str << " */";
01971
01972 XStr templateSpecLine;
01973 templateSpecLine << "\n " << generateTemplateSpec(tspec);
01974
01975
01976 str << "\n // Entry point registration at startup" << templateSpecLine
01977 << "\n static int reg_" << epStr()
01978 << "();"
01979 << "\n // Entry point index lookup" << templateSpecLine
01980 << "\n inline static int idx_" << epStr() << "() {"
01981 << "\n static int epidx = " << epRegFn(0) << ";"
01982 << "\n return epidx;"
01983 << "\n }\n";
01984
01985 if (!isConstructor()) {
01986 str << templateSpecLine << "\n inline static int idx_" << name << "(" << retType
01987 << " (" << container->baseName() << "::*)(";
01988 if (param) param->print(str);
01989 str << ") ) {"
01990 << "\n return " << epIdx(0) << ";"
01991 << "\n }\n\n";
01992 }
01993
01994
01995 #if CMK_CELL != 0
01996 if (isAccel()) {
01997 str << " static int accel_spe_func_index__" << epStr() << ";\n";
01998 }
01999 #endif
02000
02001
02002 str << templateSpecLine << "\n static int ";
02003 if (isConstructor())
02004 str << "ckNew";
02005 else
02006 str << name;
02007 str << "(" << paramType(1, 0) << ") { return " << epIdx(0) << "; }";
02008
02009
02010 if (isAccel()) {
02011 genAccelIndexWrapperDecl_general(str);
02012 #if CMK_CELL != 0
02013 genAccelIndexWrapperDecl_spe(str);
02014 #endif
02015 }
02016
02017 if (isReductionTarget()) {
02018 str << "\n // Entry point registration at startup" << templateSpecLine
02019 << "\n static int reg_" << epStr(true)
02020 << "();"
02021 << "\n // Entry point index lookup" << templateSpecLine
02022 << "\n inline static int idx_" << epStr(true) << "() {"
02023 << "\n static int epidx = " << epRegFn(0, true) << ";"
02024 << "\n return epidx;"
02025 << "\n }" << templateSpecLine << "\n static int "
02026 << "redn_wrapper_" << name << "(CkReductionMsg* impl_msg) { return "
02027 << epIdx(0, true) << "; }" << templateSpecLine << "\n static void _call_"
02028 << epStr(true) << "(void* impl_msg, void* impl_obj_void);";
02029 }
02030
02031
02032 str << templateSpecLine << "\n static void _call_" << epStr()
02033 << "(void* impl_msg, void* impl_obj);";
02034 str << templateSpecLine << "\n static void _call_sdag_" << epStr()
02035 << "(void* impl_msg, void* impl_obj);";
02036 if (isThreaded()) {
02037 str << templateSpecLine << "\n static void _callthr_" << epStr()
02038 << "(CkThrCallArg *);";
02039 }
02040 if (hasCallMarshall) {
02041 str << templateSpecLine << "\n static int _callmarshall_" << epStr()
02042 << "(char* impl_buf, void* impl_obj_void);";
02043 }
02044 if (param->isMarshalled()) {
02045 str << templateSpecLine << "\n static void _marshallmessagepup_" << epStr()
02046 << "(PUP::er &p,void *msg);";
02047 }
02048 str << "\n";
02049 }
02050
02051 void Entry::genDecls(XStr& str) {
02052 if (external) return;
02053
02054 str << "/* DECLS: ";
02055 print(str);
02056 str << " */\n";
02057
02058 if (isMigrationConstructor()) {
02059 }
02060 else if (container->isGroup()) {
02061 genGroupDecl(str);
02062 } else if (container->isArray()) {
02063 if (!isIget())
02064 genArrayDecl(str);
02065 else if (container->isForElement())
02066 genArrayDecl(str);
02067 } else {
02068 genChareDecl(str);
02069 }
02070 }
02071
02072 void Entry::genClosureEntryDecls(XStr& str) { genClosure(str, false); }
02073
02074 void Entry::genClosureEntryDefs(XStr& str) {
02075 templateGuardBegin(tspec || container->isTemplated(), str);
02076 genClosure(str, true);
02077 templateGuardEnd(str);
02078 }
02079
02080 void Entry::genClosure(XStr& decls, bool isDef) {
02081 if (isConstructor() || (isLocal() && !sdagCon)) return;
02082
02083 bool hasArray = false, isMessage = false, hasRdma = false;
02084 XStr messageType;
02085 int i = 0, addNumRdmaFields = 1;
02086 XStr structure, toPup, alloc, getter, dealloc;
02087 for (ParamList *pl = param; pl != NULL; pl = pl->next, i++) {
02088 Parameter* sv = pl->param;
02089
02090 if (XStr(sv->type->getBaseName()) == "CkArrayOptions") continue;
02091
02092 structure << " ";
02093 getter << " ";
02094
02095 if ((sv->isMessage() != 1) && (sv->isVoid() != 1)) {
02096 if (sv->isRdma()) {
02097 hasRdma = hasRdma || true;
02098 structure << "\n#if CMK_ONESIDED_IMPL\n";
02099 if (sv->isFirstRdma())
02100 structure << " "
02101 << "int num_rdma_fields;\n";
02102 structure << " "
02103 << "CkNcpyBuffer "
02104 << "ncpyBuffer_" << sv->name << ";\n";
02105 structure << "#else\n";
02106 structure << " " << sv->type << " "
02107 << "*" << sv->name << ";\n";
02108 structure << "#endif\n";
02109 if (sv->isFirstRdma()) {
02110 getter << "#if CMK_ONESIDED_IMPL\n";
02111 getter << " "
02112 << "int "
02113 << "& "
02114 << "getP" << i << "() { return "
02115 << " num_rdma_fields;}\n";
02116 getter << "#endif\n";
02117 i++;
02118 }
02119 getter << "#if CMK_ONESIDED_IMPL\n";
02120 getter << " "
02121 << "CkNcpyBuffer "
02122 << "& "
02123 << "getP" << i << "() { return "
02124 << "ncpyBuffer_" << sv->name << ";}\n";
02125 getter << "#else\n";
02126 getter << sv->type << " "
02127 << "*";
02128 getter << "& "
02129 << "getP" << i << "() { return " << sv->name << ";}\n";
02130 getter << "#endif\n";
02131 toPup << "#if CMK_ONESIDED_IMPL\n";
02132 if (sv->isFirstRdma()) {
02133 toPup << " char *impl_buf = _impl_marshall ? _impl_marshall->msgBuf : "
02134 "_impl_buf_in;\n";
02135 toPup << " "
02136 << "__p | "
02137 << "num_rdma_fields;\n";
02138 }
02139
02140
02141
02142
02143
02144 toPup << " if (__p.isPacking()) {\n";
02145 toPup << " ncpyBuffer_" << sv->name << ".ptr = ";
02146 toPup << "(void *)((char *)(ncpyBuffer_" << sv->name << ".ptr) - impl_buf);\n";
02147 toPup << " }\n";
02148 toPup << " "
02149 << "__p | "
02150 << "ncpyBuffer_" << sv->name << ";\n";
02151 toPup << "#endif\n";
02152 } else {
02153 structure << " ";
02154 getter << " ";
02155 structure << sv->type << " ";
02156 getter << sv->type << " ";
02157 }
02158
02159 if (sv->isArray() != 0) {
02160 structure << "*";
02161 getter << "*";
02162 }
02163 if (sv->isArray() != 0) {
02164 hasArray = hasArray || true;
02165 } else if (!sv->isRdma()) {
02166 toPup << " "
02167 << "__p | " << sv->name << ";\n";
02168 sv->podType = true;
02169 }
02170
02171 if (sv->name != 0) {
02172 if (!sv->isRdma()) {
02173 structure << sv->name << ";\n";
02174 getter << "& "
02175 << "getP" << i << "() { return " << sv->name << ";}\n";
02176 }
02177 }
02178
02179 } else if (sv->isVoid() != 1) {
02180 if (sv->isMessage()) {
02181 isMessage = true;
02182 if (sv->isRdma()) {
02183 structure << "CkNcpyBuffer"
02184 << " "
02185 << "ncpyBuffer_" << sv->name << ";\n";
02186 } else {
02187 structure << sv->type << " " << sv->name << ";\n";
02188 }
02189 toPup << " "
02190 << "CkPupMessage(__p, (void**)&" << sv->name << ");\n";
02191 messageType << sv->type->deref();
02192 }
02193 }
02194 }
02195
02196 structure << "\n";
02197
02198 toPup << " packClosure(__p);\n";
02199
02200 XStr initCode;
02201 initCode << " init();\n";
02202
02203 if (hasArray || hasRdma) {
02204 structure << " "
02205 << "CkMarshallMsg* _impl_marshall;\n";
02206 structure << " "
02207 << "char* _impl_buf_in;\n";
02208 structure << " "
02209 << "int _impl_buf_size;\n";
02210 dealloc << " if (_impl_marshall) CmiFree(UsrToEnv(_impl_marshall));\n";
02211 initCode << " _impl_marshall = 0;\n";
02212 initCode << " _impl_buf_in = 0;\n";
02213 initCode << " _impl_buf_size = 0;\n";
02214
02215 toPup << " __p | _impl_buf_size;\n";
02216 toPup << " bool hasMsg = (_impl_marshall != 0); __p | hasMsg;\n";
02217 toPup << " "
02218 << "if (hasMsg) CkPupMessage(__p, (void**)&"
02219 << "_impl_marshall"
02220 << ");\n";
02221 toPup << " "
02222 << "else PUParray(__p, _impl_buf_in, _impl_buf_size);\n";
02223 toPup << " if (__p.isUnpacking()) {\n";
02224 toPup << " char *impl_buf = _impl_marshall ? _impl_marshall->msgBuf : "
02225 "_impl_buf_in;\n";
02226 param->beginUnmarshallSDAG(toPup);
02227 toPup << " }\n";
02228 }
02229
02230
02231 if (isLocal()) {
02232 toPup.clear();
02233 toPup
02234 << " CkAbort(\"Can\'t migrate while a local SDAG method is active.\");\n";
02235 }
02236
02237 if (!isMessage) {
02238 genClosureTypeName = new XStr();
02239 genClosureTypeNameProxy = new XStr();
02240 *genClosureTypeNameProxy << "Closure_" << container->baseName() << "::";
02241 *genClosureTypeNameProxy << name << "_" << entryCount << "_closure";
02242 *genClosureTypeName << name << "_" << entryCount << "_closure";
02243
02244 container->sdagPUPReg << " PUPable_reg(SINGLE_ARG(" << *genClosureTypeNameProxy
02245 << "));\n";
02246
02247 if (isDef) {
02248 if (container->isTemplated()) {
02249 decls << container->tspec(false) << "\n";
02250 }
02251 decls << generateTemplateSpec(tspec) << "\n";
02252 decls << " struct " << *genClosureTypeNameProxy << " : public SDAG::Closure"
02253 << " {\n";
02254 decls << structure << "\n";
02255 decls << " " << *genClosureTypeName << "() {\n";
02256 decls << initCode;
02257 decls << " }\n";
02258 decls << " " << *genClosureTypeName << "(CkMigrateMessage*) {\n";
02259 decls << initCode;
02260 decls << " }\n";
02261 decls << getter;
02262 decls << " void pup(PUP::er& __p) {\n";
02263 decls << toPup;
02264 decls << " }\n";
02265 decls << " virtual ~" << *genClosureTypeName << "() {\n";
02266 decls << dealloc;
02267 decls << " }\n";
02268 decls << " "
02269 << ((container->isTemplated() || tspec) ? "PUPable_decl_template"
02270 : "PUPable_decl")
02271 << "(SINGLE_ARG(" << *genClosureTypeName;
02272 if (tspec) {
02273 decls << "<";
02274 tspec->genShort(decls);
02275 decls << ">";
02276 }
02277 decls << "));\n";
02278 decls << " };\n";
02279 } else {
02280 decls << generateTemplateSpec(tspec) << "\n";
02281 decls << " struct " << *genClosureTypeName << ";\n";
02282 }
02283 } else {
02284 genClosureTypeName = new XStr();
02285 genClosureTypeNameProxy = new XStr();
02286 *genClosureTypeNameProxy << messageType;
02287 *genClosureTypeName << messageType;
02288 }
02289
02290 genClosureTypeNameProxyTemp = new XStr();
02291 *genClosureTypeNameProxyTemp << (container->isTemplated() ? "typename " : "")
02292 << genClosureTypeNameProxy;
02293 }
02294
02295
02296
02297
02298 XStr Entry::callThread(const XStr& procName, int prependEntryName) {
02299 if (isConstructor() || isMigrationConstructor())
02300 die("Constructors may not be 'threaded'", first_line_);
02301
02302 XStr str, procFull;
02303 procFull << "_callthr_";
02304 if (prependEntryName) procFull << name << "_";
02305 procFull << procName;
02306
02307 str << " CthThread tid = CthCreate((CthVoidFn)" << procFull
02308 << ", new CkThrCallArg(impl_msg,impl_obj), " << getStackSize() << ");\n";
02309 str << " ((Chare *)impl_obj)->CkAddThreadListeners(tid,impl_msg);\n";
02310
02311 #if CMK_BIGSIM_CHARM
02312 str << " BgAttach(tid);\n";
02313 #endif
02314 str << " CthResume(tid);\n";
02315 str << "}\n";
02316
02317 str << makeDecl("void") << "::" << procFull << "(CkThrCallArg *impl_arg)\n";
02318 str << "{\n";
02319 str << " void *impl_msg = impl_arg->msg;\n";
02320 str << " void *impl_obj_void = impl_arg->obj;\n";
02321 str << " " << container->baseName() << " *impl_obj = static_cast<"
02322 << container->baseName() << " *>(impl_obj_void);\n";
02323 str << " delete impl_arg;\n";
02324 return str;
02325 }
02326
02327
02328
02329
02330
02331 void Entry::genCall(XStr& str, const XStr& preCall, bool redn_wrapper, bool usesImplBuf) {
02332 bool isArgcArgv = false;
02333 bool isMigMain = false;
02334 bool isSDAGGen = sdagCon || isWhenEntry;
02335 bool needsClosure = isSDAGGen && (param->isMarshalled() ||
02336 (param->isVoid() && isWhenEntry && redn_wrapper));
02337
02338 if (isConstructor() && container->isMainChare() && (!param->isVoid()) &&
02339 (!param->isCkArgMsgPtr())) {
02340 if (param->isCkMigMsgPtr())
02341 isMigMain = true;
02342 else
02343 isArgcArgv = true;
02344 } else {
02345
02346 if (redn_wrapper)
02347 param->beginRednWrapperUnmarshall(str, needsClosure);
02348 else {
02349 if (isSDAGGen)
02350 param->beginUnmarshallSDAGCall(str, usesImplBuf);
02351 else
02352 param->beginUnmarshall(str);
02353 }
02354 }
02355
02356 str << preCall;
02357 if (!isConstructor() && fortranMode && !isWhenEntry && !sdagCon) {
02358 if (!container->isArray()) {
02359 cerr << (char*)container->baseName()
02360 << ": only chare arrays are currently supported\n";
02361 exit(1);
02362 }
02363 str << "/* FORTRAN */\n";
02364 XStr dim;
02365 dim << ((Array*)container)->dim();
02366 if (dim == (const char*)"1D")
02367 str << " int index1 = impl_obj->thisIndex;\n";
02368 else if (dim == (const char*)"2D") {
02369 str << " int index1 = impl_obj->thisIndex.x;\n";
02370 str << " int index2 = impl_obj->thisIndex.y;\n";
02371 } else if (dim == (const char*)"3D") {
02372 str << " int index1 = impl_obj->thisIndex.x;\n";
02373 str << " int index2 = impl_obj->thisIndex.y;\n";
02374 str << " int index3 = impl_obj->thisIndex.z;\n";
02375 }
02376 str << " ::";
02377 str << fortranify(container->baseName(), "_Entry_", name);
02378 str << "((char **)(impl_obj->user_data)";
02379 str << ", &index1";
02380 if (dim == (const char*)"2D" || dim == (const char*)"3D") str << ", &index2";
02381 if (dim == (const char*)"3D") str << ", &index3";
02382 if (!param->isVoid()) {
02383 str << ", ";
02384 param->unmarshallAddress(str);
02385 }
02386 str << ");\n";
02387 str << "/* FORTRAN END */\n";
02388 }
02389
02390
02391 else if (isAccel()) {
02392 #if CMK_CELL != 0
02393 str << " if (1) { // DMK : TODO : For now, hardcode the condition (i.e. for now, "
02394 "do not dynamically load-balance between host and accelerator)\n";
02395 str << " _accelCall_spe_" << epStr() << "(";
02396 genAccelFullCallList(str);
02397 str << ");\n";
02398 str << " } else {\n ";
02399 #endif
02400
02401 str << " _accelCall_general_" << epStr() << "(";
02402 genAccelFullCallList(str);
02403 str << ");\n";
02404
02405 #if CMK_CELL != 0
02406 str << " }\n";
02407 #endif
02408
02409 }
02410
02411 else {
02412 if(param->hasRecvRdma()) {
02413 str << "#if CMK_ONESIDED_IMPL\n";
02414 str << " if(CMI_IS_ZC_RECV(env) || CMI_ZC_MSGTYPE(env) == CMK_ZC_BCAST_RECV_DONE_MSG) {\n";
02415 str << "#endif\n";
02416 genRegularCall(str, preCall, redn_wrapper, usesImplBuf, true);
02417 str << "#if CMK_ONESIDED_IMPL\n";
02418 str << " else if(CMI_ZC_MSGTYPE(env) == CMK_ZC_BCAST_RECV_DONE_MSG) {\n";
02419
02420 genRegularCall(str, preCall, redn_wrapper, usesImplBuf, false);
02421
02422 str << " }\n";
02423 str << " } else {\n";
02424 str << "#endif\n";
02425 }
02426 genRegularCall(str, preCall, redn_wrapper, usesImplBuf, false);
02427 if(param->hasRecvRdma()) {
02428 str << "#if CMK_ONESIDED_IMPL\n";
02429 str << " }\n";
02430 str << "#endif\n";
02431 }
02432 }
02433 }
02434
02435 void Entry::genRegularCall(XStr& str, const XStr& preCall, bool redn_wrapper, bool usesImplBuf, bool isRdmaPost) {
02436 bool isArgcArgv = false;
02437 bool isMigMain = false;
02438 bool isSDAGGen = sdagCon || isWhenEntry;
02439 bool needsClosure = isSDAGGen && (param->isMarshalled() ||
02440 (param->isVoid() && isWhenEntry && redn_wrapper));
02441
02442
02443
02444 if (isArgcArgv) str << " CkArgMsg *m=(CkArgMsg *)impl_msg;\n";
02445
02446 if (isMigrationConstructor() && container->isArray()) {
02447
02448
02449
02450 str << " call_migration_constructor<" << container->baseName()
02451 << "> c = impl_obj_void;\n"
02452 << " c";
02453 } else if (isConstructor()) {
02454 str << " new (impl_obj_void) " << container->baseName();
02455 } else {
02456 str << " impl_obj->" << (tspec ? "template " : "") << (containsWhenConstruct ? "_sdag_fnc_" : "" ) << name;
02457 if (tspec) {
02458 str << "<";
02459 tspec->genShort(str);
02460 str << ">";
02461 }
02462 }
02463
02464 if (isArgcArgv) {
02465
02466 str << "(m->argc,m->argv);\n";
02467 str << " delete m;\n";
02468 } else if (isMigMain) {
02469 str << "((CkMigrateMessage*)impl_msg);\n";
02470 } else {
02471 if (isSDAGGen) {
02472 str << "(";
02473 if (param->isMessage()) {
02474 param->unmarshall(str, false, true, isRdmaPost);
02475 } else if (needsClosure) {
02476 if(isRdmaPost)
02477 param->unmarshall(str, false, true, isRdmaPost);
02478 else
02479 str << "genClosure";
02480 }
02481
02482 if(isRdmaPost) str << ",ncpyPost";
02483 str << ");\n";
02484 if (needsClosure) {
02485 if(!isRdmaPost)
02486 str << " genClosure->deref();\n";
02487 }
02488 } else {
02489 str << "(";
02490 param->unmarshall(str, false, true, isRdmaPost);
02491
02492 if(isRdmaPost) str << ",ncpyPost";
02493 str << ");\n";
02494 }
02495 if(isRdmaPost) {
02496 str << "#if CMK_ONESIDED_IMPL\n";
02497
02498 str << " void *buffPtrs["<< numRdmaRecvParams <<"];\n";
02499 str << "#endif\n";
02500 param->storePostedRdmaPtrs(str, isSDAGGen);
02501 str << "#if CMK_ONESIDED_IMPL\n";
02502 str << " if(CMI_IS_ZC_RECV(env)) \n";
02503 str << " CkRdmaIssueRgets(env, ((CMI_ZC_MSGTYPE(env) == CMK_ZC_BCAST_RECV_MSG) ? ncpyEmApiMode::BCAST_RECV : ncpyEmApiMode::P2P_RECV), NULL, ";
02504 if(isSDAGGen)
02505 str << " genClosure->num_rdma_fields, ";
02506 else
02507 str << " impl_num_rdma_fields, ";
02508 str << " buffPtrs, ncpyPost);\n";
02509 str << "#else\n";
02510
02511 str << "#endif\n";
02512 }
02513
02514 if(param->hasRdma() && !container->isForElement() && !isRdmaPost) {
02515
02516
02517
02518 str << "#if CMK_ONESIDED_IMPL\n";
02519 if(param->hasRecvRdma())
02520
02521
02522
02523 str << " if(!CMI_IS_ZC_RECV(env) && CMI_ZC_MSGTYPE(env) != CMK_ZC_BCAST_RECV_DONE_MSG && CMI_ZC_MSGTYPE(env) != CMK_ZC_BCAST_RECV_ALL_DONE_MSG && CMI_ZC_MSGTYPE(env) != CMK_ZC_P2P_RECV_DONE_MSG)\n";
02524 str << " CkPackRdmaPtrs(impl_buf_begin);\n";
02525 str << "#endif\n";
02526 }
02527 }
02528 }
02529
02530 void Entry::genDefs(XStr& str) {
02531 if (external) return;
02532 XStr containerType = container->baseName();
02533 XStr preMarshall, preCall, postCall;
02534
02535 templateGuardBegin(tspec || container->isTemplated(), str);
02536 str << "/* DEFS: ";
02537 print(str);
02538 str << " */\n";
02539
02540 if (isMigrationConstructor()) {
02541 }
02542 else if (isTramTarget() && container->isForElement()) {
02543 genTramDefs(str);
02544 } else if (container->isGroup()) {
02545 genGroupDefs(str);
02546 } else if (container->isArray()) {
02547 genArrayDefs(str);
02548 } else
02549 genChareDefs(str);
02550
02551 if (!isConstructor() && fortranMode) {
02552 str << "/* FORTRAN SECTION */\n";
02553
02554
02555
02556 str << "extern \"C\" ";
02557 str << "void ";
02558 str << fortranify(container->baseName(), "_Entry_", name);
02559 str << "(char **";
02560 str << ", " << container->indexList();
02561 if (!param->isVoid()) {
02562 str << ", ";
02563 param->printAddress(str);
02564 }
02565 str << ");\n";
02566
02567 str << "/* FORTRAN SECTION END */\n";
02568 }
02569
02570 if (container->isMainChare() || container->isChare() || container->isForElement()) {
02571 if (isReductionTarget()) {
02572 XStr retStr;
02573 retStr << retType;
02574 str << makeDecl(retStr);
02575
02576 str << "::_call_" << epStr(true) << "(void* impl_msg, void* impl_obj_void)"
02577 << "\n{"
02578 << "\n " << container->baseName() << "* impl_obj = static_cast<"
02579 << container->baseName() << "*> (impl_obj_void);\n"
02580 << " char* impl_buf = (char*)((CkReductionMsg*)impl_msg)->getData();\n";
02581 XStr precall;
02582 genCall(str, precall, true, false);
02583 if (!(sdagCon || isWhenEntry))
02584 str << " delete (CkReductionMsg*)impl_msg;\n}\n\n";
02585 else
02586 str << " \n}\n\n";
02587 }
02588 }
02589
02590
02591 if (container->getForWhom() != forAll) {
02592 templateGuardEnd(str);
02593 return;
02594 }
02595
02596
02597 str << "\n// Entry point registration function"
02598 << "\n"
02599 << makeDecl("int") << "::reg_" << epStr() << "() {"
02600 << "\n int epidx = " << genRegEp() << ";";
02601 if (hasCallMarshall)
02602 str << "\n CkRegisterMarshallUnpackFn(epidx, "
02603 << "_callmarshall_" << epStr(false, true) << ");";
02604 if (param->isMarshalled()) {
02605 str << "\n CkRegisterMessagePupFn(epidx, "
02606 << "_marshallmessagepup_" << epStr(false, true) << ");\n";
02607 } else if (param->isMessage() && !isMigrationConstructor()) {
02608 str << "\n CkRegisterMessagePupFn(epidx, (CkMessagePupFn)";
02609 param->param->getType()->deref()->print(str);
02610 str << "::ckDebugPup);";
02611 }
02612 str << "\n return epidx;"
02613 << "\n}\n\n";
02614
02615 if (isReductionTarget()) {
02616 str << "\n// Redn wrapper registration function"
02617 << "\n"
02618 << makeDecl("int") << "::reg_" << epStr(true) << "() {"
02619 << "\n return " << genRegEp(true) << ";"
02620 << "\n}\n\n";
02621 }
02622
02623
02624 #if CMK_CELL != 0
02625 if (isAccel()) {
02626 str << "int " << indexName() << "::"
02627 << "accel_spe_func_index__" << epStr() << "=0;\n";
02628 }
02629 #endif
02630
02631
02632 if (isSync() || isIget()) {
02633
02634
02635 preMarshall
02636 << " int impl_ref = CkGetRefNum(impl_msg), impl_src = CkGetSrcPe(impl_msg);\n";
02637 if (retType->isVoid() || retType->isMessage()) preCall << " void *impl_retMsg=";
02638 if (retType->isVoid()) {
02639 preCall << "CkAllocSysMsg();\n ";
02640 } else if (retType->isMessage()) {
02641 preCall << "(void *) ";
02642 } else {
02643 preCall << " " << retType << " impl_ret_val= ";
02644 postCall << " //Marshall: impl_ret_val\n";
02645 postCall << " int impl_ret_size=0;\n";
02646 postCall << " { //Find the size of the PUP'd data\n";
02647 postCall << " PUP::sizer implPS;\n";
02648 postCall << " implPS|impl_ret_val;\n";
02649 postCall << " impl_ret_size+=implPS.size();\n";
02650 postCall << " };\n";
02651 postCall
02652 << " CkMarshallMsg *impl_retMsg=CkAllocateMarshallMsg(impl_ret_size, NULL);\n";
02653 postCall << " { //Copy over the PUP'd data;\n";
02654 postCall << " PUP::toMem implPS((void *)impl_retMsg->msgBuf);\n";
02655 postCall << " implPS|impl_ret_val;\n";
02656 postCall << " };\n";
02657 }
02658 postCall << " CkSendToFutureID(impl_ref, impl_retMsg, impl_src);\n";
02659 } else if (isExclusive()) {
02660
02661 preMarshall
02662 << " if(CmiTryLock(impl_obj->__nodelock)) {\n";
02663
02664 if (param->isMarshalled()) {
02665 preMarshall << " impl_msg = CkCopyMsg(&impl_msg);\n";
02666 }
02667 preMarshall << " CkSendMsgNodeBranch(" << epIdx()
02668 << ",impl_msg,CkMyNode(),impl_obj->CkGetNodeGroupID());\n";
02669 preMarshall << " return;\n";
02670 preMarshall << " }\n";
02671
02672 postCall << " CmiUnlock(impl_obj->__nodelock);\n";
02673 }
02674
02675 if (param->isVoid() && !isNoKeep()) {
02676
02677
02678
02679
02680
02681 postCall << " if(UsrToEnv(impl_msg)->isVarSysMsg() == 0)\n";
02682 postCall << " CkFreeSysMsg(impl_msg);\n";
02683 }
02684
02685 if (!isConstructor() && fortranMode) {
02686 str << "/* FORTRAN SECTION */\n";
02687
02688 XStr dim;
02689 dim << ((Array*)container)->dim();
02690
02691
02692
02693 str << "extern \"C\" ";
02694 str << "void ";
02695 str << fortranify(container->baseName(), "_Invoke_", name);
02696 str << "(void** aindex";
02697 str << ", " << container->indexList();
02698 if (!param->isVoid()) {
02699 str << ", ";
02700 param->printAddress(str);
02701 }
02702 str << ")\n";
02703 str << "{\n";
02704 str << " CkArrayID *aid = (CkArrayID *)*aindex;\n";
02705 str << "\n";
02706 str << " " << container->proxyName() << " h(*aid);\n";
02707 if (dim == (const char*)"1D")
02708 str << " h[*index1]." << name << "(";
02709 else if (dim == (const char*)"2D")
02710 str << " h[CkArrayIndex2D(*index1, *index2)]." << name << "(";
02711 else if (dim == (const char*)"3D")
02712 str << " h[CkArrayIndex3D(*index1, *index2, *index3)]." << name << "(";
02713 if (!param->isVoid()) param->printValue(str);
02714 str << ");\n";
02715 str << "}\n";
02716
02717 if (container->isArray()) {
02718 str << "extern \"C\" ";
02719 str << "void ";
02720 str << fortranify(container->baseName(), "_Broadcast_", name);
02721 str << "(void** aindex";
02722 if (!param->isVoid()) {
02723 str << ", ";
02724 param->printAddress(str);
02725 }
02726 str << ")\n";
02727 str << "{\n";
02728 str << " CkArrayID *aid = (CkArrayID *)*aindex;\n";
02729 str << "\n";
02730 str << " " << container->proxyName() << " h(*aid);\n";
02731 str << " h." << name << "(";
02732 if (!param->isVoid()) param->printValue(str);
02733 str << ");\n";
02734 str << "}\n";
02735 }
02736
02737 if (isReductionTarget()) {
02738 str << "extern \"C\" ";
02739 str << "int ";
02740 str << fortranify(container->baseName(), "_ReductionTarget_", name);
02741 str << "(void)\n";
02742 str << "{\n";
02743 str << " return CkReductionTarget(" << container->baseName() << ", " << name << ");\n";
02744 str << "}\n";
02745 }
02746
02747 str << "/* FORTRAN SECTION END */\n";
02748 }
02749
02750
02751
02752
02753
02754 if (isAccel()) {
02755 genAccelIndexWrapperDef_general(str);
02756 #if CMK_CELL != 0
02757 genAccelIndexWrapperDef_spe(str);
02758 #endif
02759 }
02760
02761
02762 str << makeDecl("void") << "::_call_" << epStr()
02763 << "(void* impl_msg, void* impl_obj_void)\n";
02764 str << "{\n";
02765
02766
02767 if (!isMigrationConstructor()) {
02768 str << " " << container->baseName() << "* impl_obj = static_cast<"
02769 << container->baseName() << "*>(impl_obj_void);\n";
02770 }
02771 if (!isLocal()) {
02772 if (isThreaded()) str << callThread(epStr());
02773 str << preMarshall;
02774 if (param->isMarshalled()) {
02775 if (param->hasConditional())
02776 str << " MarshallMsg_" << epStr() << " *impl_msg_typed=(MarshallMsg_" << epStr()
02777 << " *)impl_msg;\n";
02778 else
02779 str << " CkMarshallMsg *impl_msg_typed=(CkMarshallMsg *)impl_msg;\n";
02780 str << " char *impl_buf=impl_msg_typed->msgBuf;\n";
02781 str << " envelope *env = UsrToEnv(impl_msg_typed);\n";
02782 }
02783 genCall(str, preCall, false, false);
02784 param->endUnmarshall(str);
02785 str << postCall;
02786 if (isThreaded() && param->isMarshalled()) str << " delete impl_msg_typed;\n";
02787 } else {
02788 str << " CkAbort(\"This method should never be called as it refers to a LOCAL entry "
02789 "method!\");\n";
02790 }
02791 str << "}\n";
02792
02793 if (hasCallMarshall) {
02794 str << makeDecl("int") << "::_callmarshall_" << epStr()
02795 << "(char* impl_buf, void* impl_obj_void) {\n";
02796 str << " " << containerType << "* impl_obj = static_cast<" << containerType
02797 << "*>(impl_obj_void);\n";
02798 str << " envelope *env = UsrToEnv(impl_buf);\n";
02799 if (!isLocal()) {
02800 if (!param->hasConditional()) {
02801 genCall(str, preCall, false, true);
02802
02803
02804
02805 str << " return implP.size();\n";
02806 } else {
02807 str << " CkAbort(\"This method is not implemented for EPs using conditional "
02808 "packing\");\n";
02809 str << " return 0;\n";
02810 }
02811 } else {
02812 str << " CkAbort(\"This method should never be called as it refers to a LOCAL "
02813 "entry method!\");\n";
02814 str << " return 0;\n";
02815 }
02816 str << "}\n";
02817 }
02818 if (param->isMarshalled()) {
02819 str << makeDecl("void") << "::_marshallmessagepup_" << epStr()
02820 << "(PUP::er &implDestP,void *impl_msg) {\n";
02821 if (!isLocal()) {
02822 if (param->hasConditional())
02823 str << " MarshallMsg_" << epStr() << " *impl_msg_typed=(MarshallMsg_" << epStr()
02824 << " *)impl_msg;\n";
02825 else
02826 str << " CkMarshallMsg *impl_msg_typed=(CkMarshallMsg *)impl_msg;\n";
02827 str << " char *impl_buf=impl_msg_typed->msgBuf;\n";
02828 str << " envelope *env = UsrToEnv(impl_msg_typed);\n";
02829 param->beginUnmarshall(str);
02830 param->pupAllValues(str);
02831 } else {
02832 str << " /*Fake pupping since we don't really have a message */\n";
02833 str << " int n=0;\n";
02834 str << " if (implDestP.hasComments()) implDestP.comment(\"LOCAL message\");\n";
02835 str << " implDestP|n;\n";
02836 }
02837 str << "}\n";
02838 }
02839
02840
02841
02842 if ((param->isMarshalled() || param->isVoid()) && genClosureTypeNameProxy) {
02843 if (container->isTemplated()) str << container->tspec(false);
02844 if (tspec) {
02845 str << "template <";
02846 tspec->genLong(str, false);
02847 str << "> ";
02848 }
02849
02850 str << ((container->isTemplated() || tspec) ? "PUPable_def_template_nonInst"
02851 : "PUPable_def")
02852 << "(SINGLE_ARG(" << *genClosureTypeNameProxy;
02853 if (tspec) {
02854 str << "<";
02855 tspec->genShort(str);
02856 str << ">";
02857 }
02858 str << "))\n";
02859 }
02860
02861 templateGuardEnd(str);
02862 }
02863
02864 XStr Entry::genRegEp(bool isForRedn) {
02865 XStr str;
02866 str << "CkRegisterEp";
02867 if (tspec) {
02868 str << "<";
02869 tspec->genShort(str);
02870 str << ">";
02871 }
02872 str << "(\"";
02873 if (isForRedn)
02874 str << "redn_wrapper_" << name << "(CkReductionMsg *impl_msg)\",\n";
02875 else
02876 str << name << "(" << paramType(0) << ")\",\n";
02877 str << " _call_" << epStr(isForRedn, true);
02878 str << ", ";
02879
02880 if (param->isMarshalled()) {
02881 if (param->hasConditional())
02882 str << "MarshallMsg_" << epStr() << "::__idx";
02883 else
02884 str << "CkMarshallMsg::__idx";
02885 } else if (!param->isVoid() && !isMigrationConstructor()) {
02886 param->genMsgProxyName(str);
02887 str << "::__idx";
02888 } else if (isForRedn) {
02889 str << "CMessage_CkReductionMsg::__idx";
02890 } else {
02891 str << "0";
02892 }
02893
02894 str << ", __idx";
02895
02896 str << ", 0";
02897
02898
02899
02900
02901 if (!isForRedn && (attribs & SNOKEEP)) str << "+CK_EP_NOKEEP";
02902 if (attribs & SNOTRACE) str << "+CK_EP_TRACEDISABLE";
02903 if (attribs & SIMMEDIATE) {
02904 str << "+CK_EP_TRACEDISABLE";
02905 str << "+CK_EP_IMMEDIATE";
02906 }
02907 if (attribs & SINLINE) str << "+CK_EP_INLINE";
02908 if (attribs & SAPPWORK) str << "+CK_EP_APPWORK";
02909
02910
02911 if (attribs & SMEM) str << "+CK_EP_MEMCRITICAL";
02912
02913 if (internalMode) str << "+CK_EP_INTRINSIC";
02914 str << ")";
02915 return str;
02916 }
02917
02918 void Entry::genReg(XStr& str) {
02919 if (tspec) return;
02920
02921 if (external) {
02922 str << " CkIndex_" << label << "::idx_" << name;
02923 if (targs) str << "<" << targs << ">";
02924 str << "( static_cast<" << retType << " (" << label << "::*)(" << paramType(0, 0)
02925 << ")>(NULL) );\n";
02926 return;
02927 }
02928
02929 str << " // REG: " << *this;
02930 str << " " << epIdx(0) << ";\n";
02931 if (isReductionTarget()) str << " " << epIdx(0, true) << ";\n";
02932 if (isConstructor()) {
02933 if (container->isMainChare() && !isMigrationConstructor())
02934 str << " CkRegisterMainChare(__idx, " << epIdx(0) << ");\n";
02935 if (param->isVoid()) str << " CkRegisterDefaultCtor(__idx, " << epIdx(0) << ");\n";
02936 if (isMigrationConstructor())
02937 str << " CkRegisterMigCtor(__idx, " << epIdx(0) << ");\n";
02938 }
02939 }
02940
02941 void Entry::preprocess() {
02942 ParamList* pl = param;
02943 if (pl != NULL && pl->hasConditional()) {
02944 XStr str;
02945 str << "MarshallMsg_" << epStr();
02946 NamedType* nt = new NamedType(strdup(str));
02947 MsgVar* var = new MsgVar(new BuiltinType("char"), "msgBuf", 0, 1);
02948 MsgVarList* list = new MsgVarList(var);
02949 do {
02950 if (pl->param->isConditional()) {
02951 var = new MsgVar(pl->param->getType(), pl->param->getName(), 1, 0);
02952 list = new MsgVarList(var, list);
02953 }
02954 } while (NULL != (pl = pl->next));
02955 Message* m = new Message(-1, nt, list);
02956 m->setModule(container->containerModule);
02957 container->containerModule->prependConstruct(m);
02958 }
02959
02960
02961
02962 accel_numScalars = 0;
02963 accel_numArrays = 0;
02964 accel_dmaList_numReadOnly = 0;
02965 accel_dmaList_numReadWrite = 0;
02966 accel_dmaList_numWriteOnly = 0;
02967 accel_dmaList_scalarNeedsWrite = 0;
02968 if (isAccel()) {
02969 ParamList* curParam = param;
02970 if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) {
02971 curParam = curParam->next;
02972 }
02973 while (curParam != NULL) {
02974 if (curParam->param->isArray()) {
02975 accel_numArrays++;
02976 accel_dmaList_numReadOnly++;
02977 } else {
02978 accel_numScalars++;
02979 }
02980 curParam = curParam->next;
02981 }
02982 curParam = accelParam;
02983 while (curParam != NULL) {
02984 if (curParam->param->isArray()) {
02985 accel_numArrays++;
02986 switch (curParam->param->getAccelBufferType()) {
02987 case Parameter::ACCEL_BUFFER_TYPE_READWRITE:
02988 accel_dmaList_numReadWrite++;
02989 break;
02990 case Parameter::ACCEL_BUFFER_TYPE_READONLY:
02991 accel_dmaList_numReadOnly++;
02992 break;
02993 case Parameter::ACCEL_BUFFER_TYPE_WRITEONLY:
02994 accel_dmaList_numWriteOnly++;
02995 break;
02996 default:
02997 XLAT_ERROR_NOCOL("unknown accel param type", first_line_);
02998 break;
02999 }
03000 } else {
03001 accel_numScalars++;
03002 switch (curParam->param->getAccelBufferType()) {
03003 case Parameter::ACCEL_BUFFER_TYPE_READWRITE:
03004 accel_dmaList_scalarNeedsWrite++;
03005 break;
03006 case Parameter::ACCEL_BUFFER_TYPE_READONLY:
03007 break;
03008 case Parameter::ACCEL_BUFFER_TYPE_WRITEONLY:
03009 accel_dmaList_scalarNeedsWrite++;
03010 break;
03011 default:
03012 XLAT_ERROR_NOCOL("unknown accel param type", first_line_);
03013 break;
03014 }
03015 }
03016 curParam = curParam->next;
03017 }
03018 if (accel_numScalars > 0) {
03019 if (accel_dmaList_scalarNeedsWrite) {
03020 accel_dmaList_numReadWrite++;
03021 } else {
03022 accel_dmaList_numReadOnly++;
03023 }
03024 }
03025 }
03026 }
03027
03028 int Entry::paramIsMarshalled(void) { return param->isMarshalled(); }
03029
03030 int Entry::getStackSize(void) { return (stacksize ? stacksize->getIntVal() : 0); }
03031
03032 void Entry::setAccelParam(ParamList* apl) { accelParam = apl; }
03033 void Entry::setAccelCodeBody(XStr* acb) { accelCodeBody = acb; }
03034 void Entry::setAccelCallbackName(XStr* acbn) { accelCallbackName = acbn; }
03035
03036 int Entry::isThreaded(void) { return (attribs & STHREADED); }
03037 int Entry::isSync(void) { return (attribs & SSYNC); }
03038 int Entry::isIget(void) { return (attribs & SIGET); }
03039 int Entry::isConstructor(void) {
03040 return !strcmp(name, container->baseName(0).get_string());
03041 }
03042 bool Entry::isMigrationConstructor() { return isConstructor() && (attribs & SMIGRATE); }
03043 int Entry::isExclusive(void) { return (attribs & SLOCKED); }
03044 int Entry::isImmediate(void) { return (attribs & SIMMEDIATE); }
03045 int Entry::isSkipscheduler(void) { return (attribs & SSKIPSCHED); }
03046 int Entry::isInline(void) { return attribs & SINLINE; }
03047 int Entry::isLocal(void) { return attribs & SLOCAL; }
03048 int Entry::isCreate(void) { return (attribs & SCREATEHERE) || (attribs & SCREATEHOME); }
03049 int Entry::isCreateHome(void) { return (attribs & SCREATEHOME); }
03050 int Entry::isCreateHere(void) { return (attribs & SCREATEHERE); }
03051 int Entry::isPython(void) { return (attribs & SPYTHON); }
03052 int Entry::isNoTrace(void) { return (attribs & SNOTRACE); }
03053 int Entry::isAppWork(void) { return (attribs & SAPPWORK); }
03054 int Entry::isNoKeep(void) { return (attribs & SNOKEEP); }
03055 int Entry::isSdag(void) { return (sdagCon != 0); }
03056 bool Entry::isTramTarget(void) { return (attribs & SAGGREGATE) != 0; }
03057
03058
03059 int Entry::isAccel(void) { return (attribs & SACCEL); }
03060
03061 int Entry::isMemCritical(void) { return (attribs & SMEM); }
03062 int Entry::isReductionTarget(void) { return (attribs & SREDUCE); }
03063
03064 char* Entry::getEntryName() { return name; }
03065 int Entry::getLine() { return line; }
03066 Chare* Entry::getContainer(void) const { return container; }
03067
03068 }