00001
00002
00003
00004
00005
00006
00007
00008 #include "./dataloop.h"
00009
00010 #ifndef PREPEND_PREFIX
00011 #error "You must explicitly include a header that sets the PREPEND_PREFIX and includes dataloop_parts.h"
00012 #endif
00013
00014 static int DLOOP_Dataloop_create_struct_memory_error(void);
00015 static int DLOOP_Dataloop_create_unique_type_struct(int count,
00016 int *blklens,
00017 MPI_Aint *disps,
00018 DLOOP_Type *oldtypes,
00019 int type_pos,
00020 DLOOP_Dataloop **dlp_p,
00021 int *dlsz_p,
00022 int *dldepth_p,
00023 int flag);
00024 static int DLOOP_Dataloop_create_basic_all_bytes_struct(
00025 int count,
00026 int *blklens,
00027 MPI_Aint *disps,
00028 DLOOP_Type *oldtypes,
00029 DLOOP_Dataloop **dlp_p,
00030 int *dlsz_p,
00031 int *dldepth_p,
00032 int flag);
00033 static int DLOOP_Dataloop_create_flattened_struct(int count,
00034 int *blklens,
00035 MPI_Aint *disps,
00036 DLOOP_Type *oldtypes,
00037 DLOOP_Dataloop **dlp_p,
00038 int *dlsz_p,
00039 int *dldepth_p,
00040 int flag);
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 int PREPEND_PREFIX(Dataloop_create_struct)(int count,
00068 int *blklens,
00069 MPI_Aint *disps,
00070 DLOOP_Type *oldtypes,
00071 DLOOP_Dataloop **dlp_p,
00072 int *dlsz_p,
00073 int *dldepth_p,
00074 int flag)
00075 {
00076 int err, i, nr_basics = 0, nr_derived = 0, type_pos = 0;
00077
00078 DLOOP_Type first_basic = MPI_DATATYPE_NULL,
00079 first_derived = MPI_DATATYPE_NULL;
00080
00081
00082 int loop_idx, new_loop_sz, new_loop_depth;
00083 int old_loop_sz = 0, old_loop_depth = 0;
00084
00085 DLOOP_Dataloop *new_dlp, *curpos;
00086
00087
00088 if (count == 0)
00089 {
00090 err = PREPEND_PREFIX(Dataloop_create_contiguous)(0,
00091 MPI_INT,
00092 dlp_p,
00093 dlsz_p,
00094 dldepth_p,
00095 flag);
00096 return err;
00097 }
00098
00099
00100 for (i=0; i < count; i++)
00101 {
00102
00103 if (blklens[i] == 0) continue;
00104
00105 if (oldtypes[i] != MPI_LB && oldtypes[i] != MPI_UB)
00106 {
00107 int is_builtin;
00108
00109 is_builtin =
00110 (DLOOP_Handle_hasloop_macro(oldtypes[i])) ? 0 : 1;
00111
00112 if (is_builtin)
00113 {
00114 if (nr_basics == 0)
00115 {
00116 first_basic = oldtypes[i];
00117 type_pos = i;
00118 }
00119 else if (oldtypes[i] != first_basic)
00120 {
00121 first_basic = MPI_DATATYPE_NULL;
00122 }
00123 nr_basics++;
00124 }
00125 else
00126 {
00127 if (nr_derived == 0)
00128 {
00129 first_derived = oldtypes[i];
00130 type_pos = i;
00131 }
00132 else if (oldtypes[i] != first_derived)
00133 {
00134 first_derived = MPI_DATATYPE_NULL;
00135 }
00136 nr_derived++;
00137 }
00138 }
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 if (nr_basics == 0 && nr_derived == 0)
00154 {
00155 err = PREPEND_PREFIX(Dataloop_create_contiguous)(0,
00156 MPI_INT,
00157 dlp_p,
00158 dlsz_p,
00159 dldepth_p,
00160 flag);
00161 return err;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 if (nr_basics + nr_derived == 1)
00175 {
00176
00177 err = PREPEND_PREFIX(Dataloop_create_blockindexed)
00178 (1,
00179 blklens[type_pos],
00180 &disps[type_pos],
00181 1,
00182 oldtypes[type_pos],
00183 dlp_p,
00184 dlsz_p,
00185 dldepth_p,
00186 flag);
00187
00188 return err;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 if (((nr_derived == 0) && (first_basic != MPI_DATATYPE_NULL)) ||
00203 ((nr_basics == 0) && (first_derived != MPI_DATATYPE_NULL)))
00204 {
00205 return DLOOP_Dataloop_create_unique_type_struct(count,
00206 blklens,
00207 disps,
00208 oldtypes,
00209 type_pos,
00210 dlp_p,
00211 dlsz_p,
00212 dldepth_p,
00213 flag);
00214 }
00215
00216
00217
00218
00219
00220
00221
00222 if (nr_derived == 0 && ((flag == DLOOP_DATALOOP_HOMOGENEOUS) ||
00223 (flag == DLOOP_DATALOOP_ALL_BYTES)))
00224 {
00225 return DLOOP_Dataloop_create_basic_all_bytes_struct(count,
00226 blklens,
00227 disps,
00228 oldtypes,
00229 dlp_p,
00230 dlsz_p,
00231 dldepth_p,
00232 flag);
00233 }
00234
00235
00236
00237
00238
00239
00240
00241 if ((flag == DLOOP_DATALOOP_HOMOGENEOUS) ||
00242 (flag == DLOOP_DATALOOP_ALL_BYTES))
00243 {
00244 return DLOOP_Dataloop_create_flattened_struct(count,
00245 blklens,
00246 disps,
00247 oldtypes,
00248 dlp_p,
00249 dlsz_p,
00250 dldepth_p,
00251 flag);
00252 }
00253
00254
00255 for (i=0; i < count; i++)
00256 {
00257
00258 if (blklens[i] == 0) continue;
00259
00260 if (DLOOP_Handle_hasloop_macro(oldtypes[i]))
00261 {
00262 int tmp_loop_depth, tmp_loop_sz;
00263
00264 DLOOP_Handle_get_loopdepth_macro(oldtypes[i], tmp_loop_depth, flag);
00265 DLOOP_Handle_get_loopsize_macro(oldtypes[i], tmp_loop_sz, flag);
00266
00267 if (tmp_loop_depth > old_loop_depth)
00268 {
00269 old_loop_depth = tmp_loop_depth;
00270 }
00271 old_loop_sz += tmp_loop_sz;
00272 }
00273 }
00274
00275
00276
00277
00278
00279
00280 if (nr_basics > 0)
00281 {
00282
00283
00284
00285 new_loop_depth = ((old_loop_depth+1) > 2) ? (old_loop_depth+1) : 2;
00286 }
00287 else
00288 {
00289 new_loop_depth = old_loop_depth + 1;
00290 }
00291
00292 PREPEND_PREFIX(Dataloop_struct_alloc)((DLOOP_Count) nr_basics + nr_derived,
00293 old_loop_sz,
00294 nr_basics,
00295 &curpos,
00296 &new_dlp,
00297 &new_loop_sz);
00298
00299 if (!new_dlp)
00300 {
00301 return DLOOP_Dataloop_create_struct_memory_error();
00302 }
00303
00304
00305
00306 new_dlp->kind = DLOOP_KIND_STRUCT;
00307 new_dlp->el_size = -1;
00308 new_dlp->el_extent = -1;
00309 new_dlp->el_type = MPI_DATATYPE_NULL;
00310
00311 new_dlp->loop_params.s_t.count = (DLOOP_Count) nr_basics + nr_derived;
00312
00313
00314
00315
00316
00317 for (i=0, loop_idx = 0; i < count; i++)
00318 {
00319 int is_builtin;
00320
00321
00322 if (blklens[i] == 0) continue;
00323
00324 is_builtin = (DLOOP_Handle_hasloop_macro(oldtypes[i])) ? 0 : 1;
00325
00326 if (is_builtin)
00327 {
00328 DLOOP_Dataloop *dummy_dlp;
00329 int dummy_sz, dummy_depth;
00330
00331
00332 if (oldtypes[i] == MPI_LB || oldtypes[i] == MPI_UB)
00333 {
00334 continue;
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344 err = PREPEND_PREFIX(Dataloop_create_contiguous)(blklens[i],
00345 oldtypes[i],
00346 &dummy_dlp,
00347 &dummy_sz,
00348 &dummy_depth,
00349 flag);
00350
00351
00352 if (err) {
00353
00354 return -1;
00355 }
00356
00357
00358
00359
00360
00361 PREPEND_PREFIX(Dataloop_copy)(curpos, dummy_dlp, dummy_sz);
00362 new_dlp->loop_params.s_t.dataloop_array[loop_idx] = curpos;
00363 curpos = (DLOOP_Dataloop *) ((char *) curpos + dummy_sz);
00364
00365
00366 new_dlp->loop_params.s_t.blocksize_array[loop_idx] = 1;
00367 new_dlp->loop_params.s_t.el_extent_array[loop_idx] =
00368 ((DLOOP_Offset) blklens[i]) * dummy_dlp->el_extent;
00369 PREPEND_PREFIX(Dataloop_free)(&dummy_dlp);
00370 }
00371 else
00372 {
00373 DLOOP_Dataloop *old_loop_ptr;
00374 int old_loop_sz;
00375 DLOOP_Offset old_extent;
00376
00377 DLOOP_Handle_get_loopptr_macro(oldtypes[i], old_loop_ptr, flag);
00378 DLOOP_Handle_get_loopsize_macro(oldtypes[i], old_loop_sz, flag);
00379 DLOOP_Handle_get_extent_macro(oldtypes[i], old_extent);
00380
00381 PREPEND_PREFIX(Dataloop_copy)(curpos, old_loop_ptr, old_loop_sz);
00382 new_dlp->loop_params.s_t.dataloop_array[loop_idx] = curpos;
00383 curpos = (DLOOP_Dataloop *) ((char *) curpos + old_loop_sz);
00384
00385 new_dlp->loop_params.s_t.blocksize_array[loop_idx] =
00386 (DLOOP_Count) blklens[i];
00387 new_dlp->loop_params.s_t.el_extent_array[loop_idx] =
00388 old_extent;
00389 }
00390 new_dlp->loop_params.s_t.offset_array[loop_idx] =
00391 (DLOOP_Offset) disps[i];
00392 loop_idx++;
00393 }
00394
00395 *dlp_p = new_dlp;
00396 *dlsz_p = new_loop_sz;
00397 *dldepth_p = new_loop_depth;
00398
00399 return 0;
00400 }
00401
00402
00403 static int DLOOP_Dataloop_create_struct_memory_error(void)
00404 {
00405 return -1;
00406 }
00407
00408
00409 static int DLOOP_Dataloop_create_unique_type_struct(int count,
00410 int *blklens,
00411 MPI_Aint *disps,
00412 DLOOP_Type *oldtypes,
00413 int type_pos,
00414 DLOOP_Dataloop **dlp_p,
00415 int *dlsz_p,
00416 int *dldepth_p,
00417 int flag)
00418 {
00419
00420
00421
00422 int i, err, *tmp_blklens, cur_pos = 0;
00423 DLOOP_Offset *tmp_disps;
00424
00425
00426 tmp_blklens = (int *) DLOOP_Malloc(count * sizeof(int));
00427
00428 if (!tmp_blklens) {
00429
00430 return DLOOP_Dataloop_create_struct_memory_error();
00431 }
00432
00433
00434 tmp_disps = (DLOOP_Offset *)
00435 DLOOP_Malloc(count * sizeof(DLOOP_Offset));
00436
00437 if (!tmp_disps) {
00438 DLOOP_Free(tmp_blklens);
00439
00440 return DLOOP_Dataloop_create_struct_memory_error();
00441 }
00442
00443
00444 for (i=type_pos; i < count; i++)
00445 {
00446 if (oldtypes[i] == oldtypes[type_pos] && blklens != 0)
00447 {
00448 tmp_blklens[cur_pos] = blklens[i];
00449 tmp_disps[cur_pos] = disps[i];
00450 cur_pos++;
00451 }
00452 }
00453
00454 err = PREPEND_PREFIX(Dataloop_create_indexed)(cur_pos,
00455 tmp_blklens,
00456 tmp_disps,
00457 1,
00458 oldtypes[type_pos],
00459 dlp_p,
00460 dlsz_p,
00461 dldepth_p,
00462 flag);
00463
00464 DLOOP_Free(tmp_blklens);
00465 DLOOP_Free(tmp_disps);
00466
00467 return err;
00468
00469 }
00470
00471 static int DLOOP_Dataloop_create_basic_all_bytes_struct(
00472 int count,
00473 int *blklens,
00474 MPI_Aint *disps,
00475 DLOOP_Type *oldtypes,
00476 DLOOP_Dataloop **dlp_p,
00477 int *dlsz_p,
00478 int *dldepth_p,
00479 int flag)
00480 {
00481 int i, err, cur_pos = 0;
00482 int *tmp_blklens;
00483 MPI_Aint *tmp_disps;
00484
00485
00486 tmp_blklens = (int *) DLOOP_Malloc(count * sizeof(int));
00487
00488
00489 if (!tmp_blklens)
00490 {
00491 return DLOOP_Dataloop_create_struct_memory_error();
00492 }
00493
00494
00495 tmp_disps = (MPI_Aint *) DLOOP_Malloc(count * sizeof(MPI_Aint));
00496
00497
00498 if (!tmp_disps)
00499 {
00500 DLOOP_Free(tmp_blklens);
00501 return DLOOP_Dataloop_create_struct_memory_error();
00502 }
00503
00504
00505 for (i=0; i < count; i++)
00506 {
00507 if (oldtypes[i] != MPI_LB && oldtypes[i] != MPI_UB && blklens[i] != 0)
00508 {
00509 DLOOP_Offset sz;
00510
00511 DLOOP_Handle_get_size_macro(oldtypes[i], sz);
00512 tmp_blklens[cur_pos] = (int) sz * blklens[i];
00513 tmp_disps[cur_pos] = disps[i];
00514 cur_pos++;
00515 }
00516 }
00517 err = PREPEND_PREFIX(Dataloop_create_indexed)(cur_pos,
00518 tmp_blklens,
00519 tmp_disps,
00520 1,
00521 MPI_BYTE,
00522 dlp_p,
00523 dlsz_p,
00524 dldepth_p,
00525 flag);
00526
00527 DLOOP_Free(tmp_blklens);
00528 DLOOP_Free(tmp_disps);
00529
00530 return err;
00531 }
00532
00533 static int DLOOP_Dataloop_create_flattened_struct(int count,
00534 int *blklens,
00535 MPI_Aint *disps,
00536 DLOOP_Type *oldtypes,
00537 DLOOP_Dataloop **dlp_p,
00538 int *dlsz_p,
00539 int *dldepth_p,
00540 int flag)
00541 {
00542
00543 int i, err, *tmp_blklens, nr_blks = 0;
00544 MPI_Aint *tmp_disps;
00545
00546 DLOOP_Offset bytes;
00547 DLOOP_Segment *segp;
00548
00549 int first_ind, last_ind;
00550
00551 segp = PREPEND_PREFIX(Segment_alloc)();
00552
00553 if (!segp) {
00554 return DLOOP_Dataloop_create_struct_memory_error();
00555 }
00556
00557
00558
00559 for (i=0; i < count; i++)
00560 {
00561 int is_basic;
00562
00563
00564 if (blklens[i] == 0) continue;
00565
00566 is_basic = (DLOOP_Handle_hasloop_macro(oldtypes[i])) ? 0 : 1;
00567
00568 if (is_basic && (oldtypes[i] != MPI_LB &&
00569 oldtypes[i] != MPI_UB))
00570 {
00571 nr_blks++;
00572 }
00573 else
00574 {
00575 DLOOP_Count tmp_nr_blks;
00576
00577 PREPEND_PREFIX(Segment_init)(NULL,
00578 (DLOOP_Count) blklens[i],
00579 oldtypes[i],
00580 segp,
00581 flag);
00582 bytes = SEGMENT_IGNORE_LAST;
00583
00584 PREPEND_PREFIX(Segment_count_contig_blocks)(segp,
00585 0,
00586 &bytes,
00587 &tmp_nr_blks);
00588
00589 nr_blks += tmp_nr_blks;
00590 }
00591 }
00592
00593 nr_blks += 2;
00594
00595 tmp_blklens = (int *) DLOOP_Malloc(nr_blks * sizeof(int));
00596
00597 if (!tmp_blklens) {
00598 return DLOOP_Dataloop_create_struct_memory_error();
00599 }
00600
00601
00602
00603 tmp_disps = (MPI_Aint *) DLOOP_Malloc(nr_blks * sizeof(MPI_Aint));
00604
00605 if (!tmp_disps) {
00606 DLOOP_Free(tmp_blklens);
00607 return DLOOP_Dataloop_create_struct_memory_error();
00608 }
00609
00610
00611
00612 first_ind = 0;
00613 for (i=0; i < count; i++)
00614 {
00615
00616
00617
00618
00619
00620
00621
00622
00623 if (oldtypes[i] != MPI_UB && oldtypes[i] != MPI_LB && blklens[i] != 0)
00624 {
00625 PREPEND_PREFIX(Segment_init)((char *) disps[i],
00626 (DLOOP_Count) blklens[i],
00627 oldtypes[i],
00628 segp,
00629 0 );
00630
00631 last_ind = nr_blks - first_ind;
00632 bytes = SEGMENT_IGNORE_LAST;
00633 PREPEND_PREFIX(Segment_mpi_flatten)(segp,
00634 0,
00635 &bytes,
00636 &tmp_blklens[first_ind],
00637 &tmp_disps[first_ind],
00638 &last_ind);
00639 first_ind += last_ind;
00640 }
00641 }
00642 nr_blks = first_ind;
00643
00644 #if 0
00645 if (MPIU_DBG_SELECTED(DATATYPE,VERBOSE)) {
00646 MPIU_DBG_OUT(DATATYPE,"--- start of flattened type ---");
00647 for (i=0; i < nr_blks; i++) {
00648 MPIU_DBG_OUT_FMT(DATATYPE,(MPIU_DBG_FDEST,
00649 "a[%d] = (%d, %d)\n", i,
00650 tmp_blklens[i], tmp_disps[i]));
00651 }
00652 MPIU_DBG_OUT(DATATYPE,"--- end of flattened type ---");
00653 }
00654 #endif
00655
00656 PREPEND_PREFIX(Segment_free)(segp);
00657
00658 err = PREPEND_PREFIX(Dataloop_create_indexed)(nr_blks,
00659 tmp_blklens,
00660 tmp_disps,
00661 1,
00662 MPI_BYTE,
00663 dlp_p,
00664 dlsz_p,
00665 dldepth_p,
00666 flag);
00667
00668 DLOOP_Free(tmp_blklens);
00669 DLOOP_Free(tmp_disps);
00670
00671 return err;
00672 }