root/ompi/mca/io/romio321/romio/adio/ad_piofs/ad_piofs_write.c

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

DEFINITIONS

This source file includes following definitions.
  1. ADIOI_PIOFS_WriteContig
  2. ADIOI_PIOFS_WriteStrided

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
   2 /* 
   3  *
   4  *   Copyright (C) 1997 University of Chicago. 
   5  *   See COPYRIGHT notice in top-level directory.
   6  */
   7 
   8 #include "ad_piofs.h"
   9 #include "adio_extern.h"
  10 
  11 void ADIOI_PIOFS_WriteContig(ADIO_File fd, void *buf, int count, 
  12                      MPI_Datatype datatype, int file_ptr_type,
  13                      ADIO_Offset offset, ADIO_Status *status, int *error_code)
  14 {
  15     MPI_Count err=-1, datatype_size, len;
  16 #ifndef PRINT_ERR_MSG
  17     static char myname[] = "ADIOI_PIOFS_WRITECONTIG";
  18 #endif
  19 
  20     MPI_Type_size_x(datatype, &datatype_size);
  21     len = datatype_size * count;
  22 
  23     if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
  24         if (fd->fp_sys_posn != offset) {
  25             llseek(fd->fd_sys, offset, SEEK_SET);
  26         }
  27         err = write(fd->fd_sys, buf, len);
  28         fd->fp_sys_posn = offset + err;
  29         /* individual file pointer not updated */        
  30     }
  31     else { /* write from curr. location of ind. file pointer */
  32         if (fd->fp_sys_posn != fd->fp_ind) {
  33             llseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
  34         }
  35         err = write(fd->fd_sys, buf, len);
  36         fd->fp_ind += err;
  37         fd->fp_sys_posn = fd->fp_ind;
  38     }
  39 
  40 #ifdef HAVE_STATUS_SET_BYTES
  41     if (err != -1) MPIR_Status_set_bytes(status, datatype, err);
  42 #endif
  43 
  44     if (err == -1) {
  45 #ifdef MPICH
  46         *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
  47             "**io %s", strerror(errno));
  48 #elif defined(PRINT_ERR_MSG)
  49         *error_code =  MPI_ERR_UNKNOWN;
  50 #else
  51         *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
  52                               myname, "I/O Error", "%s", strerror(errno));
  53         ADIOI_Error(fd, *error_code, myname);
  54 #endif
  55     }
  56     else *error_code = MPI_SUCCESS;
  57 }
  58 
  59 
  60 
  61 void ADIOI_PIOFS_WriteStrided(ADIO_File fd, void *buf, int count,
  62                        MPI_Datatype datatype, int file_ptr_type,
  63                        ADIO_Offset offset, ADIO_Status *status, int
  64                        *error_code)
  65 {
  66 /* Since PIOFS does not support file locking, can't do buffered writes
  67    as on Unix */
  68 
  69 /* offset is in units of etype relative to the filetype. */
  70 
  71     ADIOI_Flatlist_node *flat_buf, *flat_file;
  72     struct iovec *iov;
  73     int i, j, k, err=-1, bwr_size, fwr_size=0, st_index=0;
  74     int num, size, sum, n_etypes_in_filetype, size_in_filetype;
  75     MPI_Count bufsize;
  76     int n_filetypes, etype_in_filetype;
  77     ADIO_Offset abs_off_in_filetype=0;
  78     MPI_Count filetype_size, etype_size, buftype_size;
  79     MPI_Aint filetype_extent, buftype_extent, indx, filetype_lb, buftype_lb;
  80     int buf_count, buftype_is_contig, filetype_is_contig;
  81     ADIO_Offset off, disp;
  82     int flag, new_bwr_size, new_fwr_size, err_flag=0;
  83 #ifndef PRINT_ERR_MSG
  84     static char myname[] = "ADIOI_PIOFS_WRITESTRIDED";
  85 #endif
  86 
  87     if (fd->atomicity) {
  88         FPRINTF(stderr, "ROMIO cannot guarantee atomicity of noncontiguous accesses in atomic mode, as PIOFS doesn't support file locking. Use nonatomic mode and its associated semantics.\n");
  89         MPI_Abort(MPI_COMM_WORLD, 1);
  90     }
  91 
  92     ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
  93     ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
  94 
  95     MPI_Type_size_x(fd->filetype, &filetype_size);
  96     if ( ! filetype_size ) {
  97 #ifdef HAVE_STATUS_SET_BYTES
  98         MPIR_Status_set_bytes(status, datatype, 0);
  99 #endif
 100         *error_code = MPI_SUCCESS; 
 101         return;
 102     }
 103 
 104     MPI_Type_get_extent(fd->filetype, &filetype_lb, &filetype_extent);
 105     MPI_Type_size_x(datatype, &buftype_size);
 106     MPI_Type_get_extent(datatype, &buftype_lb, &buftype_extent);
 107     etype_size = fd->etype_size;
 108     
 109     bufsize = buftype_size * count;
 110 
 111     if (!buftype_is_contig && filetype_is_contig) {
 112 
 113 /* noncontiguous in memory, contiguous in file. use writev */
 114 
 115         flat_buf = ADIOI_Flatten_and_find(datatype);
 116 
 117 /* There is a limit of 16 on the number of iovecs for readv/writev! */
 118 
 119         iov = (struct iovec *) ADIOI_Malloc(16*sizeof(struct iovec));
 120 
 121         if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
 122             off = fd->disp + etype_size * offset;
 123             llseek(fd->fd_sys, off, SEEK_SET);
 124         }
 125         else off = llseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
 126 
 127         k = 0;
 128         for (j=0; j<count; j++) 
 129             for (i=0; i<flat_buf->count; i++) {
 130                 iov[k].iov_base = ((char *) buf) + j*buftype_extent +
 131                     flat_buf->indices[i]; 
 132                 iov[k].iov_len = flat_buf->blocklens[i];
 133                 /*FPRINTF(stderr, "%d %d\n", iov[k].iov_base, iov[k].iov_len);*/
 134 
 135                 off += flat_buf->blocklens[i];
 136                 k = (k+1)%16;
 137 
 138                 if (!k) {
 139                     err = writev(fd->fd_sys, iov, 16);
 140                     if (err == -1) err_flag = 1;
 141                 }
 142             }
 143 
 144         if (k) {
 145             err = writev(fd->fd_sys, iov, k);
 146             if (err == -1) err_flag = 1;
 147         }
 148 
 149         if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
 150 
 151         ADIOI_Free(iov);
 152         if (err_flag) {
 153 #ifdef MPICH
 154             *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
 155                 "**io %s", strerror(errno));
 156 #elif defined(PRINT_ERR_MSG) 
 157             *error_code =  MPI_ERR_UNKNOWN;
 158 #else /* MPICH-1 */
 159             *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
 160                               myname, "I/O Error", "%s", strerror(errno));
 161             ADIOI_Error(fd, *error_code, myname);
 162 #endif
 163         }
 164         else *error_code = MPI_SUCCESS;
 165     } /* if (!buftype_is_contig && filetype_is_contig) ... */
 166 
 167     else {  /* noncontiguous in file */
 168 
 169 /* split up into several contiguous writes */
 170 
 171 /* find starting location in the file */
 172 
 173 /* filetype already flattened in ADIO_Open */
 174         flat_file = ADIOI_Flatlist;
 175         while (flat_file->type != fd->filetype) flat_file = flat_file->next;
 176         disp = fd->disp;
 177 
 178         if (file_ptr_type == ADIO_INDIVIDUAL) {
 179             offset = fd->fp_ind; /* in bytes */
 180             n_filetypes = -1;
 181             flag = 0;
 182             while (!flag) {
 183                 n_filetypes++;
 184                 for (i=0; i<flat_file->count; i++) {
 185                     if (disp + flat_file->indices[i] + 
 186                         (ADIO_Offset) n_filetypes*filetype_extent + flat_file->blocklens[i] 
 187                             >= offset) {
 188                         st_index = i;
 189                         fwr_size = disp + flat_file->indices[i] + 
 190                                 (ADIO_Offset) n_filetypes*filetype_extent
 191                                  + flat_file->blocklens[i] - offset;
 192                         flag = 1;
 193                         break;
 194                     }
 195                 }
 196             }
 197         }
 198         else {
 199             n_etypes_in_filetype = filetype_size/etype_size;
 200             n_filetypes = (int) (offset / n_etypes_in_filetype);
 201             etype_in_filetype = (int) (offset % n_etypes_in_filetype);
 202             size_in_filetype = etype_in_filetype * etype_size;
 203  
 204             sum = 0;
 205             for (i=0; i<flat_file->count; i++) {
 206                 sum += flat_file->blocklens[i];
 207                 if (sum > size_in_filetype) {
 208                     st_index = i;
 209                     fwr_size = sum - size_in_filetype;
 210                     abs_off_in_filetype = flat_file->indices[i] +
 211                         size_in_filetype - (sum - flat_file->blocklens[i]);
 212                     break;
 213                 }
 214             }
 215 
 216             /* abs. offset in bytes in the file */
 217             offset = disp + (ADIO_Offset) n_filetypes*filetype_extent + abs_off_in_filetype;
 218         }
 219 
 220         if (buftype_is_contig && !filetype_is_contig) {
 221 
 222 /* contiguous in memory, noncontiguous in file. should be the most
 223    common case. */
 224 
 225             i = 0;
 226             j = st_index;
 227             off = offset;
 228             fwr_size = ADIOI_MIN(fwr_size, bufsize);
 229             while (i < bufsize) {
 230                 if (fwr_size) { 
 231                     /* TYPE_UB and TYPE_LB can result in 
 232                        fwr_size = 0. save system call in such cases */ 
 233                     llseek(fd->fd_sys, off, SEEK_SET);
 234                     err = write(fd->fd_sys, ((char *) buf) + i, fwr_size);
 235                     if (err == -1) err_flag = 1;
 236                 }
 237                 i += fwr_size;
 238 
 239                 if (off + fwr_size < disp + flat_file->indices[j] +
 240                    flat_file->blocklens[j] + (ADIO_Offset) n_filetypes*filetype_extent)
 241                        off += fwr_size;
 242                 /* did not reach end of contiguous block in filetype.
 243                    no more I/O needed. off is incremented by fwr_size. */
 244                 else {
 245                     if (j < (flat_file->count - 1)) j++;
 246                     else {
 247                         j = 0;
 248                         n_filetypes++;
 249                     }
 250                     off = disp + flat_file->indices[j] + 
 251                                         (ADIO_Offset) n_filetypes*filetype_extent;
 252                     fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
 253                 }
 254             }
 255         }
 256         else {
 257 /* noncontiguous in memory as well as in file */
 258 
 259             flat_buf = ADIOI_Flatten_and_find(datatype);
 260 
 261             k = num = buf_count = 0;
 262             indx = flat_buf->indices[0];
 263             j = st_index;
 264             off = offset;
 265             bwr_size = flat_buf->blocklens[0];
 266 
 267             while (num < bufsize) {
 268                 size = ADIOI_MIN(fwr_size, bwr_size);
 269                 if (size) {
 270                     llseek(fd->fd_sys, off, SEEK_SET);
 271                     err = write(fd->fd_sys, ((char *) buf) + indx, size);
 272                     if (err == -1) err_flag = 1;
 273                 }
 274 
 275                 new_fwr_size = fwr_size;
 276                 new_bwr_size = bwr_size;
 277 
 278                 if (size == fwr_size) {
 279 /* reached end of contiguous block in file */
 280                     if (j < (flat_file->count - 1)) j++;
 281                     else {
 282                         j = 0;
 283                         n_filetypes++;
 284                     }
 285 
 286                     off = disp + flat_file->indices[j] + 
 287                                               (ADIO_Offset) n_filetypes*filetype_extent;
 288 
 289                     new_fwr_size = flat_file->blocklens[j];
 290                     if (size != bwr_size) {
 291                         indx += size;
 292                         new_bwr_size -= size;
 293                     }
 294                 }
 295 
 296                 if (size == bwr_size) {
 297 /* reached end of contiguous block in memory */
 298 
 299                     k = (k + 1)%flat_buf->count;
 300                     buf_count++;
 301                     indx = buftype_extent*(buf_count/flat_buf->count) +
 302                         flat_buf->indices[k]; 
 303                     new_bwr_size = flat_buf->blocklens[k];
 304                     if (size != fwr_size) {
 305                         off += size;
 306                         new_fwr_size -= size;
 307                     }
 308                 }
 309                 num += size;
 310                 fwr_size = new_fwr_size;
 311                 bwr_size = new_bwr_size;
 312             }
 313         }
 314 
 315         if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
 316         if (err_flag) {
 317 #ifdef MPICH
 318             *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
 319                 "**io %s", strerror(errno));
 320 #elif defined(PRINT_ERR_MSG)
 321             *error_code = MPI_ERR_UNKNOWN;
 322 #else /* MPICH-1 */
 323             *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
 324                               myname, "I/O Error", "%s", strerror(errno));
 325             ADIOI_Error(fd, *error_code, myname);
 326 #endif
 327         }
 328         else *error_code = MPI_SUCCESS;
 329     } 
 330 
 331     fd->fp_sys_posn = -1;   /* set it to null. */
 332 
 333 #ifdef HAVE_STATUS_SET_BYTES
 334     MPIR_Status_set_bytes(status, datatype, bufsize);
 335 /* This is a temporary way of filling in status. The right way is to 
 336    keep track of how much data was actually written by ADIOI_BUFFERED_WRITE. */
 337 #endif
 338 
 339     if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
 340 }

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