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