root/ompi/mca/io/romio321/romio/adio/ad_pvfs2/ad_pvfs2_read_list_classic.c

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

DEFINITIONS

This source file includes following definitions.
  1. ADIOI_PVFS2_OldReadStrided

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- 
   2  * vim: ts=8 sts=4 sw=4 noexpandtab 
   3  * 
   4  *   Copyright (C) 2008 University of Chicago. 
   5  *   See COPYRIGHT notice in top-level directory.
   6  */
   7 
   8 #include "adio.h"
   9 #include "adio_extern.h"
  10 #include "ad_pvfs2.h"
  11 
  12 #include "ad_pvfs2_common.h"
  13 
  14 void ADIOI_PVFS2_OldReadStrided(ADIO_File fd, void *buf, int count,
  15                              MPI_Datatype datatype, int file_ptr_type,
  16                              ADIO_Offset offset, ADIO_Status *status, int
  17                              *error_code)
  18 {
  19     /* offset is in units of etype relative to the filetype. */
  20     ADIOI_Flatlist_node *flat_buf, *flat_file;
  21     int i, j, k,  brd_size, frd_size=0, st_index=0;
  22     int sum, n_etypes_in_filetype, size_in_filetype;
  23     MPI_Count bufsize;
  24     int n_filetypes, etype_in_filetype;
  25     ADIO_Offset abs_off_in_filetype=0;
  26     MPI_Count filetype_size, etype_size, buftype_size;
  27     MPI_Aint filetype_extent, buftype_extent, filetype_lb, buftype_lb; 
  28     int buf_count, buftype_is_contig, filetype_is_contig;
  29     ADIO_Offset off, disp, start_off, initial_off;
  30     int flag, st_frd_size, st_n_filetypes;
  31 
  32     int mem_list_count, file_list_count;
  33     PVFS_size *mem_offsets;
  34     int64_t *file_offsets;
  35     int *mem_lengths;
  36     int32_t *file_lengths;
  37     int total_blks_to_read;
  38 
  39     int max_mem_list, max_file_list;
  40 
  41     int b_blks_read;
  42     int f_data_read;
  43     int size_read=0, n_read_lists, extra_blks;
  44 
  45     int end_brd_size, end_frd_size;
  46     int start_k, start_j, new_file_read, new_buffer_read;
  47     int start_mem_offset;
  48     PVFS_Request mem_req, file_req;
  49     ADIOI_PVFS2_fs * pvfs_fs;
  50     PVFS_sysresp_io resp_io;
  51     int err_flag=0;
  52     MPI_Offset total_bytes_read = 0;
  53     static char myname[] = "ADIOI_PVFS2_ReadStrided";
  54 
  55 #define MAX_ARRAY_SIZE 64
  56 
  57     *error_code = MPI_SUCCESS;  /* changed below if error */
  58 
  59     ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
  60     ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
  61 
  62     /* the HDF5 tests showed a bug in this list processing code (see many many
  63      * lines down below).  We added a workaround, but common HDF5 file types
  64      * are actually contiguous and do not need the expensive workarond */
  65     if (!filetype_is_contig) {
  66         flat_file = ADIOI_Flatlist;
  67         while (flat_file->type != fd->filetype) flat_file = flat_file->next;
  68         if (flat_file->count == 1 && !buftype_is_contig)
  69             filetype_is_contig = 1;
  70     }
  71 
  72     MPI_Type_size_x(fd->filetype, &filetype_size);
  73     if ( ! filetype_size ) {
  74 #ifdef HAVE_STATUS_SET_BYTES
  75         MPIR_Status_set_bytes(status, datatype, 0);
  76 #endif
  77         *error_code = MPI_SUCCESS; 
  78         return;
  79     }
  80 
  81     MPI_Type_get_extent(fd->filetype, &filetype_lb, &filetype_extent);
  82     MPI_Type_size_x(datatype, &buftype_size);
  83     MPI_Type_get_extent(datatype, &buftype_lb, &buftype_extent);
  84     etype_size = fd->etype_size;
  85 
  86     bufsize = buftype_size * count;
  87     
  88     pvfs_fs = (ADIOI_PVFS2_fs*)fd->fs_ptr;
  89 
  90     if (!buftype_is_contig && filetype_is_contig) {
  91 
  92 /* noncontiguous in memory, contiguous in file. */
  93        int64_t file_offset;
  94         int32_t file_length;
  95 
  96         flat_buf = ADIOI_Flatten_and_find(datatype);
  97 
  98         off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind : 
  99             fd->disp + etype_size * offset;
 100 
 101         file_list_count = 1;
 102         file_offset = off;
 103         file_length = 0;
 104         total_blks_to_read = count*flat_buf->count;
 105         b_blks_read = 0;
 106 
 107         /* allocate arrays according to max usage */
 108         if (total_blks_to_read > MAX_ARRAY_SIZE)
 109             mem_list_count = MAX_ARRAY_SIZE;
 110         else mem_list_count = total_blks_to_read;
 111         mem_offsets = (PVFS_size*)ADIOI_Malloc(mem_list_count*sizeof(PVFS_size));
 112         mem_lengths = (int*)ADIOI_Malloc(mem_list_count*sizeof(int));
 113 
 114         /* TODO: CHECK RESULTS OF MEMORY ALLOCATION */
 115 
 116         j = 0;
 117         /* step through each block in memory, filling memory arrays */
 118         while (b_blks_read < total_blks_to_read) {
 119             for (i=0; i<flat_buf->count; i++) {
 120                 mem_offsets[b_blks_read % MAX_ARRAY_SIZE] = 
 121                     /* TODO: fix this compiler warning */
 122                     ((PVFS_size)buf + j*buftype_extent + flat_buf->indices[i]);
 123                 mem_lengths[b_blks_read % MAX_ARRAY_SIZE] = 
 124                     flat_buf->blocklens[i];
 125                 file_length += flat_buf->blocklens[i];
 126                 b_blks_read++;
 127                 if (!(b_blks_read % MAX_ARRAY_SIZE) ||
 128                     (b_blks_read == total_blks_to_read)) {
 129 
 130                     /* in the case of the last read list call,
 131                        adjust mem_list_count */
 132                     if (b_blks_read == total_blks_to_read) {
 133                         mem_list_count = total_blks_to_read % MAX_ARRAY_SIZE;
 134                         /* in case last read list call fills max arrays */
 135                         if (!mem_list_count) mem_list_count = MAX_ARRAY_SIZE;
 136                     }
 137                     err_flag = PVFS_Request_hindexed(mem_list_count, 
 138                             mem_lengths, mem_offsets, PVFS_BYTE, &mem_req);
 139                     if (err_flag < 0) break;
 140                     err_flag = PVFS_Request_contiguous(file_length,
 141                             PVFS_BYTE, &file_req);
 142                     if (err_flag < 0) break;
 143 #ifdef ADIOI_MPE_LOGGING
 144                     MPE_Log_event( ADIOI_MPE_read_a, 0, NULL );
 145 #endif
 146                     err_flag = PVFS_sys_read(pvfs_fs->object_ref, file_req, 
 147                             file_offset, PVFS_BOTTOM, mem_req,
 148                             &(pvfs_fs->credentials), &resp_io);
 149 #ifdef ADIOI_MPE_LOGGING
 150                     MPE_Log_event( ADIOI_MPE_read_b, 0, NULL );
 151 #endif
 152                     /* --BEGIN ERROR HANDLING-- */
 153                     if (err_flag != 0) {
 154                         *error_code = MPIO_Err_create_code(MPI_SUCCESS,
 155                                                            MPIR_ERR_RECOVERABLE,
 156                                                            myname, __LINE__,
 157                                                            ADIOI_PVFS2_error_convert(err_flag),
 158                                                            "Error in PVFS_sys_read", 0);
 159                         goto error_state;
 160                     }
 161                     PVFS_Request_free(&mem_req);
 162                     PVFS_Request_free(&file_req);
 163                     total_bytes_read += resp_io.total_completed;
 164                     /* --END ERROR HANDLING-- */
 165                   
 166                     /* in the case of error or the last read list call, 
 167                      * leave here */
 168                     if (err_flag || b_blks_read == total_blks_to_read) break;
 169 
 170                     file_offset += file_length;
 171                     file_length = 0;
 172                 } 
 173             } /* for (i=0; i<flat_buf->count; i++) */
 174             j++;
 175         } /* while (b_blks_read < total_blks_to_read) */
 176         ADIOI_Free(mem_offsets);
 177         ADIOI_Free(mem_lengths);
 178 
 179         if (file_ptr_type == ADIO_INDIVIDUAL) 
 180             fd->fp_ind += total_bytes_read;
 181 
 182         fd->fp_sys_posn = -1;  /* set it to null. */
 183 
 184 #ifdef HAVE_STATUS_SET_BYTES
 185         MPIR_Status_set_bytes(status, datatype, bufsize);
 186         /* This isa temporary way of filling in status.  The right way is to
 187            keep tracke of how much data was actually read adn placed in buf
 188            by ADIOI_BUFFERED_READ. */
 189 #endif
 190         ADIOI_Delete_flattened(datatype);
 191 
 192         return;
 193     } /* if (!buftype_is_contig && filetype_is_contig) */
 194 
 195     /* know file is noncontiguous from above */
 196     /* noncontiguous in file */
 197 
 198     /* filetype already flattened in ADIO_Open */
 199     flat_file = ADIOI_Flatlist;
 200     while (flat_file->type != fd->filetype) flat_file = flat_file->next;
 201 
 202     disp = fd->disp;
 203     initial_off = offset;
 204 
 205 
 206     /* for each case - ADIO_Individual pointer or explicit, find the file
 207        offset in bytes (offset), n_filetypes (how many filetypes into
 208        file to start), frd_size (remaining amount of data in present
 209        file block), and st_index (start point in terms of blocks in
 210        starting filetype) */
 211     if (file_ptr_type == ADIO_INDIVIDUAL) {
 212         offset = fd->fp_ind; /* in bytes */
 213         n_filetypes = -1;
 214         flag = 0;
 215         while (!flag) {
 216             n_filetypes++;
 217             for (i=0; i<flat_file->count; i++) {
 218                 if (disp + flat_file->indices[i] + 
 219                     ((ADIO_Offset) n_filetypes)*filetype_extent +
 220                     flat_file->blocklens[i]  >= offset) {
 221                     st_index = i;
 222                     frd_size = (int) (disp + flat_file->indices[i] + 
 223                                     ((ADIO_Offset) n_filetypes)*filetype_extent
 224                                       + flat_file->blocklens[i] - offset);
 225                     flag = 1;
 226                     break;
 227                 }
 228             }
 229         } /* while (!flag) */
 230     } /* if (file_ptr_type == ADIO_INDIVIDUAL) */
 231     else {
 232         n_etypes_in_filetype = filetype_size/etype_size;
 233         n_filetypes = (int) (offset / n_etypes_in_filetype);
 234         etype_in_filetype = (int) (offset % n_etypes_in_filetype);
 235         size_in_filetype = etype_in_filetype * etype_size;
 236         
 237         sum = 0;
 238         for (i=0; i<flat_file->count; i++) {
 239             sum += flat_file->blocklens[i];
 240             if (sum > size_in_filetype) {
 241                 st_index = i;
 242                 frd_size = sum - size_in_filetype;
 243                 abs_off_in_filetype = flat_file->indices[i] +
 244                     size_in_filetype - (sum - flat_file->blocklens[i]);
 245                 break;
 246             }
 247         }
 248         
 249         /* abs. offset in bytes in the file */
 250         offset = disp + ((ADIO_Offset) n_filetypes)*filetype_extent + 
 251             abs_off_in_filetype;
 252     } /* else [file_ptr_type != ADIO_INDIVIDUAL] */
 253 
 254     start_off = offset;
 255     st_frd_size = frd_size;
 256     st_n_filetypes = n_filetypes;
 257     
 258     if (buftype_is_contig && !filetype_is_contig) {
 259 
 260 /* contiguous in memory, noncontiguous in file. should be the most
 261    common case. */
 262 
 263        int mem_length=0;
 264         intptr_t mem_offset;
 265         
 266         i = 0;
 267         j = st_index;
 268         n_filetypes = st_n_filetypes;
 269         
 270         mem_list_count = 1;
 271         
 272         /* determine how many blocks in file to read */
 273         f_data_read = ADIOI_MIN(st_frd_size, bufsize);
 274         total_blks_to_read = 1;
 275         if (j < (flat_file->count-1)) j++;
 276         else {
 277             j = 0;
 278             n_filetypes++;
 279         }
 280         while (f_data_read < bufsize) {
 281             f_data_read += flat_file->blocklens[j];
 282             total_blks_to_read++;
 283             if (j<(flat_file->count-1)) j++;
 284             else j = 0; 
 285         }
 286       
 287         j = st_index;
 288         n_filetypes = st_n_filetypes;
 289         n_read_lists = total_blks_to_read/MAX_ARRAY_SIZE;
 290         extra_blks = total_blks_to_read%MAX_ARRAY_SIZE;
 291         
 292         mem_offset = (intptr_t)buf;
 293         mem_lengths = 0;
 294         
 295         /* if at least one full readlist, allocate file arrays
 296            at max array size and don't free until very end */
 297         if (n_read_lists) {
 298             file_offsets = (int64_t*)ADIOI_Malloc(MAX_ARRAY_SIZE*
 299                                                   sizeof(int64_t));
 300             file_lengths = (int32_t*)ADIOI_Malloc(MAX_ARRAY_SIZE*
 301                                                   sizeof(int32_t));
 302         }
 303         /* if there's no full readlist allocate file arrays according
 304            to needed size (extra_blks) */
 305         else {
 306             file_offsets = (int64_t*)ADIOI_Malloc(extra_blks*
 307                                                   sizeof(int64_t));
 308             file_lengths = (int32_t*)ADIOI_Malloc(extra_blks*
 309                                                   sizeof(int32_t));
 310         }
 311         
 312         /* for file arrays that are of MAX_ARRAY_SIZE, build arrays */
 313         for (i=0; i<n_read_lists; i++) {
 314             file_list_count = MAX_ARRAY_SIZE;
 315             if(!i) {
 316                 file_offsets[0] = offset;
 317                 file_lengths[0] = st_frd_size;
 318                 mem_length = st_frd_size;
 319             }
 320             for (k=0; k<MAX_ARRAY_SIZE; k++) {
 321                 if (i || k) {
 322                     file_offsets[k] = disp + 
 323                         ((ADIO_Offset)n_filetypes)*filetype_extent
 324                       + flat_file->indices[j];
 325                     file_lengths[k] = flat_file->blocklens[j];
 326                     mem_lengths += file_lengths[k];
 327                 }
 328                 if (j<(flat_file->count - 1)) j++;
 329                 else {
 330                     j = 0;
 331                     n_filetypes++;
 332                 }
 333             } /* for (k=0; k<MAX_ARRAY_SIZE; k++) */
 334             err_flag = PVFS_Request_contiguous(mem_length,
 335                                                PVFS_BYTE, &mem_req);
 336             /* --BEGIN ERROR HANDLING-- */
 337             if (err_flag != 0) {
 338                 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
 339                                                    MPIR_ERR_RECOVERABLE,
 340                                                    myname, __LINE__,
 341                                                    ADIOI_PVFS2_error_convert(err_flag),
 342                                                    "Error in PVFS_Request_contiguous (memory)", 0);
 343                 goto error_state;
 344             }
 345             /* --END ERROR HANDLING-- */
 346 
 347             err_flag = PVFS_Request_hindexed(file_list_count, file_lengths, 
 348                                              file_offsets, PVFS_BYTE,
 349                                              &file_req);
 350             /* --BEGIN ERROR HANDLING-- */
 351             if (err_flag != 0) {
 352                 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
 353                                                    MPIR_ERR_RECOVERABLE,
 354                                                    myname, __LINE__,
 355                                                    ADIOI_PVFS2_error_convert(err_flag),
 356                                                    "Error in PVFS_Request_hindexed (file)", 0);
 357                 goto error_state;
 358             }
 359             /* --END ERROR HANDLING-- */
 360 
 361             /* PVFS_Request_hindexed already expresses the offsets into the
 362              * file, so we should not pass in an offset if we are using
 363              * hindexed for the file type */
 364 #ifdef ADIOI_MPE_LOGGING
 365             MPE_Log_event( ADIOI_MPE_read_a, 0, NULL );
 366 #endif
 367             err_flag = PVFS_sys_read(pvfs_fs->object_ref, file_req, 0, 
 368                                      (void *)mem_offset, mem_req,
 369                                      &(pvfs_fs->credentials), &resp_io);
 370 #ifdef ADIOI_MPE_LOGGING
 371             MPE_Log_event( ADIOI_MPE_read_b, 0, NULL );
 372 #endif
 373             /* --BEGIN ERROR HANDLING-- */
 374             if (err_flag != 0) {
 375                 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
 376                                                    MPIR_ERR_RECOVERABLE,
 377                                                    myname, __LINE__,
 378                                                    ADIOI_PVFS2_error_convert(err_flag),
 379                                                    "Error in PVFS_sys_read", 0);
 380                 goto error_state;
 381             }
 382             /* --END ERROR HANDING-- */
 383             PVFS_Request_free(&mem_req);
 384             PVFS_Request_free(&file_req);
 385 
 386             total_bytes_read += resp_io.total_completed;
 387 
 388             mem_offset += mem_length;
 389             mem_lengths = 0;
 390         } /* for (i=0; i<n_read_lists; i++) */
 391 
 392         /* for file arrays smaller than MAX_ARRAY_SIZE (last read_list call) */
 393         if (extra_blks) {
 394             file_list_count = extra_blks;
 395             if(!i) {
 396                 file_offsets[0] = offset;
 397                 file_lengths[0] = ADIOI_MIN(st_frd_size, bufsize);
 398             }
 399             for (k=0; k<extra_blks; k++) {
 400                 if(i || k) {
 401                     file_offsets[k] = disp + 
 402                         ((ADIO_Offset)n_filetypes)*filetype_extent +
 403                         flat_file->indices[j];
 404                     if (k == (extra_blks - 1)) {
 405                         file_lengths[k] = bufsize - (int32_t) mem_lengths
 406                           - mem_offset + (int32_t)  buf;
 407                     }
 408                     else file_lengths[k] = flat_file->blocklens[j];
 409                 } /* if(i || k) */
 410                 mem_lengths += file_lengths[k];
 411                 if (j<(flat_file->count - 1)) j++;
 412                 else {
 413                     j = 0;
 414                     n_filetypes++;
 415                 }
 416             } /* for (k=0; k<extra_blks; k++) */
 417             err_flag = PVFS_Request_contiguous(mem_length,
 418                                                PVFS_BYTE, &mem_req);
 419             /* --BEGIN ERROR HANDLING-- */
 420             if (err_flag != 0) {
 421                 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
 422                                                    MPIR_ERR_RECOVERABLE,
 423                                                    myname, __LINE__,
 424                                                    ADIOI_PVFS2_error_convert(err_flag),
 425                                                    "Error in PVFS_Request_contiguous (memory)", 0);
 426                 goto error_state;
 427             }
 428             /* --END ERROR HANDLING-- */
 429 
 430             err_flag = PVFS_Request_hindexed(file_list_count, file_lengths, 
 431                     file_offsets, PVFS_BYTE, &file_req);
 432             /* --BEGIN ERROR HANDLING-- */
 433             if (err_flag != 0) {
 434                 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
 435                                                    MPIR_ERR_RECOVERABLE,
 436                                                    myname, __LINE__,
 437                                                    ADIOI_PVFS2_error_convert(err_flag),
 438                                                    "Error in PVFS_Request_hindexed (file)", 0);
 439                 goto error_state;
 440             }
 441             /* --END ERROR HANDLING-- */
 442 
 443             /* as above, use 0 for 'offset' when using hindexed file type */
 444 #ifdef ADIOI_MPE_LOGGING
 445             MPE_Log_event( ADIOI_MPE_read_a, 0, NULL );
 446 #endif
 447             err_flag = PVFS_sys_read(pvfs_fs->object_ref, file_req, 0, 
 448                     (void *)mem_offset, mem_req, &(pvfs_fs->credentials), &resp_io);
 449 #ifdef ADIOI_MPE_LOGGING
 450             MPE_Log_event( ADIOI_MPE_read_b, 0, NULL );
 451 #endif
 452             /* --BEGIN ERROR HANDLING-- */
 453             if (err_flag != 0) {
 454                 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
 455                                                    MPIR_ERR_RECOVERABLE,
 456                                                    myname, __LINE__,
 457                                                    ADIOI_PVFS2_error_convert(err_flag),
 458                                                    "Error in PVFS_sys_read", 0);                
 459                 goto error_state;
 460             }
 461             /* --END ERROR HANDLING-- */
 462             PVFS_Request_free(&mem_req);
 463             PVFS_Request_free(&file_req);
 464             total_bytes_read += resp_io.total_completed;
 465         }
 466     }
 467     else {
 468 /* noncontiguous in memory as well as in file */
 469       
 470         flat_buf = ADIOI_Flatten_and_find(datatype);
 471 
 472         size_read = 0;
 473         n_filetypes = st_n_filetypes;
 474         frd_size = st_frd_size;
 475         brd_size = flat_buf->blocklens[0];
 476         buf_count = 0;
 477         start_mem_offset = 0;
 478         start_k = k = 0;
 479         start_j = st_index;
 480         max_mem_list = 0;
 481         max_file_list = 0;
 482 
 483         /* run through and file max_file_list and max_mem_list so that you 
 484            can allocate the file and memory arrays less than MAX_ARRAY_SIZE
 485            if possible */
 486 
 487         while (size_read < bufsize) {
 488             k = start_k;
 489             new_buffer_read = 0;
 490             mem_list_count = 0;
 491             while ((mem_list_count < MAX_ARRAY_SIZE) && 
 492                    (new_buffer_read < bufsize-size_read)) {
 493                 /* find mem_list_count and file_list_count such that both are
 494                    less than MAX_ARRAY_SIZE, the sum of their lengths are
 495                    equal, and the sum of all the data read and data to be
 496                    read in the next immediate read list is less than
 497                    bufsize */
 498                 if(mem_list_count) {
 499                     if((new_buffer_read + flat_buf->blocklens[k] + 
 500                         size_read) > bufsize) {
 501                         end_brd_size = new_buffer_read + 
 502                             flat_buf->blocklens[k] - (bufsize - size_read);
 503                         new_buffer_read = bufsize - size_read;
 504                     }
 505                     else {
 506                         new_buffer_read += flat_buf->blocklens[k];
 507                         end_brd_size = flat_buf->blocklens[k];
 508                     }
 509                 }
 510                 else {
 511                     if (brd_size > (bufsize - size_read)) {
 512                         new_buffer_read = bufsize - size_read;
 513                         brd_size = new_buffer_read;
 514                     }
 515                     else new_buffer_read = brd_size;
 516                 }
 517                 mem_list_count++;
 518                 k = (k + 1)%flat_buf->count;
 519              } /* while ((mem_list_count < MAX_ARRAY_SIZE) && 
 520                (new_buffer_read < bufsize-size_read)) */
 521             j = start_j;
 522             new_file_read = 0;
 523             file_list_count = 0;
 524             while ((file_list_count < MAX_ARRAY_SIZE) && 
 525                    (new_file_read < new_buffer_read)) {
 526                 if(file_list_count) {
 527                     if((new_file_read + flat_file->blocklens[j]) > 
 528                        new_buffer_read) {
 529                         end_frd_size = new_buffer_read - new_file_read;
 530                         new_file_read = new_buffer_read;
 531                         j--;
 532                     }
 533                     else {
 534                         new_file_read += flat_file->blocklens[j];
 535                         end_frd_size = flat_file->blocklens[j];
 536                     }
 537                 }
 538                 else {
 539                     if (frd_size > new_buffer_read) {
 540                         new_file_read = new_buffer_read;
 541                         frd_size = new_file_read;
 542                     }
 543                     else new_file_read = frd_size;
 544                 }
 545                 file_list_count++;
 546                 if (j < (flat_file->count - 1)) j++;
 547                 else j = 0;
 548                 
 549                 k = start_k;
 550                 if ((new_file_read < new_buffer_read) && 
 551                     (file_list_count == MAX_ARRAY_SIZE)) {
 552                     new_buffer_read = 0;
 553                     mem_list_count = 0;
 554                     while (new_buffer_read < new_file_read) {
 555                         if(mem_list_count) {
 556                             if((new_buffer_read + flat_buf->blocklens[k]) >
 557                                new_file_read) {
 558                                 end_brd_size = new_file_read - new_buffer_read;
 559                                 new_buffer_read = new_file_read;
 560                                 k--;
 561                             }
 562                             else {
 563                                 new_buffer_read += flat_buf->blocklens[k];
 564                                 end_brd_size = flat_buf->blocklens[k];
 565                             }
 566                         }
 567                         else {
 568                             new_buffer_read = brd_size;
 569                             if (brd_size > (bufsize - size_read)) {
 570                                 new_buffer_read = bufsize - size_read;
 571                                 brd_size = new_buffer_read;
 572                             }
 573                         }
 574                         mem_list_count++;
 575                         k = (k + 1)%flat_buf->count;
 576                     } /* while (new_buffer_read < new_file_read) */
 577                 } /* if ((new_file_read < new_buffer_read) && (file_list_count
 578                      == MAX_ARRAY_SIZE)) */
 579             } /* while ((mem_list_count < MAX_ARRAY_SIZE) && 
 580                  (new_buffer_read < bufsize-size_read)) */
 581 
 582             /*  fakes filling the readlist arrays of lengths found above  */
 583             k = start_k;
 584             j = start_j;
 585             for (i=0; i<mem_list_count; i++) {       
 586                 if(i) {
 587                     if (i == (mem_list_count - 1)) {
 588                         if (flat_buf->blocklens[k] == end_brd_size)
 589                             brd_size = flat_buf->blocklens[(k+1)%
 590                                                           flat_buf->count];
 591                         else {
 592                             brd_size = flat_buf->blocklens[k] - end_brd_size;
 593                             k--;
 594                             buf_count--;
 595                         }
 596                     }
 597                 }
 598                 buf_count++;
 599                 k = (k + 1)%flat_buf->count;
 600             } /* for (i=0; i<mem_list_count; i++) */
 601             for (i=0; i<file_list_count; i++) {
 602                 if (i) {
 603                     if (i == (file_list_count - 1)) {
 604                         if (flat_file->blocklens[j] == end_frd_size)
 605                             frd_size = flat_file->blocklens[(j+1)%
 606                                                           flat_file->count];   
 607                         else {
 608                             frd_size = flat_file->blocklens[j] - end_frd_size;
 609                             j--;
 610                         }
 611                     }
 612                 }
 613                 if (j < flat_file->count - 1) j++;
 614                 else {
 615                     j = 0;
 616                     n_filetypes++;
 617                 }
 618             } /* for (i=0; i<file_list_count; i++) */
 619             size_read += new_buffer_read;
 620             start_k = k;
 621             start_j = j;
 622             if (max_mem_list < mem_list_count)
 623                 max_mem_list = mem_list_count;
 624             if (max_file_list < file_list_count)
 625                 max_file_list = file_list_count;
 626         } /* while (size_read < bufsize) */
 627 
 628         /* one last check before we actually carry out the operation:
 629          * this code has hard-to-fix bugs when a noncontiguous file type has
 630          * such large pieces that the sum of the lengths of the memory type is
 631          * not larger than one of those pieces (and vice versa for large memory
 632          * types and many pices of file types.  In these cases, give up and
 633          * fall back to naive reads and writes.  The testphdf5 test created a
 634          * type with two very large memory regions and 600 very small file
 635          * regions.  The same test also created a type with one very large file
 636          * region and many (700) very small memory regions.  both cases caused
 637          * problems for this code */
 638 
 639         if ( ( (file_list_count == 1) && 
 640                     (new_file_read < flat_file->blocklens[0] ) ) ||
 641                 ((mem_list_count == 1) && 
 642                     (new_buffer_read < flat_buf->blocklens[0]) ) ||
 643                 ((file_list_count == MAX_ARRAY_SIZE) && 
 644                     (new_file_read < flat_buf->blocklens[0]) ) ||
 645                 ( (mem_list_count == MAX_ARRAY_SIZE) &&
 646                     (new_buffer_read < flat_file->blocklens[0])) )
 647         {
 648 
 649             ADIOI_Delete_flattened(datatype);
 650             ADIOI_GEN_ReadStrided_naive(fd, buf, count, datatype,
 651                     file_ptr_type, initial_off, status, error_code);
 652             return;
 653         }
 654 
 655         mem_offsets = (PVFS_size*)ADIOI_Malloc(max_mem_list*sizeof(PVFS_size));
 656         mem_lengths = (int *)ADIOI_Malloc(max_mem_list*sizeof(int));
 657         file_offsets = (int64_t *)ADIOI_Malloc(max_file_list*sizeof(int64_t));
 658         file_lengths = (int32_t *)ADIOI_Malloc(max_file_list*sizeof(int32_t));
 659             
 660         size_read = 0;
 661         n_filetypes = st_n_filetypes;
 662         frd_size = st_frd_size;
 663         brd_size = flat_buf->blocklens[0];
 664         buf_count = 0;
 665         start_mem_offset = 0;
 666         start_k = k = 0;
 667         start_j = st_index;
 668 
 669         /*  this section calculates mem_list_count and file_list_count
 670             and also finds the possibly odd sized last array elements
 671             in new_frd_size and new_brd_size  */
 672         
 673         while (size_read < bufsize) {
 674             k = start_k;
 675             new_buffer_read = 0;
 676             mem_list_count = 0;
 677             while ((mem_list_count < MAX_ARRAY_SIZE) && 
 678                    (new_buffer_read < bufsize-size_read)) {
 679                 /* find mem_list_count and file_list_count such that both are
 680                    less than MAX_ARRAY_SIZE, the sum of their lengths are
 681                    equal, and the sum of all the data read and data to be
 682                    read in the next immediate read list is less than
 683                    bufsize */
 684                 if(mem_list_count) {
 685                     if((new_buffer_read + flat_buf->blocklens[k] + 
 686                         size_read) > bufsize) {
 687                         end_brd_size = new_buffer_read + 
 688                             flat_buf->blocklens[k] - (bufsize - size_read);
 689                         new_buffer_read = bufsize - size_read;
 690                     }
 691                     else {
 692                         new_buffer_read += flat_buf->blocklens[k];
 693                         end_brd_size = flat_buf->blocklens[k];
 694                     }
 695                 }
 696                 else {
 697                     if (brd_size > (bufsize - size_read)) {
 698                         new_buffer_read = bufsize - size_read;
 699                         brd_size = new_buffer_read;
 700                     }
 701                     else new_buffer_read = brd_size;
 702                 }
 703                 mem_list_count++;
 704                 k = (k + 1)%flat_buf->count;
 705              } /* while ((mem_list_count < MAX_ARRAY_SIZE) && 
 706                (new_buffer_read < bufsize-size_read)) */
 707             j = start_j;
 708             new_file_read = 0;
 709             file_list_count = 0;
 710             while ((file_list_count < MAX_ARRAY_SIZE) && 
 711                    (new_file_read < new_buffer_read)) {
 712                 if(file_list_count) {
 713                     if((new_file_read + flat_file->blocklens[j]) > 
 714                        new_buffer_read) {
 715                         end_frd_size = new_buffer_read - new_file_read;
 716                         new_file_read = new_buffer_read;
 717                         j--;
 718                     }
 719                     else {
 720                         new_file_read += flat_file->blocklens[j];
 721                         end_frd_size = flat_file->blocklens[j];
 722                     }
 723                 }
 724                 else {
 725                     if (frd_size > new_buffer_read) {
 726                         new_file_read = new_buffer_read;
 727                         frd_size = new_file_read;
 728                     }
 729                     else new_file_read = frd_size;
 730                 }
 731                 file_list_count++;
 732                 if (j < (flat_file->count - 1)) j++;
 733                 else j = 0;
 734                 
 735                 k = start_k;
 736                 if ((new_file_read < new_buffer_read) && 
 737                     (file_list_count == MAX_ARRAY_SIZE)) {
 738                     new_buffer_read = 0;
 739                     mem_list_count = 0;
 740                     while (new_buffer_read < new_file_read) {
 741                         if(mem_list_count) {
 742                             if((new_buffer_read + flat_buf->blocklens[k]) >
 743                                new_file_read) {
 744                                 end_brd_size = new_file_read - new_buffer_read;
 745                                 new_buffer_read = new_file_read;
 746                                 k--;
 747                             }
 748                             else {
 749                                 new_buffer_read += flat_buf->blocklens[k];
 750                                 end_brd_size = flat_buf->blocklens[k];
 751                             }
 752                         }
 753                         else {
 754                             new_buffer_read = brd_size;
 755                             if (brd_size > (bufsize - size_read)) {
 756                                 new_buffer_read = bufsize - size_read;
 757                                 brd_size = new_buffer_read;
 758                             }
 759                         }
 760                         mem_list_count++;
 761                         k = (k + 1)%flat_buf->count;
 762                     } /* while (new_buffer_read < new_file_read) */
 763                 } /* if ((new_file_read < new_buffer_read) && (file_list_count
 764                      == MAX_ARRAY_SIZE)) */
 765             } /* while ((mem_list_count < MAX_ARRAY_SIZE) && 
 766                  (new_buffer_read < bufsize-size_read)) */
 767 
 768             /*  fills the allocated readlist arrays  */
 769             k = start_k;
 770             j = start_j;
 771             for (i=0; i<mem_list_count; i++) {       
 772                 mem_offsets[i] = ((PVFS_size)buf + buftype_extent*
 773                                          (buf_count/flat_buf->count) +
 774                                          (int)flat_buf->indices[k]);
 775                 if(!i) {
 776                     mem_lengths[0] = brd_size;
 777                     mem_offsets[0] += flat_buf->blocklens[k] - brd_size;
 778                 }
 779                 else {
 780                     if (i == (mem_list_count - 1)) {
 781                         mem_lengths[i] = end_brd_size;
 782                         if (flat_buf->blocklens[k] == end_brd_size)
 783                             brd_size = flat_buf->blocklens[(k+1)%
 784                                                           flat_buf->count];
 785                         else {
 786                             brd_size = flat_buf->blocklens[k] - end_brd_size;
 787                             k--;
 788                             buf_count--;
 789                         }
 790                     }
 791                     else {
 792                         mem_lengths[i] = flat_buf->blocklens[k];
 793                     }
 794                 }
 795                 buf_count++;
 796                 k = (k + 1)%flat_buf->count;
 797             } /* for (i=0; i<mem_list_count; i++) */
 798             for (i=0; i<file_list_count; i++) {
 799                 file_offsets[i] = disp + flat_file->indices[j] + 
 800                     ((ADIO_Offset)n_filetypes) * filetype_extent;
 801                 if (!i) {
 802                     file_lengths[0] = frd_size;
 803                     file_offsets[0] += flat_file->blocklens[j] - frd_size;
 804                 }
 805                 else {
 806                     if (i == (file_list_count - 1)) {
 807                         file_lengths[i] = end_frd_size;
 808                         if (flat_file->blocklens[j] == end_frd_size)
 809                             frd_size = flat_file->blocklens[(j+1)%
 810                                                           flat_file->count];   
 811                         else {
 812                             frd_size = flat_file->blocklens[j] - end_frd_size;
 813                             j--;
 814                         }
 815                     }
 816                     else file_lengths[i] = flat_file->blocklens[j];
 817                 }
 818                 if (j < flat_file->count - 1) j++;
 819                 else {
 820                     j = 0;
 821                     n_filetypes++;
 822                 }
 823             } /* for (i=0; i<file_list_count; i++) */
 824             err_flag = PVFS_Request_hindexed(mem_list_count, mem_lengths, 
 825                     mem_offsets, PVFS_BYTE, &mem_req);
 826             /* --BEGIN ERROR HANDLING-- */
 827             if (err_flag != 0 ) {
 828                 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
 829                                                    MPIR_ERR_RECOVERABLE,
 830                                                    myname, __LINE__,
 831                                                    ADIOI_PVFS2_error_convert(err_flag),
 832                                                    "Error in PVFS_Request_hindexed (memory)", 0);
 833                 goto error_state;
 834             }
 835             /* -- END ERROR HANDLING-- */
 836             err_flag = PVFS_Request_hindexed(file_list_count, file_lengths, 
 837                     file_offsets, PVFS_BYTE, &file_req);
 838             /* --BEGIN ERROR HANDLING-- */
 839             if (err_flag != 0) {
 840                 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
 841                                                    MPIR_ERR_RECOVERABLE,
 842                                                    myname, __LINE__,
 843                                                    ADIOI_PVFS2_error_convert(err_flag),
 844                                                    "Error in PVFS_Request_hindexed (file)", 0);
 845                 goto error_state;
 846             }
 847             /* --END ERROR HANDLING-- */
 848 
 849             /* offset will be expressed in memory and file datatypes */
 850 #ifdef ADIOI_MPE_LOGGING
 851             MPE_Log_event( ADIOI_MPE_read_a, 0, NULL );
 852 #endif
 853             err_flag = PVFS_sys_read(pvfs_fs->object_ref, file_req, 0, 
 854                     PVFS_BOTTOM, mem_req, &(pvfs_fs->credentials), &resp_io);
 855 #ifdef ADIOI_MPE_LOGGING
 856             MPE_Log_event( ADIOI_MPE_read_b, 0, NULL );
 857 #endif
 858             /* --BEGIN ERROR HANDLING-- */
 859             if (err_flag != 0) {
 860                 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
 861                                                    MPIR_ERR_RECOVERABLE,
 862                                                    myname, __LINE__,
 863                                                    ADIOI_PVFS2_error_convert(err_flag),
 864                                                    "Error in PVFS_sys_read", 0);
 865             }
 866             /* --END ERROR HANDLING-- */
 867             PVFS_Request_free(&mem_req);
 868             PVFS_Request_free(&file_req);
 869             total_bytes_read += resp_io.total_completed;
 870             size_read += new_buffer_read;
 871             start_k = k;
 872             start_j = j;
 873         } /* while (size_read < bufsize) */
 874         ADIOI_Free(mem_offsets);
 875         ADIOI_Free(mem_lengths);
 876     }
 877     /* Other ADIO routines will convert absolute bytes into counts of datatypes */
 878     /* when incrementing fp_ind, need to also take into account the file type:
 879      * consider an N-element 1-d subarray with a lb and ub: ( |---xxxxx-----|
 880      * if we wrote N elements, offset needs to point at beginning of type, not
 881      * at empty region at offset N+1) 
 882      *
 883      * As we discussed on mpich-discuss in may/june 2009, the code below might
 884      * look wierd, but by putting fp_ind at the last byte written, the next
 885      * time we run through the strided code we'll update the fp_ind to the
 886      * right location. */
 887     if (file_ptr_type == ADIO_INDIVIDUAL) {
 888         fd->fp_ind = file_offsets[file_list_count-1]+
 889             file_lengths[file_list_count-1];
 890     }
 891     
 892     ADIOI_Free(file_offsets);
 893     ADIOI_Free(file_lengths);
 894     
 895     if (err_flag == 0) *error_code = MPI_SUCCESS;
 896 
 897 error_state:
 898     fd->fp_sys_posn = -1;   /* set it to null. */
 899 
 900 #ifdef HAVE_STATUS_SET_BYTES
 901     MPIR_Status_set_bytes(status, datatype, bufsize);
 902     /* This is a temporary way of filling in status. The right way is to 
 903        keep track of how much data was actually read and placed in buf 
 904        by ADIOI_BUFFERED_READ. */
 905 #endif
 906     
 907     if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
 908 }
 909 

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