00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "ad_nfs.h"
00010 #include "adio_extern.h"
00011
00012 void ADIOI_NFS_ReadContig(ADIO_File fd, void *buf, int count,
00013 MPI_Datatype datatype, int file_ptr_type,
00014 ADIO_Offset offset, ADIO_Status *status, int *error_code)
00015 {
00016 int err=-1, datatype_size, len;
00017 #ifndef PRINT_ERR_MSG
00018 static char myname[] = "ADIOI_NFS_READCONTIG";
00019 #endif
00020
00021 MPI_Type_size(datatype, &datatype_size);
00022 len = datatype_size * count;
00023
00024 if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00025 if (fd->fp_sys_posn != offset)
00026 lseek(fd->fd_sys, offset, SEEK_SET);
00027 if (fd->atomicity)
00028 ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00029 else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
00030 err = read(fd->fd_sys, buf, len);
00031 ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00032 fd->fp_sys_posn = offset + err;
00033
00034 }
00035 else {
00036 offset = fd->fp_ind;
00037 if (fd->fp_sys_posn != fd->fp_ind)
00038 lseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
00039 if (fd->atomicity)
00040 ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00041 else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
00042 err = read(fd->fd_sys, buf, len);
00043 ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00044 fd->fp_ind += err;
00045 fd->fp_sys_posn = fd->fp_ind;
00046 }
00047
00048 #ifdef HAVE_STATUS_SET_BYTES
00049 if (err != -1) MPIR_Status_set_bytes(status, datatype, err);
00050 #endif
00051
00052 #ifdef PRINT_ERR_MSG
00053 *error_code = (err == -1) ? MPI_ERR_UNKNOWN : MPI_SUCCESS;
00054 #else
00055 if (err == -1) {
00056 *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
00057 myname, "I/O Error", "%s", strerror(errno));
00058 ADIOI_Error(fd, *error_code, myname);
00059 }
00060 else *error_code = MPI_SUCCESS;
00061 #endif
00062 }
00063
00064
00065
00066 #define ADIOI_BUFFERED_READ \
00067 { \
00068 if (req_off >= readbuf_off + readbuf_len) { \
00069 readbuf_off = req_off; \
00070 readbuf_len = (int) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));\
00071 lseek(fd->fd_sys, readbuf_off, SEEK_SET);\
00072 if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off, SEEK_SET, readbuf_len);\
00073 err = read(fd->fd_sys, readbuf, readbuf_len);\
00074 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off, SEEK_SET, readbuf_len);\
00075 if (err == -1) err_flag = 1; \
00076 } \
00077 while (req_len > readbuf_off + readbuf_len - req_off) { \
00078 partial_read = (int) (readbuf_off + readbuf_len - req_off); \
00079 tmp_buf = (char *) ADIOI_Malloc(partial_read); \
00080 memcpy(tmp_buf, readbuf+readbuf_len-partial_read, partial_read); \
00081 ADIOI_Free(readbuf); \
00082 readbuf = (char *) ADIOI_Malloc(partial_read + max_bufsize); \
00083 memcpy(readbuf, tmp_buf, partial_read); \
00084 ADIOI_Free(tmp_buf); \
00085 readbuf_off += readbuf_len-partial_read; \
00086 readbuf_len = (int) (partial_read + ADIOI_MIN(max_bufsize, \
00087 end_offset-readbuf_off+1)); \
00088 lseek(fd->fd_sys, readbuf_off+partial_read, SEEK_SET);\
00089 if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off+partial_read, SEEK_SET, readbuf_len-partial_read);\
00090 err = read(fd->fd_sys, readbuf+partial_read, readbuf_len-partial_read);\
00091 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off+partial_read, SEEK_SET, readbuf_len-partial_read);\
00092 if (err == -1) err_flag = 1; \
00093 } \
00094 memcpy((char *)buf + userbuf_off, readbuf+req_off-readbuf_off, req_len); \
00095 }
00096
00097
00098 void ADIOI_NFS_ReadStrided(ADIO_File fd, void *buf, int count,
00099 MPI_Datatype datatype, int file_ptr_type,
00100 ADIO_Offset offset, ADIO_Status *status, int
00101 *error_code)
00102 {
00103
00104
00105 ADIOI_Flatlist_node *flat_buf, *flat_file;
00106 int i, j, k, err=-1, brd_size, frd_size=0, st_index=0;
00107 int bufsize, num, size, sum, n_etypes_in_filetype, size_in_filetype;
00108 int n_filetypes, etype_in_filetype;
00109 ADIO_Offset abs_off_in_filetype=0;
00110 int filetype_size, etype_size, buftype_size, req_len, partial_read;
00111 MPI_Aint filetype_extent, buftype_extent;
00112 int buf_count, buftype_is_contig, filetype_is_contig;
00113 ADIO_Offset userbuf_off;
00114 ADIO_Offset off, req_off, disp, end_offset=0, readbuf_off, start_off;
00115 char *readbuf, *tmp_buf, *value;
00116 int flag, st_frd_size, st_n_filetypes, readbuf_len;
00117 int new_brd_size, new_frd_size, err_flag=0, info_flag, max_bufsize;
00118 #ifndef PRINT_ERR_MSG
00119 static char myname[] = "ADIOI_NFS_READSTRIDED";
00120 #endif
00121
00122 ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
00123 ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00124
00125 MPI_Type_size(fd->filetype, &filetype_size);
00126 if ( ! filetype_size ) {
00127 *error_code = MPI_SUCCESS;
00128 return;
00129 }
00130
00131 MPI_Type_extent(fd->filetype, &filetype_extent);
00132 MPI_Type_size(datatype, &buftype_size);
00133 MPI_Type_extent(datatype, &buftype_extent);
00134 etype_size = fd->etype_size;
00135
00136 bufsize = buftype_size * count;
00137
00138
00139
00140 value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
00141 MPI_Info_get(fd->info, "ind_rd_buffer_size", MPI_MAX_INFO_VAL, value,
00142 &info_flag);
00143 max_bufsize = atoi(value);
00144 ADIOI_Free(value);
00145
00146 if (!buftype_is_contig && filetype_is_contig) {
00147
00148
00149
00150 ADIOI_Flatten_datatype(datatype);
00151 flat_buf = ADIOI_Flatlist;
00152 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00153
00154 off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind :
00155 fd->disp + etype_size * offset;
00156
00157 start_off = off;
00158 end_offset = off + bufsize - 1;
00159 readbuf_off = off;
00160 readbuf = (char *) ADIOI_Malloc(max_bufsize);
00161 readbuf_len = (int) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));
00162
00163
00164 if (fd->atomicity)
00165 ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00166
00167 lseek(fd->fd_sys, readbuf_off, SEEK_SET);
00168 if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off, SEEK_SET, readbuf_len);
00169 err = read(fd->fd_sys, readbuf, readbuf_len);
00170 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off, SEEK_SET, readbuf_len);
00171 if (err == -1) err_flag = 1;
00172
00173 for (j=0; j<count; j++)
00174 for (i=0; i<flat_buf->count; i++) {
00175 userbuf_off = j*buftype_extent + flat_buf->indices[i];
00176 req_off = off;
00177 req_len = flat_buf->blocklens[i];
00178 ADIOI_BUFFERED_READ
00179 off += flat_buf->blocklens[i];
00180 }
00181
00182 if (fd->atomicity)
00183 ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00184
00185 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00186
00187 ADIOI_Free(readbuf);
00188
00189 #ifdef PRINT_ERR_MSG
00190 *error_code = (err_flag) ? MPI_ERR_UNKNOWN : MPI_SUCCESS;
00191 #else
00192 if (err_flag) {
00193 *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
00194 myname, "I/O Error", "%s", strerror(errno));
00195 ADIOI_Error(fd, *error_code, myname);
00196 }
00197 else *error_code = MPI_SUCCESS;
00198 #endif
00199 }
00200
00201 else {
00202
00203
00204 flat_file = ADIOI_Flatlist;
00205 while (flat_file->type != fd->filetype) flat_file = flat_file->next;
00206 disp = fd->disp;
00207
00208 if (file_ptr_type == ADIO_INDIVIDUAL) {
00209 offset = fd->fp_ind;
00210 n_filetypes = -1;
00211 flag = 0;
00212 while (!flag) {
00213 n_filetypes++;
00214 for (i=0; i<flat_file->count; i++) {
00215 if (disp + flat_file->indices[i] +
00216 (ADIO_Offset) n_filetypes*filetype_extent + flat_file->blocklens[i]
00217 >= offset) {
00218 st_index = i;
00219 frd_size = (int) (disp + flat_file->indices[i] +
00220 (ADIO_Offset) n_filetypes*filetype_extent
00221 + flat_file->blocklens[i] - offset);
00222 flag = 1;
00223 break;
00224 }
00225 }
00226 }
00227 }
00228 else {
00229 n_etypes_in_filetype = filetype_size/etype_size;
00230 n_filetypes = (int) (offset / n_etypes_in_filetype);
00231 etype_in_filetype = (int) (offset % n_etypes_in_filetype);
00232 size_in_filetype = etype_in_filetype * etype_size;
00233
00234 sum = 0;
00235 for (i=0; i<flat_file->count; i++) {
00236 sum += flat_file->blocklens[i];
00237 if (sum > size_in_filetype) {
00238 st_index = i;
00239 frd_size = sum - size_in_filetype;
00240 abs_off_in_filetype = flat_file->indices[i] +
00241 size_in_filetype - (sum - flat_file->blocklens[i]);
00242 break;
00243 }
00244 }
00245
00246
00247 offset = disp + (ADIO_Offset) n_filetypes*filetype_extent + abs_off_in_filetype;
00248 }
00249
00250 start_off = offset;
00251
00252
00253
00254
00255 st_frd_size = frd_size;
00256 st_n_filetypes = n_filetypes;
00257 i = 0;
00258 j = st_index;
00259 off = offset;
00260 frd_size = ADIOI_MIN(st_frd_size, bufsize);
00261 while (i < bufsize) {
00262 i += frd_size;
00263 end_offset = off + frd_size - 1;
00264
00265 if (j < (flat_file->count - 1)) j++;
00266 else {
00267 j = 0;
00268 n_filetypes++;
00269 }
00270
00271 off = disp + flat_file->indices[j] + (ADIO_Offset) n_filetypes*filetype_extent;
00272 frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
00273 }
00274
00275
00276 if (fd->atomicity)
00277 ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00278
00279
00280 readbuf_off = offset;
00281 readbuf = (char *) ADIOI_Malloc(max_bufsize);
00282 readbuf_len = (int) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));
00283
00284 lseek(fd->fd_sys, offset, SEEK_SET);
00285 if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, offset, SEEK_SET, readbuf_len);
00286 err = read(fd->fd_sys, readbuf, readbuf_len);
00287 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, offset, SEEK_SET, readbuf_len);
00288
00289 if (err == -1) err_flag = 1;
00290
00291 if (buftype_is_contig && !filetype_is_contig) {
00292
00293
00294
00295
00296 i = 0;
00297 j = st_index;
00298 off = offset;
00299 n_filetypes = st_n_filetypes;
00300 frd_size = ADIOI_MIN(st_frd_size, bufsize);
00301 while (i < bufsize) {
00302 if (frd_size) {
00303
00304
00305
00306
00307
00308 req_off = off;
00309 req_len = frd_size;
00310 userbuf_off = i;
00311 ADIOI_BUFFERED_READ
00312 }
00313 i += frd_size;
00314
00315 if (off + frd_size < disp + flat_file->indices[j] +
00316 flat_file->blocklens[j] + (ADIO_Offset) n_filetypes*filetype_extent)
00317 off += frd_size;
00318
00319
00320 else {
00321 if (j < (flat_file->count - 1)) j++;
00322 else {
00323 j = 0;
00324 n_filetypes++;
00325 }
00326 off = disp + flat_file->indices[j] +
00327 (ADIO_Offset) n_filetypes*filetype_extent;
00328 frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
00329 }
00330 }
00331 }
00332 else {
00333
00334
00335 ADIOI_Flatten_datatype(datatype);
00336 flat_buf = ADIOI_Flatlist;
00337 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00338
00339 k = num = buf_count = 0;
00340 i = (int) (flat_buf->indices[0]);
00341 j = st_index;
00342 off = offset;
00343 n_filetypes = st_n_filetypes;
00344 frd_size = st_frd_size;
00345 brd_size = flat_buf->blocklens[0];
00346
00347 while (num < bufsize) {
00348 size = ADIOI_MIN(frd_size, brd_size);
00349 if (size) {
00350
00351
00352
00353 req_off = off;
00354 req_len = size;
00355 userbuf_off = i;
00356 ADIOI_BUFFERED_READ
00357 }
00358
00359 new_frd_size = frd_size;
00360 new_brd_size = brd_size;
00361
00362 if (size == frd_size) {
00363
00364 if (j < (flat_file->count - 1)) j++;
00365 else {
00366 j = 0;
00367 n_filetypes++;
00368 }
00369
00370 off = disp + flat_file->indices[j] +
00371 (ADIO_Offset) n_filetypes*filetype_extent;
00372
00373 new_frd_size = flat_file->blocklens[j];
00374 if (size != brd_size) {
00375 i += size;
00376 new_brd_size -= size;
00377 }
00378 }
00379
00380 if (size == brd_size) {
00381
00382
00383 k = (k + 1)%flat_buf->count;
00384 buf_count++;
00385 i = (int) (buftype_extent*(buf_count/flat_buf->count) +
00386 flat_buf->indices[k]);
00387 new_brd_size = flat_buf->blocklens[k];
00388 if (size != frd_size) {
00389 off += size;
00390 new_frd_size -= size;
00391 }
00392 }
00393 num += size;
00394 frd_size = new_frd_size;
00395 brd_size = new_brd_size;
00396 }
00397 }
00398
00399 if (fd->atomicity)
00400 ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00401
00402 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00403
00404 ADIOI_Free(readbuf);
00405
00406 #ifdef PRINT_ERR_MSG
00407 *error_code = (err_flag) ? MPI_ERR_UNKNOWN : MPI_SUCCESS;
00408 #else
00409 if (err_flag) {
00410 *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
00411 myname, "I/O Error", "%s", strerror(errno));
00412 ADIOI_Error(fd, *error_code, myname);
00413 }
00414 else *error_code = MPI_SUCCESS;
00415 #endif
00416 }
00417
00418 fd->fp_sys_posn = -1;
00419
00420 #ifdef HAVE_STATUS_SET_BYTES
00421 MPIR_Status_set_bytes(status, datatype, bufsize);
00422
00423
00424
00425 #endif
00426
00427 if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
00428 }