00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "adio.h"
00010 #include "adio_extern.h"
00011
00012 #define ADIOI_BUFFERED_WRITE \
00013 { \
00014 if (req_off >= writebuf_off + writebuf_len) { \
00015 if (writebuf_len) { \
00016 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00017 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00018 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00019 if (*error_code != MPI_SUCCESS) return; \
00020 } \
00021 writebuf_off = req_off; \
00022 writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00023 if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00024 ADIO_ReadContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00025 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00026 if (*error_code != MPI_SUCCESS) { \
00027 FPRINTF(stderr, "ADIOI_GEN_WriteStrided: ROMIO tries to optimize this access by doing a read-modify-write, but is unable to read the file. Please give the file read permission and open it with MPI_MODE_RDWR.\n"); \
00028 MPI_Abort(MPI_COMM_WORLD, 1); \
00029 } \
00030 } \
00031 write_sz = (int) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
00032 memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
00033 while (write_sz != req_len) { \
00034 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00035 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00036 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00037 if (*error_code != MPI_SUCCESS) return; \
00038 req_len -= write_sz; \
00039 userbuf_off += write_sz; \
00040 writebuf_off += writebuf_len; \
00041 writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00042 if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00043 ADIO_ReadContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00044 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00045 if (*error_code != MPI_SUCCESS) { \
00046 FPRINTF(stderr, "ADIOI_GEN_WriteStrided: ROMIO tries to optimize this access by doing a read-modify-write, but is unable to read the file. Please give the file read permission and open it with MPI_MODE_RDWR.\n"); \
00047 MPI_Abort(MPI_COMM_WORLD, 1); \
00048 } \
00049 write_sz = ADIOI_MIN(req_len, writebuf_len); \
00050 memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
00051 } \
00052 }
00053
00054
00055
00056
00057 #define ADIOI_BUFFERED_WRITE_WITHOUT_READ \
00058 { \
00059 if (req_off >= writebuf_off + writebuf_len) { \
00060 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00061 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00062 if (*error_code != MPI_SUCCESS) return; \
00063 writebuf_off = req_off; \
00064 writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00065 } \
00066 write_sz = (int) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
00067 memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
00068 while (write_sz != req_len) { \
00069 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00070 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00071 if (*error_code != MPI_SUCCESS) return; \
00072 req_len -= write_sz; \
00073 userbuf_off += write_sz; \
00074 writebuf_off += writebuf_len; \
00075 writebuf_len = (int) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00076 write_sz = ADIOI_MIN(req_len, writebuf_len); \
00077 memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
00078 } \
00079 }
00080
00081
00082 void ADIOI_GEN_WriteStrided(ADIO_File fd, void *buf, int count,
00083 MPI_Datatype datatype, int file_ptr_type,
00084 ADIO_Offset offset, ADIO_Status *status, int
00085 *error_code)
00086 {
00087
00088
00089 ADIOI_Flatlist_node *flat_buf, *flat_file;
00090 int i, j, k, bwr_size, fwr_size=0, st_index=0;
00091 int bufsize, num, size, sum, n_etypes_in_filetype, size_in_filetype;
00092 int n_filetypes, etype_in_filetype;
00093 ADIO_Offset abs_off_in_filetype=0;
00094 int filetype_size, etype_size, buftype_size, req_len;
00095 MPI_Aint filetype_extent, buftype_extent;
00096 int buf_count, buftype_is_contig, filetype_is_contig;
00097 ADIO_Offset userbuf_off;
00098 ADIO_Offset off, req_off, disp, end_offset=0, writebuf_off, start_off;
00099 char *writebuf, *value;
00100 int flag, st_fwr_size, st_n_filetypes, writebuf_len, write_sz;
00101 ADIO_Status status1;
00102 int new_bwr_size, new_fwr_size, info_flag, max_bufsize;
00103
00104 *error_code = MPI_SUCCESS;
00105
00106 ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
00107 ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00108
00109 MPI_Type_size(fd->filetype, &filetype_size);
00110 if ( ! filetype_size ) {
00111 *error_code = MPI_SUCCESS;
00112 return;
00113 }
00114
00115 MPI_Type_extent(fd->filetype, &filetype_extent);
00116 MPI_Type_size(datatype, &buftype_size);
00117 MPI_Type_extent(datatype, &buftype_extent);
00118 etype_size = fd->etype_size;
00119
00120 bufsize = buftype_size * count;
00121
00122
00123
00124 value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
00125 MPI_Info_get(fd->info, "ind_wr_buffer_size", MPI_MAX_INFO_VAL, value,
00126 &info_flag);
00127 max_bufsize = atoi(value);
00128 ADIOI_Free(value);
00129
00130 if (!buftype_is_contig && filetype_is_contig) {
00131
00132
00133
00134 ADIOI_Flatten_datatype(datatype);
00135 flat_buf = ADIOI_Flatlist;
00136 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00137
00138 off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind :
00139 fd->disp + etype_size * offset;
00140
00141 start_off = off;
00142 end_offset = off + bufsize - 1;
00143 writebuf_off = off;
00144 writebuf = (char *) ADIOI_Malloc(max_bufsize);
00145 writebuf_len = (int) (ADIOI_MIN(max_bufsize, end_offset-writebuf_off+1));
00146
00147
00148 if (fd->atomicity)
00149 ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00150
00151 for (j=0; j<count; j++)
00152 for (i=0; i<flat_buf->count; i++) {
00153 userbuf_off = j*buftype_extent + flat_buf->indices[i];
00154 req_off = off;
00155 req_len = flat_buf->blocklens[i];
00156 ADIOI_BUFFERED_WRITE_WITHOUT_READ
00157 off += flat_buf->blocklens[i];
00158 }
00159
00160
00161 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
00162 writebuf_off, &status1, error_code);
00163
00164 if (fd->atomicity)
00165 ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00166
00167 if (*error_code != MPI_SUCCESS) return;
00168
00169 ADIOI_Free(writebuf);
00170
00171 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00172 }
00173
00174 else {
00175
00176
00177 flat_file = ADIOI_Flatlist;
00178 while (flat_file->type != fd->filetype) flat_file = flat_file->next;
00179 disp = fd->disp;
00180
00181 if (file_ptr_type == ADIO_INDIVIDUAL) {
00182 offset = fd->fp_ind;
00183 n_filetypes = -1;
00184 flag = 0;
00185 while (!flag) {
00186 n_filetypes++;
00187 for (i=0; i<flat_file->count; i++) {
00188 if (disp + flat_file->indices[i] +
00189 (ADIO_Offset) n_filetypes*filetype_extent + flat_file->blocklens[i]
00190 >= offset) {
00191 st_index = i;
00192 fwr_size = (int) (disp + flat_file->indices[i] +
00193 (ADIO_Offset) n_filetypes*filetype_extent
00194 + flat_file->blocklens[i] - offset);
00195 flag = 1;
00196 break;
00197 }
00198 }
00199 }
00200 }
00201 else {
00202 n_etypes_in_filetype = filetype_size/etype_size;
00203 n_filetypes = (int) (offset / n_etypes_in_filetype);
00204 etype_in_filetype = (int) (offset % n_etypes_in_filetype);
00205 size_in_filetype = etype_in_filetype * etype_size;
00206
00207 sum = 0;
00208 for (i=0; i<flat_file->count; i++) {
00209 sum += flat_file->blocklens[i];
00210 if (sum > size_in_filetype) {
00211 st_index = i;
00212 fwr_size = sum - size_in_filetype;
00213 abs_off_in_filetype = flat_file->indices[i] +
00214 size_in_filetype - (sum - flat_file->blocklens[i]);
00215 break;
00216 }
00217 }
00218
00219
00220 offset = disp + (ADIO_Offset) n_filetypes*filetype_extent + abs_off_in_filetype;
00221 }
00222
00223 start_off = offset;
00224
00225
00226
00227
00228 st_fwr_size = fwr_size;
00229 st_n_filetypes = n_filetypes;
00230 i = 0;
00231 j = st_index;
00232 off = offset;
00233 fwr_size = ADIOI_MIN(st_fwr_size, bufsize);
00234 while (i < bufsize) {
00235 i += fwr_size;
00236 end_offset = off + fwr_size - 1;
00237
00238 if (j < (flat_file->count - 1)) j++;
00239 else {
00240 j = 0;
00241 n_filetypes++;
00242 }
00243
00244 off = disp + flat_file->indices[j] + (ADIO_Offset) n_filetypes*filetype_extent;
00245 fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
00246 }
00247
00248
00249 if (fd->atomicity)
00250 ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00251
00252 writebuf_off = 0;
00253 writebuf_len = 0;
00254 writebuf = (char *) ADIOI_Malloc(max_bufsize);
00255
00256 if (buftype_is_contig && !filetype_is_contig) {
00257
00258
00259
00260
00261 i = 0;
00262 j = st_index;
00263 off = offset;
00264 n_filetypes = st_n_filetypes;
00265 fwr_size = ADIOI_MIN(st_fwr_size, bufsize);
00266 while (i < bufsize) {
00267 if (fwr_size) {
00268
00269
00270
00271
00272
00273 req_off = off;
00274 req_len = fwr_size;
00275 userbuf_off = i;
00276 ADIOI_BUFFERED_WRITE
00277 }
00278 i += fwr_size;
00279
00280 if (off + fwr_size < disp + flat_file->indices[j] +
00281 flat_file->blocklens[j] + (ADIO_Offset) n_filetypes*filetype_extent)
00282 off += fwr_size;
00283
00284
00285 else {
00286 if (j < (flat_file->count - 1)) j++;
00287 else {
00288 j = 0;
00289 n_filetypes++;
00290 }
00291 off = disp + flat_file->indices[j] +
00292 (ADIO_Offset) n_filetypes*filetype_extent;
00293 fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
00294 }
00295 }
00296 }
00297 else {
00298
00299
00300 ADIOI_Flatten_datatype(datatype);
00301 flat_buf = ADIOI_Flatlist;
00302 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00303
00304 k = num = buf_count = 0;
00305 i = (int) (flat_buf->indices[0]);
00306 j = st_index;
00307 off = offset;
00308 n_filetypes = st_n_filetypes;
00309 fwr_size = st_fwr_size;
00310 bwr_size = flat_buf->blocklens[0];
00311
00312 while (num < bufsize) {
00313 size = ADIOI_MIN(fwr_size, bwr_size);
00314 if (size) {
00315
00316
00317
00318 req_off = off;
00319 req_len = size;
00320 userbuf_off = i;
00321 ADIOI_BUFFERED_WRITE
00322 }
00323
00324 new_fwr_size = fwr_size;
00325 new_bwr_size = bwr_size;
00326
00327 if (size == fwr_size) {
00328
00329 if (j < (flat_file->count - 1)) j++;
00330 else {
00331 j = 0;
00332 n_filetypes++;
00333 }
00334
00335 off = disp + flat_file->indices[j] +
00336 (ADIO_Offset) n_filetypes*filetype_extent;
00337
00338 new_fwr_size = flat_file->blocklens[j];
00339 if (size != bwr_size) {
00340 i += size;
00341 new_bwr_size -= size;
00342 }
00343 }
00344
00345 if (size == bwr_size) {
00346
00347
00348 k = (k + 1)%flat_buf->count;
00349 buf_count++;
00350 i = (int) (buftype_extent*(buf_count/flat_buf->count) +
00351 flat_buf->indices[k]);
00352 new_bwr_size = flat_buf->blocklens[k];
00353 if (size != fwr_size) {
00354 off += size;
00355 new_fwr_size -= size;
00356 }
00357 }
00358 num += size;
00359 fwr_size = new_fwr_size;
00360 bwr_size = new_bwr_size;
00361 }
00362 }
00363
00364
00365 if (writebuf_len) {
00366 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
00367 writebuf_off, &status1, error_code);
00368 if (!(fd->atomicity))
00369 ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
00370 if (*error_code != MPI_SUCCESS) return;
00371 }
00372 if (fd->atomicity)
00373 ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00374
00375 ADIOI_Free(writebuf);
00376
00377 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00378 }
00379
00380 fd->fp_sys_posn = -1;
00381
00382 #ifdef HAVE_STATUS_SET_BYTES
00383 MPIR_Status_set_bytes(status, datatype, bufsize);
00384
00385
00386 #endif
00387
00388 if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
00389 }
00390