00001
00002
00003
00009
00010
00011
00012
00013
00014
00015 #include "ad_bgl.h"
00016 #include "adio_extern.h"
00017
00018 #include "ad_bgl_tuning.h"
00019
00020 void ADIOI_BGL_ReadContig(ADIO_File fd, void *buf, int count,
00021 MPI_Datatype datatype, int file_ptr_type,
00022 ADIO_Offset offset, ADIO_Status *status, int *error_code)
00023 {
00024 int err=-1, datatype_size;
00025 ADIO_Offset len;
00026 static char myname[] = "ADIOI_BGL_READCONTIG";
00027 #if BGL_PROFILE
00028
00029 double io_time, io_time2;
00030
00031 if (bglmpio_timing) {
00032 io_time = MPI_Wtime();
00033 bglmpio_prof_cr[ BGLMPIO_CIO_DATA_SIZE ] += len;
00034 }
00035 #endif
00036
00037 MPI_Type_size(datatype, &datatype_size);
00038 len = (ADIO_Offset)datatype_size * (ADIO_Offset)count;
00039 ADIOI_Assert(len == (unsigned int) len);
00040
00041 #if BGL_PROFILE
00042
00043 if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00044 if (bglmpio_timing2) io_time2 = MPI_Wtime();
00045 if (fd->fp_sys_posn != offset)
00046 lseek(fd->fd_sys, offset, SEEK_SET);
00047 if (bglmpio_timing2) bglmpio_prof_cr[ BGLMPIO_CIO_T_SEEK ] += (MPI_Wtime() - io_time2);
00048 if (fd->atomicity)
00049 ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00050 else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
00051 if (bglmpio_timing2) io_time2 = MPI_Wtime();
00052 err = read(fd->fd_sys, buf, (unsigned int)len);
00053 if (bglmpio_timing2) bglmpio_prof_cr[ BGLMPIO_CIO_T_POSI_RW ] += (MPI_Wtime() - io_time2);
00054 ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00055 fd->fp_sys_posn = offset + err;
00056
00057 }
00058 else {
00059 offset = fd->fp_ind;
00060 if (bglmpio_timing2) io_time2 = MPI_Wtime();
00061 if (fd->fp_sys_posn != fd->fp_ind)
00062 lseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
00063 if (bglmpio_timing2) bglmpio_prof_cr[ BGLMPIO_CIO_T_SEEK ] += (MPI_Wtime() - io_time2);
00064 if (fd->atomicity)
00065 ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00066 else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
00067 if (bglmpio_timing2) io_time2 = MPI_Wtime();
00068 err = read(fd->fd_sys, buf, (unsigned int)len);
00069 if (bglmpio_timing2) bglmpio_prof_cr[ BGLMPIO_CIO_T_POSI_RW ] += (MPI_Wtime() - io_time2);
00070 ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00071 fd->fp_ind += err;
00072 fd->fp_sys_posn = fd->fp_ind;
00073 }
00074
00075 #else
00076
00077 if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00078 if (fd->fp_sys_posn != offset)
00079 lseek(fd->fd_sys, offset, SEEK_SET);
00080 if (fd->atomicity)
00081 ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00082 else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
00083 err = read(fd->fd_sys, buf, (unsigned int)len);
00084 ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00085 fd->fp_sys_posn = offset + err;
00086
00087 }
00088 else {
00089 offset = fd->fp_ind;
00090 if (fd->fp_sys_posn != fd->fp_ind)
00091 lseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
00092 if (fd->atomicity)
00093 ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00094 else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
00095 err = read(fd->fd_sys, buf, (unsigned int)len);
00096 ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00097 fd->fp_ind += err;
00098 fd->fp_sys_posn = fd->fp_ind;
00099 }
00100
00101 #endif
00102
00103 #if BGL_PROFILE
00104 if (bglmpio_timing) bglmpio_prof_cr[ BGLMPIO_CIO_T_MPIO_RW ] += (MPI_Wtime() - io_time);
00105 #endif
00106
00107
00108 if (err == -1) {
00109 *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
00110 myname, __LINE__, MPI_ERR_IO,
00111 "**io", "**io %s", strerror(errno));
00112 return;
00113 }
00114
00115
00116 #ifdef HAVE_STATUS_SET_BYTES
00117 MPIR_Status_set_bytes(status, datatype, err);
00118 #endif
00119
00120 *error_code = MPI_SUCCESS;
00121 }
00122
00123
00124 #define ADIOI_BUFFERED_READ \
00125 { \
00126 if (req_off >= readbuf_off + readbuf_len) { \
00127 readbuf_off = req_off; \
00128 readbuf_len = (unsigned) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));\
00129 lseek(fd->fd_sys, readbuf_off, SEEK_SET);\
00130 if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off, SEEK_SET, readbuf_len);\
00131 err = read(fd->fd_sys, readbuf, readbuf_len);\
00132 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off, SEEK_SET, readbuf_len);\
00133 if (err == -1) err_flag = 1; \
00134 } \
00135 while (req_len > readbuf_off + readbuf_len - req_off) { \
00136 ADIOI_Assert((readbuf_off + readbuf_len - req_off) == (int) (readbuf_off + readbuf_len - req_off));\
00137 partial_read = (int) (readbuf_off + readbuf_len - req_off); \
00138 tmp_buf = (char *) ADIOI_Malloc(partial_read); \
00139 memcpy(tmp_buf, readbuf+readbuf_len-partial_read, partial_read); \
00140 ADIOI_Free(readbuf); \
00141 readbuf = (char *) ADIOI_Malloc(partial_read + max_bufsize); \
00142 memcpy(readbuf, tmp_buf, partial_read); \
00143 ADIOI_Free(tmp_buf); \
00144 readbuf_off += readbuf_len-partial_read; \
00145 readbuf_len = (unsigned) (partial_read + ADIOI_MIN(max_bufsize, \
00146 end_offset-readbuf_off+1)); \
00147 lseek(fd->fd_sys, readbuf_off+partial_read, SEEK_SET);\
00148 if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off+partial_read, SEEK_SET, readbuf_len-partial_read);\
00149 err = read(fd->fd_sys, readbuf+partial_read, readbuf_len-partial_read);\
00150 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off+partial_read, SEEK_SET, readbuf_len-partial_read);\
00151 if (err == -1) err_flag = 1; \
00152 } \
00153 ADIOI_Assert(req_len == (size_t)req_len); \
00154 memcpy((char *)buf + userbuf_off, readbuf+req_off-readbuf_off, req_len); \
00155 }
00156
00157
00158 void ADIOI_BGL_ReadStrided(ADIO_File fd, void *buf, int count,
00159 MPI_Datatype datatype, int file_ptr_type,
00160 ADIO_Offset offset, ADIO_Status *status, int
00161 *error_code)
00162 {
00163
00164
00165
00166 ADIOI_Flatlist_node *flat_buf, *flat_file;
00167 ADIO_Offset i_offset, new_brd_size, brd_size, size;
00168 int i, j, k, err=-1, st_index=0;
00169 ADIO_Offset frd_size=0, new_frd_size, st_frd_size;
00170 unsigned num, bufsize;
00171 int n_etypes_in_filetype;
00172 ADIO_Offset n_filetypes, etype_in_filetype, st_n_filetypes, size_in_filetype;
00173 ADIO_Offset abs_off_in_filetype=0;
00174 int filetype_size, etype_size, buftype_size, partial_read;
00175 MPI_Aint filetype_extent, buftype_extent;
00176 int buf_count, buftype_is_contig, filetype_is_contig;
00177 ADIO_Offset userbuf_off, req_len, sum;
00178 ADIO_Offset off, req_off, disp, end_offset=0, readbuf_off, start_off;
00179 char *readbuf, *tmp_buf, *value;
00180 int err_flag=0, info_flag;
00181 unsigned max_bufsize, readbuf_len;
00182 static char myname[] = "ADIOI_BGL_READSTRIDED";
00183
00184 if (fd->hints->ds_read == ADIOI_HINT_DISABLE) {
00185
00186
00187
00188
00189 ADIOI_GEN_ReadStrided_naive(fd,
00190 buf,
00191 count,
00192 datatype,
00193 file_ptr_type,
00194 offset,
00195 status,
00196 error_code);
00197 return;
00198 }
00199
00200
00201 ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
00202 ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00203
00204 MPI_Type_size(fd->filetype, &filetype_size);
00205 if ( ! filetype_size ) {
00206 *error_code = MPI_SUCCESS;
00207 return;
00208 }
00209
00210 MPI_Type_extent(fd->filetype, &filetype_extent);
00211 MPI_Type_size(datatype, &buftype_size);
00212 MPI_Type_extent(datatype, &buftype_extent);
00213 etype_size = fd->etype_size;
00214
00215 ADIOI_Assert((buftype_size * count) == ((ADIO_Offset)(unsigned)buftype_size * (ADIO_Offset)count));
00216 bufsize = buftype_size * count;
00217
00218
00219
00220 value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
00221 ADIOI_Info_get(fd->info, "ind_rd_buffer_size", MPI_MAX_INFO_VAL, value,
00222 &info_flag);
00223 max_bufsize = atoi(value);
00224 ADIOI_Free(value);
00225
00226 if (!buftype_is_contig && filetype_is_contig) {
00227
00228
00229
00230 ADIOI_Flatten_datatype(datatype);
00231 flat_buf = ADIOI_Flatlist;
00232 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00233
00234 off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind :
00235 fd->disp + (ADIO_Offset)etype_size * offset;
00236
00237 start_off = off;
00238 end_offset = off + bufsize - 1;
00239 readbuf_off = off;
00240 readbuf = (char *) ADIOI_Malloc(max_bufsize);
00241 readbuf_len = (unsigned) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));
00242
00243
00244 if (fd->atomicity)
00245 ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00246
00247 lseek(fd->fd_sys, readbuf_off, SEEK_SET);
00248 if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off, SEEK_SET, readbuf_len);
00249 err = read(fd->fd_sys, readbuf, readbuf_len);
00250 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off, SEEK_SET, readbuf_len);
00251 if (err == -1) err_flag = 1;
00252
00253 for (j=0; j<count; j++)
00254 {
00255 int i;
00256 for (i=0; i<flat_buf->count; i++) {
00257 userbuf_off = (ADIO_Offset)j*(ADIO_Offset)buftype_extent + flat_buf->indices[i];
00258 req_off = off;
00259 req_len = flat_buf->blocklens[i];
00260 ADIOI_BUFFERED_READ
00261 off += flat_buf->blocklens[i];
00262 }
00263 }
00264
00265 if (fd->atomicity)
00266 ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00267
00268 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00269
00270 ADIOI_Free(readbuf);
00271
00272 if (err_flag) {
00273 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00274 MPIR_ERR_RECOVERABLE, myname,
00275 __LINE__, MPI_ERR_IO, "**io",
00276 "**io %s", strerror(errno));
00277 }
00278 else *error_code = MPI_SUCCESS;
00279 }
00280
00281 else {
00282
00283
00284 flat_file = ADIOI_Flatlist;
00285 while (flat_file->type != fd->filetype) flat_file = flat_file->next;
00286 disp = fd->disp;
00287
00288 if (file_ptr_type == ADIO_INDIVIDUAL) {
00289
00290 offset = fd->fp_ind - disp;
00291 n_filetypes = (offset - flat_file->indices[0]) / filetype_extent;
00292 offset -= (ADIO_Offset)n_filetypes * filetype_extent;
00293
00294
00295
00296 for (i=0; i<flat_file->count; i++) {
00297 ADIO_Offset dist;
00298 if (flat_file->blocklens[i] == 0) continue;
00299 dist = flat_file->indices[i] + flat_file->blocklens[i] - offset;
00300
00301 if (dist == 0) {
00302 i++;
00303 offset = flat_file->indices[i];
00304 frd_size = flat_file->blocklens[i];
00305 break;
00306 }
00307 if (dist > 0) {
00308 frd_size = dist;
00309 break;
00310 }
00311 }
00312 st_index = i;
00313 offset += disp + (ADIO_Offset)n_filetypes*filetype_extent;
00314 }
00315 else {
00316 n_etypes_in_filetype = filetype_size/etype_size;
00317 n_filetypes = offset / n_etypes_in_filetype;
00318 etype_in_filetype = offset % n_etypes_in_filetype;
00319 size_in_filetype = etype_in_filetype * etype_size;
00320
00321 sum = 0;
00322 for (i=0; i<flat_file->count; i++) {
00323 sum += flat_file->blocklens[i];
00324 if (sum > size_in_filetype) {
00325 st_index = i;
00326 frd_size = sum - size_in_filetype;
00327 abs_off_in_filetype = flat_file->indices[i] +
00328 size_in_filetype - (sum - flat_file->blocklens[i]);
00329 break;
00330 }
00331 }
00332
00333
00334 offset = disp + (ADIO_Offset) n_filetypes*filetype_extent +
00335 abs_off_in_filetype;
00336 }
00337
00338 start_off = offset;
00339
00340
00341
00342
00343 if (buftype_is_contig && bufsize <= frd_size) {
00344 ADIO_ReadContig(fd, buf, bufsize, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
00345 offset, status, error_code);
00346
00347 if (file_ptr_type == ADIO_INDIVIDUAL) {
00348
00349
00350 fd->fp_ind = offset + bufsize;
00351 if (bufsize == frd_size) {
00352 do {
00353 st_index++;
00354 if (st_index == flat_file->count) {
00355 st_index = 0;
00356 n_filetypes++;
00357 }
00358 } while (flat_file->blocklens[st_index] == 0);
00359 fd->fp_ind = disp + flat_file->indices[st_index]
00360 + n_filetypes*filetype_extent;
00361 }
00362 }
00363 fd->fp_sys_posn = -1;
00364 #ifdef HAVE_STATUS_SET_BYTES
00365 MPIR_Status_set_bytes(status, datatype, bufsize);
00366 #endif
00367 return;
00368 }
00369
00370
00371
00372
00373 st_frd_size = frd_size;
00374 st_n_filetypes = n_filetypes;
00375 i_offset = 0;
00376 j = st_index;
00377 off = offset;
00378 frd_size = ADIOI_MIN(st_frd_size, bufsize);
00379 while (i_offset < bufsize) {
00380 i_offset += frd_size;
00381 end_offset = off + frd_size - 1;
00382
00383 j = (j+1) % flat_file->count;
00384 n_filetypes += (j == 0) ? 1 : 0;
00385 while (flat_file->blocklens[j]==0) {
00386 j = (j+1) % flat_file->count;
00387 n_filetypes += (j == 0) ? 1 : 0;
00388 }
00389 off = disp + flat_file->indices[j] + n_filetypes*(ADIO_Offset)filetype_extent;
00390 frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i_offset);
00391 }
00392
00393
00394 if (fd->atomicity)
00395 ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00396
00397
00398 readbuf_off = offset;
00399 readbuf = (char *) ADIOI_Malloc(max_bufsize);
00400 readbuf_len = (unsigned) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));
00401
00402 lseek(fd->fd_sys, offset, SEEK_SET);
00403 if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, offset, SEEK_SET, readbuf_len);
00404 err = read(fd->fd_sys, readbuf, readbuf_len);
00405 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, offset, SEEK_SET, readbuf_len);
00406
00407 if (err == -1) err_flag = 1;
00408
00409 if (buftype_is_contig && !filetype_is_contig) {
00410
00411
00412
00413
00414 i_offset = 0;
00415 j = st_index;
00416 off = offset;
00417 n_filetypes = st_n_filetypes;
00418 frd_size = ADIOI_MIN(st_frd_size, bufsize);
00419 while (i_offset < bufsize) {
00420 if (frd_size) {
00421
00422
00423
00424
00425
00426 req_off = off;
00427 req_len = frd_size;
00428 userbuf_off = i_offset;
00429 ADIOI_BUFFERED_READ
00430 }
00431 i_offset += frd_size;
00432
00433 if (off + frd_size < disp + flat_file->indices[j] +
00434 flat_file->blocklens[j] + n_filetypes*(ADIO_Offset)filetype_extent)
00435 off += frd_size;
00436
00437
00438 else {
00439 j = (j+1) % flat_file->count;
00440 n_filetypes += (j == 0) ? 1 : 0;
00441 while (flat_file->blocklens[j]==0) {
00442 j = (j+1) % flat_file->count;
00443 n_filetypes += (j == 0) ? 1 : 0;
00444 }
00445 off = disp + flat_file->indices[j] +
00446 n_filetypes*(ADIO_Offset)filetype_extent;
00447 frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i_offset);
00448 }
00449 }
00450 }
00451 else {
00452
00453
00454 ADIOI_Flatten_datatype(datatype);
00455 flat_buf = ADIOI_Flatlist;
00456 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00457
00458 k = num = buf_count = 0;
00459 i_offset = flat_buf->indices[0];
00460 j = st_index;
00461 off = offset;
00462 n_filetypes = st_n_filetypes;
00463 frd_size = st_frd_size;
00464 brd_size = flat_buf->blocklens[0];
00465
00466 while (num < bufsize) {
00467 size = ADIOI_MIN(frd_size, brd_size);
00468 if (size) {
00469
00470
00471
00472 req_off = off;
00473 req_len = size;
00474 userbuf_off = i_offset;
00475 ADIOI_BUFFERED_READ
00476 }
00477
00478 new_frd_size = frd_size;
00479 new_brd_size = brd_size;
00480
00481 if (size == frd_size) {
00482
00483 j = (j+1) % flat_file->count;
00484 n_filetypes += (j == 0) ? 1 : 0;
00485 while (flat_file->blocklens[j]==0) {
00486 j = (j+1) % flat_file->count;
00487 n_filetypes += (j == 0) ? 1 : 0;
00488 }
00489
00490 off = disp + flat_file->indices[j] +
00491 n_filetypes*(ADIO_Offset)filetype_extent;
00492
00493 new_frd_size = flat_file->blocklens[j];
00494 if (size != brd_size) {
00495 i_offset += size;
00496 new_brd_size -= size;
00497 }
00498 }
00499
00500 if (size == brd_size) {
00501
00502
00503 k = (k + 1)%flat_buf->count;
00504 buf_count++;
00505 i_offset = ((ADIO_Offset)buftype_extent*(ADIO_Offset)(buf_count/flat_buf->count) +
00506 flat_buf->indices[k]);
00507 new_brd_size = flat_buf->blocklens[k];
00508 if (size != frd_size) {
00509 off += size;
00510 new_frd_size -= size;
00511 }
00512 }
00513 ADIOI_Assert(((ADIO_Offset)num + size) == (unsigned)(num + size));
00514 num += size;
00515 frd_size = new_frd_size;
00516 brd_size = new_brd_size;
00517 }
00518 }
00519
00520 if (fd->atomicity)
00521 ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00522
00523 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00524
00525 ADIOI_Free(readbuf);
00526
00527 if (err_flag) {
00528 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00529 MPIR_ERR_RECOVERABLE, myname,
00530 __LINE__, MPI_ERR_IO, "**io",
00531 "**io %s", strerror(errno));
00532 }
00533 else *error_code = MPI_SUCCESS;
00534 }
00535
00536 fd->fp_sys_posn = -1;
00537
00538 #ifdef HAVE_STATUS_SET_BYTES
00539 MPIR_Status_set_bytes(status, datatype, bufsize);
00540
00541
00542
00543 #endif
00544
00545 if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
00546 }