00001 
00002 
00003 
00009 
00010 
00011 
00012 
00013 
00014 
00015 #include "ad_bgl.h"
00016 #include "adio_extern.h"
00017 
00018 #include "ad_bgl_tuning.h"
00019 
00020 void ADIOI_BGL_ReadContig(ADIO_File fd, void *buf, int count, 
00021                      MPI_Datatype datatype, int file_ptr_type,
00022              ADIO_Offset offset, ADIO_Status *status, int *error_code)
00023 {
00024     int err=-1, datatype_size;
00025     ADIO_Offset len;
00026     static char myname[] = "ADIOI_BGL_READCONTIG";
00027 #if BGL_PROFILE
00028         
00029         double io_time, io_time2;
00030 
00031         if (bglmpio_timing) {
00032             io_time = MPI_Wtime();
00033             bglmpio_prof_cr[ BGLMPIO_CIO_DATA_SIZE ] += len;
00034         }
00035 #endif
00036 
00037     MPI_Type_size(datatype, &datatype_size);
00038     len = (ADIO_Offset)datatype_size * (ADIO_Offset)count;
00039     ADIOI_Assert(len == (unsigned int) len); 
00040 
00041 #if BGL_PROFILE
00042 
00043     if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00044             if (bglmpio_timing2) io_time2 = MPI_Wtime();
00045     if (fd->fp_sys_posn != offset)
00046         lseek(fd->fd_sys, offset, SEEK_SET);
00047             if (bglmpio_timing2) bglmpio_prof_cr[ BGLMPIO_CIO_T_SEEK ] += (MPI_Wtime() - io_time2);
00048     if (fd->atomicity)
00049         ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00050     else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
00051             if (bglmpio_timing2) io_time2 = MPI_Wtime();
00052     err = read(fd->fd_sys, buf, (unsigned int)len);
00053             if (bglmpio_timing2) bglmpio_prof_cr[ BGLMPIO_CIO_T_POSI_RW ] += (MPI_Wtime() - io_time2);
00054     ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00055     fd->fp_sys_posn = offset + err;
00056             
00057     }
00058     else {  
00059     offset = fd->fp_ind;
00060             if (bglmpio_timing2) io_time2 = MPI_Wtime();
00061     if (fd->fp_sys_posn != fd->fp_ind)
00062         lseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
00063             if (bglmpio_timing2) bglmpio_prof_cr[ BGLMPIO_CIO_T_SEEK ] += (MPI_Wtime() - io_time2);
00064     if (fd->atomicity)
00065         ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00066     else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
00067             if (bglmpio_timing2) io_time2 = MPI_Wtime();
00068     err = read(fd->fd_sys, buf, (unsigned int)len);
00069             if (bglmpio_timing2) bglmpio_prof_cr[ BGLMPIO_CIO_T_POSI_RW ] += (MPI_Wtime() - io_time2);
00070     ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00071     fd->fp_ind += err;
00072     fd->fp_sys_posn = fd->fp_ind;
00073     }
00074 
00075 #else   
00076 
00077     if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00078     if (fd->fp_sys_posn != offset)
00079         lseek(fd->fd_sys, offset, SEEK_SET);
00080     if (fd->atomicity)
00081         ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00082     else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
00083     err = read(fd->fd_sys, buf, (unsigned int)len);
00084     ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00085     fd->fp_sys_posn = offset + err;
00086             
00087     }
00088     else {  
00089     offset = fd->fp_ind;
00090     if (fd->fp_sys_posn != fd->fp_ind)
00091         lseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
00092     if (fd->atomicity)
00093         ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
00094     else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
00095     err = read(fd->fd_sys, buf, (unsigned int)len);
00096     ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
00097     fd->fp_ind += err;
00098     fd->fp_sys_posn = fd->fp_ind;
00099     }
00100 
00101 #endif   
00102 
00103 #if BGL_PROFILE
00104             if (bglmpio_timing) bglmpio_prof_cr[ BGLMPIO_CIO_T_MPIO_RW ] += (MPI_Wtime() - io_time);
00105 #endif
00106 
00107     
00108     if (err == -1) {
00109     *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
00110                        myname, __LINE__, MPI_ERR_IO,
00111                        "**io", "**io %s", strerror(errno));
00112     return;
00113     }
00114     
00115 
00116 #ifdef HAVE_STATUS_SET_BYTES
00117     MPIR_Status_set_bytes(status, datatype, err);
00118 #endif
00119 
00120     *error_code = MPI_SUCCESS;
00121 }
00122 
00123 
00124 #define ADIOI_BUFFERED_READ \
00125 { \
00126     if (req_off >= readbuf_off + readbuf_len) { \
00127     readbuf_off = req_off; \
00128     readbuf_len = (unsigned) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));\
00129     lseek(fd->fd_sys, readbuf_off, SEEK_SET);\
00130         if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off, SEEK_SET, readbuf_len);\
00131         err = read(fd->fd_sys, readbuf, readbuf_len);\
00132         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off, SEEK_SET, readbuf_len);\
00133         if (err == -1) err_flag = 1; \
00134     } \
00135     while (req_len > readbuf_off + readbuf_len - req_off) { \
00136   ADIOI_Assert((readbuf_off + readbuf_len - req_off) == (int) (readbuf_off + readbuf_len - req_off));\
00137     partial_read = (int) (readbuf_off + readbuf_len - req_off); \
00138     tmp_buf = (char *) ADIOI_Malloc(partial_read); \
00139     memcpy(tmp_buf, readbuf+readbuf_len-partial_read, partial_read); \
00140     ADIOI_Free(readbuf); \
00141     readbuf = (char *) ADIOI_Malloc(partial_read + max_bufsize); \
00142     memcpy(readbuf, tmp_buf, partial_read); \
00143     ADIOI_Free(tmp_buf); \
00144     readbuf_off += readbuf_len-partial_read; \
00145     readbuf_len = (unsigned) (partial_read + ADIOI_MIN(max_bufsize, \
00146                        end_offset-readbuf_off+1)); \
00147     lseek(fd->fd_sys, readbuf_off+partial_read, SEEK_SET);\
00148         if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off+partial_read, SEEK_SET, readbuf_len-partial_read);\
00149         err = read(fd->fd_sys, readbuf+partial_read, readbuf_len-partial_read);\
00150         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off+partial_read, SEEK_SET, readbuf_len-partial_read);\
00151         if (err == -1) err_flag = 1; \
00152     } \
00153     ADIOI_Assert(req_len == (size_t)req_len); \
00154     memcpy((char *)buf + userbuf_off, readbuf+req_off-readbuf_off, req_len); \
00155 }
00156 
00157 
00158 void ADIOI_BGL_ReadStrided(ADIO_File fd, void *buf, int count,
00159                        MPI_Datatype datatype, int file_ptr_type,
00160                        ADIO_Offset offset, ADIO_Status *status, int
00161                        *error_code)
00162 {
00163 
00164 
00165 
00166     ADIOI_Flatlist_node *flat_buf, *flat_file;
00167     ADIO_Offset i_offset, new_brd_size, brd_size, size;
00168     int i, j, k, err=-1, st_index=0;
00169     ADIO_Offset frd_size=0, new_frd_size, st_frd_size;
00170     unsigned num, bufsize; 
00171     int n_etypes_in_filetype;
00172     ADIO_Offset n_filetypes, etype_in_filetype, st_n_filetypes, size_in_filetype;
00173     ADIO_Offset abs_off_in_filetype=0;
00174     int filetype_size, etype_size, buftype_size, partial_read;
00175     MPI_Aint filetype_extent, buftype_extent; 
00176     int buf_count, buftype_is_contig, filetype_is_contig;
00177     ADIO_Offset userbuf_off, req_len, sum;
00178     ADIO_Offset off, req_off, disp, end_offset=0, readbuf_off, start_off;
00179     char *readbuf, *tmp_buf, *value;
00180     int err_flag=0, info_flag;
00181     unsigned max_bufsize, readbuf_len;
00182     static char myname[] = "ADIOI_BGL_READSTRIDED";
00183 
00184     if (fd->hints->ds_read == ADIOI_HINT_DISABLE) {
00185   
00186 
00187 
00188       
00189       ADIOI_GEN_ReadStrided_naive(fd, 
00190                     buf,
00191                     count,
00192                     datatype,
00193                     file_ptr_type,
00194                     offset,
00195                     status,
00196                     error_code);
00197         return;
00198     }
00199     
00200 
00201     ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
00202     ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00203 
00204     MPI_Type_size(fd->filetype, &filetype_size);
00205     if ( ! filetype_size ) {
00206     *error_code = MPI_SUCCESS; 
00207     return;
00208     }
00209 
00210     MPI_Type_extent(fd->filetype, &filetype_extent);
00211     MPI_Type_size(datatype, &buftype_size);
00212     MPI_Type_extent(datatype, &buftype_extent);
00213     etype_size = fd->etype_size;
00214 
00215     ADIOI_Assert((buftype_size * count) == ((ADIO_Offset)(unsigned)buftype_size * (ADIO_Offset)count));
00216     bufsize = buftype_size * count;
00217 
00218 
00219 
00220     value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
00221     ADIOI_Info_get(fd->info, "ind_rd_buffer_size", MPI_MAX_INFO_VAL, value, 
00222                  &info_flag);
00223     max_bufsize = atoi(value);
00224     ADIOI_Free(value);
00225 
00226     if (!buftype_is_contig && filetype_is_contig) {
00227 
00228 
00229 
00230     ADIOI_Flatten_datatype(datatype);
00231     flat_buf = ADIOI_Flatlist;
00232     while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00233 
00234         off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind : 
00235                  fd->disp + (ADIO_Offset)etype_size * offset;
00236 
00237     start_off = off;
00238     end_offset = off + bufsize - 1;
00239         readbuf_off = off;
00240         readbuf = (char *) ADIOI_Malloc(max_bufsize);
00241         readbuf_len = (unsigned) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));
00242 
00243 
00244         if (fd->atomicity)
00245             ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00246 
00247     lseek(fd->fd_sys, readbuf_off, SEEK_SET);
00248         if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off, SEEK_SET, readbuf_len);
00249         err = read(fd->fd_sys, readbuf, readbuf_len);
00250         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off, SEEK_SET, readbuf_len);
00251         if (err == -1) err_flag = 1;
00252 
00253         for (j=0; j<count; j++) 
00254         {
00255           int i;
00256               for (i=0; i<flat_buf->count; i++) {
00257                   userbuf_off = (ADIO_Offset)j*(ADIO_Offset)buftype_extent + flat_buf->indices[i];
00258       req_off = off;
00259       req_len = flat_buf->blocklens[i];
00260       ADIOI_BUFFERED_READ
00261                   off += flat_buf->blocklens[i];
00262               }
00263         }
00264 
00265         if (fd->atomicity)
00266             ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00267 
00268         if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00269 
00270     ADIOI_Free(readbuf); 
00271 
00272     if (err_flag) {
00273         *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00274                            MPIR_ERR_RECOVERABLE, myname,
00275                            __LINE__, MPI_ERR_IO, "**io",
00276                            "**io %s", strerror(errno));
00277     }
00278     else *error_code = MPI_SUCCESS;
00279     }
00280 
00281     else {  
00282 
00283 
00284     flat_file = ADIOI_Flatlist;
00285     while (flat_file->type != fd->filetype) flat_file = flat_file->next;
00286     disp = fd->disp;
00287 
00288     if (file_ptr_type == ADIO_INDIVIDUAL) {
00289         
00290             offset       = fd->fp_ind - disp;
00291             n_filetypes  = (offset - flat_file->indices[0]) / filetype_extent;
00292         offset -= (ADIO_Offset)n_filetypes * filetype_extent;
00293         
00294 
00295             
00296             for (i=0; i<flat_file->count; i++) {
00297                 ADIO_Offset dist;
00298                 if (flat_file->blocklens[i] == 0) continue;
00299                 dist = flat_file->indices[i] + flat_file->blocklens[i] - offset;
00300                 
00301         if (dist == 0) {
00302             i++;
00303             offset   = flat_file->indices[i];
00304             frd_size = flat_file->blocklens[i];
00305             break;
00306         }
00307         if (dist > 0) {
00308                     frd_size = dist;
00309             break;
00310         }
00311         }
00312             st_index = i;  
00313             offset += disp + (ADIO_Offset)n_filetypes*filetype_extent;
00314     }
00315     else {
00316         n_etypes_in_filetype = filetype_size/etype_size;
00317         n_filetypes = offset / n_etypes_in_filetype;
00318         etype_in_filetype = offset % n_etypes_in_filetype;
00319         size_in_filetype = etype_in_filetype * etype_size;
00320  
00321         sum = 0;
00322         for (i=0; i<flat_file->count; i++) {
00323         sum += flat_file->blocklens[i];
00324         if (sum > size_in_filetype) {
00325             st_index = i;
00326             frd_size = sum - size_in_filetype;
00327             abs_off_in_filetype = flat_file->indices[i] +
00328             size_in_filetype - (sum - flat_file->blocklens[i]);
00329             break;
00330         }
00331         }
00332 
00333         
00334         offset = disp + (ADIO_Offset) n_filetypes*filetype_extent + 
00335             abs_off_in_filetype;
00336     }
00337 
00338         start_off = offset;
00339 
00340     
00341 
00342 
00343     if (buftype_is_contig && bufsize <= frd_size) {
00344             ADIO_ReadContig(fd, buf, bufsize, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
00345                              offset, status, error_code);
00346 
00347         if (file_ptr_type == ADIO_INDIVIDUAL) {
00348                 
00349 
00350         fd->fp_ind = offset + bufsize;
00351         if (bufsize == frd_size) {
00352             do {
00353             st_index++;
00354             if (st_index == flat_file->count) {
00355                 st_index = 0;
00356                 n_filetypes++;
00357             }
00358                     } while (flat_file->blocklens[st_index] == 0);
00359             fd->fp_ind = disp + flat_file->indices[st_index]
00360                                + n_filetypes*filetype_extent;
00361         }
00362         }
00363         fd->fp_sys_posn = -1;    
00364 #ifdef HAVE_STATUS_SET_BYTES
00365         MPIR_Status_set_bytes(status, datatype, bufsize);
00366 #endif 
00367             return;
00368     }
00369 
00370        
00371 
00372 
00373     st_frd_size = frd_size;
00374     st_n_filetypes = n_filetypes;
00375     i_offset = 0;
00376     j = st_index;
00377     off = offset;
00378     frd_size = ADIOI_MIN(st_frd_size, bufsize);
00379     while (i_offset < bufsize) {
00380         i_offset += frd_size;
00381         end_offset = off + frd_size - 1;
00382 
00383         j = (j+1) % flat_file->count;
00384             n_filetypes += (j == 0) ? 1 : 0;
00385             while (flat_file->blocklens[j]==0) {
00386         j = (j+1) % flat_file->count;
00387         n_filetypes += (j == 0) ? 1 : 0;
00388         }
00389         off = disp + flat_file->indices[j] + n_filetypes*(ADIO_Offset)filetype_extent;
00390         frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i_offset);
00391     }
00392 
00393 
00394         if (fd->atomicity)
00395             ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00396 
00397         
00398     readbuf_off = offset;
00399     readbuf = (char *) ADIOI_Malloc(max_bufsize);
00400     readbuf_len = (unsigned) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));
00401 
00402     lseek(fd->fd_sys, offset, SEEK_SET);
00403         if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, offset, SEEK_SET, readbuf_len);
00404         err = read(fd->fd_sys, readbuf, readbuf_len);
00405         if (!(fd->atomicity)) ADIOI_UNLOCK(fd, offset, SEEK_SET, readbuf_len);
00406 
00407         if (err == -1) err_flag = 1;
00408 
00409     if (buftype_is_contig && !filetype_is_contig) {
00410 
00411 
00412 
00413 
00414         i_offset = 0;
00415         j = st_index;
00416         off = offset;
00417         n_filetypes = st_n_filetypes;
00418         frd_size = ADIOI_MIN(st_frd_size, bufsize);
00419         while (i_offset < bufsize) {
00420                 if (frd_size) { 
00421                     
00422  
00423             
00424 
00425 
00426             req_off = off;
00427             req_len = frd_size;
00428             userbuf_off = i_offset;
00429             ADIOI_BUFFERED_READ
00430         }
00431         i_offset += frd_size;
00432 
00433                 if (off + frd_size < disp + flat_file->indices[j] +
00434                    flat_file->blocklens[j] + n_filetypes*(ADIO_Offset)filetype_extent)
00435                        off += frd_size;
00436                 
00437 
00438                 else {
00439                     j = (j+1) % flat_file->count;
00440                     n_filetypes += (j == 0) ? 1 : 0;
00441                     while (flat_file->blocklens[j]==0) {
00442                         j = (j+1) % flat_file->count;
00443                         n_filetypes += (j == 0) ? 1 : 0;
00444             }
00445             off = disp + flat_file->indices[j] + 
00446                                         n_filetypes*(ADIO_Offset)filetype_extent;
00447             frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i_offset);
00448         }
00449         }
00450     }
00451     else {
00452 
00453 
00454         ADIOI_Flatten_datatype(datatype);
00455         flat_buf = ADIOI_Flatlist;
00456         while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00457 
00458         k = num = buf_count = 0;
00459         i_offset = flat_buf->indices[0];
00460         j = st_index;
00461         off = offset;
00462         n_filetypes = st_n_filetypes;
00463         frd_size = st_frd_size;
00464         brd_size = flat_buf->blocklens[0];
00465 
00466         while (num < bufsize) {
00467         size = ADIOI_MIN(frd_size, brd_size);
00468         if (size) {
00469             
00470 
00471 
00472             req_off = off;
00473             req_len = size;
00474             userbuf_off = i_offset;
00475             ADIOI_BUFFERED_READ
00476         }
00477 
00478         new_frd_size = frd_size;
00479         new_brd_size = brd_size;
00480 
00481         if (size == frd_size) {
00482 
00483                     j = (j+1) % flat_file->count;
00484                     n_filetypes += (j == 0) ? 1 : 0;
00485                     while (flat_file->blocklens[j]==0) {
00486                         j = (j+1) % flat_file->count;
00487                         n_filetypes += (j == 0) ? 1 : 0;
00488             }
00489 
00490             off = disp + flat_file->indices[j] + 
00491                                               n_filetypes*(ADIO_Offset)filetype_extent;
00492 
00493             new_frd_size = flat_file->blocklens[j];
00494             if (size != brd_size) {
00495             i_offset += size;
00496             new_brd_size -= size;
00497             }
00498         }
00499 
00500         if (size == brd_size) {
00501 
00502 
00503             k = (k + 1)%flat_buf->count;
00504             buf_count++;
00505             i_offset = ((ADIO_Offset)buftype_extent*(ADIO_Offset)(buf_count/flat_buf->count) +
00506             flat_buf->indices[k]); 
00507             new_brd_size = flat_buf->blocklens[k];
00508             if (size != frd_size) {
00509             off += size;
00510             new_frd_size -= size;
00511             }
00512         }
00513     ADIOI_Assert(((ADIO_Offset)num + size) == (unsigned)(num + size));
00514         num += size;
00515         frd_size = new_frd_size;
00516                 brd_size = new_brd_size;
00517         }
00518     }
00519     
00520         if (fd->atomicity)
00521             ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00522 
00523     if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00524 
00525     ADIOI_Free(readbuf); 
00526 
00527     if (err_flag) {
00528         *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00529                            MPIR_ERR_RECOVERABLE, myname,
00530                            __LINE__, MPI_ERR_IO, "**io",
00531                            "**io %s", strerror(errno));
00532     }
00533     else *error_code = MPI_SUCCESS;
00534     }
00535 
00536     fd->fp_sys_posn = -1;   
00537 
00538 #ifdef HAVE_STATUS_SET_BYTES
00539     MPIR_Status_set_bytes(status, datatype, bufsize);
00540 
00541 
00542 
00543 #endif
00544 
00545     if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
00546 }