00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include "ad_pvfs.h"
00009 #include "adio_extern.h"
00010 
00011 #ifdef HAVE_PVFS_LISTIO
00012 void ADIOI_PVFS_WriteStridedListIO(ADIO_File fd, void *buf, int count,
00013                        MPI_Datatype datatype, int file_ptr_type,
00014                        ADIO_Offset offset, ADIO_Status *status, int
00015                        *error_code);
00016 #endif
00017 
00018 void ADIOI_PVFS_WriteContig(ADIO_File fd, void *buf, int count, 
00019                 MPI_Datatype datatype, int file_ptr_type,
00020                 ADIO_Offset offset, ADIO_Status *status,
00021                 int *error_code)
00022 {
00023     int err=-1, datatype_size, len;
00024     static char myname[] = "ADIOI_PVFS_WRITECONTIG";
00025 
00026     MPI_Type_size(datatype, &datatype_size);
00027     len = datatype_size * count;
00028 
00029     if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00030     if (fd->fp_sys_posn != offset) {
00031 #ifdef ADIOI_MPE_LOGGING
00032             MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00033 #endif
00034         pvfs_lseek64(fd->fd_sys, offset, SEEK_SET);
00035 #ifdef ADIOI_MPE_LOGGING
00036             MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00037 #endif
00038         }
00039 #ifdef ADIOI_MPE_LOGGING
00040         MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00041 #endif
00042     err = pvfs_write(fd->fd_sys, buf, len);
00043 #ifdef ADIOI_MPE_LOGGING
00044         MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00045 #endif
00046     if (err > 0)
00047         fd->fp_sys_posn = offset + err;
00048             
00049     }
00050     else { 
00051     if (fd->fp_sys_posn != fd->fp_ind) {
00052 #ifdef ADIOI_MPE_LOGGING
00053             MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00054 #endif
00055         pvfs_lseek64(fd->fd_sys, fd->fp_ind, SEEK_SET);
00056 #ifdef ADIOI_MPE_LOGGING
00057             MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00058 #endif
00059         }
00060 #ifdef ADIOI_MPE_LOGGING
00061         MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00062 #endif
00063     err = pvfs_write(fd->fd_sys, buf, len);
00064 #ifdef ADIOI_MPE_LOGGING
00065         MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00066 #endif
00067     if (err > 0)
00068         fd->fp_ind += err;
00069     fd->fp_sys_posn = fd->fp_ind;
00070     }
00071 
00072 #ifdef HAVE_STATUS_SET_BYTES
00073     if (err != -1) MPIR_Status_set_bytes(status, datatype, err);
00074 #endif
00075 
00076     if (err == -1) {
00077     *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
00078                        myname, __LINE__, MPI_ERR_IO,
00079                        "**io",
00080                        "**io %s", strerror(errno));
00081     }
00082     else *error_code = MPI_SUCCESS;
00083 }
00084 
00085 
00086 
00087 void ADIOI_PVFS_WriteStrided(ADIO_File fd, void *buf, int count,
00088                  MPI_Datatype datatype, int file_ptr_type,
00089                  ADIO_Offset offset, ADIO_Status *status, int
00090                  *error_code)
00091 {
00092 
00093 
00094 
00095 
00096 
00097     ADIOI_Flatlist_node *flat_buf, *flat_file;
00098     int i, j, k, err=-1, bwr_size, fwr_size=0, st_index=0;
00099     int bufsize, num, size, sum, n_etypes_in_filetype, size_in_filetype;
00100     int n_filetypes, etype_in_filetype;
00101     ADIO_Offset abs_off_in_filetype=0;
00102     int filetype_size, etype_size, buftype_size;
00103     MPI_Aint filetype_extent, buftype_extent, indx;
00104     int buf_count, buftype_is_contig, filetype_is_contig;
00105     ADIO_Offset off, disp;
00106     int flag, new_bwr_size, new_fwr_size, err_flag=0;
00107     static char myname[] = "ADIOI_PVFS_WRITESTRIDED";
00108 
00109 #ifdef HAVE_PVFS_LISTIO
00110     if ( fd->hints->fs_hints.pvfs.listio_write == ADIOI_HINT_ENABLE ) {
00111         ADIOI_PVFS_WriteStridedListIO(fd, buf, count, datatype, 
00112                 file_ptr_type, offset, status, error_code);
00113         return;
00114     }
00115 #endif
00116     
00117 
00118     
00119     if (fd->atomicity) {
00120     *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
00121                        myname, __LINE__,
00122                        MPI_ERR_INTERN,
00123                        "Atomic mode set in PVFS I/O function", 0);
00124     return;
00125     }
00126     
00127 
00128     ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
00129     ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00130 
00131     MPI_Type_size(fd->filetype, &filetype_size);
00132     if ( ! filetype_size ) {
00133     *error_code = MPI_SUCCESS; 
00134     return;
00135     }
00136 
00137     MPI_Type_extent(fd->filetype, &filetype_extent);
00138     MPI_Type_size(datatype, &buftype_size);
00139     MPI_Type_extent(datatype, &buftype_extent);
00140     etype_size = fd->etype_size;
00141     
00142     bufsize = buftype_size * count;
00143 
00144     if (!buftype_is_contig && filetype_is_contig) {
00145     char *combine_buf, *combine_buf_ptr;
00146     ADIO_Offset combine_buf_remain;
00147 
00148 
00149     ADIOI_Flatten_datatype(datatype);
00150     flat_buf = ADIOI_Flatlist;
00151     while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00152 
00153     
00154     combine_buf = (char *) ADIOI_Malloc(fd->hints->ind_wr_buffer_size);
00155     combine_buf_ptr = combine_buf;
00156     combine_buf_remain = fd->hints->ind_wr_buffer_size;
00157 
00158     
00159     if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00160         off = fd->disp + etype_size * offset;
00161 #ifdef ADIOI_MPE_LOGGING
00162             MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00163 #endif
00164         pvfs_lseek64(fd->fd_sys, off, SEEK_SET);
00165 #ifdef ADIOI_MPE_LOGGING
00166             MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00167 #endif
00168     }
00169     else {
00170 #ifdef ADIOI_MPE_LOGGING
00171             MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00172 #endif
00173             off = pvfs_lseek64(fd->fd_sys, fd->fp_ind, SEEK_SET);
00174 #ifdef ADIOI_MPE_LOGGING
00175             MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00176 #endif
00177         }
00178 
00179     
00180 
00181 
00182 
00183 
00184 
00185     for (j=0; j<count; j++) {
00186         for (i=0; i<flat_buf->count; i++) {
00187         if (flat_buf->blocklens[i] > combine_buf_remain && combine_buf != combine_buf_ptr) {
00188             
00189 #ifdef ADIOI_MPE_LOGGING
00190                     MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00191 #endif
00192             err = pvfs_write(fd->fd_sys,
00193                      combine_buf,
00194                      fd->hints->ind_wr_buffer_size - combine_buf_remain);
00195 #ifdef ADIOI_MPE_LOGGING
00196                     MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00197 #endif
00198             if (err == -1) err_flag = 1;
00199 
00200             
00201             combine_buf_ptr = combine_buf;
00202             combine_buf_remain = fd->hints->ind_wr_buffer_size;
00203         }
00204 
00205         
00206         if (flat_buf->blocklens[i] >= combine_buf_remain) {
00207             
00208 
00209 
00210 #ifdef ADIOI_MPE_LOGGING
00211                     MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00212 #endif
00213             err = pvfs_write(fd->fd_sys,
00214                      ((char *) buf) + j*buftype_extent + flat_buf->indices[i],
00215                      flat_buf->blocklens[i]);
00216 #ifdef ADIOI_MPE_LOGGING
00217                     MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00218 #endif
00219             if (err == -1) err_flag = 1;
00220             off += flat_buf->blocklens[i]; 
00221         }
00222         else {
00223             
00224             memcpy(combine_buf_ptr,
00225                ((char *) buf) + j*buftype_extent + flat_buf->indices[i],
00226                flat_buf->blocklens[i]);
00227             combine_buf_ptr += flat_buf->blocklens[i];
00228             combine_buf_remain -= flat_buf->blocklens[i];
00229             off += flat_buf->blocklens[i]; 
00230         }
00231         }
00232     }
00233 
00234     if (combine_buf_ptr != combine_buf) {
00235         
00236 #ifdef ADIOI_MPE_LOGGING
00237             MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00238 #endif
00239         err = pvfs_write(fd->fd_sys,
00240                  combine_buf,
00241                  fd->hints->ind_wr_buffer_size - combine_buf_remain);
00242 #ifdef ADIOI_MPE_LOGGING
00243             MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00244 #endif
00245         if (err == -1) err_flag = 1;
00246     }
00247 
00248     if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00249 
00250     ADIOI_Free(combine_buf);
00251 
00252     if (err_flag) {
00253         *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00254                            MPIR_ERR_RECOVERABLE, myname,
00255                            __LINE__, MPI_ERR_IO, "**io",
00256                            "**io %s", strerror(errno));
00257     }
00258     else *error_code = MPI_SUCCESS;
00259     } 
00260 
00261     else {  
00262 
00263 
00264 
00265 
00266 
00267 
00268     flat_file = ADIOI_Flatlist;
00269     while (flat_file->type != fd->filetype) flat_file = flat_file->next;
00270         disp = fd->disp;
00271 
00272     if (file_ptr_type == ADIO_INDIVIDUAL) {
00273         offset = fd->fp_ind; 
00274             n_filetypes = -1;
00275             flag = 0;
00276             while (!flag) {
00277                 n_filetypes++;
00278                 for (i=0; i<flat_file->count; i++) {
00279                     if (disp + flat_file->indices[i] + 
00280                         (ADIO_Offset) n_filetypes*filetype_extent + flat_file->blocklens[i] 
00281                             >= offset) {
00282                         st_index = i;
00283                         fwr_size = disp + flat_file->indices[i] + 
00284                                 (ADIO_Offset) n_filetypes*filetype_extent
00285                                  + flat_file->blocklens[i] - offset;
00286                         flag = 1;
00287                         break;
00288                     }
00289                 }
00290             }
00291     }
00292     else {
00293         n_etypes_in_filetype = filetype_size/etype_size;
00294         n_filetypes = (int) (offset / n_etypes_in_filetype);
00295         etype_in_filetype = (int) (offset % n_etypes_in_filetype);
00296         size_in_filetype = etype_in_filetype * etype_size;
00297  
00298         sum = 0;
00299         for (i=0; i<flat_file->count; i++) {
00300         sum += flat_file->blocklens[i];
00301         if (sum > size_in_filetype) {
00302             st_index = i;
00303             fwr_size = sum - size_in_filetype;
00304             abs_off_in_filetype = flat_file->indices[i] +
00305             size_in_filetype - (sum - flat_file->blocklens[i]);
00306             break;
00307         }
00308         }
00309 
00310         
00311             offset = disp + (ADIO_Offset) n_filetypes*filetype_extent + abs_off_in_filetype;
00312     }
00313 
00314     if (buftype_is_contig && !filetype_is_contig) {
00315 
00316 
00317 
00318 
00319         i = 0;
00320         j = st_index;
00321         off = offset;
00322         fwr_size = ADIOI_MIN(fwr_size, bufsize);
00323         while (i < bufsize) {
00324                 if (fwr_size) { 
00325                     
00326  
00327 #ifdef ADIOI_MPE_LOGGING
00328                     MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00329 #endif
00330             pvfs_lseek64(fd->fd_sys, off, SEEK_SET);
00331 #ifdef ADIOI_MPE_LOGGING
00332                     MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00333 #endif
00334 #ifdef ADIOI_MPE_LOGGING
00335                     MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00336 #endif
00337             err = pvfs_write(fd->fd_sys, ((char *) buf) + i, fwr_size);
00338 #ifdef ADIOI_MPE_LOGGING
00339                     MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00340 #endif
00341             if (err == -1) err_flag = 1;
00342         }
00343         i += fwr_size;
00344 
00345                 if (off + fwr_size < disp + flat_file->indices[j] +
00346                    flat_file->blocklens[j] + (ADIO_Offset) n_filetypes*filetype_extent)
00347                        off += fwr_size;
00348                 
00349 
00350                 else {
00351             if (j < (flat_file->count - 1)) j++;
00352             else {
00353             j = 0;
00354             n_filetypes++;
00355             }
00356             off = disp + flat_file->indices[j] + 
00357                                         (ADIO_Offset) n_filetypes*filetype_extent;
00358             fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
00359         }
00360         }
00361     }
00362     else {
00363 
00364 
00365         ADIOI_Flatten_datatype(datatype);
00366         flat_buf = ADIOI_Flatlist;
00367         while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00368 
00369         k = num = buf_count = 0;
00370         indx = flat_buf->indices[0];
00371         j = st_index;
00372         off = offset;
00373         bwr_size = flat_buf->blocklens[0];
00374 
00375         while (num < bufsize) {
00376         size = ADIOI_MIN(fwr_size, bwr_size);
00377         if (size) {
00378 #ifdef ADIOI_MPE_LOGGING
00379                     MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00380 #endif
00381             pvfs_lseek64(fd->fd_sys, off, SEEK_SET);
00382 #ifdef ADIOI_MPE_LOGGING
00383                     MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00384 #endif
00385 #ifdef ADIOI_MPE_LOGGING
00386                     MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00387 #endif
00388             err = pvfs_write(fd->fd_sys, ((char *) buf) + indx, size);
00389 #ifdef ADIOI_MPE_LOGGING
00390                     MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00391 #endif
00392             if (err == -1) err_flag = 1;
00393         }
00394 
00395         new_fwr_size = fwr_size;
00396         new_bwr_size = bwr_size;
00397 
00398         if (size == fwr_size) {
00399 
00400                     if (j < (flat_file->count - 1)) j++;
00401                     else {
00402                         j = 0;
00403                         n_filetypes++;
00404                     }
00405 
00406                     off = disp + flat_file->indices[j] + 
00407                                    (ADIO_Offset) n_filetypes*filetype_extent;
00408 
00409             new_fwr_size = flat_file->blocklens[j];
00410             if (size != bwr_size) {
00411             indx += size;
00412             new_bwr_size -= size;
00413             }
00414         }
00415 
00416         if (size == bwr_size) {
00417 
00418 
00419             k = (k + 1)%flat_buf->count;
00420             buf_count++;
00421             indx = buftype_extent*(buf_count/flat_buf->count) +
00422             flat_buf->indices[k]; 
00423             new_bwr_size = flat_buf->blocklens[k];
00424             if (size != fwr_size) {
00425             off += size;
00426             new_fwr_size -= size;
00427             }
00428         }
00429         num += size;
00430         fwr_size = new_fwr_size;
00431                 bwr_size = new_bwr_size;
00432         }
00433     }
00434 
00435         if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00436     if (err_flag) {
00437         *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00438                            MPIR_ERR_RECOVERABLE, myname,
00439                            __LINE__, MPI_ERR_IO, "**io",
00440                            "**io %s", strerror(errno));
00441     }
00442     else *error_code = MPI_SUCCESS;
00443     }
00444 
00445     fd->fp_sys_posn = -1;   
00446 
00447 #ifdef HAVE_STATUS_SET_BYTES
00448     MPIR_Status_set_bytes(status, datatype, bufsize);
00449 
00450 
00451 #endif
00452 
00453     if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
00454 }
00455 
00456 #ifdef HAVE_PVFS_LISTIO
00457 void ADIOI_PVFS_WriteStridedListIO(ADIO_File fd, void *buf, int count,
00458                        MPI_Datatype datatype, int file_ptr_type,
00459                        ADIO_Offset offset, ADIO_Status *status, int
00460                        *error_code) 
00461 {
00462 
00463 
00464 
00465 
00466 
00467     ADIOI_Flatlist_node *flat_buf, *flat_file;
00468     int i, j, k, err=-1, bwr_size, fwr_size=0, st_index=0;
00469     int bufsize, size, sum, n_etypes_in_filetype, size_in_filetype;
00470     int n_filetypes, etype_in_filetype;
00471     ADIO_Offset abs_off_in_filetype=0;
00472     int filetype_size, etype_size, buftype_size;
00473     MPI_Aint filetype_extent, buftype_extent;
00474     int buf_count, buftype_is_contig, filetype_is_contig;
00475     ADIO_Offset userbuf_off;
00476     ADIO_Offset off, disp, start_off;
00477     int flag, st_fwr_size, st_n_filetypes;
00478     int new_bwr_size, new_fwr_size, err_flag=0;
00479 
00480     int mem_list_count, file_list_count;
00481     char ** mem_offsets;
00482     int64_t *file_offsets;
00483     int *mem_lengths;
00484     int32_t *file_lengths;
00485     int total_blks_to_write;
00486 
00487     int max_mem_list, max_file_list;
00488 
00489     int b_blks_wrote;
00490     int f_data_wrote;
00491     int size_wrote=0, n_write_lists, extra_blks;
00492 
00493     int end_bwr_size, end_fwr_size;
00494     int start_k, start_j, new_file_write, new_buffer_write;
00495     int start_mem_offset;
00496 #define MAX_ARRAY_SIZE 1024
00497     static char myname[] = "ADIOI_PVFS_WRITESTRIDED";
00498 
00499 
00500 
00501 
00502     
00503     if (fd->atomicity) {
00504     *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
00505                        myname, __LINE__,
00506                        MPI_ERR_INTERN,
00507                        "Atomic mode set in PVFS I/O function", 0);
00508     return;
00509     }
00510     
00511 
00512     ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
00513     ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00514 
00515     MPI_Type_size(fd->filetype, &filetype_size);
00516     if ( ! filetype_size ) {
00517     *error_code = MPI_SUCCESS; 
00518     return;
00519     }
00520 
00521     MPI_Type_extent(fd->filetype, &filetype_extent);
00522     MPI_Type_size(datatype, &buftype_size);
00523     MPI_Type_extent(datatype, &buftype_extent);
00524     etype_size = fd->etype_size;
00525     
00526     bufsize = buftype_size * count;
00527 
00528     if (!buftype_is_contig && filetype_is_contig) {
00529 
00530 
00531         int64_t file_offsets;
00532     int32_t file_lengths;
00533 
00534     ADIOI_Flatten_datatype(datatype);
00535     flat_buf = ADIOI_Flatlist;
00536     while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00537     
00538     if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00539         off = fd->disp + etype_size * offset;
00540 #ifdef ADIOI_MPE_LOGGING
00541             MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00542 #endif
00543         pvfs_lseek64(fd->fd_sys, fd->fp_ind, SEEK_SET);
00544 #ifdef ADIOI_MPE_LOGGING
00545             MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00546 #endif
00547     }
00548     else {
00549 #ifdef ADIOI_MPE_LOGGING
00550             MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00551 #endif
00552             off = pvfs_lseek64(fd->fd_sys, fd->fp_ind, SEEK_SET);
00553 #ifdef ADIOI_MPE_LOGGING
00554             MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00555 #endif
00556         }
00557 
00558     file_list_count = 1;
00559     file_offsets = off;
00560     file_lengths = 0;
00561     total_blks_to_write = count*flat_buf->count;
00562     b_blks_wrote = 0;
00563 
00564     
00565     if (total_blks_to_write > MAX_ARRAY_SIZE)
00566         mem_list_count = MAX_ARRAY_SIZE;
00567     else mem_list_count = total_blks_to_write;
00568     mem_offsets = (char**)ADIOI_Malloc(mem_list_count*sizeof(char*));
00569     mem_lengths = (int*)ADIOI_Malloc(mem_list_count*sizeof(int));
00570 
00571     j = 0;
00572     
00573     while (b_blks_wrote < total_blks_to_write) {
00574         for (i=0; i<flat_buf->count; i++) {
00575         mem_offsets[b_blks_wrote % MAX_ARRAY_SIZE] = 
00576             ((char*)buf + j*buftype_extent + flat_buf->indices[i]);
00577         mem_lengths[b_blks_wrote % MAX_ARRAY_SIZE] = 
00578             flat_buf->blocklens[i];
00579         file_lengths += flat_buf->blocklens[i];
00580         b_blks_wrote++;
00581         if (!(b_blks_wrote % MAX_ARRAY_SIZE) ||
00582             (b_blks_wrote == total_blks_to_write)) {
00583 
00584             
00585 
00586             if (b_blks_wrote == total_blks_to_write) {
00587                 mem_list_count = total_blks_to_write % MAX_ARRAY_SIZE;
00588             
00589             if (!mem_list_count) mem_list_count = MAX_ARRAY_SIZE;
00590             }
00591 
00592             pvfs_write_list(fd->fd_sys ,mem_list_count, mem_offsets,
00593                    mem_lengths, file_list_count,
00594                    &file_offsets, &file_lengths);
00595           
00596             
00597             if (b_blks_wrote == total_blks_to_write) break;
00598 
00599             file_offsets += file_lengths;
00600             file_lengths = 0;
00601         } 
00602         } 
00603         j++;
00604     } 
00605     ADIOI_Free(mem_offsets);
00606     ADIOI_Free(mem_lengths);
00607 
00608     if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00609 
00610     if (err_flag) {
00611         *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00612                            MPIR_ERR_RECOVERABLE, myname,
00613                            __LINE__, MPI_ERR_IO, "**io",
00614                            "**io %s", strerror(errno));
00615     }
00616     else *error_code = MPI_SUCCESS;
00617 
00618     fd->fp_sys_posn = -1;   
00619 
00620 #ifdef HAVE_STATUS_SET_BYTES
00621     MPIR_Status_set_bytes(status, datatype, bufsize);
00622 
00623 
00624 #endif
00625 
00626     ADIOI_Delete_flattened(datatype);
00627     return;
00628     } 
00629 
00630     
00631     
00632 
00633 
00634     flat_file = ADIOI_Flatlist;
00635     while (flat_file->type != fd->filetype) flat_file = flat_file->next;
00636 
00637     disp = fd->disp;
00638 
00639     
00640 
00641 
00642 
00643 
00644     if (file_ptr_type == ADIO_INDIVIDUAL) {
00645         offset = fd->fp_ind; 
00646     n_filetypes = -1;
00647     flag = 0;
00648     while (!flag) {
00649         n_filetypes++;
00650         for (i=0; i<flat_file->count; i++) {
00651             if (disp + flat_file->indices[i] + 
00652             (ADIO_Offset) n_filetypes*filetype_extent +
00653               flat_file->blocklens[i] >= offset) {
00654           st_index = i;
00655           fwr_size = disp + flat_file->indices[i] + 
00656             (ADIO_Offset) n_filetypes*filetype_extent
00657             + flat_file->blocklens[i] - offset;
00658           flag = 1;
00659           break;
00660         }
00661         }
00662     } 
00663     } 
00664     else {
00665         n_etypes_in_filetype = filetype_size/etype_size;
00666     n_filetypes = (int) (offset / n_etypes_in_filetype);
00667     etype_in_filetype = (int) (offset % n_etypes_in_filetype);
00668     size_in_filetype = etype_in_filetype * etype_size;
00669     
00670     sum = 0;
00671     for (i=0; i<flat_file->count; i++) {
00672         sum += flat_file->blocklens[i];
00673         if (sum > size_in_filetype) {
00674             st_index = i;
00675         fwr_size = sum - size_in_filetype;
00676         abs_off_in_filetype = flat_file->indices[i] +
00677             size_in_filetype - (sum - flat_file->blocklens[i]);
00678         break;
00679         }
00680     }
00681 
00682     
00683     offset = disp + (ADIO_Offset) n_filetypes*filetype_extent +
00684         abs_off_in_filetype;
00685     } 
00686 
00687     start_off = offset;
00688     st_fwr_size = fwr_size;
00689     st_n_filetypes = n_filetypes;
00690     
00691     if (buftype_is_contig && !filetype_is_contig) {
00692 
00693 
00694 
00695 
00696         int mem_lengths;
00697     char *mem_offsets;
00698         
00699     i = 0;
00700     j = st_index;
00701     off = offset;
00702     n_filetypes = st_n_filetypes;
00703         
00704     mem_list_count = 1;
00705         
00706     
00707     f_data_wrote = ADIOI_MIN(st_fwr_size, bufsize);
00708     total_blks_to_write = 1;
00709     j++;
00710     while (f_data_wrote < bufsize) {
00711         f_data_wrote += flat_file->blocklens[j];
00712         total_blks_to_write++;
00713         if (j<(flat_file->count-1)) j++;
00714         else j = 0; 
00715     }
00716         
00717     j = st_index;
00718     n_filetypes = st_n_filetypes;
00719     n_write_lists = total_blks_to_write/MAX_ARRAY_SIZE;
00720     extra_blks = total_blks_to_write%MAX_ARRAY_SIZE;
00721         
00722     mem_offsets = buf;
00723     mem_lengths = 0;
00724         
00725     
00726 
00727     if (n_write_lists) {
00728         file_offsets = (int64_t*)ADIOI_Malloc(MAX_ARRAY_SIZE*
00729                           sizeof(int64_t));
00730         file_lengths = (int32_t*)ADIOI_Malloc(MAX_ARRAY_SIZE*
00731                           sizeof(int32_t));
00732     }
00733     
00734 
00735     else {
00736         file_offsets = (int64_t*)ADIOI_Malloc(extra_blks*
00737                                                   sizeof(int64_t));
00738             file_lengths = (int32_t*)ADIOI_Malloc(extra_blks*
00739                                                   sizeof(int32_t));
00740         }
00741         
00742         
00743         for (i=0; i<n_write_lists; i++) {
00744             file_list_count = MAX_ARRAY_SIZE;
00745             if(!i) {
00746                 file_offsets[0] = offset;
00747                 file_lengths[0] = st_fwr_size;
00748                 mem_lengths = st_fwr_size;
00749             }
00750             for (k=0; k<MAX_ARRAY_SIZE; k++) {
00751                 if (i || k) {
00752                     file_offsets[k] = disp + n_filetypes*filetype_extent
00753                       + flat_file->indices[j];
00754                     file_lengths[k] = flat_file->blocklens[j];
00755                     mem_lengths += file_lengths[k];
00756                 }
00757                 if (j<(flat_file->count - 1)) j++;
00758                 else {
00759                     j = 0;
00760                     n_filetypes++;
00761                 }
00762             } 
00763             pvfs_write_list(fd->fd_sys, mem_list_count,
00764                            &mem_offsets, &mem_lengths,
00765                            file_list_count, file_offsets,
00766                            file_lengths);
00767             mem_offsets += mem_lengths;
00768             mem_lengths = 0;
00769         } 
00770 
00771         
00772         if (extra_blks) {
00773             file_list_count = extra_blks;
00774             if(!i) {
00775                 file_offsets[0] = offset;
00776                 file_lengths[0] = st_fwr_size;
00777             }
00778             for (k=0; k<extra_blks; k++) {
00779                 if(i || k) {
00780                     file_offsets[k] = disp + n_filetypes*filetype_extent +
00781                       flat_file->indices[j];
00782                     if (k == (extra_blks - 1)) {
00783                         file_lengths[k] = bufsize - (int32_t) mem_lengths
00784                           - (int32_t) mem_offsets + (int32_t)  buf;
00785                     }
00786                     else file_lengths[k] = flat_file->blocklens[j];
00787                 } 
00788                 mem_lengths += file_lengths[k];
00789                 if (j<(flat_file->count - 1)) j++;
00790                 else {
00791                     j = 0;
00792                     n_filetypes++;
00793                 }
00794             } 
00795             pvfs_write_list(fd->fd_sys, mem_list_count, &mem_offsets,
00796                            &mem_lengths, file_list_count, file_offsets,
00797                            file_lengths);
00798         }
00799     } 
00800     else {
00801         
00802 
00803         ADIOI_Flatten_datatype(datatype);
00804     flat_buf = ADIOI_Flatlist;
00805     while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00806 
00807     size_wrote = 0;
00808     n_filetypes = st_n_filetypes;
00809     fwr_size = st_fwr_size;
00810     bwr_size = flat_buf->blocklens[0];
00811     buf_count = 0;
00812     start_mem_offset = 0;
00813     start_k = k = 0;
00814     start_j = st_index;
00815     max_mem_list = 0;
00816     max_file_list = 0;
00817 
00818     
00819 
00820 
00821 
00822     while (size_wrote < bufsize) {
00823         k = start_k;
00824         new_buffer_write = 0;
00825         mem_list_count = 0;
00826         while ((mem_list_count < MAX_ARRAY_SIZE) && 
00827            (new_buffer_write < bufsize-size_wrote)) {
00828             
00829 
00830 
00831 
00832 
00833             if(mem_list_count) {
00834             if((new_buffer_write + flat_buf->blocklens[k] + 
00835             size_wrote) > bufsize) {
00836                 end_bwr_size = new_buffer_write + 
00837                 flat_buf->blocklens[k] - (bufsize - size_wrote);
00838             new_buffer_write = bufsize - size_wrote;
00839             }
00840             else {
00841                 new_buffer_write += flat_buf->blocklens[k];
00842             end_bwr_size = flat_buf->blocklens[k];
00843             }
00844         }
00845         else {
00846             if (bwr_size > (bufsize - size_wrote)) {
00847                 new_buffer_write = bufsize - size_wrote;
00848             bwr_size = new_buffer_write;
00849             }
00850             else new_buffer_write = bwr_size;
00851         }
00852         mem_list_count++;
00853         k = (k + 1)%flat_buf->count;
00854          } 
00855 
00856         j = start_j;
00857         new_file_write = 0;
00858         file_list_count = 0;
00859         while ((file_list_count < MAX_ARRAY_SIZE) && 
00860            (new_file_write < new_buffer_write)) {
00861             if(file_list_count) {
00862             if((new_file_write + flat_file->blocklens[j]) > 
00863                new_buffer_write) {
00864                 end_fwr_size = new_buffer_write - new_file_write;
00865             new_file_write = new_buffer_write;
00866             j--;
00867             }
00868             else {
00869                 new_file_write += flat_file->blocklens[j];
00870             end_fwr_size = flat_file->blocklens[j];
00871             }
00872         }
00873         else {
00874             if (fwr_size > new_buffer_write) {
00875                 new_file_write = new_buffer_write;
00876             fwr_size = new_file_write;
00877             }
00878             else new_file_write = fwr_size;
00879         }
00880         file_list_count++;
00881         if (j < (flat_file->count - 1)) j++;
00882         else j = 0;
00883         
00884         k = start_k;
00885         if ((new_file_write < new_buffer_write) && 
00886             (file_list_count == MAX_ARRAY_SIZE)) {
00887             new_buffer_write = 0;
00888             mem_list_count = 0;
00889             while (new_buffer_write < new_file_write) {
00890                 if(mem_list_count) {
00891                 if((new_buffer_write + flat_buf->blocklens[k]) >
00892                    new_file_write) {
00893                     end_bwr_size = new_file_write - 
00894                     new_buffer_write;
00895                 new_buffer_write = new_file_write;
00896                 k--;
00897                 }
00898                 else {
00899                     new_buffer_write += flat_buf->blocklens[k];
00900                 end_bwr_size = flat_buf->blocklens[k];
00901                 }
00902             }
00903             else {
00904                 new_buffer_write = bwr_size;
00905                 if (bwr_size > (bufsize - size_wrote)) {
00906                     new_buffer_write = bufsize - size_wrote;
00907                 bwr_size = new_buffer_write;
00908                 }
00909             }
00910             mem_list_count++;
00911             k = (k + 1)%flat_buf->count;
00912             } 
00913         } 
00914 
00915         } 
00916 
00917 
00918         
00919         k = start_k;
00920         j = start_j;
00921         for (i=0; i<mem_list_count; i++) {       
00922         if(i) {
00923             if (i == (mem_list_count - 1)) {
00924             if (flat_buf->blocklens[k] == end_bwr_size)
00925                 bwr_size = flat_buf->blocklens[(k+1)%
00926                               flat_buf->count];
00927             else {
00928                 bwr_size = flat_buf->blocklens[k] - end_bwr_size;
00929                 k--;
00930                 buf_count--;
00931             }
00932             }
00933         }
00934         buf_count++;
00935         k = (k + 1)%flat_buf->count;
00936         } 
00937         for (i=0; i<file_list_count; i++) {
00938         if (i) {
00939             if (i == (file_list_count - 1)) {
00940             if (flat_file->blocklens[j] == end_fwr_size)
00941                 fwr_size = flat_file->blocklens[(j+1)%
00942                               flat_file->count];   
00943             else {
00944                 fwr_size = flat_file->blocklens[j] - end_fwr_size;
00945                 j--;
00946             }
00947             }
00948         }
00949         if (j < flat_file->count - 1) j++;
00950         else {
00951             j = 0;
00952             n_filetypes++;
00953         }
00954         } 
00955         size_wrote += new_buffer_write;
00956         start_k = k;
00957         start_j = j;
00958         if (max_mem_list < mem_list_count)
00959             max_mem_list = mem_list_count;
00960         if (max_file_list < file_list_count)
00961             max_file_list = file_list_count;
00962     } 
00963 
00964     mem_offsets = (char **)ADIOI_Malloc(max_mem_list*sizeof(char *));
00965     mem_lengths = (int *)ADIOI_Malloc(max_mem_list*sizeof(int));
00966     file_offsets = (int64_t *)ADIOI_Malloc(max_file_list*sizeof(int64_t));
00967     file_lengths = (int32_t *)ADIOI_Malloc(max_file_list*sizeof(int32_t));
00968         
00969     size_wrote = 0;
00970     n_filetypes = st_n_filetypes;
00971     fwr_size = st_fwr_size;
00972     bwr_size = flat_buf->blocklens[0];
00973     buf_count = 0;
00974     start_mem_offset = 0;
00975     start_k = k = 0;
00976     start_j = st_index;
00977 
00978     
00979 
00980 
00981     
00982     while (size_wrote < bufsize) {
00983         k = start_k;
00984         new_buffer_write = 0;
00985         mem_list_count = 0;
00986         while ((mem_list_count < MAX_ARRAY_SIZE) && 
00987            (new_buffer_write < bufsize-size_wrote)) {
00988             
00989 
00990 
00991 
00992 
00993             if(mem_list_count) {
00994             if((new_buffer_write + flat_buf->blocklens[k] + 
00995             size_wrote) > bufsize) {
00996                 end_bwr_size = new_buffer_write + 
00997                 flat_buf->blocklens[k] - (bufsize - size_wrote);
00998             new_buffer_write = bufsize - size_wrote;
00999             }
01000             else {
01001                 new_buffer_write += flat_buf->blocklens[k];
01002             end_bwr_size = flat_buf->blocklens[k];
01003             }
01004         }
01005         else {
01006             if (bwr_size > (bufsize - size_wrote)) {
01007                 new_buffer_write = bufsize - size_wrote;
01008             bwr_size = new_buffer_write;
01009             }
01010             else new_buffer_write = bwr_size;
01011         }
01012         mem_list_count++;
01013         k = (k + 1)%flat_buf->count;
01014          } 
01015 
01016         j = start_j;
01017         new_file_write = 0;
01018         file_list_count = 0;
01019         while ((file_list_count < MAX_ARRAY_SIZE) && 
01020            (new_file_write < new_buffer_write)) {
01021             if(file_list_count) {
01022             if((new_file_write + flat_file->blocklens[j]) > 
01023                new_buffer_write) {
01024                 end_fwr_size = new_buffer_write - new_file_write;
01025             new_file_write = new_buffer_write;
01026             j--;
01027             }
01028             else {
01029                 new_file_write += flat_file->blocklens[j];
01030             end_fwr_size = flat_file->blocklens[j];
01031             }
01032         }
01033         else {
01034             if (fwr_size > new_buffer_write) {
01035                 new_file_write = new_buffer_write;
01036             fwr_size = new_file_write;
01037             }
01038             else new_file_write = fwr_size;
01039         }
01040         file_list_count++;
01041         if (j < (flat_file->count - 1)) j++;
01042         else j = 0;
01043         
01044         k = start_k;
01045         if ((new_file_write < new_buffer_write) && 
01046             (file_list_count == MAX_ARRAY_SIZE)) {
01047             new_buffer_write = 0;
01048             mem_list_count = 0;
01049             while (new_buffer_write < new_file_write) {
01050                 if(mem_list_count) {
01051                 if((new_buffer_write + flat_buf->blocklens[k]) >
01052                    new_file_write) {
01053                     end_bwr_size = new_file_write -
01054                   new_buffer_write;
01055                 new_buffer_write = new_file_write;
01056                 k--;
01057                 }
01058                 else {
01059                     new_buffer_write += flat_buf->blocklens[k];
01060                 end_bwr_size = flat_buf->blocklens[k];
01061                 }
01062             }
01063             else {
01064                 new_buffer_write = bwr_size;
01065                 if (bwr_size > (bufsize - size_wrote)) {
01066                     new_buffer_write = bufsize - size_wrote;
01067                 bwr_size = new_buffer_write;
01068                 }
01069             }
01070             mem_list_count++;
01071             k = (k + 1)%flat_buf->count;
01072             } 
01073         } 
01074 
01075         } 
01076 
01077 
01078         
01079         k = start_k;
01080         j = start_j;
01081         for (i=0; i<mem_list_count; i++) {       
01082             mem_offsets[i] = ((char*)buf + buftype_extent*
01083                      (buf_count/flat_buf->count) +
01084                      (int)flat_buf->indices[k]);
01085         
01086         if(!i) {
01087             mem_lengths[0] = bwr_size;
01088             mem_offsets[0] += flat_buf->blocklens[k] - bwr_size;
01089         }
01090         else {
01091             if (i == (mem_list_count - 1)) {
01092                 mem_lengths[i] = end_bwr_size;
01093             if (flat_buf->blocklens[k] == end_bwr_size)
01094                 bwr_size = flat_buf->blocklens[(k+1)%
01095                               flat_buf->count];
01096             else {
01097                 bwr_size = flat_buf->blocklens[k] - end_bwr_size;
01098                 k--;
01099                 buf_count--;
01100             }
01101             }
01102             else {
01103                 mem_lengths[i] = flat_buf->blocklens[k];
01104             }
01105         }
01106         buf_count++;
01107         k = (k + 1)%flat_buf->count;
01108         } 
01109         for (i=0; i<file_list_count; i++) {
01110             file_offsets[i] = disp + flat_file->indices[j] + n_filetypes *
01111             filetype_extent;
01112             if (!i) {
01113             file_lengths[0] = fwr_size;
01114             file_offsets[0] += flat_file->blocklens[j] - fwr_size;
01115         }
01116         else {
01117             if (i == (file_list_count - 1)) {
01118                 file_lengths[i] = end_fwr_size;
01119             if (flat_file->blocklens[j] == end_fwr_size)
01120                 fwr_size = flat_file->blocklens[(j+1)%
01121                               flat_file->count];   
01122             else {
01123                 fwr_size = flat_file->blocklens[j] - end_fwr_size;
01124                 j--;
01125             }
01126             }
01127             else file_lengths[i] = flat_file->blocklens[j];
01128         }
01129         if (j < flat_file->count - 1) j++;
01130         else {
01131             j = 0;
01132             n_filetypes++;
01133         }
01134         } 
01135         pvfs_write_list(fd->fd_sys,mem_list_count, mem_offsets,
01136                mem_lengths, file_list_count, file_offsets,
01137                file_lengths);
01138         size_wrote += new_buffer_write;
01139         start_k = k;
01140         start_j = j;
01141     } 
01142     ADIOI_Free(mem_offsets);
01143     ADIOI_Free(mem_lengths);
01144     }
01145     ADIOI_Free(file_offsets);
01146     ADIOI_Free(file_lengths);
01147 
01148     if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
01149     if (err_flag) {
01150     *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
01151                        myname, __LINE__, MPI_ERR_IO,
01152                        "**io",
01153                        "**io %s", strerror(errno));
01154     }
01155     else *error_code = MPI_SUCCESS;
01156 
01157     fd->fp_sys_posn = -1;   
01158 
01159 #ifdef HAVE_STATUS_SET_BYTES
01160     MPIR_Status_set_bytes(status, datatype, bufsize);
01161 
01162 
01163 #endif
01164 
01165     if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
01166 }
01167 #endif