00001
00002
00003
00004
00005
00006
00007 #include "adio.h"
00008 #include "adio_extern.h"
00009
00010
00011
00012 #ifdef ROMIO_INSIDE_MPICH2
00013 #include "mpid_datatype.h"
00014 #endif
00015
00016 #ifdef USE_DBG_LOGGING
00017 #define FLATTEN_DEBUG 1
00018 #endif
00019
00020 void ADIOI_Optimize_flattened(ADIOI_Flatlist_node *flat_type);
00021
00022 void ADIOI_Flatten_datatype(MPI_Datatype datatype)
00023 {
00024 #ifdef HAVE_MPIR_TYPE_FLATTEN
00025 MPI_Aint flatten_idx;
00026 #endif
00027 int curr_index=0, is_contig;
00028 ADIOI_Flatlist_node *flat, *prev=0;
00029
00030 #ifdef ROMIO_INSIDE_MPICH2
00031 if(MPIU_DBG_SELECTED(DATATYPE,TYPICAL)) MPIDU_Datatype_debug(datatype, 4);
00032 #endif
00033
00034
00035
00036 ADIOI_Datatype_iscontig(datatype, &is_contig);
00037 #ifdef FLATTEN_DEBUG
00038 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: is_contig %#X\n",is_contig);
00039 #endif
00040 if (is_contig) return;
00041
00042
00043 flat = CtvAccess(ADIOI_Flatlist);
00044 while (flat) {
00045 if (flat->type == datatype) {
00046 #ifdef FLATTEN_DEBUG
00047 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: found datatype %#X\n", datatype);
00048 #endif
00049 return;
00050 }
00051 else {
00052 prev = flat;
00053 flat = flat->next;
00054 }
00055 }
00056
00057
00058 flat = prev;
00059 flat->next = (ADIOI_Flatlist_node *)ADIOI_Malloc(sizeof(ADIOI_Flatlist_node));
00060 flat = flat->next;
00061
00062 flat->type = datatype;
00063 flat->next = NULL;
00064 flat->blocklens = NULL;
00065 flat->indices = NULL;
00066
00067 flat->count = ADIOI_Count_contiguous_blocks(datatype, &curr_index);
00068 #ifdef FLATTEN_DEBUG
00069 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: count %#X, cur_idx = %#X\n",flat->count,curr_index);
00070 #endif
00071
00072
00073 if (flat->count) {
00074 flat->blocklens = (ADIO_Offset *) ADIOI_Malloc(flat->count * sizeof(ADIO_Offset));
00075 flat->indices = (ADIO_Offset *) ADIOI_Malloc(flat->count * sizeof(ADIO_Offset));
00076 }
00077
00078 curr_index = 0;
00079 #ifdef HAVE_MPIR_TYPE_FLATTEN
00080 flatten_idx = (MPI_Aint) flat->count;
00081 MPIR_Type_flatten(datatype, flat->indices, flat->blocklens, &flatten_idx);
00082 #ifdef FLATTEN_DEBUG
00083 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: MPIR_Type_flatten\n");
00084 #endif
00085 #else
00086 ADIOI_Flatten(datatype, flat, 0, &curr_index);
00087 #ifdef FLATTEN_DEBUG
00088 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: ADIOI_Flatten\n");
00089 #endif
00090
00091 ADIOI_Optimize_flattened(flat);
00092 #endif
00093
00094 #ifdef FLATTEN_DEBUG
00095 {
00096 int i;
00097 for (i=0; i<flat->count; i++)
00098 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: i %#X, blocklens %#llX, indices %#llX\n",
00099 i,
00100 flat->blocklens[i],
00101 flat->indices[i]
00102 );
00103 }
00104 #endif
00105
00106 }
00107
00108
00109
00110
00111
00112 void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
00113 ADIO_Offset st_offset, int *curr_index)
00114 {
00115 int i, j, k, m, n, num, basic_num, prev_index;
00116 int combiner, old_combiner, old_is_contig;
00117 int nints, nadds, ntypes, old_nints, old_nadds, old_ntypes;
00118
00119
00120 ADIO_Offset top_count;
00121
00122 unsigned old_size;
00123 MPI_Aint old_extent;
00124 int *ints;
00125 MPI_Aint *adds;
00126 MPI_Datatype *types;
00127 MPI_Type_get_envelope(datatype, &nints, &nadds, &ntypes, &combiner);
00128 ints = (int *) ADIOI_Malloc((nints+1)*sizeof(int));
00129 adds = (MPI_Aint *) ADIOI_Malloc((nadds+1)*sizeof(MPI_Aint));
00130 types = (MPI_Datatype *) ADIOI_Malloc((ntypes+1)*sizeof(MPI_Datatype));
00131 MPI_Type_get_contents(datatype, nints, nadds, ntypes, ints, adds, types);
00132
00133 #ifdef FLATTEN_DEBUG
00134 DBG_FPRINTF(stderr,"ADIOI_Flatten:: st_offset %#llX, curr_index %#X\n",st_offset,*curr_index);
00135 DBG_FPRINTF(stderr,"ADIOI_Flatten:: nints %#X, nadds %#X, ntypes %#X\n",nints, nadds, ntypes);
00136 for(i=0; i< nints; ++i)
00137 {
00138 DBG_FPRINTF(stderr,"ADIOI_Flatten:: ints[%d]=%#X\n",i,ints[i]);
00139 }
00140 for(i=0; i< nadds; ++i)
00141 {
00142 DBG_FPRINTF(stderr,"ADIOI_Flatten:: adds[%d]="MPI_AINT_FMT_HEX_SPEC"\n",i,adds[i]);
00143 }
00144 for(i=0; i< ntypes; ++i)
00145 {
00146 DBG_FPRINTF(stderr,"ADIOI_Flatten:: types[%d]=%#llX\n",i,(unsigned long long)(unsigned long)types[i]);
00147 }
00148 if(MPIU_DBG_SELECTED(DATATYPE,TYPICAL)) MPIDU_Datatype_debug(datatype, 4);
00149 #endif
00150 switch (combiner) {
00151 #ifdef MPIIMPL_HAVE_MPI_COMBINER_DUP
00152 case MPI_COMBINER_DUP:
00153 #ifdef FLATTEN_DEBUG
00154 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_DUP\n");
00155 #endif
00156 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00157 &old_ntypes, &old_combiner);
00158 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00159 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00160 ADIOI_Flatten(types[0], flat, st_offset, curr_index);
00161 break;
00162 #endif
00163 #ifdef MPIIMPL_HAVE_MPI_COMBINER_SUBARRAY
00164 case MPI_COMBINER_SUBARRAY:
00165 {
00166 int dims = ints[0];
00167 MPI_Datatype stype;
00168 #ifdef FLATTEN_DEBUG
00169 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_SUBARRAY\n");
00170 #endif
00171
00172 ADIO_Type_create_subarray(dims,
00173 &ints[1],
00174 &ints[dims+1],
00175 &ints[2*dims+1],
00176 ints[3*dims+1],
00177 types[0],
00178 &stype);
00179 ADIOI_Flatten(stype, flat, st_offset, curr_index);
00180 MPI_Type_free(&stype);
00181 }
00182 break;
00183 #endif
00184 #ifdef MPIIMPL_HAVE_MPI_COMBINER_DARRAY
00185 case MPI_COMBINER_DARRAY:
00186 {
00187 int dims = ints[2];
00188 MPI_Datatype dtype;
00189 #ifdef FLATTEN_DEBUG
00190 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_DARRAY\n");
00191 #endif
00192
00193 ADIO_Type_create_darray(ints[0],
00194 ints[1],
00195 dims,
00196 &ints[3],
00197 &ints[dims+3],
00198 &ints[2*dims+3],
00199 &ints[3*dims+3],
00200 ints[4*dims+3],
00201 types[0],
00202 &dtype);
00203 #ifdef FLATTEN_DEBUG
00204 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_DARRAY <ADIOI_Flatten(dtype, flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX, st_offset %#llX, curr_index %#X);\n",
00205 0, flat->indices[0], 0, flat->blocklens[0], st_offset, *curr_index);
00206 #endif
00207 ADIOI_Flatten(dtype, flat, st_offset, curr_index);
00208 #ifdef FLATTEN_DEBUG
00209 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_DARRAY >ADIOI_Flatten(dtype, flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX, st_offset %#llX, curr_index %#X);\n",
00210 0, flat->indices[0], 0, flat->blocklens[0], st_offset, *curr_index);
00211 #endif
00212 MPI_Type_free(&dtype);
00213 }
00214 break;
00215 #endif
00216 case MPI_COMBINER_CONTIGUOUS:
00217 #ifdef FLATTEN_DEBUG
00218 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_CONTIGUOUS\n");
00219 #endif
00220 top_count = ints[0];
00221 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00222 &old_ntypes, &old_combiner);
00223 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00224
00225 prev_index = *curr_index;
00226 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00227 ADIOI_Flatten(types[0], flat, st_offset, curr_index);
00228
00229 if (prev_index == *curr_index) {
00230
00231 j = *curr_index;
00232 flat->indices[j] = st_offset;
00233 MPI_Type_size(types[0], (int*)&old_size);
00234 flat->blocklens[j] = top_count * old_size;
00235 #ifdef FLATTEN_DEBUG
00236 DBG_FPRINTF(stderr,"ADIOI_Flatten:: simple flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX\n",j, flat->indices[j], j, flat->blocklens[j]);
00237 #endif
00238 (*curr_index)++;
00239 }
00240 else {
00241
00242 j = *curr_index;
00243 num = *curr_index - prev_index;
00244
00245
00246 MPI_Type_extent(types[0], &old_extent);
00247 for (m=1; m<top_count; m++) {
00248 for (i=0; i<num; i++) {
00249 flat->indices[j] = flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
00250 flat->blocklens[j] = flat->blocklens[j-num];
00251 #ifdef FLATTEN_DEBUG
00252 DBG_FPRINTF(stderr,"ADIOI_Flatten:: derived flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX\n",j, flat->indices[j], j, flat->blocklens[j]);
00253 #endif
00254 j++;
00255 }
00256 }
00257 *curr_index = j;
00258 }
00259 break;
00260
00261 case MPI_COMBINER_VECTOR:
00262 #ifdef FLATTEN_DEBUG
00263 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_VECTOR\n");
00264 #endif
00265 top_count = ints[0];
00266 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00267 &old_ntypes, &old_combiner);
00268 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00269
00270 prev_index = *curr_index;
00271 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00272 ADIOI_Flatten(types[0], flat, st_offset, curr_index);
00273
00274 if (prev_index == *curr_index) {
00275
00276
00277
00278 ADIO_Offset blocklength = ints[1], stride = ints[2];
00279 j = *curr_index;
00280 flat->indices[j] = st_offset;
00281 MPI_Type_size(types[0], (int*)&old_size);
00282 flat->blocklens[j] = blocklength * old_size;
00283 for (i=j+1; i<j+top_count; i++) {
00284 flat->indices[i] = flat->indices[i-1] + stride * old_size;
00285 flat->blocklens[i] = flat->blocklens[j];
00286 }
00287 *curr_index = i;
00288 }
00289 else {
00290
00291
00292
00293 ADIO_Offset blocklength = ints[1], stride = ints[2];
00294
00295 j = *curr_index;
00296 num = *curr_index - prev_index;
00297
00298
00299
00300 MPI_Type_extent(types[0], &old_extent);
00301 for (m=1; m<blocklength; m++) {
00302 for (i=0; i<num; i++) {
00303 flat->indices[j] = flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
00304 flat->blocklens[j] = flat->blocklens[j-num];
00305 j++;
00306 }
00307 }
00308 *curr_index = j;
00309
00310
00311 num = *curr_index - prev_index;
00312 for (i=1; i<top_count; i++) {
00313 for (m=0; m<num; m++) {
00314 flat->indices[j] = flat->indices[j-num] + stride * ADIOI_AINT_CAST_TO_OFFSET old_extent;
00315 flat->blocklens[j] = flat->blocklens[j-num];
00316 j++;
00317 }
00318 }
00319 *curr_index = j;
00320 }
00321 break;
00322
00323 case MPI_COMBINER_HVECTOR:
00324 case MPI_COMBINER_HVECTOR_INTEGER:
00325 #ifdef FLATTEN_DEBUG
00326 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_HVECTOR_INTEGER\n");
00327 #endif
00328 top_count = ints[0];
00329 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00330 &old_ntypes, &old_combiner);
00331 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00332
00333 prev_index = *curr_index;
00334 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00335 ADIOI_Flatten(types[0], flat, st_offset, curr_index);
00336
00337 if (prev_index == *curr_index) {
00338
00339
00340
00341 ADIO_Offset blocklength = ints[1];
00342 j = *curr_index;
00343 flat->indices[j] = st_offset;
00344 MPI_Type_size(types[0], (int*)&old_size);
00345 flat->blocklens[j] = blocklength * old_size;
00346 for (i=j+1; i<j+top_count; i++) {
00347 flat->indices[i] = flat->indices[i-1] + adds[0];
00348 flat->blocklens[i] = flat->blocklens[j];
00349 }
00350 *curr_index = i;
00351 }
00352 else {
00353
00354
00355
00356 ADIO_Offset blocklength = ints[1];
00357
00358 j = *curr_index;
00359 num = *curr_index - prev_index;
00360
00361
00362
00363 MPI_Type_extent(types[0], &old_extent);
00364 for (m=1; m<blocklength; m++) {
00365 for (i=0; i<num; i++) {
00366 flat->indices[j] = flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
00367 flat->blocklens[j] = flat->blocklens[j-num];
00368 j++;
00369 }
00370 }
00371 *curr_index = j;
00372
00373
00374 num = *curr_index - prev_index;
00375 for (i=1; i<top_count; i++) {
00376 for (m=0; m<num; m++) {
00377 flat->indices[j] = flat->indices[j-num] + adds[0];
00378 flat->blocklens[j] = flat->blocklens[j-num];
00379 j++;
00380 }
00381 }
00382 *curr_index = j;
00383 }
00384 break;
00385
00386 case MPI_COMBINER_INDEXED:
00387 #ifdef FLATTEN_DEBUG
00388 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_INDEXED\n");
00389 #endif
00390 top_count = ints[0];
00391 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00392 &old_ntypes, &old_combiner);
00393 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00394 MPI_Type_extent(types[0], &old_extent);
00395
00396 prev_index = *curr_index;
00397 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00398 {
00399
00400
00401 ADIO_Offset stride = ints[top_count+1];
00402 ADIOI_Flatten(types[0], flat,
00403 st_offset+stride* ADIOI_AINT_CAST_TO_OFFSET old_extent, curr_index);
00404 }
00405
00406 if (prev_index == *curr_index) {
00407
00408 j = *curr_index;
00409 for (i=j; i<j+top_count; i++) {
00410
00411
00412 ADIO_Offset blocklength = ints[1+i-j], stride = ints[top_count+1+i-j];
00413 flat->indices[i] = st_offset + stride* ADIOI_AINT_CAST_TO_OFFSET old_extent;
00414 flat->blocklens[i] = blocklength* ADIOI_AINT_CAST_TO_OFFSET old_extent;
00415 }
00416 *curr_index = i;
00417 }
00418 else {
00419
00420
00421 j = *curr_index;
00422 num = *curr_index - prev_index;
00423 basic_num = num;
00424
00425
00426
00427 for (m=1; m<ints[1]; m++) {
00428 for (i=0; i<num; i++) {
00429 flat->indices[j] = flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
00430 flat->blocklens[j] = flat->blocklens[j-num];
00431 j++;
00432 }
00433 }
00434 *curr_index = j;
00435
00436
00437 for (i=1; i<top_count; i++) {
00438 num = *curr_index - prev_index;
00439 prev_index = *curr_index;
00440 for (m=0; m<basic_num; m++) {
00441
00442
00443 ADIO_Offset stride = ints[top_count+1+i]-ints[top_count+i];
00444 flat->indices[j] = flat->indices[j-num] + stride* ADIOI_AINT_CAST_TO_OFFSET old_extent;
00445 flat->blocklens[j] = flat->blocklens[j-num];
00446 j++;
00447 }
00448 *curr_index = j;
00449 for (m=1; m<ints[1+i]; m++) {
00450 for (k=0; k<basic_num; k++) {
00451 flat->indices[j] = flat->indices[j-basic_num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
00452 flat->blocklens[j] = flat->blocklens[j-basic_num];
00453 j++;
00454 }
00455 }
00456 *curr_index = j;
00457 }
00458 }
00459 break;
00460
00461 case MPI_COMBINER_INDEXED_BLOCK:
00462 #ifdef FLATTEN_DEBUG
00463 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_INDEXED_BLOCK\n");
00464 #endif
00465 top_count = ints[0];
00466 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00467 &old_ntypes, &old_combiner);
00468 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00469 MPI_Type_extent(types[0], &old_extent);
00470
00471 prev_index = *curr_index;
00472 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00473 {
00474
00475
00476 ADIO_Offset stride = ints[1+1];
00477 ADIOI_Flatten(types[0], flat,
00478 st_offset+stride* ADIOI_AINT_CAST_TO_OFFSET old_extent, curr_index);
00479 }
00480
00481 if (prev_index == *curr_index) {
00482
00483 j = *curr_index;
00484 for (i=j; i<j+top_count; i++) {
00485
00486
00487 ADIO_Offset blocklength = ints[1], stride = ints[1+1+i-j];
00488 flat->indices[i] = st_offset + stride* ADIOI_AINT_CAST_TO_OFFSET old_extent;
00489 flat->blocklens[i] = blocklength* ADIOI_AINT_CAST_TO_OFFSET old_extent;
00490 }
00491 *curr_index = i;
00492 }
00493 else {
00494
00495
00496 j = *curr_index;
00497 num = *curr_index - prev_index;
00498
00499
00500
00501 for (m=1; m<ints[1]; m++) {
00502 for (i=0; i<num; i++) {
00503 flat->indices[j] = flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
00504 flat->blocklens[j] = flat->blocklens[j-num];
00505 j++;
00506 }
00507 }
00508 *curr_index = j;
00509
00510
00511 num = *curr_index - prev_index;
00512 for (i=1; i<top_count; i++) {
00513 for (m=0; m<num; m++) {
00514
00515
00516 ADIO_Offset stride = ints[2+i]-ints[1+i];
00517 flat->indices[j] = flat->indices[j-num] + stride* ADIOI_AINT_CAST_TO_OFFSET old_extent;
00518 flat->blocklens[j] = flat->blocklens[j-num];
00519 j++;
00520 }
00521 }
00522 *curr_index = j;
00523 }
00524 break;
00525
00526 case MPI_COMBINER_HINDEXED:
00527 case MPI_COMBINER_HINDEXED_INTEGER:
00528 #ifdef FLATTEN_DEBUG
00529 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_HINDEXED_INTEGER\n");
00530 #endif
00531 top_count = ints[0];
00532 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00533 &old_ntypes, &old_combiner);
00534 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00535
00536 prev_index = *curr_index;
00537 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00538 {
00539 ADIOI_Flatten(types[0], flat, st_offset+adds[0], curr_index);
00540 }
00541
00542 if (prev_index == *curr_index) {
00543
00544 j = *curr_index;
00545 MPI_Type_size(types[0], (int*)&old_size);
00546 for (i=j; i<j+top_count; i++) {
00547
00548
00549 ADIO_Offset blocklength = ints[1+i-j];
00550 flat->indices[i] = st_offset + adds[i-j];
00551 flat->blocklens[i] = blocklength*old_size;
00552 }
00553 *curr_index = i;
00554 }
00555 else {
00556
00557
00558 j = *curr_index;
00559 num = *curr_index - prev_index;
00560 basic_num = num;
00561
00562
00563
00564 MPI_Type_extent(types[0], &old_extent);
00565 for (m=1; m<ints[1]; m++) {
00566 for (i=0; i<num; i++) {
00567 flat->indices[j] = flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
00568 flat->blocklens[j] = flat->blocklens[j-num];
00569 j++;
00570 }
00571 }
00572 *curr_index = j;
00573
00574
00575 for (i=1; i<top_count; i++) {
00576 num = *curr_index - prev_index;
00577 prev_index = *curr_index;
00578 for (m=0; m<basic_num; m++) {
00579 flat->indices[j] = flat->indices[j-num] + adds[i] - adds[i-1];
00580 flat->blocklens[j] = flat->blocklens[j-num];
00581 j++;
00582 }
00583 *curr_index = j;
00584 for (m=1; m<ints[1+i]; m++) {
00585 for (k=0; k<basic_num; k++) {
00586 flat->indices[j] = flat->indices[j-basic_num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
00587 flat->blocklens[j] = flat->blocklens[j-basic_num];
00588 j++;
00589 }
00590 }
00591 *curr_index = j;
00592 }
00593 }
00594 break;
00595
00596 case MPI_COMBINER_STRUCT:
00597 case MPI_COMBINER_STRUCT_INTEGER:
00598 #ifdef FLATTEN_DEBUG
00599 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_STRUCT_INTEGER\n");
00600 #endif
00601 top_count = ints[0];
00602 for (n=0; n<top_count; n++) {
00603 MPI_Type_get_envelope(types[n], &old_nints, &old_nadds,
00604 &old_ntypes, &old_combiner);
00605 ADIOI_Datatype_iscontig(types[n], &old_is_contig);
00606
00607 prev_index = *curr_index;
00608 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00609 ADIOI_Flatten(types[n], flat, st_offset+adds[n], curr_index);
00610
00611 if (prev_index == *curr_index) {
00612
00613
00614
00615 ADIO_Offset blocklength = ints[1+n];
00616 j = *curr_index;
00617 flat->indices[j] = st_offset + adds[n];
00618 MPI_Type_size(types[n], (int*)&old_size);
00619 flat->blocklens[j] = blocklength * old_size;
00620 #ifdef FLATTEN_DEBUG
00621 DBG_FPRINTF(stderr,"ADIOI_Flatten:: simple adds[%#X] "MPI_AINT_FMT_HEX_SPEC", flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX\n",n,adds[n],j, flat->indices[j], j, flat->blocklens[j]);
00622 #endif
00623 (*curr_index)++;
00624 }
00625 else {
00626
00627
00628 j = *curr_index;
00629 num = *curr_index - prev_index;
00630
00631
00632 MPI_Type_extent(types[n], &old_extent);
00633 for (m=1; m<ints[1+n]; m++) {
00634 for (i=0; i<num; i++) {
00635 flat->indices[j] = flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
00636 flat->blocklens[j] = flat->blocklens[j-num];
00637 #ifdef FLATTEN_DEBUG
00638 DBG_FPRINTF(stderr,"ADIOI_Flatten:: simple old_extent "MPI_AINT_FMT_HEX_SPEC", flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX\n",old_extent,j, flat->indices[j], j, flat->blocklens[j]);
00639 #endif
00640 j++;
00641 }
00642 }
00643 *curr_index = j;
00644 }
00645 }
00646 break;
00647
00648 case MPI_COMBINER_RESIZED:
00649 #ifdef FLATTEN_DEBUG
00650 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_RESIZED\n");
00651 #endif
00652
00653
00654
00655
00656 j = *curr_index;
00657 flat->indices[j] = st_offset + adds[0];
00658 flat->blocklens[j] = 0;
00659
00660 #ifdef FLATTEN_DEBUG
00661 DBG_FPRINTF(stderr,"ADIOI_Flatten:: simple adds[%#X] "MPI_AINT_FMT_HEX_SPEC", flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX\n",0,adds[0],j, flat->indices[j], j, flat->blocklens[j]);
00662 #endif
00663
00664 (*curr_index)++;
00665
00666
00667
00668 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00669 &old_ntypes, &old_combiner);
00670 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00671
00672 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig)) {
00673 ADIOI_Flatten(types[0], flat, st_offset+adds[0], curr_index);
00674 }
00675 else {
00676
00677 j = *curr_index;
00678 flat->indices[j] = st_offset;
00679 MPI_Type_size(types[0], (int*)&old_size);
00680 flat->blocklens[j] = old_size;
00681
00682 #ifdef FLATTEN_DEBUG
00683 DBG_FPRINTF(stderr,"ADIOI_Flatten:: simple adds[%#X] "MPI_AINT_FMT_HEX_SPEC", flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX\n",0,adds[0],j, flat->indices[j], j, flat->blocklens[j]);
00684 #endif
00685
00686 (*curr_index)++;
00687 }
00688
00689
00690 j = *curr_index;
00691 flat->indices[j] = st_offset + adds[0] + adds[1];
00692 flat->blocklens[j] = 0;
00693
00694 #ifdef FLATTEN_DEBUG
00695 DBG_FPRINTF(stderr,"ADIOI_Flatten:: simple adds[%#X] "MPI_AINT_FMT_HEX_SPEC", flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX\n",1,adds[1],j, flat->indices[j], j, flat->blocklens[j]);
00696 #endif
00697
00698 (*curr_index)++;
00699
00700 break;
00701
00702 default:
00703
00704 DBG_FPRINTF(stderr, "Error: Unsupported datatype passed to ADIOI_Flatten\n");
00705 MPI_Abort(MPI_COMM_WORLD, 1);
00706 }
00707
00708 #ifndef MPISGI
00709
00710
00711 for (i=0; i<ntypes; i++) {
00712 MPI_Type_get_envelope(types[i], &old_nints, &old_nadds, &old_ntypes,
00713 &old_combiner);
00714 if (old_combiner != MPI_COMBINER_NAMED) MPI_Type_free(types+i);
00715 }
00716 #endif
00717
00718 ADIOI_Free(ints);
00719 ADIOI_Free(adds);
00720 ADIOI_Free(types);
00721
00722 #ifdef FLATTEN_DEBUG
00723 DBG_FPRINTF(stderr,"ADIOI_Flatten:: return st_offset %#llX, curr_index %#X\n",st_offset,*curr_index);
00724 #endif
00725
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737 int ADIOI_Count_contiguous_blocks(MPI_Datatype datatype, int *curr_index)
00738 {
00739 #ifdef HAVE_MPIR_TYPE_GET_CONTIG_BLOCKS
00740
00741 int blks;
00742 MPIR_Type_get_contig_blocks(datatype, &blks);
00743 *curr_index = blks;
00744 return blks;
00745 #else
00746 int count=0, i, n, num, basic_num, prev_index;
00747 int top_count, combiner, old_combiner, old_is_contig;
00748 int nints, nadds, ntypes, old_nints, old_nadds, old_ntypes;
00749 int *ints;
00750 MPI_Aint *adds;
00751 MPI_Datatype *types;
00752
00753 MPI_Type_get_envelope(datatype, &nints, &nadds, &ntypes, &combiner);
00754 ints = (int *) ADIOI_Malloc((nints+1)*sizeof(int));
00755 adds = (MPI_Aint *) ADIOI_Malloc((nadds+1)*sizeof(MPI_Aint));
00756 types = (MPI_Datatype *) ADIOI_Malloc((ntypes+1)*sizeof(MPI_Datatype));
00757 MPI_Type_get_contents(datatype, nints, nadds, ntypes, ints, adds, types);
00758
00759 switch (combiner) {
00760 #ifdef MPIIMPL_HAVE_MPI_COMBINER_DUP
00761 case MPI_COMBINER_DUP:
00762 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00763 &old_ntypes, &old_combiner);
00764 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00765 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00766 count = ADIOI_Count_contiguous_blocks(types[0], curr_index);
00767 else {
00768 count = 1;
00769 (*curr_index)++;
00770 }
00771 break;
00772 #endif
00773 #ifdef MPIIMPL_HAVE_MPI_COMBINER_SUBARRAY
00774 case MPI_COMBINER_SUBARRAY:
00775 {
00776 int dims = ints[0];
00777 MPI_Datatype stype;
00778
00779 ADIO_Type_create_subarray(dims,
00780 &ints[1],
00781 &ints[dims+1],
00782 &ints[2*dims+1],
00783 ints[3*dims+1],
00784 types[0],
00785 &stype);
00786 count = ADIOI_Count_contiguous_blocks(stype, curr_index);
00787
00788
00789
00790 MPI_Type_free(&stype);
00791
00792 }
00793 break;
00794 #endif
00795 #ifdef MPIIMPL_HAVE_MPI_COMBINER_DARRAY
00796 case MPI_COMBINER_DARRAY:
00797 {
00798 int dims = ints[2];
00799 MPI_Datatype dtype;
00800
00801 ADIO_Type_create_darray(ints[0],
00802 ints[1],
00803 dims,
00804 &ints[3],
00805 &ints[dims+3],
00806 &ints[2*dims+3],
00807 &ints[3*dims+3],
00808 ints[4*dims+3],
00809 types[0],
00810 &dtype);
00811 count = ADIOI_Count_contiguous_blocks(dtype, curr_index);
00812
00813
00814
00815 MPI_Type_free(&dtype);
00816 }
00817 break;
00818 #endif
00819 case MPI_COMBINER_CONTIGUOUS:
00820 top_count = ints[0];
00821 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00822 &old_ntypes, &old_combiner);
00823 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00824
00825 prev_index = *curr_index;
00826 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00827 count = ADIOI_Count_contiguous_blocks(types[0], curr_index);
00828 else count = 1;
00829
00830 if (prev_index == *curr_index)
00831
00832 (*curr_index)++;
00833 else {
00834
00835 num = *curr_index - prev_index;
00836 count *= top_count;
00837 *curr_index += (top_count - 1)*num;
00838 }
00839 break;
00840
00841 case MPI_COMBINER_VECTOR:
00842 case MPI_COMBINER_HVECTOR:
00843 case MPI_COMBINER_HVECTOR_INTEGER:
00844 top_count = ints[0];
00845 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00846 &old_ntypes, &old_combiner);
00847 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00848
00849 prev_index = *curr_index;
00850 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00851 count = ADIOI_Count_contiguous_blocks(types[0], curr_index);
00852 else count = 1;
00853
00854 if (prev_index == *curr_index) {
00855
00856 count = top_count;
00857 *curr_index += count;
00858 }
00859 else {
00860
00861 num = *curr_index - prev_index;
00862
00863
00864
00865 count *= ints[1] * top_count;
00866
00867
00868 *curr_index += (ints[1] - 1)*num;
00869
00870
00871 num = *curr_index - prev_index;
00872 *curr_index += (top_count - 1)*num;
00873 }
00874 break;
00875
00876 case MPI_COMBINER_INDEXED:
00877 case MPI_COMBINER_HINDEXED:
00878 case MPI_COMBINER_HINDEXED_INTEGER:
00879 top_count = ints[0];
00880 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00881 &old_ntypes, &old_combiner);
00882 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00883
00884 prev_index = *curr_index;
00885 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00886 count = ADIOI_Count_contiguous_blocks(types[0], curr_index);
00887 else count = 1;
00888
00889 if (prev_index == *curr_index) {
00890
00891 count = top_count;
00892 *curr_index += count;
00893 }
00894 else {
00895
00896 basic_num = *curr_index - prev_index;
00897
00898
00899
00900 *curr_index += (ints[1]-1) * basic_num;
00901 count *= ints[1];
00902
00903
00904 for (i=1; i<top_count; i++) {
00905 count += ints[1+i] * basic_num;
00906 *curr_index += ints[1+i] * basic_num;
00907 }
00908 }
00909 break;
00910
00911 case MPI_COMBINER_INDEXED_BLOCK:
00912 top_count = ints[0];
00913 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00914 &old_ntypes, &old_combiner);
00915 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00916
00917 prev_index = *curr_index;
00918 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00919 count = ADIOI_Count_contiguous_blocks(types[0], curr_index);
00920 else count = 1;
00921
00922 if (prev_index == *curr_index) {
00923
00924 count = top_count;
00925 *curr_index += count;
00926 }
00927 else {
00928
00929 basic_num = *curr_index - prev_index;
00930
00931
00932
00933 *curr_index += (ints[1]-1) * basic_num;
00934 count *= ints[1];
00935
00936
00937 *curr_index += (top_count-1) * count;
00938 count *= top_count;
00939 }
00940 break;
00941
00942 case MPI_COMBINER_STRUCT:
00943 case MPI_COMBINER_STRUCT_INTEGER:
00944 top_count = ints[0];
00945 count = 0;
00946 for (n=0; n<top_count; n++) {
00947 MPI_Type_get_envelope(types[n], &old_nints, &old_nadds,
00948 &old_ntypes, &old_combiner);
00949 ADIOI_Datatype_iscontig(types[n], &old_is_contig);
00950
00951 prev_index = *curr_index;
00952 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
00953 count += ADIOI_Count_contiguous_blocks(types[n], curr_index);
00954
00955 if (prev_index == *curr_index) {
00956
00957 count++;
00958 (*curr_index)++;
00959 }
00960 else {
00961
00962
00963
00964 num = *curr_index - prev_index;
00965 count += (ints[1+n]-1)*num;
00966 (*curr_index) += (ints[1+n]-1)*num;
00967 }
00968 }
00969 break;
00970
00971 case MPI_COMBINER_RESIZED:
00972
00973
00974
00975 (*curr_index) += 2;
00976 count += 2;
00977
00978
00979 MPI_Type_get_envelope(types[0], &old_nints, &old_nadds,
00980 &old_ntypes, &old_combiner);
00981 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
00982
00983 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig)) {
00984 count += ADIOI_Count_contiguous_blocks(types[0], curr_index);
00985 }
00986 else {
00987
00988 count++;
00989 (*curr_index)++;
00990 }
00991 break;
00992
00993 default:
00994
00995 DBG_FPRINTF(stderr, "Error: Unsupported datatype passed to ADIOI_Count_contiguous_blocks, combiner = %d\n", combiner);
00996 MPI_Abort(MPI_COMM_WORLD, 1);
00997 }
00998
00999 #ifndef MPISGI
01000
01001
01002 for (i=0; i<ntypes; i++) {
01003 MPI_Type_get_envelope(types[i], &old_nints, &old_nadds, &old_ntypes,
01004 &old_combiner);
01005 if (old_combiner != MPI_COMBINER_NAMED) MPI_Type_free(types+i);
01006 }
01007 #endif
01008
01009 ADIOI_Free(ints);
01010 ADIOI_Free(adds);
01011 ADIOI_Free(types);
01012 return count;
01013 #endif
01014 }
01015
01016
01017
01018
01019
01020 static void removezeros(ADIOI_Flatlist_node *flat_type)
01021 {
01022 int i,j,opt_blocks;
01023 ADIO_Offset *opt_blocklens;
01024 ADIO_Offset *opt_indices;
01025
01026
01027
01028
01029
01030 if (flat_type->count <= 2) return;
01031
01032 opt_blocks = 2;
01033 for (i=1; i < flat_type->count -1; i++) {
01034 if(flat_type->blocklens[i] != 0)
01035 opt_blocks++;
01036 }
01037
01038 if (opt_blocks == flat_type->count) return;
01039 opt_blocklens = (ADIO_Offset *) ADIOI_Malloc(opt_blocks * sizeof(ADIO_Offset));
01040 opt_indices = (ADIO_Offset *)ADIOI_Malloc(opt_blocks*sizeof(ADIO_Offset));
01041
01042
01043 opt_blocklens[0] = flat_type->blocklens[0];
01044 opt_indices[0] = flat_type->indices[0];
01045 j = 1;
01046 for (i=1; i< flat_type->count -1; i++) {
01047 if( flat_type->blocklens[i] != 0) {
01048 opt_indices[j] = flat_type->indices[i];
01049 opt_blocklens[j] = flat_type->blocklens[i];
01050 j++;
01051 }
01052 }
01053 opt_indices[j] = flat_type->indices[flat_type->count -1];
01054 opt_blocklens[j] = flat_type->blocklens[flat_type->count -1];
01055
01056 flat_type->count = opt_blocks;
01057 ADIOI_Free(flat_type->blocklens);
01058 ADIOI_Free(flat_type->indices);
01059 flat_type->blocklens = opt_blocklens;
01060 flat_type->indices = opt_indices;
01061 return;
01062 }
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077 void ADIOI_Optimize_flattened(ADIOI_Flatlist_node *flat_type)
01078 {
01079 int i, j, opt_blocks;
01080 ADIO_Offset *opt_blocklens;
01081 ADIO_Offset *opt_indices;
01082
01083 opt_blocks = 1;
01084
01085
01086 for (i=0; i < (flat_type->count - 1); i++) {
01087 if ((flat_type->indices[i] + flat_type->blocklens[i] !=
01088 flat_type->indices[i + 1]))
01089 opt_blocks++;
01090 }
01091
01092
01093 if (opt_blocks == flat_type->count) return;
01094
01095 opt_blocklens = (ADIO_Offset *) ADIOI_Malloc(opt_blocks * sizeof(ADIO_Offset));
01096 opt_indices = (ADIO_Offset *)ADIOI_Malloc(opt_blocks*sizeof(ADIO_Offset));
01097
01098
01099 opt_blocklens[0] = flat_type->blocklens[0];
01100 opt_indices[0] = flat_type->indices[0];
01101 j = 0;
01102 for (i=0; i < (flat_type->count - 1); i++) {
01103 if ((flat_type->indices[i] + flat_type->blocklens[i] ==
01104 flat_type->indices[i + 1]))
01105 opt_blocklens[j] += flat_type->blocklens[i + 1];
01106 else {
01107 j++;
01108 opt_indices[j] = flat_type->indices[i + 1];
01109 opt_blocklens[j] = flat_type->blocklens[i + 1];
01110 }
01111 }
01112 flat_type->count = opt_blocks;
01113 ADIOI_Free(flat_type->blocklens);
01114 ADIOI_Free(flat_type->indices);
01115 flat_type->blocklens = opt_blocklens;
01116 flat_type->indices = opt_indices;
01117 removezeros(flat_type);
01118 return;
01119 }
01120
01121 void ADIOI_Delete_flattened(MPI_Datatype datatype)
01122 {
01123 ADIOI_Flatlist_node *flat, *prev;
01124
01125 prev = flat = CtvAccess(ADIOI_Flatlist);
01126 while (flat && (flat->type != datatype)) {
01127 prev = flat;
01128 flat = flat->next;
01129 }
01130 if (flat) {
01131 prev->next = flat->next;
01132 if (flat->blocklens) ADIOI_Free(flat->blocklens);
01133 if (flat->indices) ADIOI_Free(flat->indices);
01134 ADIOI_Free(flat);
01135 }
01136 }