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 }