00001 #include "ddt.h"
00002 #include <algorithm>
00003 #include <limits>
00004
00005 using std::numeric_limits;
00006
00007 void
00008 CkDDT::pup(PUP::er &p) noexcept
00009 {
00010 p|types;
00011 if (p.isUnpacking()) {
00012 userTypeTable.resize(types.size(), nullptr);
00013 for (int i=0; i<types.size(); i++) {
00014 switch (types[i]) {
00015 case MPI_DATATYPE_NULL:
00016 break;
00017 case CkDDT_CONTIGUOUS:
00018 userTypeTable[i] = new CkDDT_Contiguous;
00019 break;
00020 case CkDDT_VECTOR:
00021 userTypeTable[i] = new CkDDT_Vector;
00022 break;
00023 case CkDDT_HVECTOR:
00024 userTypeTable[i] = new CkDDT_HVector;
00025 break;
00026 case CkDDT_INDEXED_BLOCK:
00027 userTypeTable[i] = new CkDDT_Indexed_Block;
00028 break;
00029 case CkDDT_HINDEXED_BLOCK:
00030 userTypeTable[i] = new CkDDT_HIndexed_Block;
00031 break;
00032 case CkDDT_INDEXED:
00033 userTypeTable[i] = new CkDDT_Indexed;
00034 break;
00035 case CkDDT_HINDEXED:
00036 userTypeTable[i] = new CkDDT_HIndexed;
00037 break;
00038 case CkDDT_STRUCT:
00039 userTypeTable[i] = new CkDDT_Struct;
00040 break;
00041 default:
00042 userTypeTable[i] = new CkDDT_DataType;
00043 break;
00044 }
00045 }
00046 }
00047
00048 for (int i=0; i<types.size(); i++) {
00049 if (types[i] != MPI_DATATYPE_NULL) {
00050 userTypeTable[i]->pupType(p, this);
00051 }
00052 }
00053 }
00054
00055 void
00056 CkDDT::freeType(int index) noexcept
00057 {
00058 CkAssert(types.size() == userTypeTable.size());
00059 if (index > AMPI_MAX_PREDEFINED_TYPE) {
00060 int idx = index - AMPI_MAX_PREDEFINED_TYPE - 1;
00061
00062 if (userTypeTable[idx]->decRefCount() == 0) {
00063
00064 if (userTypeTable[idx]->getType() == CkDDT_STRUCT) {
00065 int count = userTypeTable[idx]->getCount();
00066 vector<int> &baseIndices = static_cast<CkDDT_Struct &>(*userTypeTable[idx]).getBaseIndices();
00067 for (int i=0; i<count; i++) {
00068 freeType(baseIndices[i]);
00069 }
00070 }
00071 else {
00072 freeType(userTypeTable[idx]->getBaseIndex());
00073 }
00074
00075
00076 delete userTypeTable[idx];
00077 userTypeTable[idx] = nullptr;
00078 types[idx] = MPI_DATATYPE_NULL;
00079
00080 while (!userTypeTable.empty() && userTypeTable.back() == nullptr) {
00081 userTypeTable.pop_back();
00082 CkAssert(types.back() == MPI_DATATYPE_NULL);
00083 types.pop_back();
00084 }
00085 }
00086 }
00087 CkAssert(types.size() == userTypeTable.size());
00088 }
00089
00090 CkDDT::~CkDDT() noexcept
00091 {
00092 for (int i=0; i<userTypeTable.size(); i++) {
00093 if (userTypeTable[i] != nullptr) {
00094 delete userTypeTable[i];
00095 }
00096 }
00097 }
00098
00099 int
00100 CkDDT::insertType(CkDDT_DataType* ptr, int type) noexcept
00101 {
00102
00103 CkAssert(types.size() == userTypeTable.size());
00104 for (int i=0; i<types.size(); i++) {
00105 if (types[i] == MPI_DATATYPE_NULL) {
00106 types[i] = type;
00107 userTypeTable[i] = ptr;
00108 return AMPI_MAX_PREDEFINED_TYPE + 1 + i;
00109 }
00110 }
00111 types.push_back(type);
00112 userTypeTable.push_back(ptr);
00113 return AMPI_MAX_PREDEFINED_TYPE + types.size();
00114 }
00115
00116 void
00117 CkDDT::createDup(int nIndexOld, int *nIndexNew) noexcept
00118 {
00119 CkDDT_DataType *dttype = getType(nIndexOld);
00120 CkDDT_DataType *type;
00121 int typeClass;
00122
00123 switch (dttype->getType()) {
00124 case CkDDT_CONTIGUOUS:
00125 type = new CkDDT_Contiguous(static_cast<CkDDT_Contiguous&> (*dttype));
00126 typeClass = CkDDT_CONTIGUOUS;
00127 break;
00128 case CkDDT_VECTOR:
00129 type = new CkDDT_Vector(static_cast<CkDDT_Vector&> (*dttype));
00130 typeClass = CkDDT_VECTOR;
00131 break;
00132 case CkDDT_HVECTOR:
00133 type = new CkDDT_HVector(static_cast<CkDDT_HVector&> (*dttype));
00134 typeClass = CkDDT_HVECTOR;
00135 break;
00136 case CkDDT_INDEXED_BLOCK:
00137 type = new CkDDT_Indexed_Block(static_cast<CkDDT_Indexed_Block&> (*dttype));
00138 typeClass = CkDDT_INDEXED_BLOCK;
00139 break;
00140 case CkDDT_HINDEXED_BLOCK:
00141 type = new CkDDT_HIndexed_Block(static_cast<CkDDT_HIndexed_Block&> (*dttype));
00142 typeClass = CkDDT_HINDEXED_BLOCK;
00143 break;
00144 case CkDDT_INDEXED:
00145 type = new CkDDT_Indexed(static_cast<CkDDT_Indexed&> (*dttype));
00146 typeClass = CkDDT_INDEXED;
00147 break;
00148 case CkDDT_HINDEXED:
00149 type = new CkDDT_HIndexed(static_cast<CkDDT_HIndexed&> (*dttype));
00150 typeClass = CkDDT_HINDEXED;
00151 break;
00152 case CkDDT_STRUCT:
00153 type = new CkDDT_Struct(static_cast<CkDDT_Struct&> (*dttype));
00154 typeClass = CkDDT_STRUCT;
00155 break;
00156 default:
00157 type = new CkDDT_DataType(*dttype);
00158 typeClass = dttype->getType();
00159 break;
00160 }
00161
00162 *nIndexNew = insertType(type, typeClass);
00163 }
00164
00165 int
00166 CkDDT::getEnvelope(int nIndex, int *ni, int *na, int *nd, int *combiner) const noexcept
00167 {
00168 CkDDT_DataType* dttype = getType(nIndex);
00169 return dttype->getEnvelope(ni, na, nd, combiner);
00170 }
00171
00172 int
00173 CkDDT::getContents(int nIndex, int ni, int na, int nd, int i[], MPI_Aint a[], int d[]) noexcept
00174 {
00175 CkDDT_DataType* dttype = getType(nIndex);
00176 int ret = dttype->getContents(ni, na, nd, i, a, d);
00177 if (dttype->getType() == CkDDT_STRUCT) {
00178 int count = dttype->getCount();
00179 vector<CkDDT_DataType *> &baseTypes = static_cast<CkDDT_Struct &>(*dttype).getBaseTypes();
00180 for (int i=0; i<count; i++) {
00181 baseTypes[i]->incRefCount();
00182 }
00183 }
00184 else {
00185 dttype->getBaseType()->incRefCount();
00186 }
00187 return ret;
00188 }
00189
00190 void
00191 CkDDT::createResized(MPI_Datatype oldtype, MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newType) noexcept
00192 {
00193 CkDDT_DataType *dttype = getType(oldtype);
00194 CkDDT_DataType *type;
00195 int typeClass;
00196
00197 switch (dttype->getType()) {
00198 case CkDDT_CONTIGUOUS:
00199 type = new CkDDT_Contiguous(static_cast<CkDDT_Contiguous &>(*dttype));
00200 type->setSize(lb, extent);
00201 typeClass = CkDDT_CONTIGUOUS;
00202 break;
00203 case CkDDT_VECTOR:
00204 type = new CkDDT_Vector(static_cast<CkDDT_Vector &>(*dttype));
00205 type->setSize(lb, extent);
00206 typeClass = CkDDT_VECTOR;
00207 break;
00208 case CkDDT_HVECTOR:
00209 type = new CkDDT_HVector(static_cast<CkDDT_HVector &>(*dttype));
00210 type->setSize(lb, extent);
00211 typeClass = CkDDT_HVECTOR;
00212 break;
00213 case CkDDT_INDEXED_BLOCK:
00214 type = new CkDDT_Indexed_Block(static_cast<CkDDT_Indexed_Block &>(*dttype));
00215 type->setSize(lb, extent);
00216 typeClass = CkDDT_INDEXED_BLOCK;
00217 break;
00218 case CkDDT_HINDEXED_BLOCK:
00219 type = new CkDDT_HIndexed_Block(static_cast<CkDDT_HIndexed_Block &>(*dttype));
00220 type->setSize(lb, extent);
00221 typeClass = CkDDT_HINDEXED_BLOCK;
00222 break;
00223 case CkDDT_INDEXED:
00224 type = new CkDDT_Indexed(static_cast<CkDDT_Indexed &>(*dttype));
00225 type->setSize(lb, extent);
00226 typeClass = CkDDT_INDEXED;
00227 break;
00228 case CkDDT_HINDEXED:
00229 type = new CkDDT_HIndexed(static_cast<CkDDT_HIndexed &>(*dttype));
00230 type->setSize(lb, extent);
00231 typeClass = CkDDT_HINDEXED;
00232 break;
00233 case CkDDT_STRUCT:
00234 type = new CkDDT_Struct(static_cast<CkDDT_Struct &>(*dttype));
00235 type->setSize(lb, extent);
00236 typeClass = CkDDT_STRUCT;
00237 break;
00238 default:
00239 type = new CkDDT_DataType(*dttype, lb, extent);
00240 typeClass = dttype->getType();
00241 break;
00242 }
00243
00244 *newType = insertType(type, typeClass);
00245 }
00246
00247 void
00248 CkDDT::newContiguous(int count, MPI_Datatype oldType, MPI_Datatype *newType) noexcept
00249 {
00250 CkDDT_DataType *type = new CkDDT_Contiguous(count, oldType, getType(oldType));
00251 *newType = insertType(type, CkDDT_CONTIGUOUS);
00252 }
00253
00254 void
00255 CkDDT::newVector(int count, int blocklength, int stride,
00256 MPI_Datatype oldType, MPI_Datatype* newType) noexcept
00257 {
00258 CkDDT_DataType* type = new CkDDT_Vector(count, blocklength, stride, oldType, getType(oldType));
00259 *newType = insertType(type, CkDDT_VECTOR);
00260 }
00261
00262 void
00263 CkDDT::newHVector(int count, int blocklength, int stride,
00264 MPI_Datatype oldtype, MPI_Datatype* newType) noexcept
00265 {
00266 CkDDT_DataType* type = new CkDDT_HVector(count, blocklength, stride, oldtype, getType(oldtype));
00267 *newType = insertType(type, CkDDT_HVECTOR);
00268 }
00269
00270 void
00271 CkDDT::newIndexedBlock(int count, int Blocklength, const int *arrDisp, MPI_Datatype oldtypeIdx,
00272 MPI_Datatype *newType) noexcept
00273 {
00274
00275
00276
00277 CkDDT_DataType* oldtype = getType(oldtypeIdx);
00278 std::vector<MPI_Aint> arrDispBytes(count);
00279 for (int i=0; i<count; i++) {
00280 arrDispBytes[i] = static_cast<MPI_Aint>(arrDisp[i] * oldtype->getExtent());
00281 }
00282 CkDDT_DataType *type = new CkDDT_Indexed_Block(count, Blocklength, arrDispBytes.data(),
00283 arrDisp, oldtypeIdx, oldtype);
00284 *newType = insertType(type, CkDDT_INDEXED_BLOCK);
00285 }
00286
00287 void
00288 CkDDT::newHIndexedBlock(int count, int Blocklength, const MPI_Aint *arrDisp, MPI_Datatype oldtype,
00289 MPI_Datatype *newType) noexcept
00290 {
00291 CkDDT_DataType *type = new CkDDT_HIndexed_Block(count, Blocklength, arrDisp,
00292 oldtype, getType(oldtype));
00293 *newType = insertType(type, CkDDT_HINDEXED_BLOCK);
00294 }
00295
00296 void
00297 CkDDT::newIndexed(int count, const int* arrbLength, MPI_Aint* arrDisp,
00298 MPI_Datatype oldtypeIdx, MPI_Datatype* newType) noexcept
00299 {
00300 CkDDT_DataType* oldtype = getType(oldtypeIdx);
00301 vector<MPI_Aint> dispBytesArr(count);
00302 for (int i=0; i<count; i++) {
00303 dispBytesArr[i] = arrDisp[i] * oldtype->getExtent();
00304 }
00305 CkDDT_DataType* type = new CkDDT_Indexed(count, arrbLength, dispBytesArr.data(), arrDisp,
00306 oldtypeIdx, oldtype);
00307 *newType = insertType(type, CkDDT_INDEXED);
00308 }
00309
00310 void
00311 CkDDT::newHIndexed(int count, const int* arrbLength, const MPI_Aint* arrDisp,
00312 MPI_Datatype oldtype, MPI_Datatype* newType) noexcept
00313 {
00314 CkDDT_DataType* type = new CkDDT_HIndexed(count, arrbLength, arrDisp, oldtype, getType(oldtype));
00315 *newType = insertType(type, CkDDT_HINDEXED);
00316 }
00317
00318 void
00319 CkDDT::newStruct(int count, const int* arrbLength, const MPI_Aint* arrDisp,
00320 const MPI_Datatype *oldtype, MPI_Datatype* newType) noexcept
00321 {
00322 vector<CkDDT_DataType *> olddatatypes(count);
00323 for(int i=0;i<count;i++){
00324 olddatatypes[i] = getType(oldtype[i]);
00325 }
00326 CkDDT_DataType* type = new CkDDT_Struct(count, arrbLength, arrDisp, oldtype, olddatatypes.data());
00327 *newType = insertType(type, CkDDT_STRUCT);
00328 }
00329
00330 CkDDT_DataType::CkDDT_DataType(int type) noexcept : datatype(type)
00331 {
00332 count = 1;
00333 switch (datatype) {
00334 case MPI_DOUBLE:
00335 size = sizeof(double);
00336 numElements = 1;
00337 name = "MPI_DOUBLE";
00338 break;
00339 case MPI_INT:
00340 size = sizeof(signed int);
00341 numElements = 1;
00342 name = "MPI_INT";
00343 break;
00344 case MPI_FLOAT:
00345 size = sizeof(float);
00346 numElements = 1;
00347 name = "MPI_FLOAT";
00348 break;
00349 case MPI_CHAR:
00350 size = sizeof(char);
00351 numElements = 1;
00352 name = "MPI_CHAR";
00353 break;
00354 case MPI_BYTE:
00355 size = 1 ;
00356 numElements = 1;
00357 name = "MPI_BYTE";
00358 break;
00359 case MPI_PACKED:
00360 size = 1 ;
00361 numElements = 1;
00362 name = "MPI_PACKED";
00363 break;
00364 case MPI_C_BOOL:
00365
00366 size = sizeof(bool) ;
00367 numElements = 1;
00368 name = "MPI_C_BOOL";
00369 break;
00370 case MPI_LOGICAL:
00371 size = sizeof(int) ;
00372 numElements = 1;
00373 name = "MPI_LOGICAL";
00374 break;
00375 case MPI_SHORT:
00376 size = sizeof(signed short int);
00377 numElements = 1;
00378 name = "MPI_SHORT";
00379 break;
00380 case MPI_LONG:
00381 size = sizeof(signed long);
00382 numElements = 1;
00383 name = "MPI_LONG";
00384 break;
00385 case MPI_UNSIGNED_CHAR:
00386 size = sizeof(unsigned char);
00387 numElements = 1;
00388 name = "MPI_UNSIGNED_CHAR";
00389 break;
00390 case MPI_UNSIGNED_SHORT:
00391 size = sizeof(unsigned short);
00392 numElements = 1;
00393 name = "MPI_UNSIGNED_SHORT";
00394 break;
00395 case MPI_UNSIGNED:
00396 size = sizeof(unsigned);
00397 numElements = 1;
00398 name = "MPI_UNSIGNED";
00399 break;
00400 case MPI_UNSIGNED_LONG:
00401 size = sizeof(unsigned long);
00402 numElements = 1;
00403 name = "MPI_UNSIGNED_LONG";
00404 break;
00405 case MPI_LONG_DOUBLE:
00406 size = sizeof(long double);
00407 numElements = 1;
00408 name = "MPI_LONG_DOUBLE";
00409 break;
00410 case MPI_SIGNED_CHAR:
00411 size = sizeof(signed char);
00412 numElements = 1;
00413 name = "MPI_SIGNED_CHAR";
00414 break;
00415 case MPI_UNSIGNED_LONG_LONG:
00416 size = sizeof(unsigned long long);
00417 numElements = 1;
00418 name = "MPI_UNSIGNED_LONG_LONG";
00419 break;
00420 case MPI_WCHAR:
00421 size = sizeof(wchar_t);
00422 numElements = 1;
00423 name = "MPI_WCHAR";
00424 break;
00425 case MPI_INT8_T:
00426 size = sizeof(int8_t);
00427 numElements = 1;
00428 name = "MPI_INT8_T";
00429 break;
00430 case MPI_INT16_T:
00431 size = sizeof(int16_t);
00432 numElements = 1;
00433 name = "MPI_INT16_T";
00434 break;
00435 case MPI_INT32_T:
00436 size = sizeof(int32_t);
00437 numElements = 1;
00438 name = "MPI_INT32_T";
00439 break;
00440 case MPI_INT64_T:
00441 size = sizeof(int64_t);
00442 numElements = 1;
00443 name = "MPI_INT64_T";
00444 break;
00445 case MPI_UINT8_T:
00446 size = sizeof(uint8_t);
00447 numElements = 1;
00448 name = "MPI_UINT8_T";
00449 break;
00450 case MPI_UINT16_T:
00451 size = sizeof(uint16_t);
00452 numElements = 1;
00453 name = "MPI_UINT16_T";
00454 break;
00455 case MPI_UINT32_T:
00456 size = sizeof(uint32_t);
00457 numElements = 1;
00458 name = "MPI_UINT32_T";
00459 break;
00460 case MPI_UINT64_T:
00461 size = sizeof(uint64_t);
00462 numElements = 1;
00463 name = "MPI_UINT64_T";
00464 break;
00465 case MPI_AINT:
00466 size = sizeof(MPI_Aint);
00467 numElements = 1;
00468 name = "MPI_AINT";
00469 break;
00470 case MPI_LB:
00471 size = 0;
00472 numElements = 0;
00473 name = "MPI_LB";
00474 break;
00475 case MPI_UB:
00476 size = 0;
00477 numElements = 0;
00478 name = "MPI_UB";
00479 break;
00480 #if CMK_LONG_LONG_DEFINED
00481 case MPI_LONG_LONG_INT:
00482 size = sizeof(signed long long);
00483 name = "MPI_LONG_LONG_INT";
00484 break;
00485 #endif
00486 default:
00487 CkAbort("CkDDT: Trying to make primitive type with unsupported type");
00488 }
00489
00490 trueExtent = size;
00491 extent = size;
00492 lb = 0;
00493 ub = size;
00494 trueLB = 0;
00495 iscontig = true;
00496 baseType = NULL;
00497 baseSize = 0;
00498 baseExtent = 0;
00499 baseIndex = -1;
00500 refCount = 1;
00501
00502 DDTDEBUG("CkDDT_DataType constructor: type=%d, size=%d, extent=%ld, iscontig=%d\n",
00503 type, size, extent, iscontig);
00504 }
00505
00506 CkDDT_DataType::CkDDT_DataType(int datatype, int size, MPI_Aint extent, int count, MPI_Aint lb,
00507 MPI_Aint ub, bool iscontig, int baseSize, MPI_Aint baseExtent,
00508 CkDDT_DataType* baseType, int numElements, int baseIndex,
00509 MPI_Aint trueExtent, MPI_Aint trueLB) noexcept :
00510 iscontig(iscontig), isAbsolute(false), size(size), count(count), datatype(datatype),
00511 refCount(1), baseSize(baseSize), baseIndex(baseIndex), numElements(numElements),
00512 extent(extent), ub(ub), lb(lb), trueExtent(trueExtent), trueLB(trueLB),
00513 baseExtent(baseExtent), baseType(baseType)
00514 {
00515 if (baseType) {
00516 baseType->incRefCount();
00517 }
00518 }
00519
00520 CkDDT_DataType::CkDDT_DataType(const CkDDT_DataType &obj, MPI_Aint _lb, MPI_Aint _extent) noexcept :
00521 iscontig(obj.iscontig)
00522 ,isAbsolute(obj.isAbsolute)
00523 ,size(obj.size)
00524 ,count(obj.count)
00525 ,datatype(obj.datatype)
00526 ,refCount(1)
00527 ,baseSize(obj.baseSize)
00528 ,baseIndex(obj.baseIndex)
00529 ,numElements(obj.numElements)
00530 ,extent(obj.extent)
00531 ,ub(obj.ub)
00532 ,lb(obj.lb)
00533 ,trueExtent(obj.trueExtent)
00534 ,trueLB(obj.trueLB)
00535 ,baseExtent(obj.baseExtent)
00536 ,baseType(obj.baseType)
00537 ,name(obj.name)
00538 {
00539 if (baseType) {
00540 baseType->incRefCount();
00541 }
00542 if ((_lb != 0 || _lb != obj.lb) ||
00543 (_extent != 0 || _extent != obj.extent)) {
00544 setSize(_lb, _extent);
00545 }
00546 }
00547
00548 void
00549 CkDDT_DataType::setSize(MPI_Aint _lb, MPI_Aint _extent) noexcept
00550 {
00551 extent = _extent;
00552 lb = _lb;
00553 ub = lb + extent;
00554
00555 if (extent != size) {
00556 iscontig = false;
00557 }
00558 else {
00559 if (baseType != NULL) {
00560 iscontig = baseType->isContig();
00561 }
00562 else {
00563 iscontig = true;
00564 }
00565 }
00566 }
00567
00568 int
00569 CkDDT_DataType::getNumBasicElements(int bytes) const noexcept
00570 {
00571 int extent = getSize();
00572 if (extent == 0) {
00573 return 0;
00574 }
00575 else {
00576 return (bytes/extent) * getNumElements();
00577 }
00578 }
00579
00580 void
00581 CkDDT_DataType::pupType(PUP::er &p, CkDDT* ddt) noexcept
00582 {
00583 p|datatype;
00584 p|refCount;
00585 p|size;
00586 p|extent;
00587 p|count;
00588 p|baseSize;
00589 p|baseExtent;
00590 p|baseIndex;
00591 p|trueExtent;
00592 p|trueLB;
00593 p|lb;
00594 p|ub;
00595 p|iscontig;
00596 p|isAbsolute;
00597 p|numElements;
00598 p|keyvals;
00599 p|name;
00600 if (p.isUnpacking()) {
00601 baseType = NULL;
00602 }
00603 }
00604
00605 int
00606 CkDDT_DataType::getEnvelope(int *ni, int *na, int *nd, int *combiner) const noexcept
00607 {
00608 *ni = 0;
00609 *na = 0;
00610 *nd = 0;
00611 *combiner = MPI_COMBINER_NAMED;
00612 return MPI_SUCCESS;
00613 }
00614
00615 int
00616 CkDDT_DataType::getContents(int ni, int na, int nd, int i[], MPI_Aint a[], int d[]) const noexcept
00617 {
00618 return MPI_ERR_TYPE;
00619 }
00620
00621 CkDDT_Contiguous::CkDDT_Contiguous(int nCount, int bindex, CkDDT_DataType* oldType) noexcept
00622 {
00623 datatype = CkDDT_CONTIGUOUS;
00624 count = nCount;
00625 baseType = oldType;
00626 baseIndex = bindex;
00627 baseSize = baseType->getSize();
00628 baseExtent = baseType->getExtent();
00629 refCount = 1;
00630 baseType->incRefCount();
00631 size = count * baseSize;
00632 numElements = count * baseType->getNumElements();
00633
00634 if (baseType->getLB() > baseType->getUB()) {
00635 lb = baseType->getLB() + (baseExtent*(count-1));
00636 ub = baseType->getUB();
00637 trueLB = baseType->getTrueLB() + (baseExtent*(count-1));
00638 trueExtent = baseType->getTrueLB() + baseType->getTrueExtent() - ((count-1)*baseExtent);
00639 }
00640 else {
00641 lb = baseType->getLB();
00642 ub = lb + count * baseExtent;
00643 trueLB = baseType->getTrueLB();
00644 trueExtent = ((count - 1) * baseExtent) + baseType->getTrueExtent();
00645 }
00646
00647 extent = ub - lb;
00648
00649 if (extent != size || count == 0) {
00650 iscontig = false;
00651 }
00652 else {
00653 iscontig = baseType->isContig();
00654 }
00655 }
00656
00657 size_t
00658 CkDDT_Contiguous::serialize(char* userdata, char* buffer, int num, int msgLength, CkDDT_Dir dir) const noexcept
00659 {
00660 DDTDEBUG("CkDDT_Contiguous::serialize, %s %d objects of type %d (iscontig=%d)\n",
00661 (dir==PACK)?"packing":"unpacking", num, baseType->getType(), (int)iscontig);
00662 size_t bytesCopied = 0;
00663 if (iscontig) {
00664 bytesCopied = (size_t)num * (size_t)count * (size_t)baseSize;
00665 serializeContig(userdata, buffer, std::min(bytesCopied, (size_t)msgLength), dir);
00666 }
00667 else {
00668 for (; num>0; num--) {
00669 int bytesProcessed = baseType->serialize(userdata, buffer, count, msgLength, dir);
00670 bytesCopied += bytesProcessed;
00671 msgLength -= bytesProcessed;
00672 buffer += size;
00673 userdata += extent;
00674 if (msgLength == 0) {
00675 return bytesCopied;
00676 }
00677 }
00678 }
00679 return bytesCopied;
00680 }
00681
00682 void
00683 CkDDT_Contiguous::pupType(PUP::er &p, CkDDT *ddt) noexcept
00684 {
00685 CkDDT_DataType::pupType(p, ddt);
00686 if (p.isUnpacking()) {
00687 baseType = ddt->getType(baseIndex);
00688 }
00689 }
00690
00691 int
00692 CkDDT_Contiguous::getEnvelope(int *ni, int *na, int *nd, int *combiner) const noexcept
00693 {
00694 *ni = 1;
00695 *na = 0;
00696 *nd = 1;
00697 *combiner = MPI_COMBINER_CONTIGUOUS;
00698 return MPI_SUCCESS;
00699 }
00700
00701 int
00702 CkDDT_Contiguous::getContents(int ni, int na, int nd, int i[], MPI_Aint a[], int d[]) const noexcept
00703 {
00704 i[0] = count;
00705 d[0] = baseIndex;
00706 return MPI_SUCCESS;
00707 }
00708
00709 int
00710 CkDDT_Contiguous::getNumBasicElements(int bytes) const noexcept
00711 {
00712 return getBaseType()->getNumBasicElements(bytes);
00713 }
00714
00715 CkDDT_Vector::CkDDT_Vector(int nCount, int blength, int stride, int bindex, CkDDT_DataType* oldType) noexcept
00716 {
00717 datatype = CkDDT_VECTOR;
00718 count = nCount;
00719 blockLength = blength;
00720 strideLength = stride;
00721 baseIndex = bindex;
00722 baseType = oldType;
00723 baseSize = baseType->getSize();
00724 baseExtent = baseType->getExtent();
00725 refCount = 1;
00726 baseType->incRefCount();
00727 numElements = count * baseType->getNumElements();
00728 size = count * blockLength * baseSize;
00729
00730 int absBaseExtent = std::abs(baseExtent);
00731 int absStrideLength = std::abs(strideLength);
00732
00733 if (baseType->getLB() > baseType->getUB()) {
00734 if (strideLength > 0) {
00735
00736 lb = baseType->getUB() + (((strideLength*count)-2-(absStrideLength-blockLength))*baseExtent);
00737 ub = baseType->getUB();
00738 trueLB = lb - baseType->getLB();
00739 }
00740 else {
00741
00742 lb = baseType->getLB() + ((blockLength-1)*baseExtent);
00743 ub = baseType->getUB() + (strideLength*(count-1)*baseExtent);
00744 trueLB = baseType->getLB() - baseType->getUB() + (blockLength*baseExtent);
00745 }
00746 }
00747 else {
00748 if (strideLength > 0) {
00749
00750 lb = baseType->getLB();
00751 ub = lb + (count*blockLength + ((strideLength-blockLength)*(count-1))) * baseExtent;
00752 trueLB = baseType->getTrueLB();
00753 }
00754 else {
00755
00756 lb = baseType->getLB() + (strideLength*baseExtent*(count-1));
00757 ub = lb + blockLength*baseExtent + absStrideLength*(count-1)*baseExtent;
00758 trueLB = baseType->getTrueLB() + ((count-1) * strideLength * baseType->getExtent());
00759 }
00760 }
00761
00762 extent = ub - lb;
00763
00764 if (absStrideLength < blockLength) {
00765 trueExtent = ((count-1) * stride * absBaseExtent) + (blockLength * absBaseExtent) -
00766 (absBaseExtent - baseType->getTrueExtent());
00767 }
00768 else {
00769 trueExtent = (((absStrideLength*count)-(absStrideLength-blockLength))*absBaseExtent) -
00770 (absBaseExtent - baseType->getTrueExtent());
00771 }
00772
00773 if (extent != size || count == 0) {
00774 iscontig = false;
00775 }
00776 else {
00777 if (count==1 || (strideLength==1 && blockLength==1)) {
00778 iscontig = baseType->isContig();
00779 }
00780 else {
00781 iscontig = false;
00782 }
00783 }
00784 }
00785
00786 size_t
00787 CkDDT_Vector::serialize(char* userdata, char* buffer, int num, int msgLength, CkDDT_Dir dir) const noexcept
00788 {
00789 DDTDEBUG("CkDDT_Vector::serialize, %s %d objects of type %d (iscontig=%d)\n",
00790 (dir==PACK)?"packing":"unpacking", num, baseType->getType(), (int)iscontig);
00791
00792 size_t bytesCopied = 0;
00793 if (iscontig) {
00794 bytesCopied = (size_t)num * (size_t)count * (size_t)blockLength * (size_t)baseSize;
00795 serializeContig(userdata, buffer, std::min(bytesCopied, (size_t)msgLength), dir);
00796 }
00797 else {
00798 for (; num>0; num--) {
00799 char* saveUserdata = userdata;
00800 for (int i=0; i<count; i++) {
00801 int bytesProcessed = baseType->serialize(userdata, buffer, blockLength, msgLength, dir);
00802 bytesCopied += bytesProcessed;
00803 msgLength -= bytesProcessed;
00804 buffer += (blockLength*baseSize);
00805 userdata += (strideLength*baseExtent);
00806 if (msgLength == 0) {
00807 return bytesCopied;
00808 }
00809 }
00810 userdata = saveUserdata + extent;
00811 }
00812 }
00813 return bytesCopied;
00814 }
00815
00816 void
00817 CkDDT_Vector::pupType(PUP::er &p, CkDDT* ddt) noexcept
00818 {
00819 CkDDT_DataType::pupType(p, ddt);
00820 p|blockLength;
00821 p|strideLength;
00822 if (p.isUnpacking()) {
00823 baseType = ddt->getType(baseIndex);
00824 }
00825 }
00826
00827 int
00828 CkDDT_Vector::getEnvelope(int *ni, int *na, int *nd, int *combiner) const noexcept
00829 {
00830 *ni = 3;
00831 *na = 0;
00832 *nd = 1;
00833 *combiner = MPI_COMBINER_VECTOR;
00834 return MPI_SUCCESS;
00835 }
00836
00837 int
00838 CkDDT_Vector::getContents(int ni, int na, int nd, int i[], MPI_Aint a[], int d[]) const noexcept
00839 {
00840 i[0] = count;
00841 i[1] = blockLength;
00842 i[2] = strideLength;
00843 d[0] = baseIndex;
00844 return MPI_SUCCESS;
00845 }
00846
00847 int
00848 CkDDT_Vector::getNumBasicElements(int bytes) const noexcept
00849 {
00850 return getBaseType()->getNumBasicElements(bytes);
00851 }
00852
00853 CkDDT_HVector::CkDDT_HVector(int nCount, int blength, int stride, int bindex,
00854 CkDDT_DataType* oldType) noexcept
00855 {
00856 datatype = CkDDT_HVECTOR;
00857 count = nCount;
00858 blockLength = blength;
00859 strideLength = stride;
00860 baseIndex = bindex;
00861 baseType = oldType;
00862 baseSize = baseType->getSize();
00863 baseExtent = baseType->getExtent();
00864 refCount = 1;
00865 baseType->incRefCount();
00866 numElements = count * baseType->getNumElements();
00867 size = count * blockLength * baseSize;
00868
00869 if (strideLength < 0) {
00870 extent = blockLength*baseExtent + (-1)*strideLength*(count-1);
00871 }
00872 else {
00873 extent = count*blockLength*baseExtent + ((strideLength-blockLength*baseExtent)*(count-1));
00874 }
00875
00876 lb = baseType->getLB();
00877 if (strideLength < 0) {
00878 lb += (strideLength*(count-1));
00879 }
00880 ub = lb + extent;
00881
00882 trueExtent = extent;
00883 trueLB = lb;
00884 if (extent != size || count == 0) {
00885 iscontig = false;
00886 }
00887 else {
00888 if (count==1 || (strideLength==1 && blockLength==1)) {
00889 iscontig = baseType->isContig();
00890 }
00891 else {
00892 iscontig = false;
00893 }
00894 }
00895 }
00896
00897 size_t
00898 CkDDT_HVector::serialize(char* userdata, char* buffer, int num, int msgLength, CkDDT_Dir dir) const noexcept
00899 {
00900 DDTDEBUG("CkDDT_HVector::serialize, %s %d objects of type %d (iscontig=%d)\n",
00901 (dir==PACK)?"packing":"unpacking", num, baseType->getType(), (int)iscontig);
00902
00903 size_t bytesCopied = 0;
00904 if (iscontig) {
00905 bytesCopied = (size_t)num * (size_t)count * (size_t)blockLength * (size_t)baseSize;
00906 serializeContig(userdata, buffer, std::min(bytesCopied, (size_t)msgLength), dir);
00907 }
00908 else {
00909 for (; num>0; num--) {
00910 char* saveUserdata = userdata;
00911 for (int i=0; i<count; i++) {
00912 int bytesProcessed = baseType->serialize(userdata, buffer, blockLength, msgLength, dir);
00913 bytesCopied += bytesProcessed;
00914 msgLength -= bytesProcessed;
00915 buffer += (blockLength*baseSize);
00916 userdata += strideLength;
00917 if (msgLength == 0) {
00918 return bytesCopied;
00919 }
00920 }
00921 userdata = saveUserdata + extent;
00922 }
00923 }
00924 return bytesCopied;
00925 }
00926
00927 void
00928 CkDDT_HVector::pupType(PUP::er &p, CkDDT* ddt) noexcept
00929 {
00930 CkDDT_Vector::pupType(p, ddt);
00931 }
00932
00933 int
00934 CkDDT_HVector::getEnvelope(int *ni, int *na, int *nd, int *combiner) const noexcept
00935 {
00936 *ni = 2;
00937 *na = 1;
00938 *nd = 1;
00939 *combiner = MPI_COMBINER_HVECTOR;
00940 return MPI_SUCCESS;
00941 }
00942
00943 int
00944 CkDDT_HVector::getContents(int ni, int na, int nd, int i[], MPI_Aint a[], int d[]) const noexcept
00945 {
00946 i[0] = count;
00947 i[1] = blockLength;
00948 a[0] = strideLength;
00949 d[0] = baseIndex;
00950 return MPI_SUCCESS;
00951 }
00952
00953 int
00954 CkDDT_HVector::getNumBasicElements(int bytes) const noexcept
00955 {
00956 return getBaseType()->getNumBasicElements(bytes);
00957 }
00958
00959 CkDDT_Indexed_Block::CkDDT_Indexed_Block(int count, int Blength, const MPI_Aint *arrBytesDisp,
00960 const int *ArrDisp, int index, CkDDT_DataType *type) noexcept
00961 : CkDDT_HIndexed_Block(count, Blength, arrBytesDisp, index, type)
00962 {
00963 for (int i=0; i<count; i++) {
00964 arrayDisplacements[i] = static_cast<MPI_Aint>(ArrDisp[i]);
00965 }
00966 datatype = CkDDT_INDEXED_BLOCK;
00967 }
00968
00969 size_t
00970 CkDDT_Indexed_Block::serialize(char *userdata, char *buffer, int num, int msgLength, CkDDT_Dir dir) const noexcept
00971 {
00972 DDTDEBUG("CkDDT_Indexed_Block::serialize, %s %d objects of type %d (iscontig=%d)\n",
00973 (dir==PACK)?"packing":"unpacking", num, baseType->getType(), (int)iscontig);
00974
00975 size_t bytesCopied = 0;
00976 if (iscontig) {
00977 bytesCopied = (size_t)num * (size_t)count * (size_t)blockLength * (size_t)baseSize;
00978 serializeContig(userdata, buffer, std::min(bytesCopied, (size_t)msgLength), dir);
00979 }
00980 else {
00981 for (; num>0; num--) {
00982 char* saveUserdata = userdata;
00983 for (int i=0; i<count; i++) {
00984 userdata = saveUserdata + baseExtent * arrayDisplacements[i];
00985 for (int j=0; j<blockLength ; j++) {
00986 int bytesProcessed = baseType->serialize(userdata, buffer, 1, msgLength, dir);
00987 bytesCopied += bytesProcessed;
00988 msgLength -= bytesProcessed;
00989 buffer += baseSize;
00990 userdata += baseExtent;
00991 if (msgLength == 0) {
00992 return bytesCopied;
00993 }
00994 }
00995 }
00996 userdata = saveUserdata + extent;
00997 }
00998 }
00999 return bytesCopied;
01000 }
01001
01002 void
01003 CkDDT_Indexed_Block::pupType(PUP::er &p, CkDDT *ddt) noexcept
01004 {
01005 CkDDT_HIndexed_Block::pupType(p, ddt);
01006 }
01007
01008 int
01009 CkDDT_Indexed_Block::getEnvelope(int *ni, int *na, int *nd, int *combiner) const noexcept
01010 {
01011 *ni = count+2;
01012 *na = 0;
01013 *nd = 1;
01014 *combiner = MPI_COMBINER_INDEXED_BLOCK;
01015 return MPI_SUCCESS;
01016 }
01017
01018 int
01019 CkDDT_Indexed_Block::getContents(int ni, int na, int nd, int i[], MPI_Aint a[], int d[]) const noexcept
01020 {
01021 i[0] = count;
01022 i[1] = blockLength;
01023 for (int z=0; z<i[0]; z++) {
01024 i[z+2] = arrayDisplacements[z];
01025 }
01026 d[0] = baseIndex;
01027 return MPI_SUCCESS;
01028 }
01029
01030 int
01031 CkDDT_Indexed_Block::getNumBasicElements(int bytes) const noexcept
01032 {
01033 return getBaseType()->getNumBasicElements(bytes);
01034 }
01035
01036 CkDDT_HIndexed_Block::CkDDT_HIndexed_Block(int count, int Blength, const MPI_Aint *ArrDisp,
01037 int index, CkDDT_DataType *type) noexcept
01038 : CkDDT_DataType(CkDDT_INDEXED_BLOCK, 0, 0, count, 0, 0, 0, type->getSize(),
01039 type->getExtent(), type, count * type->getNumElements(), index, 0, 0),
01040 blockLength(Blength),
01041 arrayDisplacements(count)
01042 {
01043 datatype = CkDDT_HINDEXED_BLOCK;
01044 bool validElem = false;
01045 MPI_Aint positiveExtent = 0;
01046 MPI_Aint negativeExtent = 0;
01047 for (int i=0; i<count; i++) {
01048 arrayDisplacements[i] = ArrDisp[i];
01049 size += Blength * baseSize;
01050 if (Blength > 0) {
01051 if (!validElem) {
01052 negativeExtent = arrayDisplacements[i];
01053 positiveExtent = arrayDisplacements[i] + (Blength*baseExtent);
01054 validElem = true;
01055 }
01056 negativeExtent = std::min(arrayDisplacements[i], negativeExtent);
01057 positiveExtent = std::max(arrayDisplacements[i] + (Blength*baseExtent), positiveExtent);
01058 }
01059 }
01060 lb = baseType->getLB() + negativeExtent;
01061 ub = baseType->getLB() + positiveExtent;
01062 extent = positiveExtent + (-1)*negativeExtent;
01063
01064 trueExtent = extent;
01065 trueLB = lb;
01066
01067
01068 if (extent != size || count == 0) {
01069 iscontig = false;
01070 }
01071 else if (count == 1) {
01072 iscontig = baseType->isContig();
01073 }
01074 else if (blockLength != 1) {
01075 iscontig = false;
01076 }
01077 else {
01078 bool contig = true;
01079 for (int j=0; j<count; j++) {
01080 if (arrayDisplacements[j] != 1) {
01081 contig = false;
01082 break;
01083 }
01084 }
01085 iscontig = (contig && baseType->isContig());
01086 }
01087 }
01088
01089 size_t
01090 CkDDT_HIndexed_Block::serialize(char *userdata, char *buffer, int num, int msgLength, CkDDT_Dir dir) const noexcept
01091 {
01092 DDTDEBUG("CkDDT_HIndexed_Block::serialize, %s %d objects of type %d (iscontig=%d)\n",
01093 (dir==PACK)?"packing":"unpacking", num, baseType->getType(), (int)iscontig);
01094
01095 size_t bytesCopied = 0;
01096 if (iscontig) {
01097 bytesCopied = (size_t)num * (size_t)count * (size_t)blockLength * (size_t)baseSize;
01098 serializeContig(userdata, buffer, std::min(bytesCopied, (size_t)msgLength), dir);
01099 }
01100 else {
01101 for (; num>0; num--) {
01102 char* saveUserdata = userdata;
01103 for (int i=0; i<count; i++) {
01104 userdata = (isAbsolute) ? (char*)arrayDisplacements[i] : saveUserdata+arrayDisplacements[i];
01105 for (int j=0; j<blockLength ; j++) {
01106 int bytesProcessed = baseType->serialize(userdata, buffer, 1, msgLength, dir);
01107 bytesCopied += bytesProcessed;
01108 msgLength -= bytesProcessed;
01109 buffer += baseSize;
01110 userdata += baseExtent ;
01111 if (msgLength == 0) {
01112 return bytesCopied;
01113 }
01114 }
01115 }
01116 userdata = saveUserdata + extent;
01117 }
01118 }
01119 return bytesCopied;
01120 }
01121
01122 void
01123 CkDDT_HIndexed_Block::pupType(PUP::er &p, CkDDT *ddt) noexcept
01124 {
01125 CkDDT_DataType::pupType(p, ddt);
01126 p|blockLength;
01127 p|arrayDisplacements;
01128 if (p.isUnpacking()) {
01129 baseType = ddt->getType(baseIndex);
01130 }
01131 }
01132
01133 int
01134 CkDDT_HIndexed_Block::getEnvelope(int *ni, int *na, int *nd, int *combiner) const noexcept
01135 {
01136 *ni = 2;
01137 *na = count;
01138 *nd = 1;
01139 *combiner = MPI_COMBINER_HINDEXED_BLOCK;
01140 return MPI_SUCCESS;
01141 }
01142
01143 int
01144 CkDDT_HIndexed_Block::getContents(int ni, int na, int nd, int i[], MPI_Aint a[], int d[]) const noexcept
01145 {
01146 i[0] = count;
01147 i[1] = blockLength;
01148 for (int z=0; z<i[0]; z++) {
01149 a[z] = arrayDisplacements[z];
01150 }
01151 d[0] = baseIndex;
01152 return MPI_SUCCESS;
01153 }
01154
01155 int
01156 CkDDT_HIndexed_Block::getNumBasicElements(int bytes) const noexcept
01157 {
01158 return getBaseType()->getNumBasicElements(bytes);
01159 }
01160
01161 CkDDT_Indexed::CkDDT_Indexed(int nCount, const int* arrBlock, const MPI_Aint* arrBytesDisp,
01162 const MPI_Aint* arrDisp, int bindex, CkDDT_DataType* base) noexcept
01163 : CkDDT_HIndexed(nCount, arrBlock, arrBytesDisp, bindex, base)
01164 {
01165 for (int i=0; i<count; i++) {
01166 arrayDisplacements[i] = arrDisp[i];
01167 }
01168 datatype = CkDDT_INDEXED;
01169 }
01170
01171 size_t
01172 CkDDT_Indexed::serialize(char* userdata, char* buffer, int num, int msgLength, CkDDT_Dir dir) const noexcept
01173 {
01174 DDTDEBUG("CkDDT_Indexed::serialize, %s %d objects of type %d (iscontig=%d)\n",
01175 (dir==PACK)?"packing":"unpacking", num, baseType->getType(), (int)iscontig);
01176
01177 size_t bytesCopied = 0;
01178 if (iscontig) {
01179
01180 bytesCopied = (size_t)num * (size_t)count * (size_t)arrayBlockLength[1] * (size_t)baseSize;
01181 serializeContig(userdata, buffer, std::min(bytesCopied, (size_t)msgLength), dir);
01182 }
01183 else {
01184 char* saveUserdata = userdata;
01185 for (int iter=0; iter<num; iter++) {
01186 for (int i=0; i<count; i++) {
01187 userdata = saveUserdata + (baseExtent * arrayDisplacements[i]) + (iter * extent);
01188 for (int j=0; j<arrayBlockLength[i]; j++) {
01189 int bytesProcessed = baseType->serialize(userdata, buffer, 1, msgLength, dir);
01190 bytesCopied += bytesProcessed;
01191 msgLength -= bytesProcessed;
01192 buffer += baseSize;
01193 userdata += baseExtent;
01194 if (msgLength == 0) {
01195 return bytesCopied;
01196 }
01197 }
01198 }
01199 userdata = saveUserdata + extent;
01200 }
01201 }
01202 return bytesCopied;
01203 }
01204
01205 void
01206 CkDDT_Indexed::pupType(PUP::er &p, CkDDT* ddt) noexcept
01207 {
01208 CkDDT_DataType::pupType(p, ddt);
01209 p|arrayBlockLength;
01210 p|arrayDisplacements;
01211 if (p.isUnpacking()) {
01212 baseType = ddt->getType(baseIndex);
01213 }
01214 }
01215
01216 int
01217 CkDDT_Indexed::getEnvelope(int *ni, int *na, int *nd, int *combiner) const noexcept
01218 {
01219 *ni = count*2+1;
01220 *na = 0;
01221 *nd = 1;
01222 *combiner = MPI_COMBINER_INDEXED;
01223 return MPI_SUCCESS;
01224 }
01225
01226 int
01227 CkDDT_Indexed::getContents(int ni, int na, int nd, int i[], MPI_Aint a[], int d[]) const noexcept
01228 {
01229 i[0] = count;
01230 for(int z=0; z<i[0]; z++) {
01231 i[z+1] = arrayBlockLength[z];
01232 i[z+i[0]+1] = arrayDisplacements[z];
01233 }
01234 d[0] = baseIndex;
01235 return MPI_SUCCESS;
01236 }
01237
01238 int
01239 CkDDT_Indexed::getNumBasicElements(int bytes) const noexcept
01240 {
01241 return getBaseType()->getNumBasicElements(bytes);
01242 }
01243
01244 CkDDT_HIndexed::CkDDT_HIndexed(int nCount, const int* arrBlock, const MPI_Aint* arrDisp, int bindex,
01245 CkDDT_DataType* base) noexcept
01246 : CkDDT_DataType(CkDDT_HINDEXED, 0, 0, nCount, 0, 0, 0, base->getSize(), base->getExtent(),
01247 base, 0, bindex, 0, 0),
01248 arrayBlockLength(nCount),
01249 arrayDisplacements(nCount)
01250 {
01251 datatype = CkDDT_HINDEXED;
01252 size = 0;
01253 if (count == 0) {
01254 lb = 0;
01255 ub = 0;
01256 extent = 0;
01257 }
01258 else {
01259 bool validElem = false;
01260 MPI_Aint positiveExtent = 0;
01261 MPI_Aint negativeExtent = 0;
01262 for (int i=0; i<count; i++) {
01263 arrayBlockLength[i] = arrBlock[i];
01264 arrayDisplacements[i] = arrDisp[i];
01265 size += ( arrBlock[i] * baseSize);
01266 if (arrayBlockLength[i] > 0) {
01267 if (!validElem) {
01268 negativeExtent = arrayDisplacements[i];
01269 positiveExtent = arrayDisplacements[i] + (arrayBlockLength[i]*baseExtent);
01270 validElem = true;
01271 }
01272 negativeExtent = std::min(arrayDisplacements[i], negativeExtent);
01273 positiveExtent = std::max(arrayDisplacements[i] + (arrayBlockLength[i]*baseExtent), positiveExtent);
01274 }
01275 }
01276 lb = baseType->getLB() + negativeExtent;
01277 ub = baseType->getLB() + positiveExtent;
01278 extent = positiveExtent + (-1)*negativeExtent;
01279 }
01280
01281 trueExtent = extent;
01282 trueLB = lb;
01283
01284
01285 if (extent != size || count == 0) {
01286 iscontig = false;
01287 }
01288 else if (count == 1) {
01289 iscontig = baseType->isContig();
01290 }
01291 else {
01292 bool contig = true;
01293 for (int j=0; j<count; j++) {
01294 if (arrayDisplacements[j] != 1 || arrayBlockLength[j] != 1) {
01295 contig = false;
01296 break;
01297 }
01298 }
01299 iscontig = (contig && baseType->isContig());
01300 }
01301 }
01302
01303 size_t
01304 CkDDT_HIndexed::serialize(char* userdata, char* buffer, int num, int msgLength, CkDDT_Dir dir) const noexcept
01305 {
01306 DDTDEBUG("CkDDT_HIndexed::serialize, %s %d objects of type %d (iscontig=%d)\n",
01307 (dir==PACK)?"packing":"unpacking", num, baseType->getType(), (int)iscontig);
01308
01309 size_t bytesCopied = 0;
01310 if (iscontig) {
01311
01312 bytesCopied = (size_t)num * (size_t)count * (size_t)arrayBlockLength[0] * (size_t)baseSize;
01313 serializeContig(userdata, buffer, std::min(bytesCopied, (size_t)msgLength), dir);
01314 }
01315 else {
01316 for (; num>0; num--) {
01317 char *saveUserdata = userdata;
01318 for (int i=0; i<count; i++) {
01319 userdata = (isAbsolute) ? (char*)arrayDisplacements[i] : saveUserdata+arrayDisplacements[i];
01320 for (int j=0; j<arrayBlockLength[i]; j++) {
01321 int bytesProcessed = baseType->serialize(userdata, buffer, 1, msgLength, dir);
01322 bytesCopied += bytesProcessed;
01323 msgLength -= bytesProcessed;
01324 buffer += baseSize;
01325 userdata += baseExtent;
01326 if (msgLength == 0) {
01327 return bytesCopied;
01328 }
01329 }
01330 }
01331 userdata = saveUserdata + extent;
01332 }
01333 }
01334 return bytesCopied;
01335 }
01336
01337 void
01338 CkDDT_HIndexed::pupType(PUP::er &p, CkDDT* ddt) noexcept
01339 {
01340 CkDDT_DataType::pupType(p, ddt);
01341 p|arrayBlockLength;
01342 p|arrayDisplacements;
01343 if (p.isUnpacking()) {
01344 baseType = ddt->getType(baseIndex);
01345 }
01346 }
01347
01348 int
01349 CkDDT_HIndexed::getEnvelope(int *ni, int *na, int *nd, int *combiner) const noexcept
01350 {
01351 *ni = count+1;
01352 *na = count;
01353 *nd = 1;
01354 *combiner = MPI_COMBINER_HINDEXED;
01355 return MPI_SUCCESS;
01356 }
01357
01358 int
01359 CkDDT_HIndexed::getContents(int ni, int na, int nd, int i[], MPI_Aint a[], int d[]) const noexcept
01360 {
01361 i[0] = count;
01362 for (int z=0; z<i[0]; z++) {
01363 i[z+1] = arrayBlockLength[z];
01364 a[z] = arrayDisplacements[z];
01365 }
01366 d[0] = baseIndex;
01367 return MPI_SUCCESS;
01368 }
01369
01370 int
01371 CkDDT_HIndexed::getNumBasicElements(int bytes) const noexcept
01372 {
01373 return getBaseType()->getNumBasicElements(bytes);
01374 }
01375
01376 CkDDT_Struct::CkDDT_Struct(int nCount, const int* arrBlock, const MPI_Aint* arrDisp,
01377 const int *bindex, CkDDT_DataType** arrBase,
01378 const char* name) noexcept
01379 : CkDDT_DataType(CkDDT_STRUCT, 0, 0, nCount, 0, 0, 0, 0, 0, NULL, 0, 0, 0, 0),
01380 arrayBlockLength(nCount),
01381 arrayDisplacements(nCount),
01382 index(nCount),
01383 arrayDataType(nCount)
01384 {
01385 if (name != nullptr) setName(name);
01386 int saveExtent = 0;
01387 for (int i=0; i<count; i++) {
01388 arrayBlockLength[i] = arrBlock[i];
01389 arrayDisplacements[i] = arrDisp[i];
01390 arrayDataType[i] = arrBase[i];
01391 arrayDataType[i]->incRefCount();
01392 numElements += arrayBlockLength[i] * arrayDataType[i]->getNumElements();
01393 index[i] = bindex[i];
01394 size += arrBlock[i]*arrayDataType[i]->getSize();
01395 if (arrayDataType[i]->getExtent() > saveExtent) {
01396 saveExtent = arrayDataType[i]->getExtent();
01397 }
01398 }
01399
01400 bool explicit_lb = false;
01401 bool explicit_ub = false;
01402 for (int i=0; i<count; i++) {
01403 MPI_Aint xlb = arrayDataType[i]->getLB() + arrayDisplacements[i];
01404 MPI_Aint xub = arrayDisplacements[i] + arrayBlockLength[i]*arrayDataType[i]->getUB();
01405 if (arrayDataType[i]->getType() == MPI_LB) {
01406 if (!explicit_lb) lb = xlb;
01407 explicit_lb = true;
01408 if (xlb < lb) lb = xlb;
01409 }
01410 else if(arrayDataType[i]->getType() == MPI_UB) {
01411 if (!explicit_ub) ub = xub;
01412 explicit_ub = true;
01413 if (xub > ub) ub = xub;
01414 }
01415 else {
01416 if (!explicit_lb && xlb < lb) lb = xlb;
01417 if (!explicit_ub && xub > ub) ub = xub;
01418 }
01419 }
01420
01421 extent = ub - lb;
01422 if (!explicit_ub && (saveExtent != 0) && (extent % saveExtent != 0)) {
01423 extent += (saveExtent - (extent % saveExtent));
01424 }
01425
01426 trueLB = 0;
01427 MPI_Aint trueUB = 0;
01428 int trueUBi = 0;
01429 bool trueLB_set = false;
01430 bool trueUB_set = false;
01431 bool empty = true;
01432 for (int i=0; i<count; i++) {
01433 if (!(arrayDataType[i]->getType() == MPI_LB || arrayDataType[i]->getType() == MPI_UB)) {
01434 if (trueLB > arrayDisplacements[i] || !trueLB_set) {
01435 trueLB_set = true;
01436 trueLB = arrayDisplacements[i];
01437 }
01438 empty = false;
01439 if (trueUB < arrayDisplacements[i] || !trueUB_set) {
01440 trueUBi = i;
01441 trueUB_set = true;
01442 trueUB = arrayDisplacements[i];
01443 }
01444 }
01445 }
01446
01447 if (empty) {
01448 trueExtent = 0;
01449 } else {
01450 trueExtent = trueUB + (arrayDataType[trueUBi]->getExtent()*arrayBlockLength[trueUBi]) - trueLB;
01451 }
01452
01453
01454 if (extent != size || count == 0) {
01455 iscontig = false;
01456 }
01457 else if (count == 1) {
01458 iscontig = arrayDataType[0]->isContig();
01459 }
01460 else {
01461 bool contig = true;
01462 for (int j=0; j<count; j++) {
01463 if (arrayDisplacements[j] != 1 || arrayBlockLength[j] != 1) {
01464 contig = false;
01465 break;
01466 }
01467 }
01468 if (contig) {
01469 for (int j=0; j<count; j++) {
01470 if (!arrayDataType[j]->isContig()) {
01471 contig = false;
01472 break;
01473 }
01474 }
01475 iscontig = contig;
01476 }
01477 else {
01478 iscontig = false;
01479 }
01480 }
01481 DDTDEBUG("type %d: ub=%ld, lb=%ld, extent=%ld, size=%d, iscontig=%d\n",datatype,ub,lb,extent,size,iscontig);
01482 }
01483
01484 size_t
01485 CkDDT_Struct::serialize(char* userdata, char* buffer, int num, int msgLength, CkDDT_Dir dir) const noexcept
01486 {
01487 size_t bytesCopied = 0;
01488
01489 if (iscontig) {
01490 DDTDEBUG("CkDDT_Struct::serialize, %s %d objects (iscontig=%d)\n",
01491 (dir==PACK)?"packing":"unpacking", num, (int)iscontig);
01492
01493 for (int i=0; i<count; i++) {
01494 bytesCopied += (size_t)num * (size_t)arrayBlockLength[0] * (size_t)arrayDataType[i]->getSize();
01495 }
01496 serializeContig(userdata, buffer, std::min(bytesCopied, (size_t)msgLength), dir);
01497 }
01498 else {
01499 char* sbuf = userdata;
01500 char* dbuf = buffer;
01501 char* absoluteOffset = (isAbsolute) ? 0 : userdata;
01502 for (; num>0; num--) {
01503 char *buf = buffer;
01504 for (int i=0; i<count; i++) {
01505 int saveSize = arrayDataType[i]->getSize();
01506 int saveExtent = arrayDataType[i]->getExtent();
01507 for (int j=0; j<arrayBlockLength[i]; j++) {
01508 DDTDEBUG("CkDDT_Struct::serialize %s block of type %d (size %d) from offset %d to offset %d\n",
01509 (dir==PACK)?"packing":"unpacking", arrayDataType[i]->getType(),
01510 saveSize, absoluteOffset + (j*saveExtent) + arrayDisplacements[i]-sbuf, buffer-dbuf);
01511 if (msgLength == 0) {
01512 return bytesCopied;
01513 }
01514 int bytesProcessed = arrayDataType[i]->serialize(
01515 arrayDisplacements[i] + j*saveExtent + absoluteOffset,
01516 buffer,
01517 1,
01518 msgLength,
01519 dir);
01520 bytesCopied += bytesProcessed;
01521 msgLength -= bytesProcessed;
01522 buffer += saveSize;
01523 }
01524 }
01525 buffer = buf + size;
01526 absoluteOffset += extent;
01527 }
01528 }
01529 return bytesCopied;
01530 }
01531
01532 void
01533 CkDDT_Struct::pupType(PUP::er &p, CkDDT* ddt) noexcept
01534 {
01535 CkDDT_DataType::pupType(p, ddt);
01536 p|arrayBlockLength;
01537 p|arrayDisplacements;
01538 p|index;
01539 if (p.isUnpacking()) {
01540 arrayDataType.resize(count);
01541 for (int i=0; i<count; i++) {
01542 arrayDataType[i] = ddt->getType(index[i]);
01543 }
01544 }
01545 }
01546
01547 int
01548 CkDDT_Struct::getEnvelope(int *ni, int *na, int *nd, int *combiner) const noexcept
01549 {
01550 *ni = count+1;
01551 *na = count;
01552 *nd = count;
01553 *combiner = MPI_COMBINER_STRUCT;
01554 return MPI_SUCCESS;
01555 }
01556
01557 int
01558 CkDDT_Struct::getContents(int ni, int na, int nd, int i[], MPI_Aint a[], int d[]) const noexcept
01559 {
01560 i[0] = count;
01561 for (int z=0; z<i[0]; z++) {
01562 i[z+1] = arrayBlockLength[z];
01563 a[z] = arrayDisplacements[z];
01564 d[z] = index[z];
01565 }
01566 return MPI_SUCCESS;
01567 }
01568
01569 int
01570 CkDDT_Struct::getNumBasicElements(int bytes) const noexcept
01571 {
01572 int size = getSize();
01573 if (size == 0) {
01574 return 0;
01575 }
01576
01577 int rem = bytes % size;
01578 const vector<CkDDT_DataType *> &types = getBaseTypes();
01579 int basicTypes = 0;
01580 for (int i=0; i<types.size(); i++) {
01581 basicTypes += types[i]->getNumBasicElements(types[i]->getSize());
01582 }
01583
01584 int count = (bytes / size) * basicTypes;
01585 if (rem == 0) {
01586 return count;
01587 }
01588
01589 for (int i=0; i<types.size(); i++) {
01590 int type_size = types[i]->getSize();
01591 if ((type_size * arrayBlockLength[i]) > rem) {
01592 return count + types[i]->getNumBasicElements(rem);
01593 }
01594 else {
01595 count += types[i]->getNumBasicElements(type_size) * arrayBlockLength[i];
01596 rem -= type_size * arrayBlockLength[i];
01597 }
01598 if (rem == 0) {
01599 return count;
01600 }
01601 }
01602 return count;
01603 }
01604