root/ompi/mca/io/romio321/romio/adio/common/ad_read_str_naive.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ADIOI_GEN_ReadStrided_naive

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
   2 /* 
   3  *
   4  *   Copyright (C) 2001 University of Chicago. 
   5  *   See COPYRIGHT notice in top-level directory.
   6  */
   7 
   8 #include "adio.h"
   9 #include "adio_extern.h"
  10 
  11 void ADIOI_GEN_ReadStrided_naive(ADIO_File fd, void *buf, int count,
  12                        MPI_Datatype buftype, int file_ptr_type,
  13                        ADIO_Offset offset, ADIO_Status *status, int
  14                        *error_code)
  15 {
  16     /* offset is in units of etype relative to the filetype. */
  17 
  18     ADIOI_Flatlist_node *flat_buf, *flat_file;
  19     ADIO_Offset size, brd_size, frd_size=0, req_len, sum;
  20     int b_index;
  21     int n_etypes_in_filetype;
  22     ADIO_Offset n_filetypes, etype_in_filetype;
  23     ADIO_Offset abs_off_in_filetype=0;
  24     MPI_Count bufsize, filetype_size, buftype_size, size_in_filetype;
  25     ADIO_Offset etype_size;
  26     MPI_Aint filetype_extent, buftype_extent, lb; 
  27     int buf_count, buftype_is_contig, filetype_is_contig;
  28     ADIO_Offset userbuf_off;
  29     ADIO_Offset off, req_off, disp, end_offset=0, start_off;
  30     ADIO_Status status1;
  31 
  32     *error_code = MPI_SUCCESS;  /* changed below if error */
  33 
  34     ADIOI_Datatype_iscontig(buftype, &buftype_is_contig);
  35     ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
  36 
  37     MPI_Type_size_x(fd->filetype, &filetype_size);
  38     if ( ! filetype_size ) {
  39 #ifdef HAVE_STATUS_SET_BYTES
  40         MPIR_Status_set_bytes(status, buftype, 0);
  41 #endif
  42         *error_code = MPI_SUCCESS; 
  43         return;
  44     }
  45 
  46     MPI_Type_get_extent(fd->filetype, &lb, &filetype_extent);
  47     MPI_Type_size_x(buftype, &buftype_size);
  48     MPI_Type_get_extent(buftype, &lb, &buftype_extent);
  49     etype_size = fd->etype_size;
  50 
  51     ADIOI_Assert((buftype_size * count) == ((ADIO_Offset)buftype_size * (ADIO_Offset)count));
  52     bufsize = buftype_size * count;
  53 
  54     /* contiguous in buftype and filetype is handled elsewhere */
  55 
  56     if (!buftype_is_contig && filetype_is_contig) {
  57         int b_count;
  58         /* noncontiguous in memory, contiguous in file. */
  59 
  60         flat_buf = ADIOI_Flatten_and_find(buftype);
  61 
  62         off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind : 
  63               fd->disp + etype_size * offset;
  64 
  65         start_off = off;
  66         end_offset = off + bufsize - 1;
  67 
  68         /* if atomicity is true, lock (exclusive) the region to be accessed */
  69         if ((fd->atomicity) && ADIO_Feature(fd, ADIO_LOCKS))
  70         {
  71             ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
  72         }
  73 
  74         /* for each region in the buffer, grab the data and put it in
  75          * place
  76          */
  77         for (b_count=0; b_count < count; b_count++) {
  78             for (b_index=0; b_index < flat_buf->count; b_index++) {
  79                 userbuf_off = (ADIO_Offset)b_count*(ADIO_Offset)buftype_extent + 
  80                               flat_buf->indices[b_index];
  81                 req_off = off;
  82                 req_len = flat_buf->blocklens[b_index];
  83 
  84     ADIOI_Assert((((ADIO_Offset)(MPIU_Upint)buf) + userbuf_off) == (ADIO_Offset)(MPIU_Upint)((MPIU_Upint)buf + userbuf_off));
  85     ADIOI_Assert(req_len == (int) req_len);
  86                 ADIO_ReadContig(fd, 
  87                                 (char *) buf + userbuf_off,
  88                                 req_len, 
  89                                 MPI_BYTE, 
  90                                 ADIO_EXPLICIT_OFFSET,
  91                                 req_off,
  92                                 &status1,
  93                                 error_code);
  94                 if (*error_code != MPI_SUCCESS) return;
  95 
  96                 /* off is (potentially) used to save the final offset later */
  97                 off += flat_buf->blocklens[b_index];
  98             }
  99         }
 100 
 101         if ((fd->atomicity) && ADIO_Feature(fd, ADIO_LOCKS))
 102         {
 103             ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
 104         }
 105 
 106         if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
 107 
 108     }
 109 
 110     else {  /* noncontiguous in file */
 111         int f_index, st_index = 0; 
 112       ADIO_Offset st_n_filetypes;
 113       ADIO_Offset st_frd_size;
 114         int flag;
 115 
 116         /* First we're going to calculate a set of values for use in all
 117          * the noncontiguous in file cases:
 118          * start_off - starting byte position of data in file
 119          * end_offset - last byte offset to be acessed in the file
 120          * st_n_filetypes - how far into the file we start in terms of
 121          *                  whole filetypes
 122          * st_index - index of block in first filetype that we will be
 123          *            starting in (?)
 124          * st_frd_size - size of the data in the first filetype block
 125          *               that we will read (accounts for being part-way
 126          *               into reading this block of the filetype
 127          *
 128          */
 129 
 130         /* filetype already flattened in ADIO_Open */
 131         flat_file = ADIOI_Flatlist;
 132         while (flat_file->type != fd->filetype) flat_file = flat_file->next;
 133         disp = fd->disp;
 134 
 135         if (file_ptr_type == ADIO_INDIVIDUAL) {
 136             start_off = fd->fp_ind; /* in bytes */
 137             n_filetypes = -1;
 138             flag = 0;
 139             while (!flag) {
 140                 n_filetypes++;
 141                 for (f_index=0; f_index < flat_file->count; f_index++) {
 142                     if (disp + flat_file->indices[f_index] + 
 143                        n_filetypes*(ADIO_Offset)filetype_extent + 
 144                        flat_file->blocklens[f_index] >= start_off) 
 145                     {
 146                         /* this block contains our starting position */
 147 
 148                         st_index = f_index;
 149                         frd_size = disp + flat_file->indices[f_index] + 
 150                                    n_filetypes*(ADIO_Offset)filetype_extent + 
 151                                    flat_file->blocklens[f_index] - start_off;
 152                         flag = 1;
 153                         break;
 154                     }
 155                 }
 156             }
 157         }
 158         else {
 159             n_etypes_in_filetype = filetype_size/etype_size;
 160             n_filetypes = offset / n_etypes_in_filetype;
 161             etype_in_filetype = (int) (offset % n_etypes_in_filetype);
 162             size_in_filetype = (unsigned)etype_in_filetype * (unsigned)etype_size;
 163  
 164             sum = 0;
 165             for (f_index=0; f_index < flat_file->count; f_index++) {
 166                 sum += flat_file->blocklens[f_index];
 167                 if (sum > size_in_filetype) {
 168                     st_index = f_index;
 169                     frd_size = sum - size_in_filetype;
 170                     abs_off_in_filetype = flat_file->indices[f_index] +
 171                                           size_in_filetype - 
 172                                           (sum - flat_file->blocklens[f_index]);
 173                     break;
 174                 }
 175             }
 176 
 177             /* abs. offset in bytes in the file */
 178             start_off = disp + n_filetypes*(ADIO_Offset)filetype_extent + 
 179                         abs_off_in_filetype;
 180         }
 181 
 182         st_frd_size = frd_size;
 183         st_n_filetypes = n_filetypes;
 184 
 185         /* start_off, st_n_filetypes, st_index, and st_frd_size are 
 186          * all calculated at this point
 187          */
 188 
 189         /* Calculate end_offset, the last byte-offset that will be accessed.
 190          * e.g., if start_off=0 and 100 bytes to be read, end_offset=99
 191          */
 192         userbuf_off = 0;
 193         f_index = st_index;
 194         off = start_off;
 195         frd_size = ADIOI_MIN(st_frd_size, bufsize);
 196         while (userbuf_off < bufsize) {
 197             userbuf_off += frd_size;
 198             end_offset = off + frd_size - 1;
 199 
 200             if (f_index < (flat_file->count - 1)) f_index++;
 201             else {
 202                 f_index = 0;
 203                 n_filetypes++;
 204             }
 205 
 206             off = disp + flat_file->indices[f_index] + 
 207                   n_filetypes*(ADIO_Offset)filetype_extent;
 208             frd_size = ADIOI_MIN(flat_file->blocklens[f_index], 
 209                                  bufsize-(unsigned)userbuf_off);
 210         }
 211 
 212         /* End of calculations.  At this point the following values have
 213          * been calculated and are ready for use:
 214          * - start_off
 215          * - end_offset
 216          * - st_n_filetypes
 217          * - st_index
 218          * - st_frd_size
 219          */
 220 
 221         /* if atomicity is true, lock (exclusive) the region to be accessed */
 222         if ((fd->atomicity) && ADIO_Feature(fd, ADIO_LOCKS))
 223         {
 224             ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
 225         }
 226 
 227         if (buftype_is_contig && !filetype_is_contig) {
 228             /* contiguous in memory, noncontiguous in file. should be the
 229              * most common case.
 230              */
 231 
 232             userbuf_off = 0;
 233             f_index = st_index;
 234             off = start_off;
 235             n_filetypes = st_n_filetypes;
 236             frd_size = ADIOI_MIN(st_frd_size, bufsize);
 237 
 238             /* while there is still space in the buffer, read more data */
 239             while (userbuf_off < bufsize) {
 240                 if (frd_size) { 
 241                     /* TYPE_UB and TYPE_LB can result in 
 242                        frd_size = 0. save system call in such cases */ 
 243                     req_off = off;
 244                     req_len = frd_size;
 245 
 246         ADIOI_Assert((((ADIO_Offset)(MPIU_Upint)buf) + userbuf_off) == (ADIO_Offset)(MPIU_Upint)((MPIU_Upint)buf + userbuf_off));
 247         ADIOI_Assert(req_len == (int) req_len);
 248                     ADIO_ReadContig(fd, 
 249                                     (char *) buf + userbuf_off,
 250                                     req_len, 
 251                                     MPI_BYTE, 
 252                                     ADIO_EXPLICIT_OFFSET,
 253                                     req_off,
 254                                     &status1,
 255                                     error_code);
 256                     if (*error_code != MPI_SUCCESS) return;
 257                 }
 258                 userbuf_off += frd_size;
 259 
 260                 if (off + frd_size < disp + flat_file->indices[f_index] +
 261                    flat_file->blocklens[f_index] + 
 262                    n_filetypes*(ADIO_Offset)filetype_extent)
 263                 {
 264                     /* important that this value be correct, as it is
 265                      * used to set the offset in the fd near the end of
 266                      * this function.
 267                      */
 268                     off += frd_size;
 269                 }
 270                 /* did not reach end of contiguous block in filetype.
 271                  * no more I/O needed. off is incremented by frd_size.
 272                  */
 273                 else {
 274                     if (f_index < (flat_file->count - 1)) f_index++;
 275                     else {
 276                         f_index = 0;
 277                         n_filetypes++;
 278                     }
 279                     off = disp + flat_file->indices[f_index] + 
 280                           n_filetypes*(ADIO_Offset)filetype_extent;
 281                     frd_size = ADIOI_MIN(flat_file->blocklens[f_index], 
 282                                          bufsize-(unsigned)userbuf_off);
 283                 }
 284             }
 285         }
 286         else {
 287             ADIO_Offset i_offset, tmp_bufsize = 0;
 288             /* noncontiguous in memory as well as in file */
 289 
 290             flat_buf = ADIOI_Flatten_and_find(buftype);
 291 
 292             b_index = buf_count = 0;
 293             i_offset = flat_buf->indices[0];
 294             f_index = st_index;
 295             off = start_off;
 296             n_filetypes = st_n_filetypes;
 297             frd_size = st_frd_size;
 298             brd_size = flat_buf->blocklens[0];
 299 
 300             /* while we haven't read size * count bytes, keep going */
 301             while (tmp_bufsize < bufsize) {
 302                 ADIO_Offset new_brd_size = brd_size, new_frd_size = frd_size;
 303 
 304                 size = ADIOI_MIN(frd_size, brd_size);
 305                 if (size) {
 306                     req_off = off;
 307                     req_len = size;
 308                     userbuf_off = i_offset;
 309 
 310         ADIOI_Assert((((ADIO_Offset)(MPIU_Upint)buf) + userbuf_off) == (ADIO_Offset)(MPIU_Upint)((MPIU_Upint)buf + userbuf_off));
 311         ADIOI_Assert(req_len == (int) req_len);
 312                     ADIO_ReadContig(fd, 
 313                                     (char *) buf + userbuf_off,
 314                                     req_len, 
 315                                     MPI_BYTE, 
 316                                     ADIO_EXPLICIT_OFFSET,
 317                                     req_off,
 318                                     &status1,
 319                                     error_code);
 320                     if (*error_code != MPI_SUCCESS) return;
 321                 }
 322 
 323                 if (size == frd_size) {
 324                     /* reached end of contiguous block in file */
 325                     if (f_index < (flat_file->count - 1)) f_index++;
 326                     else {
 327                         f_index = 0;
 328                         n_filetypes++;
 329                     }
 330 
 331                     off = disp + flat_file->indices[f_index] + 
 332                           n_filetypes*(ADIO_Offset)filetype_extent;
 333 
 334                     new_frd_size = flat_file->blocklens[f_index];
 335                     if (size != brd_size) {
 336                         i_offset += size;
 337                         new_brd_size -= size;
 338                     }
 339                 }
 340 
 341                 if (size == brd_size) {
 342                     /* reached end of contiguous block in memory */
 343 
 344                     b_index = (b_index + 1)%flat_buf->count;
 345                     buf_count++;
 346                     i_offset = buftype_extent*(buf_count/flat_buf->count) +
 347                         flat_buf->indices[b_index];
 348                     new_brd_size = flat_buf->blocklens[b_index];
 349                     if (size != frd_size) {
 350                         off += size;
 351                         new_frd_size -= size;
 352                     }
 353                 }
 354                 tmp_bufsize += size;
 355                 frd_size = new_frd_size;
 356                 brd_size = new_brd_size;
 357             }
 358         }
 359 
 360         /* unlock the file region if we locked it */
 361         if ((fd->atomicity) && (fd->file_system != ADIO_PIOFS) && 
 362            (fd->file_system != ADIO_PVFS) && (fd->file_system != ADIO_PVFS2))
 363         {
 364             ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
 365         }
 366 
 367         if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
 368     } /* end of (else noncontiguous in file) */
 369 
 370     fd->fp_sys_posn = -1;   /* mark it as invalid. */
 371 
 372 #ifdef HAVE_STATUS_SET_BYTES
 373     MPIR_Status_set_bytes(status, buftype, bufsize);
 374     /* This is a temporary way of filling in status. The right way is to 
 375      * keep track of how much data was actually read and placed in buf 
 376      */
 377 #endif
 378 
 379     if (!buftype_is_contig) ADIOI_Delete_flattened(buftype);
 380 }

/* [<][>][^][v][top][bottom][index][help] */