00001
00002
00003
00004
00005
00006
00007
00008 #include "adio.h"
00009 #include "adio_extern.h"
00010
00011 #define ADIOI_BUFFERED_WRITE \
00012 { \
00013 if (req_off >= writebuf_off + writebuf_len) { \
00014 if (writebuf_len) { \
00015 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00016 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00017 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00018 if (*error_code != MPI_SUCCESS) { \
00019 *error_code = MPIO_Err_create_code(*error_code, \
00020 MPIR_ERR_RECOVERABLE, myname, \
00021 __LINE__, MPI_ERR_IO, \
00022 "**iowswc", 0); \
00023 return; \
00024 } \
00025 } \
00026 writebuf_off = req_off; \
00027 writebuf_len = (unsigned) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00028 if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00029 ADIO_ReadContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00030 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00031 if (*error_code != MPI_SUCCESS) { \
00032 *error_code = MPIO_Err_create_code(*error_code, \
00033 MPIR_ERR_RECOVERABLE, myname, \
00034 __LINE__, MPI_ERR_IO, \
00035 "**iowsrc", 0); \
00036 return; \
00037 } \
00038 } \
00039 write_sz = (unsigned) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
00040 ADIOI_Assert((ADIO_Offset)write_sz == ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off));\
00041 memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
00042 while (write_sz != req_len) { \
00043 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00044 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00045 if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00046 if (*error_code != MPI_SUCCESS) { \
00047 *error_code = MPIO_Err_create_code(*error_code, \
00048 MPIR_ERR_RECOVERABLE, myname, \
00049 __LINE__, MPI_ERR_IO, \
00050 "**iowswc", 0); \
00051 return; \
00052 } \
00053 req_len -= write_sz; \
00054 userbuf_off += write_sz; \
00055 writebuf_off += writebuf_len; \
00056 writebuf_len = (unsigned) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00057 if (!(fd->atomicity)) ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \
00058 ADIO_ReadContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00059 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00060 if (*error_code != MPI_SUCCESS) { \
00061 *error_code = MPIO_Err_create_code(*error_code, \
00062 MPIR_ERR_RECOVERABLE, myname, \
00063 __LINE__, MPI_ERR_IO, \
00064 "**iowsrc", 0); \
00065 return; \
00066 } \
00067 write_sz = ADIOI_MIN(req_len, writebuf_len); \
00068 memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
00069 } \
00070 }
00071
00072
00073
00074
00075 #define ADIOI_BUFFERED_WRITE_WITHOUT_READ \
00076 { \
00077 if (req_off >= writebuf_off + writebuf_len) { \
00078 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00079 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00080 if (*error_code != MPI_SUCCESS) { \
00081 *error_code = MPIO_Err_create_code(*error_code, \
00082 MPIR_ERR_RECOVERABLE, myname, \
00083 __LINE__, MPI_ERR_IO, \
00084 "**iowswc", 0); \
00085 return; \
00086 } \
00087 writebuf_off = req_off; \
00088 writebuf_len = (unsigned) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00089 } \
00090 write_sz = (unsigned) (ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \
00091 ADIOI_Assert((ADIO_Offset)write_sz == ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off));\
00092 memcpy(writebuf+req_off-writebuf_off, (char *)buf +userbuf_off, write_sz);\
00093 while (write_sz != req_len) { \
00094 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \
00095 ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \
00096 if (*error_code != MPI_SUCCESS) { \
00097 *error_code = MPIO_Err_create_code(*error_code, \
00098 MPIR_ERR_RECOVERABLE, myname, \
00099 __LINE__, MPI_ERR_IO, \
00100 "**iowswc", 0); \
00101 return; \
00102 } \
00103 req_len -= write_sz; \
00104 userbuf_off += write_sz; \
00105 writebuf_off += writebuf_len; \
00106 writebuf_len = (unsigned) (ADIOI_MIN(max_bufsize,end_offset-writebuf_off+1));\
00107 write_sz = ADIOI_MIN(req_len, writebuf_len); \
00108 memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\
00109 } \
00110 }
00111 void ADIOI_GEN_WriteStrided(ADIO_File fd, void *buf, int count,
00112 MPI_Datatype datatype, int file_ptr_type,
00113 ADIO_Offset offset, ADIO_Status *status, int
00114 *error_code)
00115 {
00116
00117
00118
00119 ADIOI_Flatlist_node *flat_buf, *flat_file;
00120 ADIO_Offset i_offset, sum, size_in_filetype;
00121 int i, j, k, st_index=0;
00122 int n_etypes_in_filetype;
00123 ADIO_Offset num, size, n_filetypes, etype_in_filetype, st_n_filetypes;
00124 ADIO_Offset abs_off_in_filetype=0;
00125 int filetype_size, etype_size, buftype_size;
00126 MPI_Aint filetype_extent, buftype_extent;
00127 int buf_count, buftype_is_contig, filetype_is_contig;
00128 ADIO_Offset userbuf_off;
00129 ADIO_Offset off, req_off, disp, end_offset=0, writebuf_off, start_off;
00130 char *writebuf;
00131 unsigned bufsize, writebuf_len, max_bufsize, write_sz;
00132 ADIO_Status status1;
00133 ADIO_Offset new_bwr_size, new_fwr_size, st_fwr_size, fwr_size=0, bwr_size, req_len;
00134 static char myname[] = "ADIOI_GEN_WriteStrided";
00135
00136 if (fd->hints->ds_write == ADIOI_HINT_DISABLE) {
00137
00138
00139
00140
00141 ADIOI_GEN_WriteStrided_naive(fd,
00142 buf,
00143 count,
00144 datatype,
00145 file_ptr_type,
00146 offset,
00147 status,
00148 error_code);
00149 return;
00150 }
00151
00152
00153 *error_code = MPI_SUCCESS;
00154
00155 ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
00156 ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00157
00158 MPI_Type_size(fd->filetype, &filetype_size);
00159 if ( ! filetype_size ) {
00160 *error_code = MPI_SUCCESS;
00161 return;
00162 }
00163
00164 MPI_Type_extent(fd->filetype, &filetype_extent);
00165 MPI_Type_size(datatype, &buftype_size);
00166 MPI_Type_extent(datatype, &buftype_extent);
00167 etype_size = fd->etype_size;
00168
00169 ADIOI_Assert((buftype_size * count) == ((ADIO_Offset)(unsigned)buftype_size * (ADIO_Offset)count));
00170 bufsize = buftype_size * count;
00171
00172
00173
00174 max_bufsize = fd->hints->ind_wr_buffer_size;
00175
00176 if (!buftype_is_contig && filetype_is_contig) {
00177
00178
00179
00180 ADIOI_Flatten_datatype(datatype);
00181 flat_buf = CtvAccess(ADIOI_Flatlist);
00182 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00183
00184 off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind :
00185 fd->disp + (ADIO_Offset)etype_size * offset;
00186
00187 start_off = off;
00188 end_offset = off + bufsize - 1;
00189 writebuf_off = off;
00190 writebuf = (char *) ADIOI_Malloc(max_bufsize);
00191 writebuf_len = (unsigned) (ADIOI_MIN(max_bufsize, end_offset-writebuf_off+1));
00192
00193
00194 if (fd->atomicity)
00195 ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00196
00197 for (j=0; j<count; j++)
00198 {
00199 for (i=0; i<flat_buf->count; i++) {
00200 userbuf_off = (ADIO_Offset)j*(ADIO_Offset)buftype_extent + flat_buf->indices[i];
00201 req_off = off;
00202 req_len = flat_buf->blocklens[i];
00203 ADIOI_BUFFERED_WRITE_WITHOUT_READ
00204 off += flat_buf->blocklens[i];
00205 }
00206 }
00207
00208
00209 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
00210 writebuf_off, &status1, error_code);
00211
00212 if (fd->atomicity)
00213 ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00214
00215 if (*error_code != MPI_SUCCESS) return;
00216
00217 ADIOI_Free(writebuf);
00218
00219 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00220 }
00221
00222 else {
00223
00224
00225 flat_file = CtvAccess(ADIOI_Flatlist);
00226 while (flat_file->type != fd->filetype) flat_file = flat_file->next;
00227 disp = fd->disp;
00228
00229 if (file_ptr_type == ADIO_INDIVIDUAL) {
00230
00231 offset = fd->fp_ind - disp;
00232 n_filetypes = (offset - flat_file->indices[0]) / filetype_extent;
00233 offset -= (ADIO_Offset)n_filetypes * filetype_extent;
00234
00235
00236
00237 for (i=0; i<flat_file->count; i++) {
00238 ADIO_Offset dist;
00239 if (flat_file->blocklens[i] == 0) continue;
00240 dist = flat_file->indices[i] + flat_file->blocklens[i] - offset;
00241
00242 if (dist == 0) {
00243 i++;
00244 offset = flat_file->indices[i];
00245 fwr_size = flat_file->blocklens[i];
00246 break;
00247 }
00248 if (dist > 0) {
00249 fwr_size = dist;
00250 break;
00251 }
00252 }
00253 st_index = i;
00254 offset += disp + (ADIO_Offset)n_filetypes*filetype_extent;
00255 }
00256 else {
00257 n_etypes_in_filetype = filetype_size/etype_size;
00258 n_filetypes = offset / n_etypes_in_filetype;
00259 etype_in_filetype = offset % n_etypes_in_filetype;
00260 size_in_filetype = etype_in_filetype * etype_size;
00261
00262 sum = 0;
00263 for (i=0; i<flat_file->count; i++) {
00264 sum += flat_file->blocklens[i];
00265 if (sum > size_in_filetype) {
00266 st_index = i;
00267 fwr_size = sum - size_in_filetype;
00268 abs_off_in_filetype = flat_file->indices[i] +
00269 size_in_filetype - (sum - flat_file->blocklens[i]);
00270 break;
00271 }
00272 }
00273
00274
00275 offset = disp + (ADIO_Offset) n_filetypes*filetype_extent +
00276 abs_off_in_filetype;
00277 }
00278
00279 start_off = offset;
00280
00281
00282
00283
00284 if (buftype_is_contig && bufsize <= fwr_size) {
00285 ADIO_WriteContig(fd, buf, bufsize, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
00286 offset, status, error_code);
00287
00288 if (file_ptr_type == ADIO_INDIVIDUAL) {
00289
00290
00291 fd->fp_ind = offset + bufsize;
00292 if (bufsize == fwr_size) {
00293 do {
00294 st_index++;
00295 if (st_index == flat_file->count) {
00296 st_index = 0;
00297 n_filetypes++;
00298 }
00299 } while (flat_file->blocklens[st_index] == 0);
00300 fd->fp_ind = disp + flat_file->indices[st_index]
00301 + (ADIO_Offset)n_filetypes*filetype_extent;
00302 }
00303 }
00304 fd->fp_sys_posn = -1;
00305 #ifdef HAVE_STATUS_SET_BYTES
00306 MPIR_Status_set_bytes(status, datatype, bufsize);
00307 #endif
00308 return;
00309 }
00310
00311
00312
00313
00314 st_fwr_size = fwr_size;
00315 st_n_filetypes = n_filetypes;
00316 i_offset = 0;
00317 j = st_index;
00318 off = offset;
00319 fwr_size = ADIOI_MIN(st_fwr_size, bufsize);
00320 while (i_offset < bufsize) {
00321 i_offset += fwr_size;
00322 end_offset = off + fwr_size - 1;
00323
00324 j = (j+1) % flat_file->count;
00325 n_filetypes += (j == 0) ? 1 : 0;
00326 while (flat_file->blocklens[j]==0) {
00327 j = (j+1) % flat_file->count;
00328 n_filetypes += (j == 0) ? 1 : 0;
00329 }
00330
00331 off = disp + flat_file->indices[j] +
00332 n_filetypes*(ADIO_Offset)filetype_extent;
00333 fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i_offset);
00334 }
00335
00336
00337 if (fd->atomicity)
00338 ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00339
00340 writebuf_off = 0;
00341 writebuf_len = 0;
00342 writebuf = (char *) ADIOI_Malloc(max_bufsize);
00343 memset(writebuf, -1, max_bufsize);
00344
00345 if (buftype_is_contig && !filetype_is_contig) {
00346
00347
00348
00349
00350 i_offset = 0;
00351 j = st_index;
00352 off = offset;
00353 n_filetypes = st_n_filetypes;
00354 fwr_size = ADIOI_MIN(st_fwr_size, bufsize);
00355 while (i_offset < bufsize) {
00356 if (fwr_size) {
00357
00358
00359
00360
00361
00362 req_off = off;
00363 req_len = fwr_size;
00364 userbuf_off = i_offset;
00365 ADIOI_BUFFERED_WRITE
00366 }
00367 i_offset += fwr_size;
00368
00369 if (off + fwr_size < disp + flat_file->indices[j] +
00370 flat_file->blocklens[j] + n_filetypes*(ADIO_Offset)filetype_extent)
00371 off += fwr_size;
00372
00373
00374 else {
00375 j = (j+1) % flat_file->count;
00376 n_filetypes += (j == 0) ? 1 : 0;
00377 while (flat_file->blocklens[j]==0) {
00378 j = (j+1) % flat_file->count;
00379 n_filetypes += (j == 0) ? 1 : 0;
00380 }
00381 off = disp + flat_file->indices[j] +
00382 n_filetypes*(ADIO_Offset)filetype_extent;
00383 fwr_size = ADIOI_MIN(flat_file->blocklens[j],
00384 bufsize-i_offset);
00385 }
00386 }
00387 }
00388 else {
00389
00390
00391 ADIOI_Flatten_datatype(datatype);
00392 flat_buf = CtvAccess(ADIOI_Flatlist);
00393 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00394
00395 k = num = buf_count = 0;
00396 i_offset = flat_buf->indices[0];
00397 j = st_index;
00398 off = offset;
00399 n_filetypes = st_n_filetypes;
00400 fwr_size = st_fwr_size;
00401 bwr_size = flat_buf->blocklens[0];
00402
00403 while (num < bufsize) {
00404 size = ADIOI_MIN(fwr_size, bwr_size);
00405 if (size) {
00406
00407
00408
00409 req_off = off;
00410 req_len = size;
00411 userbuf_off = i_offset;
00412 ADIOI_BUFFERED_WRITE
00413 }
00414
00415 new_fwr_size = fwr_size;
00416 new_bwr_size = bwr_size;
00417
00418 if (size == fwr_size) {
00419
00420 j = (j+1) % flat_file->count;
00421 n_filetypes += (j == 0) ? 1 : 0;
00422 while (flat_file->blocklens[j]==0) {
00423 j = (j+1) % flat_file->count;
00424 n_filetypes += (j == 0) ? 1 : 0;
00425 }
00426
00427 off = disp + flat_file->indices[j] +
00428 n_filetypes*(ADIO_Offset)filetype_extent;
00429
00430 new_fwr_size = flat_file->blocklens[j];
00431 if (size != bwr_size) {
00432 i_offset += size;
00433 new_bwr_size -= size;
00434 }
00435 }
00436
00437 if (size == bwr_size) {
00438
00439
00440 k = (k + 1)%flat_buf->count;
00441 buf_count++;
00442 i_offset = (ADIO_Offset)buftype_extent*(ADIO_Offset)(buf_count/flat_buf->count) +
00443 flat_buf->indices[k];
00444 new_bwr_size = flat_buf->blocklens[k];
00445 if (size != fwr_size) {
00446 off += size;
00447 new_fwr_size -= size;
00448 }
00449 }
00450 num += size;
00451 fwr_size = new_fwr_size;
00452 bwr_size = new_bwr_size;
00453 }
00454 }
00455
00456
00457 if (writebuf_len) {
00458 ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
00459 writebuf_off, &status1, error_code);
00460 if (!(fd->atomicity))
00461 ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len);
00462 if (*error_code != MPI_SUCCESS) return;
00463 }
00464 if (fd->atomicity)
00465 ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
00466
00467 ADIOI_Free(writebuf);
00468
00469 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00470 }
00471
00472 fd->fp_sys_posn = -1;
00473
00474 #ifdef HAVE_STATUS_SET_BYTES
00475 MPIR_Status_set_bytes(status, datatype, bufsize);
00476
00477
00478 #endif
00479
00480 if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
00481 }
00482