00001
00002
00003
00004
00005
00006
00007
00008 #include <unistd.h>
00009
00010 #include "adio.h"
00011 #include "adio_extern.h"
00012
00013
00014
00015 void ADIOI_NOLOCK_WriteStrided(ADIO_File fd, void *buf, int count,
00016 MPI_Datatype datatype, int file_ptr_type,
00017 ADIO_Offset offset, ADIO_Status *status, int
00018 *error_code)
00019 {
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 ADIOI_Flatlist_node *flat_buf, *flat_file;
00030 int j, k, err=-1, st_index=0;
00031 ADIO_Offset fwr_size=0, bwr_size, new_bwr_size, new_fwr_size, i_offset, num;
00032 unsigned bufsize;
00033 int n_etypes_in_filetype;
00034 ADIO_Offset n_filetypes, etype_in_filetype, size, sum;
00035 ADIO_Offset abs_off_in_filetype=0, size_in_filetype;
00036 int filetype_size, etype_size, buftype_size;
00037 MPI_Aint filetype_extent, buftype_extent, indx;
00038 int buf_count, buftype_is_contig, filetype_is_contig;
00039 ADIO_Offset off, disp;
00040 int flag, err_flag=0;
00041 static char myname[] = "ADIOI_NOLOCK_WRITESTRIDED";
00042 #ifdef IO_DEBUG
00043 int rank,nprocs;
00044 #endif
00045
00046
00047 if (fd->atomicity) {
00048 *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
00049 myname, __LINE__,
00050 MPI_ERR_INTERN,
00051 "Atomic mode set in I/O function", 0);
00052 return;
00053 }
00054
00055
00056 ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
00057 ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00058
00059 MPI_Type_size(fd->filetype, &filetype_size);
00060 if ( ! filetype_size ) {
00061 *error_code = MPI_SUCCESS;
00062 return;
00063 }
00064
00065 #ifdef IO_DEBUG
00066 MPI_Comm_rank(fd->comm, &rank);
00067 MPI_Comm_size(fd->comm, &nprocs);
00068 #endif
00069
00070 MPI_Type_extent(fd->filetype, &filetype_extent);
00071 MPI_Type_size(datatype, &buftype_size);
00072 MPI_Type_extent(datatype, &buftype_extent);
00073 etype_size = fd->etype_size;
00074
00075 ADIOI_Assert((buftype_size * count) == ((ADIO_Offset)(unsigned)buftype_size * (ADIO_Offset)count));
00076 bufsize = buftype_size * count;
00077
00078 if (!buftype_is_contig && filetype_is_contig) {
00079 char *combine_buf, *combine_buf_ptr;
00080 ADIO_Offset combine_buf_remain;
00081
00082
00083 ADIOI_Flatten_datatype(datatype);
00084 flat_buf = CtvAccess(ADIOI_Flatlist);
00085 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00086
00087
00088 combine_buf = (char *) ADIOI_Malloc(fd->hints->ind_wr_buffer_size);
00089 combine_buf_ptr = combine_buf;
00090 combine_buf_remain = fd->hints->ind_wr_buffer_size;
00091
00092
00093 if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
00094 off = fd->disp + etype_size * offset;
00095 lseek(fd->fd_sys, off, SEEK_SET);
00096 }
00097 else off = lseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
00098
00099
00100
00101
00102
00103
00104
00105 for (j=0; j<count; j++) {
00106 int i;
00107 for (i=0; i<flat_buf->count; i++) {
00108 if (flat_buf->blocklens[i] > combine_buf_remain && combine_buf != combine_buf_ptr) {
00109
00110 #ifdef IO_DEBUG
00111 printf("[%d/%d] nc mem c file (0) writing loc = %Ld sz = %Ld\n",
00112 rank, nprocs, off,
00113 fd->hints->ind_wr_buffer_size-combine_buf_remain);
00114 #endif
00115 #ifdef ADIOI_MPE_LOGGING
00116 MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00117 #endif
00118 err = write(fd->fd_sys,
00119 combine_buf,
00120 fd->hints->ind_wr_buffer_size - combine_buf_remain);
00121 #ifdef ADIOI_MPE_LOGGING
00122 MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00123 #endif
00124 if (err == -1) err_flag = 1;
00125
00126
00127 combine_buf_ptr = combine_buf;
00128 combine_buf_remain = fd->hints->ind_wr_buffer_size;
00129 }
00130
00131
00132 if (flat_buf->blocklens[i] >= combine_buf_remain) {
00133
00134
00135
00136 #ifdef IO_DEBUG
00137 printf("[%d/%d] nc mem c file (1) writing loc = %Ld sz = %d\n",
00138 rank, nprocs, off,
00139 flat_buf->blocklens[i]);
00140 #endif
00141 ADIOI_Assert(flat_buf->blocklens[i] == (unsigned)flat_buf->blocklens[i]);
00142 ADIOI_Assert((((ADIO_Offset)(MPIR_Upint)buf) + (ADIO_Offset)j*(ADIO_Offset)buftype_extent + flat_buf->indices[i]) == (ADIO_Offset)((MPIR_Upint)buf + (ADIO_Offset)j*(ADIO_Offset)buftype_extent + flat_buf->indices[i]));
00143 #ifdef ADIOI_MPE_LOGGING
00144 MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00145 #endif
00146 err = write(fd->fd_sys,
00147 ((char *) buf) + (ADIO_Offset)j*(ADIO_Offset)buftype_extent + flat_buf->indices[i],
00148 (unsigned)flat_buf->blocklens[i]);
00149 #ifdef ADIOI_MPE_LOGGING
00150 MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00151 #endif
00152 if (err == -1) err_flag = 1;
00153 off += flat_buf->blocklens[i];
00154 }
00155 else {
00156
00157 memcpy(combine_buf_ptr,
00158 ((char *) buf) + j*buftype_extent + flat_buf->indices[i],
00159 flat_buf->blocklens[i]);
00160 combine_buf_ptr += flat_buf->blocklens[i];
00161 combine_buf_remain -= flat_buf->blocklens[i];
00162 off += flat_buf->blocklens[i];
00163 }
00164 }
00165 }
00166
00167 if (combine_buf_ptr != combine_buf) {
00168
00169 #ifdef IO_DEBUG
00170 printf("[%d/%d] nc mem c file (2) writing loc = %Ld sz = %Ld\n",
00171 rank, nprocs, off,
00172 fd->hints->ind_wr_buffer_size-combine_buf_remain);
00173 #endif
00174 #ifdef ADIOI_MPE_LOGGING
00175 MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00176 #endif
00177 err = write(fd->fd_sys,
00178 combine_buf,
00179 fd->hints->ind_wr_buffer_size - combine_buf_remain);
00180 #ifdef ADIOI_MPE_LOGGING
00181 MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00182 #endif
00183 if (err == -1) err_flag = 1;
00184 }
00185
00186 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00187
00188 ADIOI_Free(combine_buf);
00189
00190 if (err_flag) {
00191 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00192 MPIR_ERR_RECOVERABLE, myname,
00193 __LINE__, MPI_ERR_IO, "**io",
00194 "**io %s", strerror(errno));
00195 }
00196 else *error_code = MPI_SUCCESS;
00197 }
00198
00199 else {
00200
00201
00202
00203
00204
00205
00206 flat_file = CtvAccess(ADIOI_Flatlist);
00207 while (flat_file->type != fd->filetype) flat_file = flat_file->next;
00208 disp = fd->disp;
00209
00210 if (file_ptr_type == ADIO_INDIVIDUAL) {
00211 offset = fd->fp_ind;
00212 n_filetypes = -1;
00213 flag = 0;
00214 while (!flag) {
00215 int i;
00216 n_filetypes++;
00217 for (i=0; i<flat_file->count; i++) {
00218 if (disp + flat_file->indices[i] +
00219 n_filetypes*(ADIO_Offset)filetype_extent + flat_file->blocklens[i]
00220 >= offset) {
00221 st_index = i;
00222 fwr_size = disp + flat_file->indices[i] +
00223 n_filetypes*(ADIO_Offset)filetype_extent
00224 + flat_file->blocklens[i] - offset;
00225 flag = 1;
00226 break;
00227 }
00228 }
00229 }
00230 }
00231 else {
00232 int i;
00233 n_etypes_in_filetype = filetype_size/etype_size;
00234 n_filetypes = offset / n_etypes_in_filetype;
00235 etype_in_filetype = offset % n_etypes_in_filetype;
00236 size_in_filetype = etype_in_filetype * etype_size;
00237
00238 sum = 0;
00239 for (i=0; i<flat_file->count; i++) {
00240 sum += flat_file->blocklens[i];
00241 if (sum > size_in_filetype) {
00242 st_index = i;
00243 fwr_size = sum - size_in_filetype;
00244 abs_off_in_filetype = flat_file->indices[i] +
00245 size_in_filetype - (sum - flat_file->blocklens[i]);
00246 break;
00247 }
00248 }
00249
00250
00251 offset = disp + n_filetypes*(ADIO_Offset)filetype_extent + abs_off_in_filetype;
00252 }
00253
00254 if (buftype_is_contig && !filetype_is_contig) {
00255
00256
00257
00258
00259 i_offset = 0;
00260 j = st_index;
00261 off = offset;
00262 fwr_size = ADIOI_MIN(fwr_size, bufsize);
00263 while (i_offset < bufsize) {
00264 if (fwr_size) {
00265
00266
00267 #ifdef ADIOI_MPE_LOGGING
00268 MPE_Log_event(ADIOI_MPE_lseek_a, 0, NULL);
00269 #endif
00270 #ifdef IO_DEBUG
00271 printf("[%d/%d] c mem nc file writing loc = %Ld sz = %d\n",
00272 rank, nprocs, off, fwr_size);
00273 #endif
00274 err = lseek(fd->fd_sys, off, SEEK_SET);
00275 #ifdef ADIOI_MPE_LOGGING
00276 MPE_Log_event(ADIOI_MPE_lseek_b, 0, NULL);
00277 #endif
00278 if (err == -1) err_flag = 1;
00279 #ifdef ADIOI_MPE_LOGGING
00280 MPE_Log_event(ADIOI_MPE_write_a, 0, NULL);
00281 #endif
00282 err = write(fd->fd_sys, ((char *) buf) + i_offset, fwr_size);
00283 #ifdef ADIOI_MPE_LOGGING
00284 MPE_Log_event(ADIOI_MPE_write_b, 0, NULL);
00285 #endif
00286 if (err == -1) err_flag = 1;
00287 }
00288 i_offset += fwr_size;
00289
00290 if (off + fwr_size < disp + flat_file->indices[j] +
00291 flat_file->blocklens[j] + n_filetypes*(ADIO_Offset)filetype_extent)
00292 off += fwr_size;
00293
00294
00295 else {
00296 if (j < (flat_file->count - 1)) j++;
00297 else {
00298 j = 0;
00299 n_filetypes++;
00300 }
00301 off = disp + flat_file->indices[j] +
00302 n_filetypes*(ADIO_Offset)filetype_extent;
00303 fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i_offset);
00304 }
00305 }
00306 }
00307 else {
00308
00309
00310 ADIOI_Flatten_datatype(datatype);
00311 flat_buf = CtvAccess(ADIOI_Flatlist);
00312 while (flat_buf->type != datatype) flat_buf = flat_buf->next;
00313
00314 k = num = buf_count = 0;
00315 indx = flat_buf->indices[0];
00316 j = st_index;
00317 off = offset;
00318 bwr_size = flat_buf->blocklens[0];
00319
00320 while (num < bufsize) {
00321 size = ADIOI_MIN(fwr_size, bwr_size);
00322 if (size) {
00323 #ifdef IO_DEBUG
00324 printf("[%d/%d] nc mem nc file writing loc = %Ld sz = %d\n",
00325 rank, nprocs, off, size);
00326 #endif
00327 #ifdef ADIOI_MPE_LOGGING
00328 MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
00329 #endif
00330 lseek(fd->fd_sys, off, SEEK_SET);
00331 #ifdef ADIOI_MPE_LOGGING
00332 MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
00333 #endif
00334 if (err == -1) err_flag = 1;
00335 #ifdef ADIOI_MPE_LOGGING
00336 MPE_Log_event( ADIOI_MPE_write_a, 0, NULL );
00337 #endif
00338 ADIOI_Assert(size == (size_t) size);
00339 ADIOI_Assert(off == (off_t) off);
00340 err = write(fd->fd_sys, ((char *) buf) + indx, size);
00341 #ifdef ADIOI_MPE_LOGGING
00342 MPE_Log_event( ADIOI_MPE_write_b, 0, NULL );
00343 #endif
00344 if (err == -1) err_flag = 1;
00345 }
00346
00347 new_fwr_size = fwr_size;
00348 new_bwr_size = bwr_size;
00349
00350 if (size == fwr_size) {
00351
00352 if (j < (flat_file->count - 1)) j++;
00353 else {
00354 j = 0;
00355 n_filetypes++;
00356 }
00357
00358 off = disp + flat_file->indices[j] +
00359 n_filetypes*(ADIO_Offset)filetype_extent;
00360
00361 new_fwr_size = flat_file->blocklens[j];
00362 if (size != bwr_size) {
00363 indx += size;
00364 new_bwr_size -= size;
00365 }
00366 }
00367
00368 if (size == bwr_size) {
00369
00370
00371 k = (k + 1)%flat_buf->count;
00372 buf_count++;
00373 indx = buftype_extent*(buf_count/flat_buf->count) +
00374 flat_buf->indices[k];
00375 new_bwr_size = flat_buf->blocklens[k];
00376 if (size != fwr_size) {
00377 off += size;
00378 new_fwr_size -= size;
00379 }
00380 }
00381 num += size;
00382 fwr_size = new_fwr_size;
00383 bwr_size = new_bwr_size;
00384 }
00385 }
00386
00387 if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
00388 if (err_flag) {
00389 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00390 MPIR_ERR_RECOVERABLE, myname,
00391 __LINE__, MPI_ERR_IO, "**io",
00392 "**io %s", strerror(errno));
00393 }
00394 else *error_code = MPI_SUCCESS;
00395 }
00396
00397 fd->fp_sys_posn = -1;
00398
00399 #ifdef HAVE_STATUS_SET_BYTES
00400 MPIR_Status_set_bytes(status, datatype, bufsize);
00401
00402
00403 #endif
00404
00405 if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
00406 }