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