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