00001 #include "xi-Entry.h"
00002 #include "xi-Parameter.h"
00003 #include "xi-Type.h"
00004 #include "xi-Value.h"
00005 #include "xi-Chare.h"
00006
00007 namespace xi {
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 Parameter::Parameter(int Nline, Type* Ntype, const char* Nname, const char* NarrLen,
00049 Value* Nvalue)
00050 : type(Ntype),
00051 name(Nname),
00052 arrLen(NarrLen),
00053 val(Nvalue),
00054 line(Nline),
00055 byConst(false),
00056 conditional(0),
00057 given_name(Nname),
00058 podType(false),
00059 rdma(CMK_REG_NO_ZC_MSG),
00060 firstRdma(false) {
00061 if (isMessage()) {
00062 name = "impl_msg";
00063 }
00064 if (name == NULL && !isVoid()) {
00065 static int unnamedCount = 0;
00066 name = new char[50];
00067 sprintf((char*)name, "impl_noname_%x", unnamedCount++);
00068 }
00069 byReference = false;
00070 declaredReference = false;
00071 if ((arrLen == NULL) && (val == NULL)) {
00072 if (type->isNamed()) {
00073 byReference = true;
00074 }
00075 if (type->isReference()) {
00076 byReference = true;
00077 declaredReference = true;
00078
00079
00080 type = type->deref();
00081 }
00082 if (type->isConst()) {
00083 byConst = true;
00084 type = type->deref();
00085 }
00086 }
00087 }
00088
00089 ParamList::ParamList(ParamList* pl)
00090 : manyPointers(false), param(pl->param), next(pl->next) {}
00091
00092 int ParamList::print(XStr& str, int withDefaultValues, int useConst, int fwdNum) {
00093 fwdNum = param->print(str, withDefaultValues, useConst, fwdNum);
00094 if (next) {
00095 str << ", ";
00096 fwdNum = next->print(str, withDefaultValues, useConst, fwdNum);
00097 }
00098 return fwdNum;
00099 }
00100
00101 void ParamList::printTypes(XStr& str, int withDefaultValues, int useConst) {
00102 XStr typeStr;
00103 param->getType()->print(typeStr);
00104 str << typeStr;
00105 if (next) {
00106 str << ", ";
00107 next->printTypes(str, withDefaultValues, useConst);
00108 }
00109 }
00110
00111 int Parameter::print(XStr& str, int withDefaultValues, int useConst, int fwdNum) {
00112 if (isRdma()) {
00113 str << "CkNcpyBuffer ncpyBuffer_" << name;
00114 } else if (arrLen != NULL) {
00115 if (useConst) str << "const ";
00116 str << type << " *";
00117 if (name != NULL) str << name;
00118 } else {
00119 if (conditional) {
00120 str << type << " *" << name;
00121 } else if (byReference) {
00122 if (fwdNum) {
00123 str << "Fwd" << fwdNum++ << " &&";
00124 } else {
00125 if (useConst || byConst) str << "const ";
00126 str << type << " &";
00127 }
00128 if (name != NULL) str << name;
00129 } else {
00130
00131
00132
00133
00134 if (!type->isVoid()) str << type;
00135 if (name != NULL) str << " " << name;
00136 if (withDefaultValues && val != NULL) {
00137 str << " = ";
00138 val->print(str);
00139 }
00140 }
00141 }
00142 return fwdNum;
00143 }
00144
00145 void ParamList::printAddress(XStr& str) {
00146 param->printAddress(str);
00147 if (next) {
00148 str << ", ";
00149 next->printAddress(str);
00150 }
00151 }
00152
00153 void Parameter::printAddress(XStr& str) {
00154 type->print(str);
00155 str << "*";
00156 if (name != NULL) str << " " << name;
00157 }
00158
00159 void ParamList::printValue(XStr& str) {
00160 param->printValue(str);
00161 if (next) {
00162 str << ", ";
00163 next->printValue(str);
00164 }
00165 }
00166
00167 void Parameter::printValue(XStr& str) {
00168 if (arrLen == NULL) str << "*";
00169 if (name != NULL) str << name;
00170 }
00171
00172 int ParamList::orEach(pred_t f) {
00173 ParamList* cur = this;
00174 int ret = 0;
00175 do {
00176 ret |= ((cur->param)->*f)();
00177 } while (NULL != (cur = cur->next));
00178 return ret;
00179 }
00180
00181 void ParamList::callEach(fn_t f, XStr& str) {
00182 ParamList* cur = this;
00183 do {
00184 ((cur->param)->*f)(str);
00185 } while (NULL != (cur = cur->next));
00186 }
00187
00188 void ParamList::callEach(rdmafn_t f, XStr& str, bool isArray) {
00189 ParamList* cur = this;
00190 do {
00191 ((cur->param)->*f)(str, isArray);
00192 } while (NULL != (cur = cur->next));
00193 }
00194
00195 void ParamList::callEach(rdmarecvfn_t f, XStr& str, bool genRdma, bool isSDAGGen) {
00196 ParamList* cur = this;
00197 int count = 0;
00198 do {
00199 ((cur->param)->*f)(str, genRdma, isSDAGGen, count);
00200 } while (NULL != (cur = cur->next));
00201 }
00202
00203 int ParamList::hasConditional() { return orEach(&Parameter::isConditional); }
00204
00206 void ParamList::marshall(XStr& str, XStr& entry_str) {
00207 if (isVoid())
00208 str << " void *impl_msg = CkAllocSysMsg(impl_e_opts);\n";
00209 else if (isMarshalled()) {
00210 str << " //Marshall: ";
00211 print(str, 0);
00212 str << "\n";
00213
00214 str << " int impl_off=0;\n";
00215 int hasArrays = orEach(&Parameter::isArray);
00216 if (hasArrays) {
00217 str << " int impl_arrstart=0;\n";
00218 callEach(&Parameter::marshallRegArraySizes, str);
00219 }
00220 bool hasrdma = hasRdma();
00221 bool hasrecvrdma = hasRecvRdma();
00222 if (hasrdma) {
00223 str << "#if CMK_ONESIDED_IMPL\n";
00224 str << " int impl_num_rdma_fields = "<<entry->numRdmaSendParams + entry->numRdmaRecvParams<<";\n";
00225 callEach(&Parameter::marshallRdmaParameters, str, true);
00226 str << "#else\n";
00227 if (!hasArrays) str << " int impl_arrstart=0;\n";
00228 callEach(&Parameter::marshallRdmaParameters, str, false);
00229 str << "#endif\n";
00230 }
00231 str << " { //Find the size of the PUP'd data\n";
00232 str << " PUP::sizer implP;\n";
00233 callEach(&Parameter::pup, str);
00234 if (hasrdma) {
00235 str << "#if CMK_ONESIDED_IMPL\n";
00236 str << " implP|impl_num_rdma_fields;\n";
00237
00238 callEach(&Parameter::pupRdma, str, true);
00239 str << "#else\n";
00240 callEach(&Parameter::pupRdma, str, false);
00241 if (!hasArrays) {
00242 str << " impl_arrstart=CK_ALIGN(implP.size(),16);\n";
00243 str << " impl_off+=impl_arrstart;\n";
00244 }
00245 str << "#endif\n";
00246 }
00247 if (hasArrays) {
00248 str << " impl_arrstart=CK_ALIGN(implP.size(),16);\n";
00249 str << " impl_off+=impl_arrstart;\n";
00250 } else
00251 str << " impl_off+=implP.size();\n";
00252 str << " }\n";
00253
00254 if (hasConditional())
00255 str << " MarshallMsg_" << entry_str << " *impl_msg=CkAllocateMarshallMsgT<MarshallMsg_"
00256 << entry_str << ">(impl_off,impl_e_opts);\n";
00257 else
00258 str << " CkMarshallMsg *impl_msg=CkAllocateMarshallMsg(impl_off,impl_e_opts);\n";
00259
00260 str << " { //Copy over the PUP'd data\n";
00261 str << " PUP::toMem implP((void *)impl_msg->msgBuf);\n";
00262 if (hasRdma()) {
00263 str << "#if CMK_ONESIDED_IMPL\n";
00264 str << " implP|impl_num_rdma_fields;\n";
00265 callEach(&Parameter::pupRdma, str, true);
00266 str << "#else\n";
00267 callEach(&Parameter::pupRdma, str, false);
00268 str << "#endif\n";
00269 }
00270 callEach(&Parameter::pup, str);
00271 callEach(&Parameter::copyPtr, str);
00272 str << " }\n";
00273 if (hasArrays) {
00274 str << " char *impl_buf=impl_msg->msgBuf+impl_arrstart;\n";
00275 callEach(&Parameter::marshallArrayData, str);
00276 }
00277 if (hasrdma) {
00278 str << "#if CMK_ONESIDED_IMPL\n";
00279 Chare *container = entry->getContainer();
00280 if(container->isChare() || container->isForElement()) {
00281 if(hasSendRdma())
00282 str << " CMI_ZC_MSGTYPE((char *)UsrToEnv(impl_msg)) = CMK_ZC_P2P_SEND_MSG;\n";
00283 else if(hasrecvrdma)
00284 str << " CMI_ZC_MSGTYPE((char *)UsrToEnv(impl_msg)) = CMK_ZC_P2P_RECV_MSG;\n";
00285 } else {
00286 if(hasSendRdma())
00287 str << " CMI_ZC_MSGTYPE((char *)UsrToEnv(impl_msg)) = CMK_ZC_BCAST_SEND_MSG;\n";
00288 else if(hasrecvrdma)
00289 str << " CMI_ZC_MSGTYPE((char *)UsrToEnv(impl_msg)) = CMK_ZC_BCAST_RECV_MSG;\n";
00290 }
00291 str << "#else\n";
00292 if (!hasArrays) str << " char *impl_buf=impl_msg->msgBuf+impl_arrstart;\n";
00293 callEach(&Parameter::marshallRdmaArrayData, str);
00294 str << "#endif\n";
00295 }
00296 }
00297 }
00298
00299 void Parameter::check() {
00300 Type* dt = type->deref();
00301 checkPointer(dt);
00302 }
00303
00304 void Parameter::checkPointer(Type* dt) {
00305 if (dt->isPointer())
00306 XLAT_ERROR_NOCOL(
00307 "can't pass pointers across processors--\n"
00308 "Indicate the array length with []'s, or pass a reference",
00309 line);
00310 }
00311
00312 void Parameter::marshallArraySizes(XStr& str, Type* dt) {
00313 str << " int impl_off_" << name << ", impl_cnt_" << name << ";\n";
00314 str << " impl_off_" << name << "=impl_off=CK_ALIGN(impl_off,sizeof(" << dt << "));\n";
00315 str << " impl_off+=(impl_cnt_" << name << "=sizeof(" << dt << ")*(" << arrLen
00316 << "));\n";
00317 }
00318
00319 void Parameter::marshallRegArraySizes(XStr& str) {
00320 Type* dt = type->deref();
00321 if (isArray()) marshallArraySizes(str, dt);
00322 }
00323
00324 void Parameter::marshallRdmaParameters(XStr& str, bool genRdma) {
00325 if (isRdma()) {
00326 Type* dt = type->deref();
00327 if (genRdma) {
00328 str << " ncpyBuffer_" << name << ".cnt=sizeof(" << dt << ")*(" << arrLen
00329 << ");\n";
00330 str << " ncpyBuffer_" << name << ".registerMem()" << ";\n";
00331 } else {
00332 marshallArraySizes(str, dt);
00333 }
00334 }
00335 }
00336
00337 void Parameter::pupRdma(XStr& str, bool genRdma) {
00338 if (isRdma()) {
00339 if (genRdma)
00340 str << " implP|ncpyBuffer_" << name << ";\n";
00341 else
00342 pupArray(str);
00343 }
00344 }
00345
00346 void Parameter::pupArray(XStr& str) {
00347 str << " implP|impl_off_" << name << ";\n";
00348 str << " implP|impl_cnt_" << name << ";\n";
00349 }
00350
00351 void Parameter::pup(XStr& str) {
00352 if (isArray()) {
00353 pupArray(str);
00354 } else if (!conditional) {
00355 if (byReference) {
00356 str << " //Have to cast away const-ness to get pup routine\n";
00357 str << " implP|(typename std::remove_cv<typename std::remove_reference<" << type << ">::type>::type &)" << name << ";\n";
00358 } else if (!isRdma())
00359 str << " implP|" << name << ";\n";
00360 }
00361 }
00362
00363 void Parameter::marshallRdmaArrayData(XStr& str) {
00364 if (isRdma()) {
00365 str << " memcpy(impl_buf+impl_off_" << name << ","
00366 << "ncpyBuffer_" << name << ".ptr"
00367 << ",impl_cnt_" << name << ");\n";
00368 str << " ncpyBuffer_" << name << ".cb.send("
00369 << "sizeof(CkNcpyBuffer)"
00370 << ","
00371 << "&ncpyBuffer_" << name
00372 << ");\n";
00373 }
00374 }
00375
00376 void Parameter::marshallArrayData(XStr& str) {
00377 if (isArray())
00378 str << " memcpy(impl_buf+impl_off_" << name << "," << name << ",impl_cnt_" << name
00379 << ");\n";
00380 }
00381
00382 void Parameter::copyPtr(XStr& str) {
00383 if (isConditional()) {
00384 str << " impl_msg->" << name << "=" << name << ";\n";
00385 }
00386 }
00387
00388 void ParamList::beginRednWrapperUnmarshall(XStr& str, bool needsClosure) {
00389 if (needsClosure) {
00390 str << *entry->genClosureTypeNameProxyTemp << "*"
00391 << " genClosure = new " << *entry->genClosureTypeNameProxyTemp << "()"
00392 << ";\n";
00393 }
00394
00395 if (isMarshalled()) {
00396 str << " /*Unmarshall pup'd fields: ";
00397 print(str, 0);
00398 str << "*/\n";
00399 str << " PUP::fromMem implP(impl_buf);\n";
00400 if (next != NULL && next->next == NULL) {
00401
00402 if (isArray() && !next->isArray()) {
00403 if (!needsClosure) {
00404 Type* dtLen = next->param->type->deref();
00405 str << " PUP::detail::TemporaryObjectHolder<" << dtLen << "> "
00406 << next->param->name << "; " << next->param->name << ".t = "
00407 << "((CkReductionMsg*)impl_msg)->getLength() / sizeof("
00408 << param->type->deref() << ");\n";
00409 Type* dt = param->type->deref();
00410 str << " " << dt << "* " << param->name << "; " << param->name << " = (" << dt
00411 << "*)impl_buf;\n";
00412 } else {
00413 str << " genClosure->" << next->param->name << " = "
00414 << "((CkReductionMsg*)impl_msg)->getLength() / sizeof("
00415 << param->type->deref() << ");\n";
00416 Type* dt = param->type->deref();
00417 str << " genClosure->" << param->name << " = (" << dt << "*)impl_buf;\n";
00418 }
00419 } else if (!isArray() && next->isArray()) {
00420 if (!needsClosure) {
00421 Type* dt = param->type->deref();
00422 str << " PUP::detail::TemporaryObjectHolder<" << dt << "> " << param->name
00423 << "; " << param->name << ".t = "
00424 << "((CkReductionMsg*)impl_msg)->getLength() / sizeof("
00425 << next->param->type->deref() << ");\n";
00426 dt = next->param->type->deref();
00427 str << " " << dt << "* " << next->param->name << "; " << next->param->name
00428 << " = (" << dt << "*)impl_buf;\n";
00429 } else {
00430 str << " genClosure->" << param->name << " = "
00431 << "((CkReductionMsg*)impl_msg)->getLength() / sizeof("
00432 << next->param->type->deref() << ");\n";
00433 Type* dt = next->param->type->deref();
00434 str << " genClosure->" << next->param->name << " = (" << dt << "*)impl_buf;\n";
00435 }
00436 } else {
00437 if (!needsClosure) {
00438 if (hasRdma()) {
00439 str << "#if CMK_ONESIDED_IMPL\n";
00440 str << " char *impl_buf_begin = impl_buf;\n";
00441 if(hasRecvRdma())
00442
00443
00444 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";
00445 str << " CkUnpackRdmaPtrs(impl_buf_begin);\n";
00446 str << " int impl_num_rdma_fields; implP|impl_num_rdma_fields;\n";
00447 callEach(&Parameter::beginUnmarshallRdma, str, true);
00448 str << "#else\n";
00449 callEach(&Parameter::beginUnmarshallRdma, str, false);
00450 str << "#endif\n";
00451 }
00452 callEach(&Parameter::beginUnmarshall, str);
00453 } else {
00454 if (hasRdma()) {
00455 str << "#if CMK_ONESIDED_IMPL\n";
00456 str << " char *impl_buf_begin = impl_buf;\n";
00457 if(hasRecvRdma())
00458
00459
00460 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";
00461 str << " CkUnpackRdmaPtrs(impl_buf_begin);\n";
00462 callEach(&Parameter::beginUnmarshallSDAGCallRdma, str, true);
00463 str << "#else\n";
00464 callEach(&Parameter::beginUnmarshallSDAGCallRdma, str, false);
00465 str << "#endif\n";
00466 }
00467 callEach(&Parameter::beginUnmarshallSDAGCall, str);
00468 }
00469 }
00470 } else if (next == NULL && isArray()) {
00471
00472 Type* dt = param->type->deref();
00473 if (!needsClosure) {
00474 str << " " << dt << "* " << param->name << "; " << param->name << " = (" << dt
00475 << "*)impl_buf;\n";
00476 } else {
00477 str << " genClosure->" << param->name << " = (" << dt << "*)impl_buf;\n";
00478 }
00479 } else {
00480 str << " /* non two-param case */\n";
00481 if (!needsClosure) {
00482 if (hasRdma()) {
00483 str << "#if CMK_ONESIDED_IMPL\n";
00484 str << " char *impl_buf_begin = impl_buf;\n";
00485 if(hasRecvRdma())
00486
00487
00488 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";
00489 str << " CkUnpackRdmaPtrs(impl_buf_begin);\n";
00490 str << " int impl_num_rdma_fields; implP|impl_num_rdma_fields;\n";
00491 callEach(&Parameter::beginUnmarshallRdma, str, true);
00492 str << "#else\n";
00493 callEach(&Parameter::beginUnmarshallRdma, str, false);
00494 str << "#endif\n";
00495 }
00496 callEach(&Parameter::beginUnmarshall, str);
00497 } else
00498 callEach(&Parameter::beginUnmarshallSDAGCall, str);
00499 str << " impl_buf+=CK_ALIGN(implP.size(),16);\n";
00500 str << " /*Unmarshall arrays:*/\n";
00501 if (!needsClosure)
00502 callEach(&Parameter::unmarshallRegArrayData, str);
00503 else
00504 callEach(&Parameter::unmarshallRegArrayDataSDAGCall, str);
00505 }
00506 }
00507 if (needsClosure) {
00508 str << " genClosure->setRefnum(CkGetRefNum((CkReductionMsg*)impl_msg));\n";
00509 }
00510 }
00511
00513 void ParamList::beginUnmarshall(XStr& str) {
00514 if (isMarshalled()) {
00515 str << " /*Unmarshall pup'd fields: ";
00516 print(str, 0);
00517 str << "*/\n";
00518 str << " PUP::fromMem implP(impl_buf);\n";
00519 if (hasRdma()) {
00520 str << "#if CMK_ONESIDED_IMPL\n";
00521 str << " char *impl_buf_begin = impl_buf;\n";
00522 if(hasRecvRdma())
00523
00524
00525 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";
00526 str << " CkUnpackRdmaPtrs(impl_buf_begin);\n";
00527 str << " int impl_num_rdma_fields; implP|impl_num_rdma_fields; \n";
00528 callEach(&Parameter::beginUnmarshallRdma, str, true);
00529 str << "#else\n";
00530 callEach(&Parameter::beginUnmarshallRdma, str, false);
00531 str << "#endif\n";
00532 if (hasRecvRdma()) {
00533 str << " CkNcpyBufferPost ncpyPost[" << entry->numRdmaRecvParams << "];\n";
00534 for(int index=0; index < entry->numRdmaRecvParams; index++) {
00535 str << " ncpyPost[" <<index<< "].regMode = CK_BUFFER_REG;\n";
00536 str << " ncpyPost[" <<index<< "].deregMode = CK_BUFFER_DEREG;\n";
00537 }
00538 }
00539 }
00540 callEach(&Parameter::beginUnmarshall, str);
00541 str << " impl_buf+=CK_ALIGN(implP.size(),16);\n";
00542 str << " /*Unmarshall arrays:*/\n";
00543 callEach(&Parameter::unmarshallRegArrayData, str);
00544 if (hasRdma()) {
00545 str << "#if !CMK_ONESIDED_IMPL\n";
00546 callEach(&Parameter::unmarshallRdmaArrayData, str, true);
00547 str << "#endif\n";
00548 }
00549 }
00550 }
00551
00552 void ParamList::storePostedRdmaPtrs(XStr& str, bool isSDAGGen) {
00553 str << "#if CMK_ONESIDED_IMPL\n";
00554 callEach(&Parameter::storePostedRdmaPtrs, str, true, isSDAGGen);
00555 str << "#else\n";
00556 callEach(&Parameter::storePostedRdmaPtrs, str, false, isSDAGGen);
00557 str << "#endif\n";
00558 }
00559
00560 void Parameter::storePostedRdmaPtrs(XStr& str, bool genRdma, bool isSDAGGen, int &count) {
00561 if(isRdma()) {
00562 if(genRdma) {
00563 str << " if(CMI_IS_ZC_RECV(env)) \n";
00564 str << " buffPtrs["<< count++ <<"] = (void *)" << "ncpyBuffer_";
00565 str << name << "_ptr;\n";
00566
00567 str << " else if(CMI_ZC_MSGTYPE(env) == CMK_ZC_BCAST_RECV_DONE_MSG) \n";
00568 str << " memcpy(" << "ncpyBuffer_" << name << "_ptr,";
00569 if(isSDAGGen)
00570 str << "genClosure->";
00571 str << "ncpyBuffer_" << name << ".ptr,";
00572 if(isSDAGGen)
00573 str << "genClosure->";
00574 str << "ncpyBuffer_" << name << ".cnt);\n";
00575 } else {
00576 Type* dt = type->deref();
00577
00578 str << " memcpy(" << "ncpyBuffer_" << name << "_ptr,";
00579 if(isSDAGGen)
00580 str << "genClosure->";
00581 str << name << "," << "impl_cnt_" << name << ");\n";
00582 }
00583 }
00584 }
00585
00586 void Parameter::beginUnmarshallArray(XStr& str) {
00587 str << " int impl_off_" << name << ", impl_cnt_" << name << ";\n";
00588 str << " implP|impl_off_" << name << ";\n";
00589 str << " implP|impl_cnt_" << name << ";\n";
00590
00591 if(isRecvRdma()) {
00592 Type* dt = type->deref();
00593 str << " " << dt << " *ncpyBuffer_" << name <<"_ptr = NULL;\n";
00594 }
00595 }
00596
00597 void Parameter::beginUnmarshallRdma(XStr& str,
00598 bool genRdma) {
00599 Type* dt = type->deref();
00600 if (isRdma()) {
00601 if (genRdma) {
00602 str << " CkNcpyBuffer ncpyBuffer_" << name << ";\n";
00603 str << " implP|ncpyBuffer_" << name << ";\n";
00604
00605 str << " " << dt << " *ncpyBuffer_" << name <<"_ptr = ";
00606 str << "("<<dt<< " *)" << " ncpyBuffer_" << name <<".ptr;\n";
00607 } else
00608 beginUnmarshallArray(str);
00609 }
00610 }
00611
00612 void Parameter::beginUnmarshall(XStr& str) {
00613 Type* dt = type->deref();
00614 if (isArray())
00615 beginUnmarshallArray(str);
00616 else if (isConditional())
00617 str << " " << dt << " *" << name << "=impl_msg_typed->" << name << ";\n";
00618 else if (!isRdma())
00619 str << " PUP::detail::TemporaryObjectHolder<" << dt << "> " << name << ";\n"
00620 << " "
00621 << "implP|" << name << ";\n";
00622 }
00623
00624 void Parameter::beginUnmarshallSDAGCallRdma(XStr& str, bool genRdma) {
00625 if (isRdma()) {
00626 if (genRdma) {
00627 if (isFirstRdma()) {
00628 str << " implP|genClosure->num_rdma_fields;\n";
00629 }
00630 str << " implP|genClosure->ncpyBuffer_" << name << ";\n";
00631 if(isRecvRdma()) {
00632 Type* dt = type->deref();
00633 str << " " << dt << " *ncpyBuffer_" << name <<"_ptr = ";
00634 str << "("<<dt<< " *)" << " (genClosure->ncpyBuffer_" << name <<").ptr;\n";
00635 }
00636 } else {
00637 beginUnmarshallArray(str);
00638 }
00639 }
00640 }
00641
00642 void Parameter::beginUnmarshallSDAGCall(XStr& str) {
00643 Type* dt = type->deref();
00644 if (isArray()) {
00645 beginUnmarshallArray(str);
00646 } else if (isRdma()) {
00647
00648 } else {
00649 str << " implP|" << (podType ? "" : "*") << "genClosure->" << name << ";\n";
00650 }
00651 }
00652
00654 void ParamList::beginUnmarshallSDAGCall(XStr& str, bool usesImplBuf) {
00655 bool hasArray = false;
00656 for (ParamList* pl = this; pl != NULL; pl = pl->next) {
00657 hasArray = hasArray || pl->param->isArray();
00658 }
00659
00660 if (isMarshalled()) {
00661 str << " PUP::fromMem implP(impl_buf);\n";
00662 str << " " << *entry->genClosureTypeNameProxyTemp << "*"
00663 << " genClosure = new " << *entry->genClosureTypeNameProxyTemp << "()"
00664 << ";\n";
00665 if (hasRdma()) {
00666 if(hasRecvRdma()) {
00667 str << " CkNcpyBufferPost ncpyPost[" << entry->numRdmaRecvParams << "];\n";
00668 for(int index=0; index < entry->numRdmaRecvParams; index++) {
00669 str << " ncpyPost[" <<index<< "].regMode = CK_BUFFER_REG;\n";
00670 str << " ncpyPost[" <<index<< "].deregMode = CK_BUFFER_DEREG;\n";
00671 }
00672 }
00673 str << "#if CMK_ONESIDED_IMPL\n";
00674 str << " char *impl_buf_begin = impl_buf;\n";
00675 if(hasRecvRdma())
00676
00677 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";
00678 str << " CkUnpackRdmaPtrs(impl_buf_begin);\n";
00679 callEach(&Parameter::beginUnmarshallSDAGCallRdma, str, true);
00680 str << "#else\n";
00681 callEach(&Parameter::beginUnmarshallSDAGCallRdma, str, false);
00682 str << "#endif\n";
00683 }
00684 callEach(&Parameter::beginUnmarshallSDAGCall, str);
00685 str << " impl_buf+=CK_ALIGN(implP.size(),16);\n";
00686 if (hasRdma()) str << "#if !CMK_ONESIDED_IMPL\n";
00687 callEach(&Parameter::unmarshallRdmaArrayDataSDAGCall, str);
00688 if (hasRdma()) str << "#endif\n";
00689 callEach(&Parameter::unmarshallRegArrayDataSDAGCall, str);
00690 if (hasArray || hasRdma()) {
00691 if (!usesImplBuf) {
00692 str << " genClosure->_impl_marshall = impl_msg_typed;\n";
00693 str << " CmiReference(UsrToEnv(genClosure->_impl_marshall));\n";
00694 } else {
00695 if (hasRdma() && !hasArray) str << "#if !CMK_ONESIDED_IMPL\n";
00696 str << " genClosure->_impl_buf_in = impl_buf;\n";
00697 str << " genClosure->_impl_buf_size = implP.size();\n";
00698 if (hasRdma() && !hasArray) str << "#endif\n";
00699 }
00700 }
00701 }
00702 }
00703 void ParamList::beginUnmarshallSDAG(XStr& str) {
00704 if (isMarshalled()) {
00705 str << " PUP::fromMem implP(impl_buf);\n";
00706 if (hasRdma()) {
00707 str << "#if CMK_ONESIDED_IMPL\n";
00708
00709
00710
00711
00712
00713
00714
00715 callEach(&Parameter::adjustUnmarshalledRdmaPtrsSDAG, str);
00716 str << " implP|num_rdma_fields;\n";
00717 callEach(&Parameter::beginUnmarshallRdma, str, true);
00718 str << "#else\n";
00719 callEach(&Parameter::beginUnmarshallRdma, str, false);
00720 str << "#endif\n";
00721 }
00722 callEach(&Parameter::beginUnmarshall, str);
00723 str << " impl_buf+=CK_ALIGN(implP.size(),16);\n";
00724
00725 str << "#if !CMK_ONESIDED_IMPL\n";
00726 callEach(&Parameter::unmarshallRdmaArrayDataSDAG, str);
00727 str << "#endif\n";
00728 callEach(&Parameter::unmarshallRegArrayDataSDAG, str);
00729 }
00730 }
00731
00732 void Parameter::unmarshallRegArrayDataSDAG(XStr& str) {
00733 if (isArray()) {
00734 Type* dt = type->deref();
00735 str << " " << name << " = (" << dt << " *)(impl_buf+impl_off_" << name
00736 << ");\n";
00737 }
00738 }
00739
00740 void Parameter::adjustUnmarshalledRdmaPtrsSDAG(XStr& str) {
00741 if (isRdma()) {
00742 str << " ncpyBuffer_" << name << ".ptr = ";
00743 str << "(void *)(impl_buf + (size_t)(ncpyBuffer_" << name << ".ptr));\n";
00744 }
00745 }
00746
00747 void Parameter::unmarshallRdmaArrayDataSDAG(XStr& str) {
00748 if (isRdma()) {
00749 Type* dt = type->deref();
00750 str << " " << name << " = (" << dt << " *)(impl_buf+impl_off_" << name
00751 << ");\n";
00752 }
00753 }
00754
00755 void Parameter::unmarshallRegArrayDataSDAGCall(XStr& str) {
00756 if (isArray()) {
00757 Type* dt = type->deref();
00758 str << " genClosure->" << name << " = (" << dt << " *)(impl_buf+impl_off_" << name
00759 << ");\n";
00760 }
00761 }
00762
00763 void Parameter::unmarshallRdmaArrayDataSDAGCall(XStr& str) {
00764 if (isRdma()) {
00765 Type* dt = type->deref();
00766 str << " genClosure->" << name << " = (" << dt << " *)(impl_buf+impl_off_" << name
00767 << ");\n";
00768 }
00769 }
00770
00771 void ParamList::unmarshallSDAGCall(XStr& str, int isFirst) {
00772 if (isFirst && isMessage())
00773 str << "(" << param->type << ")impl_msg";
00774 else if (!isVoid()) {
00775 str << "genClosure->";
00776 str << param->getName();
00777 if (next) {
00778 str << ", ";
00779 next->unmarshallSDAGCall(str, 0);
00780 }
00781 }
00782 }
00783
00784 void Parameter::unmarshallArrayData(XStr& str) {
00785 Type* dt = type->deref();
00786 str << " " << dt << " *" << name << "=(" << dt << " *)(impl_buf+impl_off_" << name
00787 << ");\n";
00788 }
00789
00790 void Parameter::unmarshallRdmaArrayData(XStr& str, bool genRegArray) {
00791 if (isRdma() && genRegArray) unmarshallArrayData(str);
00792 }
00793
00794 void Parameter::unmarshallRegArrayData(
00795 XStr& str) {
00796 if (isArray()) unmarshallArrayData(str);
00797 }
00798
00799 void ParamList::unmarshall(XStr& str, bool isInline, bool isFirst, bool isRdmaPost)
00800 {
00801 if (isFirst && isMessage())
00802 str << "(" << param->type << ")impl_msg";
00803 else if (!isVoid()) {
00804 bool isSDAGGen = entry->sdagCon || entry->isWhenEntry;
00805 if (param->isRdma()) {
00806 str << "\n#if CMK_ONESIDED_IMPL\n";
00807 str << "ncpyBuffer_" << param->getName() << "_ptr";
00808 str << "\n#else\n";
00809
00810 if(param->isRecvRdma())
00811 str << "ncpyBuffer_" << param->getName() << "_ptr";
00812 else
00813 str << param->getName();
00814 str << "\n#endif\n";
00815 } else if (param->isArray() || isInline) {
00816 if(isRdmaPost && isSDAGGen) str << "genClosure->";
00817 str << param->getName();
00818 } else {
00819 if(isRdmaPost) {
00820 if(isSDAGGen)
00821 str << "genClosure->" << param->getName();
00822 else
00823 str << param->getName() << ".t ";
00824 }
00825 else
00826 str << "std::move(" << param->getName() << ".t)";
00827 }
00828
00829 if (next) {
00830 str << ", ";
00831 next->unmarshall(str, isInline, false, isRdmaPost);
00832 }
00833 }
00834 }
00835
00836
00837 void ParamList::unmarshallForward(XStr& str,
00838 bool isInline,
00839 bool isFirst,
00840 bool isRdmaPost,
00841 int fwdNum)
00842 {
00843 if (!isInline)
00844 unmarshall(str, isInline, isFirst, isRdmaPost);
00845 if (isReference()) {
00846 str << "std::forward<Fwd" << fwdNum++ << ">(" << param->getName() << ")";
00847 if (next) {
00848 str << ", ";
00849 next->unmarshallForward(str, isInline, false, isRdmaPost, fwdNum);
00850 }
00851 } else {
00852 unmarshall(str, isInline, isFirst, isRdmaPost);
00853 }
00854 }
00855
00856 void ParamList::unmarshallAddress(XStr& str,
00857 int isFirst)
00858 {
00859 if (isFirst && isMessage())
00860 str << "(" << param->type << ")impl_msg";
00861 else if (!isVoid()) {
00862
00863 if (param->isArray())
00864 str << param->getName();
00865 else
00866 str << "& " << param->getName() << ".t";
00867 if (next) {
00868 str << ", ";
00869 next->unmarshallAddress(str, 0);
00870 }
00871 }
00872 }
00873
00874 void ParamList::pupAllValues(XStr& str) {
00875 if (isMarshalled()) callEach(&Parameter::pupAllValues, str);
00876 }
00877
00878 void Parameter::pupAllValues(XStr& str) {
00879 str << " if (implDestP.hasComments()) implDestP.comment(\"" << name << "\");\n";
00880 if (isArray()) {
00881 str << " implDestP.synchronize(PUP::sync_begin_array);\n"
00882 " for (int impl_i=0;impl_i*(sizeof(*"
00883 << name << "))<impl_cnt_" << name
00884 << ";impl_i++) {\n"
00885 " implDestP.synchronize(PUP::sync_item);\n"
00886 " implDestP|"
00887 << name
00888 << "[impl_i];\n"
00889 " }\n"
00890 " implDestP.synchronize(PUP::sync_end_array);\n";
00891 } else if (isRdma()) {
00892 str << "#if CMK_ONESIDED_IMPL\n";
00893 str << " implDestP|ncpyBuffer_" << name << ";\n";
00894 str << "#else\n";
00895 str << " implDestP.synchronize(PUP::sync_begin_array);\n"
00896 " { for (int impl_i=0;impl_i*(sizeof(*"
00897 << name << "))<impl_cnt_" << name
00898 << ";impl_i++) { \n"
00899 " implDestP.synchronize(PUP::sync_item);\n"
00900 " implDestP|"
00901 << name
00902 << "[impl_i];\n"
00903 " } } \n"
00904 " implDestP.synchronize(PUP::sync_end_array);\n";
00905 str << "#endif\n";
00906 } else {
00907 if (isConditional())
00908 str << " pup_pointer(&implDestP, (void**)&" << name << ");\n";
00909 else
00910 str << " implDestP|" << name << ";\n";
00911 }
00912 }
00913
00914 void ParamList::endUnmarshall(XStr&) {
00915
00916
00917
00918
00919
00920 }
00921
00922 void ParamList::printMsg(XStr& str) {
00923 ParamList* pl;
00924 param->printMsg(str);
00925 pl = next;
00926 while (pl != NULL) {
00927 str << ", ";
00928 pl->param->printMsg(str);
00929 pl = pl->next;
00930 }
00931 }
00932
00933 void Parameter::printMsg(XStr& str) {
00934 type->print(str);
00935 if (given_name != 0) str << given_name;
00936 }
00937
00938 int Parameter::isMessage(void) const { return type->isMessage(); }
00939 int Parameter::isVoid(void) const { return type->isVoid(); }
00940 int Parameter::isCkArgMsgPtr(void) const { return type->isCkArgMsgPtr(); }
00941 int Parameter::isCkMigMsgPtr(void) const { return type->isCkMigMsgPtr(); }
00942 int Parameter::isArray(void) const { return (arrLen != NULL && !isRdma()); }
00943 int Parameter::isConditional(void) const { return conditional; }
00944 int Parameter::isRdma(void) const { return (rdma != CMK_REG_NO_ZC_MSG); }
00945 int Parameter::isSendRdma(void) const { return (rdma == CMK_ZC_P2P_SEND_MSG); }
00946 int Parameter::isRecvRdma(void) const { return (rdma == CMK_ZC_P2P_RECV_MSG); }
00947 int Parameter::getRdma(void) const { return rdma; }
00948 int Parameter::isFirstRdma(void) const { return firstRdma; }
00949
00950 int Parameter::operator==(const Parameter& parm) const { return *type == *parm.type; }
00951
00952 void Parameter::setConditional(int c) {
00953 conditional = c;
00954 if (c) byReference = false;
00955 }
00956
00957 void Parameter::setRdma(int r) { rdma = r; }
00958
00959 void Parameter::setFirstRdma(bool fr) { firstRdma = fr; }
00960
00961 void Parameter::setAccelBufferType(int abt) {
00962 accelBufferType = ((abt < ACCEL_BUFFER_TYPE_MIN || abt > ACCEL_BUFFER_TYPE_MAX)
00963 ? (ACCEL_BUFFER_TYPE_UNKNOWN)
00964 : (abt));
00965 }
00966
00967 int Parameter::getAccelBufferType() { return accelBufferType; }
00968 void Parameter::setAccelInstName(XStr* ain) { accelInstName = ain; }
00969 XStr* Parameter::getAccelInstName(void) { return accelInstName; }
00970
00971 ParamList::ParamList(Parameter* Nparam, ParamList* Nnext) : param(Nparam), next(Nnext) {
00972 manyPointers = false;
00973 if (next != NULL && (param->isMessage() || next->isMessage())) {
00974 manyPointers = true;
00975 }
00976 }
00977
00978 int ParamList::isNamed(void) const { return param->type->isNamed(); }
00979 int ParamList::isBuiltin(void) const { return param->type->isBuiltin(); }
00980 int ParamList::isMessage(void) const { return (next == NULL) && param->isMessage(); }
00981 int ParamList::hasRdma(void) { return orEach(&Parameter::isRdma); }
00982 int ParamList::hasSendRdma(void) { return orEach(&Parameter::isSendRdma); }
00983 int ParamList::hasRecvRdma(void) { return orEach(&Parameter::isRecvRdma); }
00984 int ParamList::isRdma(void) { return param->isRdma(); }
00985 int ParamList::getRdma(void) { return param->getRdma(); }
00986 int ParamList::isFirstRdma(void) { return param->isFirstRdma(); }
00987 int ParamList::isRecvRdma(void) { return param->isRecvRdma(); }
00988 const char* ParamList::getArrayLen(void) const { return param->getArrayLen(); }
00989 int ParamList::isArray(void) const { return param->isArray(); }
00990 int ParamList::isReference(void) const {
00991 return param->type->isReference() || param->byReference;
00992 }
00993 int ParamList::declaredReference(void) const {
00994 return param->type->isReference() || param->declaredReference;
00995 }
00996 bool ParamList::isConst(void) const { return param->type->isConst() || param->byConst; }
00997 int ParamList::isVoid(void) const { return (next == NULL) && param->isVoid(); }
00998 int ParamList::isPointer(void) const { return param->type->isPointer(); }
00999 const char* ParamList::getGivenName(void) const { return param->getGivenName(); }
01000 void ParamList::setGivenName(const char* s) { param->setGivenName(s); }
01001 const char* ParamList::getName(void) const { return param->getName(); }
01002 int ParamList::isMarshalled(void) const { return !isVoid() && !isMessage(); }
01003 int ParamList::isCkArgMsgPtr(void) const {
01004 return (next == NULL) && param->isCkArgMsgPtr();
01005 }
01006 int ParamList::isCkMigMsgPtr(void) const {
01007 return (next == NULL) && param->isCkMigMsgPtr();
01008 }
01009 int ParamList::getNumStars(void) const { return param->type->getNumStars(); }
01010 const char* ParamList::getBaseName(void) { return param->type->getBaseName(); }
01011 void ParamList::genMsgProxyName(XStr& str) { param->type->genMsgProxyName(str); }
01012
01013 void ParamList::checkParamList() {
01014 if (manyPointers) {
01015 XLAT_ERROR_NOCOL(
01016 "multiple pointers passed to a non-local entry method\n"
01017 "You may pass only a single pointer to it, which should point to a message.",
01018 param->line);
01019 }
01020 }
01021
01022 int ParamList::operator==(ParamList& plist) {
01023 if (!(*param == *(plist.param))) return 0;
01024 if (!next && !plist.next) return 1;
01025 if (!next || !plist.next) return 0;
01026 return *next == *plist.next;
01027 }
01028
01029 }