00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 
00024 #include "romio_dataloop.h"
00025 #include "typesize_support.h"
00026 
00027 typedef struct MPIO_Datatype_s {
00028     int             valid, refct;
00029     int             dloop_size, dloop_depth; 
00030     DLOOP_Offset    size, extent; 
00031     DLOOP_Offset    true_lb, true_extent;
00032     DLOOP_Dataloop *dloop;
00033     DLOOP_Count     contig_blks;
00034 } MPIO_Datatype;
00035 
00036 
00037 #define MPIO_DATATYPE_VALID_DLOOP_PTR    1
00038 #define MPIO_DATATYPE_VALID_DLOOP_SIZE   2
00039 #define MPIO_DATATYPE_VALID_DLOOP_DEPTH  4
00040 #define MPIO_DATATYPE_VALID_TYPESZEXT    8
00041 #define MPIO_DATATYPE_VALID_CONTIG_BLKS 16
00042 
00043 #define MPIO_DATATYPE_VALID_DATALOOP (MPIO_DATATYPE_VALID_DLOOP_PTR | \
00044                                       MPIO_DATATYPE_VALID_DLOOP_SIZE | \
00045                                       MPIO_DATATYPE_VALID_DLOOP_DEPTH)
00046 
00047 
00048 static int MPIO_Datatype_keyval = MPI_KEYVAL_INVALID;
00049 static int MPIO_Datatype_finalize_keyval = MPI_KEYVAL_INVALID;
00050 
00051 static MPIO_Datatype *MPIO_Datatype_allocate(MPI_Datatype type);
00052 static void MPIO_Datatype_set_szext(MPI_Datatype type, MPIO_Datatype *dtp);
00053 static int MPIO_Datatype_initialize(void);
00054 static int MPIO_Datatype_finalize(MPI_Comm comm, int comm_keyval,
00055                   void *attrval, void *extrastate);
00056 static int MPIO_Datatype_copy_attr_function(MPI_Datatype type, int type_keyval,
00057                         void *extra_state,
00058                         void *attribute_val_in,
00059                         void *attribute_val_out, int *flag);
00060 static int MPIO_Datatype_delete_attr_function(MPI_Datatype type,
00061                           int type_keyval,
00062                           void *attribute_val,
00063                           void *extra_state);
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 void MPIO_Datatype_init_dataloop(MPI_Datatype type)
00072 {
00073     int mpi_errno, attrflag;
00074     MPIO_Datatype *dtp;
00075 
00076     
00077     if (!(MPIO_Datatype_is_nontrivial(type))) return;
00078 
00079     if (MPIO_Datatype_keyval != MPI_KEYVAL_INVALID) {
00080     MPIO_Datatype_initialize();
00081     }
00082 
00083     mpi_errno = MPI_Type_get_attr(type, MPIO_Datatype_keyval, &dtp, &attrflag);
00084     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00085 
00086     if (!attrflag) {
00087     
00088     dtp = MPIO_Datatype_allocate(type);
00089     }
00090     if (!(dtp->valid | MPIO_DATATYPE_VALID_DLOOP_PTR)) {
00091     MPIO_Dataloop_create(type,
00092                  &dtp->dloop,
00093                  &dtp->dloop_size,
00094                  &dtp->dloop_depth,
00095                  0);
00096     }
00097 
00098     return;
00099 }
00100 
00101 void MPIO_Datatype_get_size(MPI_Datatype type, MPI_Offset *size_p)
00102 {
00103     int mpi_errno, attrflag;
00104     MPIO_Datatype *dtp;
00105 
00106     if (MPIO_Datatype_keyval != MPI_KEYVAL_INVALID) {
00107     MPIO_Datatype_initialize();
00108     }
00109 
00110     mpi_errno = MPI_Type_get_attr(type, MPIO_Datatype_keyval, &dtp, &attrflag);
00111     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00112     
00113     if (!attrflag) {
00114     dtp = MPIO_Datatype_allocate(type);
00115     }
00116 
00117     if (!(dtp->valid & MPIO_DATATYPE_VALID_TYPESZEXT)) {
00118     MPIO_Datatype_set_szext(type, dtp);
00119     }
00120 
00121     *size_p = dtp->size;
00122     return;
00123 }
00124 
00125 void MPIO_Datatype_get_extent(MPI_Datatype type, MPI_Offset *extent_p)
00126 {
00127     int mpi_errno, attrflag;
00128     MPIO_Datatype *dtp;
00129 
00130     if (MPIO_Datatype_keyval != MPI_KEYVAL_INVALID) {
00131     MPIO_Datatype_initialize();
00132     }
00133 
00134     mpi_errno = MPI_Type_get_attr(type, MPIO_Datatype_keyval, &dtp, &attrflag);
00135     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00136     
00137     if (!attrflag) {
00138     dtp = MPIO_Datatype_allocate(type);
00139     }
00140 
00141     if (!(dtp->valid & MPIO_DATATYPE_VALID_TYPESZEXT)) {
00142     MPIO_Datatype_set_szext(type, dtp);
00143     }
00144 
00145     *extent_p = dtp->extent;
00146     return;
00147 }
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 void MPIO_Datatype_get_block_info(MPI_Datatype type,
00159                   MPI_Offset *true_lb_p,
00160                   MPI_Offset *count_p,
00161                   int *n_contig_p)
00162 {
00163     int mpi_errno, attrflag;
00164     int nr_ints, nr_aints, nr_types, combiner;
00165 
00166     mpi_errno = MPI_Type_get_envelope(type, &nr_ints, &nr_aints,
00167                        &nr_types, &combiner);
00168     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00169 
00170     if (combiner == MPI_COMBINER_NAMED &&
00171     (type != MPI_FLOAT_INT &&
00172      type != MPI_DOUBLE_INT &&
00173      type != MPI_LONG_INT &&
00174      type != MPI_SHORT_INT &&
00175      type != MPI_LONG_DOUBLE_INT))
00176     {
00177     *true_lb_p  = 0;
00178     *count_p    = 1;
00179     *n_contig_p = 1;
00180     }
00181     else {
00182     MPIO_Datatype *dtp;
00183     MPIO_Segment  *segp;
00184     MPI_Offset     bytes;
00185 
00186     mpi_errno = MPI_Type_get_attr(type, MPIO_Datatype_keyval, &dtp,
00187                       &attrflag);
00188     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00189     if (!attrflag) {
00190         
00191         dtp = MPIO_Datatype_allocate(type);
00192     }
00193     if (!(dtp->valid | MPIO_DATATYPE_VALID_DLOOP_PTR)) {
00194         MPIO_Dataloop_create(type,
00195                  &dtp->dloop,
00196                  &dtp->dloop_size,
00197                  &dtp->dloop_depth, 0);
00198         DLOOP_Assert(dtp->dloop != NULL);
00199     }
00200         
00201     DLOOP_Assert((dtp->valid | MPIO_DATATYPE_VALID_DLOOP_PTR) &&
00202              (dtp->valid | MPIO_DATATYPE_VALID_DLOOP_SIZE) &&
00203              (dtp->valid | MPIO_DATATYPE_VALID_DLOOP_DEPTH));
00204 
00205     segp = MPIO_Segment_alloc();
00206     DLOOP_Assert(segp != NULL);
00207 
00208     MPIO_Segment_init(NULL, 1, type, segp, 0);
00209     bytes = SEGMENT_IGNORE_LAST;
00210 
00211     MPIO_Segment_count_contig_blocks(segp, 0, &bytes, &dtp->contig_blks);
00212     MPIO_Segment_free(segp);
00213     dtp->valid |= MPIO_DATATYPE_VALID_CONTIG_BLKS;
00214 
00215     if (!(dtp->valid | MPIO_DATATYPE_VALID_TYPESZEXT)) {
00216         MPIO_Datatype_set_szext(type, dtp);
00217     }
00218     *true_lb_p  = dtp->true_lb;
00219     *count_p    = dtp->contig_blks;
00220     *n_contig_p = (dtp->contig_blks == 1 &&
00221                dtp->true_extent == dtp->extent) ? 1 : 0;
00222     }
00223 
00224     return;
00225 }
00226 
00227 void MPIO_Datatype_get_el_type(MPI_Datatype type,
00228                    MPI_Datatype *eltype_p,
00229                    int flag)
00230 {
00231     int mpi_errno;
00232     int nr_ints, nr_aints, nr_types, combiner;
00233 
00234     mpi_errno = MPI_Type_get_envelope(type, &nr_ints, &nr_aints,
00235                        &nr_types, &combiner);
00236     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00237 
00238     if (combiner == MPI_COMBINER_NAMED) {
00239     if (type == MPI_FLOAT_INT ||
00240         type == MPI_DOUBLE_INT ||
00241         type == MPI_LONG_INT ||
00242         type == MPI_SHORT_INT ||
00243         type == MPI_LONG_DOUBLE_INT)
00244     {
00245         *eltype_p = MPI_DATATYPE_NULL;
00246     }
00247     else if (type == MPI_2INT) {
00248         *eltype_p = MPI_INT;
00249     }
00250     else {
00251         
00252         *eltype_p = type;
00253     }
00254     }
00255     else {
00256     MPIO_Dataloop *dlp;
00257     MPIO_Datatype_get_loopptr(type, &dlp, flag);
00258 
00259     *eltype_p = dlp->el_type;
00260     }
00261     return;
00262 }
00263 
00264 
00265 void MPIO_Datatype_get_loopptr(MPI_Datatype type,
00266                    MPIO_Dataloop **ptr_p,
00267                    int flag)
00268 {
00269     int mpi_errno, attrflag;
00270     MPIO_Datatype *dtp;
00271 
00272     if (MPIO_Datatype_keyval != MPI_KEYVAL_INVALID) {
00273     MPIO_Datatype_initialize();
00274     }
00275 
00276     mpi_errno = MPI_Type_get_attr(type, MPIO_Datatype_keyval, &dtp, &attrflag);
00277     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00278 
00279     if (!(dtp->valid & MPIO_DATATYPE_VALID_DLOOP_PTR))
00280     *ptr_p = NULL;
00281     else 
00282     *ptr_p = dtp->dloop;
00283 
00284     return;
00285 }
00286 
00287 void MPIO_Datatype_get_loopsize(MPI_Datatype type, int *size_p, int flag)
00288 {
00289     int mpi_errno, attrflag;
00290     MPIO_Datatype *dtp;
00291 
00292     if (MPIO_Datatype_keyval != MPI_KEYVAL_INVALID) {
00293     MPIO_Datatype_initialize();
00294     }
00295 
00296     mpi_errno = MPI_Type_get_attr(type, MPIO_Datatype_keyval, &dtp, &attrflag);
00297     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00298 
00299     if (!(dtp->valid & MPIO_DATATYPE_VALID_DLOOP_SIZE))
00300     *size_p = -1;
00301     else
00302     *size_p = dtp->dloop_size;
00303 
00304     return;
00305 }
00306 
00307 void MPIO_Datatype_get_loopdepth(MPI_Datatype type, int *depth_p, int flag)
00308 {
00309     int mpi_errno, attrflag;
00310     MPIO_Datatype *dtp;
00311 
00312     if (MPIO_Datatype_keyval != MPI_KEYVAL_INVALID) {
00313     MPIO_Datatype_initialize();
00314     }
00315 
00316     mpi_errno = MPI_Type_get_attr(type, MPIO_Datatype_keyval, &dtp, &attrflag);
00317     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00318 
00319     if (!(dtp->valid & MPIO_DATATYPE_VALID_DLOOP_DEPTH))
00320     *depth_p = -1;
00321     else
00322     *depth_p = dtp->dloop_depth;
00323 
00324     return;
00325 }
00326 
00327 void MPIO_Datatype_set_loopptr(MPI_Datatype type, MPIO_Dataloop *ptr, int flag)
00328 {
00329     int mpi_errno, attrflag;
00330     MPIO_Datatype *dtp;
00331 
00332     if (MPIO_Datatype_keyval != MPI_KEYVAL_INVALID) {
00333     MPIO_Datatype_initialize();
00334     }
00335 
00336     mpi_errno = MPI_Type_get_attr(type, MPIO_Datatype_keyval, &dtp, &attrflag);
00337     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00338     if (!attrflag) {
00339     dtp = MPIO_Datatype_allocate(type);
00340     }
00341 
00342     printf("set loopptr = %x\n", (int) ptr);
00343 
00344     dtp->dloop  = ptr;
00345     dtp->valid |= MPIO_DATATYPE_VALID_DLOOP_PTR;
00346     return;
00347 }
00348 
00349 void MPIO_Datatype_set_loopsize(MPI_Datatype type, int size, int flag)
00350 {
00351     int mpi_errno, attrflag;
00352     MPIO_Datatype *dtp;
00353 
00354     if (MPIO_Datatype_keyval != MPI_KEYVAL_INVALID) {
00355     MPIO_Datatype_initialize();
00356     }
00357 
00358     mpi_errno = MPI_Type_get_attr(type, MPIO_Datatype_keyval, &dtp, &attrflag);
00359     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00360     if (!attrflag) {
00361     dtp = MPIO_Datatype_allocate(type);
00362     }
00363 
00364     dtp->dloop_size  = size;
00365     dtp->valid      |= MPIO_DATATYPE_VALID_DLOOP_SIZE;
00366     return;
00367 }
00368 
00369 void MPIO_Datatype_set_loopdepth(MPI_Datatype type, int depth, int flag)
00370 {
00371     int mpi_errno, attrflag;
00372     MPIO_Datatype *dtp;
00373 
00374     if (MPIO_Datatype_keyval != MPI_KEYVAL_INVALID) {
00375     MPIO_Datatype_initialize();
00376     }
00377 
00378     mpi_errno = MPI_Type_get_attr(type, MPIO_Datatype_keyval, &dtp, &attrflag);
00379     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00380     if (!attrflag) {
00381     dtp = MPIO_Datatype_allocate(type);
00382     }
00383 
00384     dtp->dloop_depth  = depth;
00385     dtp->valid       |= MPIO_DATATYPE_VALID_DLOOP_DEPTH;
00386     return;
00387 }
00388 
00389 int MPIO_Datatype_is_nontrivial(MPI_Datatype type)
00390 {
00391     int nr_ints, nr_aints, nr_types, combiner;
00392 
00393     MPI_Type_get_envelope(type, &nr_ints, &nr_aints, &nr_types, &combiner);
00394     if (combiner != MPI_COMBINER_NAMED ||
00395     type == MPI_FLOAT_INT ||
00396     type == MPI_DOUBLE_INT ||
00397     type == MPI_LONG_INT ||
00398     type == MPI_SHORT_INT ||
00399     type == MPI_LONG_DOUBLE_INT) return 1;
00400     else return 0;
00401 }
00402 
00403 
00404 
00405 static int MPIO_Datatype_initialize(void)
00406 {
00407     int mpi_errno;
00408 
00409     DLOOP_Assert(MPIO_Datatype_keyval == MPI_KEYVAL_INVALID);
00410 
00411     
00412     mpi_errno = MPI_Type_create_keyval(MPIO_Datatype_copy_attr_function,
00413                        MPIO_Datatype_delete_attr_function,
00414                        &MPIO_Datatype_keyval,
00415                        NULL);
00416     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00417 
00418     
00419     mpi_errno = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,
00420                     MPIO_Datatype_finalize,
00421                     &MPIO_Datatype_finalize_keyval,
00422                     NULL);
00423     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00424 
00425     mpi_errno = MPI_Comm_set_attr(MPI_COMM_WORLD,
00426                    MPIO_Datatype_finalize_keyval,
00427                    NULL);
00428     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00429 
00430     printf("created keyval\n");
00431 
00432     return 0;
00433 }
00434 
00435 
00436 
00437 static int MPIO_Datatype_finalize(MPI_Comm comm,
00438                   int comm_keyval,
00439                   void *attrval,
00440                   void *extrastate)
00441 {
00442     int mpi_errno;
00443 
00444     DLOOP_Assert(MPIO_Datatype_keyval != MPI_KEYVAL_INVALID);
00445 
00446     
00447     mpi_errno = MPI_Type_free_keyval(&MPIO_Datatype_keyval);
00448     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00449 
00450     mpi_errno = MPI_Type_free_keyval(&MPIO_Datatype_finalize_keyval);
00451     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00452 
00453     printf("freed keyvals\n");
00454     
00455     return MPI_SUCCESS;
00456 }
00457 
00458 static MPIO_Datatype *MPIO_Datatype_allocate(MPI_Datatype type)
00459 {
00460     int mpi_errno;
00461     MPIO_Datatype *dtp;
00462 
00463     dtp = (MPIO_Datatype *) malloc(sizeof(MPIO_Datatype));
00464     DLOOP_Assert(dtp != NULL);
00465     dtp->valid       = 0;
00466     dtp->refct       = 1;
00467     dtp->dloop       = NULL;
00468     dtp->dloop_size  = -1;
00469     dtp->dloop_depth = -1;
00470     
00471     mpi_errno = MPI_Type_set_attr(type, MPIO_Datatype_keyval, dtp);
00472     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00473 
00474     printf("allocated attr struct\n");
00475 
00476     return dtp;
00477 }
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 static void MPIO_Datatype_set_szext(MPI_Datatype type, MPIO_Datatype *dtp)
00490 {
00491     int mpi_errno;
00492 
00493     if (sizeof(int) >= sizeof(MPI_Offset) &&
00494     sizeof(MPI_Aint) >= sizeof(MPI_Offset))
00495     {
00496     int size;
00497     MPI_Aint lb, extent, true_lb, true_extent;
00498     
00499     mpi_errno = MPI_Type_size(type, &size);
00500     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00501     
00502     mpi_errno = MPI_Type_get_extent(type, &lb, &extent);
00503     DLOOP_Assert(mpi_errno == MPI_SUCCESS);
00504     
00505     mpi_errno = MPI_Type_get_true_extent(type, &true_lb, &true_extent); 
00506 
00507     dtp->size        = (MPI_Offset) size;
00508     dtp->extent      = (MPI_Offset) extent;
00509     dtp->true_lb     = (MPI_Offset) true_lb;
00510     dtp->true_extent = (MPI_Offset) true_extent;
00511     }
00512     else {
00513     MPIO_Type_footprint tfp;
00514     
00515     MPIO_Type_calc_footprint(type, &tfp);
00516     dtp->size        = tfp.size;
00517     dtp->extent      = tfp.extent;
00518     dtp->true_lb     = tfp.true_lb;
00519     dtp->true_extent = tfp.true_ub - tfp.true_lb;
00520     }
00521 
00522     dtp->valid |= MPIO_DATATYPE_VALID_TYPESZEXT;
00523     return;
00524 }
00525 
00526 static int MPIO_Datatype_copy_attr_function(MPI_Datatype type,
00527                         int type_keyval,
00528                         void *extra_state,
00529                         void *attribute_val_in,
00530                         void *attribute_val_out,
00531                         int *flag)
00532 {
00533     MPIO_Datatype *dtp = (MPIO_Datatype *) attribute_val_in;
00534 
00535     printf("copy fn. called\n");
00536 
00537     DLOOP_Assert(dtp->refct);
00538 
00539     dtp->refct++;
00540 
00541     * (MPIO_Datatype **) attribute_val_out = dtp;
00542     *flag = 1;
00543 
00544     printf("inc'd refct.\n");
00545 
00546     return MPI_SUCCESS;
00547 }
00548 
00549 static int MPIO_Datatype_delete_attr_function(MPI_Datatype type,
00550                           int type_keyval,
00551                           void *attribute_val,
00552                           void *extra_state)
00553 {
00554     MPIO_Datatype *dtp = (MPIO_Datatype *) attribute_val;
00555 
00556     printf("delete fn. called\n");
00557 
00558     DLOOP_Assert(dtp->refct);
00559 
00560     printf("dec'd refct\n");
00561     
00562     dtp->refct--;
00563     if (dtp->refct == 0) {
00564     free(dtp);
00565     printf("freed attr structure\n");
00566     }
00567 
00568     return MPI_SUCCESS;
00569 }
00570 
00571 
00572 
00573 
00574 
00575