00001
00002
00003
00004
00005
00006
00007
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010
00011 #include "romio_dataloop.h"
00012 #include "typesize_support.h"
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 struct MPIO_File_ib_params {
00035 int direction;
00036 char *ib_ptr;
00037 MPI_Offset ib_file_off, ib_file_size;
00038 MPI_Offset fv_disp;
00039
00040 DLOOP_Segment *ub_segp;
00041 };
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 struct MPIO_File_ds_params {
00058 int direction;
00059 MPI_Offset fv_disp;
00060 MPI_Offset ib_size;
00061
00062
00063
00064
00065 MPI_Offset ib_file_off, ib_file_size;
00066 MPI_Offset ib_fv_off, ib_fv_last;
00067
00068 struct MPIO_File_ib_params ib;
00069 DLOOP_Segment *ib_segp;
00070 };
00071
00072 static int MPIO_Segment_contig_file_ds(MPI_Offset *blocks_p,
00073 MPI_Datatype el_type,
00074 MPI_Offset rel_off,
00075 void *unused,
00076 void *v_paramp);
00077
00078 static int MPIO_Segment_contig_fv2ib(DLOOP_Offset *blocks_p,
00079 DLOOP_Type el_type,
00080 DLOOP_Offset rel_off,
00081 void *unused,
00082 void *v_paramp);
00083 static int MPIO_File_datasieve(struct MPIO_File_ds_params *dsp,
00084 MPI_Offset *fv_lastp);
00085
00086
00087 static int MPIO_Segment_contig_m2m_fake(DLOOP_Offset *blocks_p,
00088 DLOOP_Type el_type,
00089 DLOOP_Offset rel_off,
00090 void *unused,
00091 void *v_paramp);
00092
00093 int MPIO_File_ds_io(MPI_Aint *ub_ptr,
00094 int ub_count,
00095 MPI_Datatype ub_type,
00096 MPI_Offset fv_off,
00097 MPI_Offset fv_disp,
00098 MPI_Datatype fv_type,
00099 int direction,
00100 MPI_Offset ib_size)
00101 {
00102
00103 int ub_ncontig, fv_ncontig;
00104 MPI_Offset ub_blkoff, ub_blkct, ub_typesize;
00105 MPI_Offset fv_blkoff, fv_blkct, fv_size, fv_count, fv_counttouch;
00106
00107 MPI_Offset size;
00108 char *ib_ptr;
00109 struct MPIO_File_ds_params *dsp;
00110 struct MPIO_File_ib_params *ibp;
00111 DLOOP_Segment *ds_segp;
00112
00113 MPIO_Datatype_get_size(fv_type, &fv_size);
00114
00115
00116 MPIO_Datatype_get_size(ub_type, &ub_typesize);
00117 size = ub_typesize * ub_count;
00118
00119
00120
00121
00122 fv_counttouch = (((fv_off % fv_size) ? 1 : 0) +
00123 (size - fv_size + (fv_off % fv_size)) / fv_size +
00124 (((size - fv_size + (fv_off % fv_size)) % fv_size) ? 1:0));
00125
00126 MPIO_Datatype_get_block_info(ub_type, &ub_blkoff, &ub_blkct, &ub_ncontig);
00127 MPIO_Datatype_get_block_info(fv_type, &fv_blkoff, &fv_blkct, &fv_ncontig);
00128
00129
00130 DLOOP_Assert(ib_size > 0);
00131 if (size < ib_size) ib_size = size;
00132 ib_ptr = (char *) DLOOP_Malloc(ib_size);
00133
00134
00135 if (ub_ncontig || (ub_count == 1 && ub_blkct == 1)) {
00136
00137 MPI_Datatype eltype;
00138 MPI_Offset eltypesz;
00139
00140 MPIO_Datatype_get_el_type(ub_type, &eltype, 0);
00141 if (eltype == MPI_DATATYPE_NULL) eltype = MPI_BYTE;
00142
00143 MPIO_Datatype_get_size(eltype, &eltypesz);
00144 DLOOP_Assert((size / eltypesz) * eltypesz == size);
00145
00146
00147
00148
00149
00150
00151
00152 ub_ptr += ub_blkoff;
00153 ub_type = eltype;
00154 ub_count = size / eltypesz;
00155 }
00156
00157 if (fv_ncontig || (fv_counttouch == 1 && fv_blkct == 1)) {
00158
00159 MPI_Datatype eltype;
00160
00161 MPIO_Datatype_get_el_type(fv_type, &eltype, 0);
00162 if (eltype == MPI_DATATYPE_NULL) eltype = MPI_BYTE;
00163
00164 MPIO_Datatype_get_size(eltype, &fv_size);
00165
00166 fv_off += fv_blkoff;
00167 fv_type = eltype;
00168
00169 }
00170
00171
00172
00173
00174 fv_count = ((fv_off + size) / fv_size) +
00175 (((fv_off + size) % fv_size) ? 1 : 0);
00176
00177
00178 dsp = (struct MPIO_File_ds_params *)
00179 DLOOP_Malloc(sizeof(struct MPIO_File_ds_params));
00180 DLOOP_Assert(dsp != NULL);
00181
00182 dsp->direction = direction;
00183 dsp->fv_disp = fv_disp;
00184 dsp->ib_size = ib_size;
00185 dsp->ib_file_off = (MPI_Offset) -1;
00186 dsp->ib_file_size = 0;
00187 dsp->ib_fv_off = (MPI_Offset) -1;
00188 dsp->ib_fv_last = fv_off;
00189
00190 dsp->ib_segp = MPIO_Segment_alloc();
00191 MPIO_Segment_init(NULL,
00192 fv_count,
00193 fv_type,
00194 dsp->ib_segp,
00195 0);
00196
00197
00198 ibp = (struct MPIO_File_ib_params *)
00199 DLOOP_Malloc(sizeof(struct MPIO_File_ib_params));
00200 DLOOP_Assert(ibp != NULL);
00201
00202 ibp->ib_ptr = ib_ptr;
00203 ibp->direction = direction;
00204 ibp->ib_file_off = (MPI_Offset) -1;
00205 ibp->ib_file_size = (MPI_Offset) -1;
00206
00207 ibp->ub_segp = MPIO_Segment_alloc();
00208 MPIO_Segment_init(ub_ptr,
00209 ub_count,
00210 ub_type,
00211 ibp->ub_segp,
00212 0);
00213
00214
00215 ds_segp = MPIO_Segment_alloc();
00216 MPIO_Segment_init(NULL,
00217 fv_count,
00218 fv_type,
00219 ds_segp,
00220 0);
00221
00222 MPIO_Segment_manipulate(ds_segp,
00223 fv_off,
00224 &size,
00225 MPIO_Segment_contig_file_ds,
00226 NULL, NULL, NULL, NULL, 0);
00227
00228
00229 if (dsp->ib_file_off != 0) {
00230 MPIO_File_datasieve(dsp, &size);
00231 }
00232
00233
00234 DLOOP_Free(ib_ptr);
00235 MPIO_Segment_free(dsp->ib_segp);
00236 DLOOP_Free(dsp);
00237 MPIO_Segment_free(ibp->ub_segp);
00238 DLOOP_Free(ibp);
00239 MPIO_Segment_free(ds_segp);
00240
00241 return 0;
00242 }
00243
00244
00245
00246
00247
00248
00249 static int MPIO_Segment_contig_file_ds(MPI_Offset *fv_blocks_p,
00250 MPI_Datatype fv_eltype,
00251 MPI_Offset rel_file_off,
00252 void *unused,
00253 void *v_paramp)
00254 {
00255 MPI_Offset fv_blocks = *fv_blocks_p, fv_elsize;
00256 struct MPIO_File_ds_params *dsp = v_paramp;
00257
00258 MPIO_Datatype_get_size(fv_eltype, &fv_elsize);
00259
00260 while (fv_blocks > 0) {
00261
00262 MPI_Offset thisfirstbyte, blocksizebytes, pastlastbyte;
00263 MPI_Offset min_access_size, full_access_size;
00264 MPI_Offset fv_last;
00265
00266 blocksizebytes = fv_blocks * fv_elsize;
00267 thisfirstbyte = dsp->fv_disp + rel_file_off;
00268 pastlastbyte = dsp->fv_disp + rel_file_off + blocksizebytes;
00269
00270
00271 if (dsp->ib_file_off == (MPI_Offset) -1) {
00272 dsp->ib_file_off = thisfirstbyte;
00273 dsp->ib_file_size = 0;
00274 dsp->ib_fv_off = dsp->ib_fv_last;
00275 }
00276
00277
00278
00279
00280 DLOOP_Assert(thisfirstbyte >= dsp->ib_file_off);
00281
00282
00283
00284
00285 min_access_size = (thisfirstbyte - dsp->ib_file_off) + fv_elsize;
00286 full_access_size = pastlastbyte - dsp->ib_file_off;
00287
00288 if (dsp->ib_size > full_access_size) {
00289
00290
00291
00292
00293 dsp->ib_file_size = pastlastbyte - dsp->ib_file_off;
00294 dsp->ib_fv_last = dsp->ib_fv_last + blocksizebytes;
00295
00296
00297
00298
00299
00300
00301
00302 fv_blocks = 0;
00303
00304 continue;
00305 }
00306
00307 if (dsp->ib_size < min_access_size) {
00308
00309
00310
00311 }
00312 else if (dsp->ib_size <= full_access_size) {
00313
00314 MPI_Offset remaining_iobuf, partial_elements;
00315
00316 remaining_iobuf = dsp->ib_size - (thisfirstbyte - dsp->ib_file_off);
00317 partial_elements = (remaining_iobuf / fv_elsize);
00318
00319
00320 dsp->ib_fv_last += partial_elements * fv_elsize;
00321
00322
00323 fv_blocks -= partial_elements;
00324 rel_file_off += partial_elements * fv_elsize;
00325 }
00326
00327 fv_last = dsp->ib_fv_last;
00328
00329
00330 MPIO_File_datasieve(dsp, &fv_last);
00331 }
00332
00333 return 0;
00334 }
00335
00336
00337
00338
00339 static int MPIO_File_datasieve(struct MPIO_File_ds_params *dsp,
00340 MPI_Offset *fv_lastp)
00341 {
00342 DLOOP_Assert(*fv_lastp == dsp->ib_fv_last);
00343
00344
00345 printf("READ: buf = %x, off = %d, size = %d\n",
00346 (unsigned int) dsp->ib.ib_ptr,
00347 (int) dsp->ib_file_off,
00348 (int) dsp->ib_file_size);
00349
00350
00351 MPIO_Segment_manipulate(dsp->ib_segp,
00352 dsp->ib_fv_off,
00353 fv_lastp,
00354 MPIO_Segment_contig_fv2ib,
00355 NULL, NULL, NULL, NULL,
00356 &dsp->ib);
00357
00358 DLOOP_Assert(*fv_lastp == dsp->ib_fv_last);
00359
00360 if (dsp->direction == DLOOP_M2M_FROM_USERBUF) {
00361
00362 printf("WRITE: buf = %x, off = %d, size = %d\n",
00363 (unsigned int) dsp->ib.ib_ptr,
00364 (int) dsp->ib_file_off,
00365 (int) dsp->ib_file_size);
00366 }
00367
00368
00369 dsp->ib_file_off = (MPI_Offset) -1;
00370 dsp->ib_file_size = 0;
00371 dsp->ib_fv_off = (MPI_Offset) -1;
00372
00373
00374 return 0;
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 static int MPIO_Segment_contig_fv2ib(DLOOP_Offset *fv_blocks_p,
00393 DLOOP_Type fv_eltype,
00394 DLOOP_Offset rel_file_off,
00395 void *unused,
00396 void *v_paramp)
00397 {
00398 MPI_Offset fv_elsize, file_off, ub_first, ub_last;
00399 MPI_Aint ib_off;
00400 struct MPIO_File_ib_params *ibp = v_paramp;
00401 struct MPIO_m2m_params m2m_params;
00402
00403 MPIO_Datatype_get_size(fv_eltype, &fv_elsize);
00404
00405 file_off = ibp->fv_disp + rel_file_off;
00406 ib_off = (MPI_Aint) (file_off - ibp->ib_file_off);
00407
00408
00409
00410
00411 DLOOP_Assert(ib_off >= 0);
00412 DLOOP_Assert((ib_off + (*fv_blocks_p * fv_elsize)) <= ibp->ib_file_size);
00413
00414
00415 m2m_params.direction = ibp->direction;
00416 m2m_params.streambuf = ibp->ib_ptr + ib_off;
00417 m2m_params.userbuf = ibp->ub_segp->ptr;
00418
00419
00420
00421
00422 ub_first = ibp->ub_segp->stream_off;
00423 ub_last = *fv_blocks_p * fv_elsize;
00424
00425
00426 MPIO_Segment_manipulate(ibp->ub_segp, ub_first, &ub_last,
00427 #if 0
00428 MPIO_Segment_contig_m2m,
00429 MPIO_Segment_vector_m2m,
00430 MPIO_Segment_blkidx_m2m,
00431 MPIO_Segment_index_m2m,
00432 #else
00433 MPIO_Segment_contig_m2m_fake,
00434 NULL, NULL, NULL,
00435 #endif
00436 NULL,
00437 &m2m_params);
00438
00439
00440 DLOOP_Assert(ub_last == *fv_blocks_p * fv_elsize);
00441
00442 return 0;
00443 }
00444
00445 static int MPIO_Segment_contig_m2m_fake(DLOOP_Offset *blocks_p,
00446 DLOOP_Type el_type,
00447 DLOOP_Offset rel_off,
00448 void *unused,
00449 void *v_paramp)
00450 {
00451 DLOOP_Offset el_size;
00452 DLOOP_Offset size;
00453 struct PREPEND_PREFIX(m2m_params) *paramp = v_paramp;
00454
00455 DLOOP_Handle_get_size_macro(el_type, el_size);
00456 size = *blocks_p * el_size;
00457
00458 printf("\t[%s: ub_start=%x (%x+%x), ib_start=%x, sz=%d (%d*%d)]\n",
00459 (paramp->direction == DLOOP_M2M_TO_USERBUF) ? "unpack" : "pack",
00460 (unsigned int) (paramp->userbuf + rel_off),
00461 (unsigned) paramp->userbuf, (unsigned) rel_off,
00462 (unsigned) paramp->streambuf,
00463 (int) size,
00464 (int) *blocks_p, (int) el_size);
00465
00466 #if 0
00467 if (paramp->direction == DLOOP_M2M_TO_USERBUF) {
00468 memcpy((char *) (paramp->userbuf + rel_off), paramp->streambuf, size);
00469 }
00470 else {
00471 memcpy(paramp->streambuf, (char *) (paramp->userbuf + rel_off), size);
00472 }
00473 #endif
00474 paramp->streambuf += size;
00475 return 0;
00476 }
00477
00478
00479
00480
00481
00482