00001
00002
00003
00004
00005
00006
00007
00008 #include "ad_piofs.h"
00009 #include "adio_extern.h"
00010
00011 void ADIOI_PIOFS_WriteContig(ADIO_File fd, void *buf, int count,
00012 MPI_Datatype datatype, int file_ptr_type,
00013 ADIO_Offset offset, ADIO_Status *status, int *error_code)
00014 {
00015 int err=-1, datatype_size, len;
00016 #ifndef PRINT_ERR_MSG
00017 static char myname[] = "ADIOI_PIOFS_WRITECONTIG";
00018 #endif
00019
00020 MPI_Type_size(datatype, &datatype_size);
00021 len = datatype_size * count;
00022
00023 if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00024 if (fd->fp_sys_posn != offset) {
00025 llseek(fd->fd_sys, offset, SEEK_SET);
00026 }
00027 err = write(fd->fd_sys, buf, len);
00028 fd->fp_sys_posn = offset + err;
00029
00030 }
00031 else {
00032 if (fd->fp_sys_posn != fd->fp_ind) {
00033 llseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
00034 }
00035 err = write(fd->fd_sys, buf, len);
00036 fd->fp_ind += err;
00037 fd->fp_sys_posn = fd->fp_ind;
00038 }
00039
00040 #ifdef HAVE_STATUS_SET_BYTES
00041 if (err != -1) MPIR_Status_set_bytes(status, datatype, err);
00042 #endif
00043
00044 if (err == -1) {
00045 #ifdef MPICH2
00046 *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
00047 "**io %s", strerror(errno));
00048 #elif defined(PRINT_ERR_MSG)
00049 *error_code = MPI_ERR_UNKNOWN;
00050 #else
00051 *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
00052 myname, "I/O Error", "%s", strerror(errno));
00053 ADIOI_Error(fd, *error_code, myname);
00054 #endif
00055 }
00056 else *error_code = MPI_SUCCESS;
00057 }
00058
00059
00060
00061 void ADIOI_PIOFS_WriteStrided(ADIO_File fd, void *buf, int count,
00062 MPI_Datatype datatype, int file_ptr_type,
00063 ADIO_Offset offset, ADIO_Status *status, int
00064 *error_code)
00065 {
00066
00067
00068
00069
00070
00071 ADIOI_Flatlist_node *flat_buf, *flat_file;
00072 struct iovec *iov;
00073 int i, j, k, err=-1, bwr_size, fwr_size=0, st_index=0;
00074 int bufsize, num, size, sum, n_etypes_in_filetype, size_in_filetype;
00075 int n_filetypes, etype_in_filetype;
00076 ADIO_Offset abs_off_in_filetype=0;
00077 int filetype_size, etype_size, buftype_size;
00078 MPI_Aint filetype_extent, buftype_extent, indx;
00079 int buf_count, buftype_is_contig, filetype_is_contig;
00080 ADIO_Offset off, disp;
00081 int flag, new_bwr_size, new_fwr_size, err_flag=0;
00082 #ifndef PRINT_ERR_MSG
00083 static char myname[] = "ADIOI_PIOFS_WRITESTRIDED";
00084 #endif
00085
00086 if (fd->atomicity) {
00087 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");
00088 MPI_Abort(MPI_COMM_WORLD, 1);
00089 }
00090
00091 ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
00092 ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00093
00094 MPI_Type_size(fd->filetype, &filetype_size);
00095 if ( ! filetype_size ) {
00096 *error_code = MPI_SUCCESS;
00097 return;
00098 }
00099
00100 MPI_Type_extent(fd->filetype, &filetype_extent);
00101 MPI_Type_size(datatype, &buftype_size);
00102 MPI_Type_extent(datatype, &buftype_extent);
00103 etype_size = fd->etype_size;
00104
00105 bufsize = buftype_size * count;
00106
00107 if (!buftype_is_contig && filetype_is_contig) {
00108
00109
00110
00111 ADIOI_Flatten_datatype(datatype);
00112 flat_buf = ADIOI_Flatlist;
00113 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00114
00115
00116
00117 iov = (struct iovec *) ADIOI_Malloc(16*sizeof(struct iovec));
00118
00119 if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00120 off = fd->disp + etype_size * offset;
00121 llseek(fd->fd_sys, off, SEEK_SET);
00122 }
00123 else off = llseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
00124
00125 k = 0;
00126 for (j=0; j<count; j++)
00127 for (i=0; i<flat_buf->count; i++) {
00128 iov[k].iov_base = ((char *) buf) + j*buftype_extent +
00129 flat_buf->indices[i];
00130 iov[k].iov_len = flat_buf->blocklens[i];
00131
00132
00133 off += flat_buf->blocklens[i];
00134 k = (k+1)%16;
00135
00136 if (!k) {
00137 err = writev(fd->fd_sys, iov, 16);
00138 if (err == -1) err_flag = 1;
00139 }
00140 }
00141
00142 if (k) {
00143 err = writev(fd->fd_sys, iov, k);
00144 if (err == -1) err_flag = 1;
00145 }
00146
00147 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00148
00149 ADIOI_Free(iov);
00150 if (err_flag) {
00151 #ifdef MPICH2
00152 *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
00153 "**io %s", strerror(errno));
00154 #elif defined(PRINT_ERR_MSG)
00155 *error_code = MPI_ERR_UNKNOWN;
00156 #else
00157 *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
00158 myname, "I/O Error", "%s", strerror(errno));
00159 ADIOI_Error(fd, *error_code, myname);
00160 #endif
00161 }
00162 else *error_code = MPI_SUCCESS;
00163 }
00164
00165 else {
00166
00167
00168
00169
00170
00171
00172 flat_file = ADIOI_Flatlist;
00173 while (flat_file->type != fd->filetype) flat_file = flat_file->next;
00174 disp = fd->disp;
00175
00176 if (file_ptr_type == ADIO_INDIVIDUAL) {
00177 offset = fd->fp_ind;
00178 n_filetypes = -1;
00179 flag = 0;
00180 while (!flag) {
00181 n_filetypes++;
00182 for (i=0; i<flat_file->count; i++) {
00183 if (disp + flat_file->indices[i] +
00184 (ADIO_Offset) n_filetypes*filetype_extent + flat_file->blocklens[i]
00185 >= offset) {
00186 st_index = i;
00187 fwr_size = disp + flat_file->indices[i] +
00188 (ADIO_Offset) n_filetypes*filetype_extent
00189 + flat_file->blocklens[i] - offset;
00190 flag = 1;
00191 break;
00192 }
00193 }
00194 }
00195 }
00196 else {
00197 n_etypes_in_filetype = filetype_size/etype_size;
00198 n_filetypes = (int) (offset / n_etypes_in_filetype);
00199 etype_in_filetype = (int) (offset % n_etypes_in_filetype);
00200 size_in_filetype = etype_in_filetype * etype_size;
00201
00202 sum = 0;
00203 for (i=0; i<flat_file->count; i++) {
00204 sum += flat_file->blocklens[i];
00205 if (sum > size_in_filetype) {
00206 st_index = i;
00207 fwr_size = sum - size_in_filetype;
00208 abs_off_in_filetype = flat_file->indices[i] +
00209 size_in_filetype - (sum - flat_file->blocklens[i]);
00210 break;
00211 }
00212 }
00213
00214
00215 offset = disp + (ADIO_Offset) n_filetypes*filetype_extent + abs_off_in_filetype;
00216 }
00217
00218 if (buftype_is_contig && !filetype_is_contig) {
00219
00220
00221
00222
00223 i = 0;
00224 j = st_index;
00225 off = offset;
00226 fwr_size = ADIOI_MIN(fwr_size, bufsize);
00227 while (i < bufsize) {
00228 if (fwr_size) {
00229
00230
00231 llseek(fd->fd_sys, off, SEEK_SET);
00232 err = write(fd->fd_sys, ((char *) buf) + i, fwr_size);
00233 if (err == -1) err_flag = 1;
00234 }
00235 i += fwr_size;
00236
00237 if (off + fwr_size < disp + flat_file->indices[j] +
00238 flat_file->blocklens[j] + (ADIO_Offset) n_filetypes*filetype_extent)
00239 off += fwr_size;
00240
00241
00242 else {
00243 if (j < (flat_file->count - 1)) j++;
00244 else {
00245 j = 0;
00246 n_filetypes++;
00247 }
00248 off = disp + flat_file->indices[j] +
00249 (ADIO_Offset) n_filetypes*filetype_extent;
00250 fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
00251 }
00252 }
00253 }
00254 else {
00255
00256
00257 ADIOI_Flatten_datatype(datatype);
00258 flat_buf = ADIOI_Flatlist;
00259 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00260
00261 k = num = buf_count = 0;
00262 indx = flat_buf->indices[0];
00263 j = st_index;
00264 off = offset;
00265 bwr_size = flat_buf->blocklens[0];
00266
00267 while (num < bufsize) {
00268 size = ADIOI_MIN(fwr_size, bwr_size);
00269 if (size) {
00270 llseek(fd->fd_sys, off, SEEK_SET);
00271 err = write(fd->fd_sys, ((char *) buf) + indx, size);
00272 if (err == -1) err_flag = 1;
00273 }
00274
00275 new_fwr_size = fwr_size;
00276 new_bwr_size = bwr_size;
00277
00278 if (size == fwr_size) {
00279
00280 if (j < (flat_file->count - 1)) j++;
00281 else {
00282 j = 0;
00283 n_filetypes++;
00284 }
00285
00286 off = disp + flat_file->indices[j] +
00287 (ADIO_Offset) n_filetypes*filetype_extent;
00288
00289 new_fwr_size = flat_file->blocklens[j];
00290 if (size != bwr_size) {
00291 indx += size;
00292 new_bwr_size -= size;
00293 }
00294 }
00295
00296 if (size == bwr_size) {
00297
00298
00299 k = (k + 1)%flat_buf->count;
00300 buf_count++;
00301 indx = buftype_extent*(buf_count/flat_buf->count) +
00302 flat_buf->indices[k];
00303 new_bwr_size = flat_buf->blocklens[k];
00304 if (size != fwr_size) {
00305 off += size;
00306 new_fwr_size -= size;
00307 }
00308 }
00309 num += size;
00310 fwr_size = new_fwr_size;
00311 bwr_size = new_bwr_size;
00312 }
00313 }
00314
00315 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00316 if (err_flag) {
00317 #ifdef MPICH2
00318 *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
00319 "**io %s", strerror(errno));
00320 #elif defined(PRINT_ERR_MSG)
00321 *error_code = MPI_ERR_UNKNOWN;
00322 #else
00323 *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
00324 myname, "I/O Error", "%s", strerror(errno));
00325 ADIOI_Error(fd, *error_code, myname);
00326 #endif
00327 }
00328 else *error_code = MPI_SUCCESS;
00329 }
00330
00331 fd->fp_sys_posn = -1;
00332
00333 #ifdef HAVE_STATUS_SET_BYTES
00334 MPIR_Status_set_bytes(status, datatype, bufsize);
00335
00336
00337 #endif
00338
00339 if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
00340 }