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