diff -ubr mpich2-1.2.1/src/mpi/romio/adio/ad_lustre/ad_lustre_aggregate.c mpich2-1.2.1-new/src/mpi/romio/adio/ad_lustre/ad_lustre_aggregate.c --- mpich2-1.2.1/src/mpi/romio/adio/ad_lustre/ad_lustre_aggregate.c 2009-07-02 09:19:27.000000000 -0600 +++ mpich2-1.2.1-new/src/mpi/romio/adio/ad_lustre/ad_lustre_aggregate.c 2010-01-02 20:23:58.000000000 -0700 @@ -24,7 +24,6 @@ */ int stripe_size, stripe_count, CO = 1, CO_max = 1, CO_nodes, lflag; int avail_cb_nodes, divisor, nprocs_for_coll = fd->hints->cb_nodes; - char *value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL + 1) * sizeof(char)); /* Get hints value */ /* stripe size */ @@ -59,20 +58,8 @@ * so that each OST is accessed by only one or more constant clients. */ CO_nodes = stripe_count * CO; avail_cb_nodes = ADIOI_MIN(nprocs_for_coll, CO_nodes); - if (avail_cb_nodes == CO_nodes) { - do { - /* find the divisor of CO_nodes */ - divisor = 1; - do { - divisor ++; - } while (CO_nodes % divisor); - CO_nodes = CO_nodes / divisor; - /* if stripe_count*CO is a prime number, change nothing */ - if ((CO_nodes <= avail_cb_nodes) && (CO_nodes != 1)) { - avail_cb_nodes = CO_nodes; - break; - } - } while (CO_nodes != 1); + while (CO_nodes % avail_cb_nodes != 0) { + avail_cb_nodes--; } *striping_info_ptr = (int *) ADIOI_Malloc(3 * sizeof(int)); @@ -80,8 +67,6 @@ striping_info[0] = stripe_size; striping_info[1] = stripe_count; striping_info[2] = avail_cb_nodes; - - ADIOI_Free(value); } int ADIOI_LUSTRE_Calc_aggregator(ADIO_File fd, ADIO_Offset off, @@ -125,11 +110,11 @@ int *count_my_req_procs_ptr, int **count_my_req_per_proc_ptr, ADIOI_Access **my_req_ptr, - int **buf_idx_ptr) + int ***buf_idx_ptr) { /* Nothing different from ADIOI_Calc_my_req(), except calling * ADIOI_Lustre_Calc_aggregator() instead of the old one */ - int *count_my_req_per_proc, count_my_req_procs, *buf_idx; + int *count_my_req_per_proc, count_my_req_procs, **buf_idx; int i, l, proc; ADIO_Offset avail_len, rem_len, curr_idx, off; ADIOI_Access *my_req; @@ -142,17 +127,6 @@ * MPI_Alltoall later on. */ - buf_idx = (int *) ADIOI_Malloc(nprocs * sizeof(int)); - /* buf_idx is relevant only if buftype_is_contig. - * buf_idx[i] gives the index into user_buf where data received - * from proc. i should be placed. This allows receives to be done - * without extra buffer. This can't be done if buftype is not contig. - */ - - /* initialize buf_idx to -1 */ - for (i = 0; i < nprocs; i++) - buf_idx[i] = -1; - /* one pass just to calculate how much space to allocate for my_req; * contig_access_count was calculated way back in ADIOI_Calc_my_off_len() */ @@ -186,6 +160,21 @@ } } + buf_idx = (int **) ADIOI_Malloc(nprocs * sizeof(int *)); + /* buf_idx is relevant only if buftype_is_contig. + * buf_idx[i] gives the index into user_buf where data received + * from proc. i should be placed. This allows receives to be done + * without extra buffer. This can't be done if buftype is not contig. + */ + + /* initialize buf_idx vectors */ + for (i = 0; i < nprocs; i++) { + /* add one to count_my_req_per_proc[i] to avoid zero size + * malloc */ + buf_idx[i] = (int *) ADIOI_Malloc((count_my_req_per_proc[i] + 1) + * sizeof(int)); + } + /* now allocate space for my_req, offset, and len */ *my_req_ptr = (ADIOI_Access *) ADIOI_Malloc(nprocs * sizeof(ADIOI_Access)); my_req = *my_req_ptr; @@ -212,15 +201,13 @@ continue; off = offset_list[i]; avail_len = len_list[i]; - proc = ADIOI_LUSTRE_Calc_aggregator(fd, off, &avail_len, striping_info); - - /* for each separate contiguous access from this process */ - if (buf_idx[proc] == -1) - buf_idx[proc] = (int) curr_idx; - + proc = ADIOI_LUSTRE_Calc_aggregator(fd, off, &avail_len, + striping_info); l = my_req[proc].count; - curr_idx += (int) avail_len; /* NOTE: Why is curr_idx an int? Fix? */ - + ADIOI_Assert(curr_idx == (int) curr_idx); + ADIOI_Assert(l < count_my_req_per_proc[proc]); + buf_idx[proc][l] = (int) curr_idx; + curr_idx += avail_len; rem_len = len_list[i] - avail_len; /* store the proc, offset, and len information in an array @@ -229,6 +216,7 @@ * and the associated count. */ my_req[proc].offsets[l] = off; + ADIOI_Assert(avail_len == (int) avail_len); my_req[proc].lens[l] = (int) avail_len; my_req[proc].count++; @@ -237,14 +225,16 @@ avail_len = rem_len; proc = ADIOI_LUSTRE_Calc_aggregator(fd, off, &avail_len, striping_info); - if (buf_idx[proc] == -1) - buf_idx[proc] = (int) curr_idx; - l = my_req[proc].count; + ADIOI_Assert(curr_idx == (int) curr_idx); + ADIOI_Assert(l < count_my_req_per_proc[proc]); + buf_idx[proc][l] = (int) curr_idx; + curr_idx += avail_len; rem_len -= avail_len; my_req[proc].offsets[l] = off; + ADIOI_Assert(avail_len == (int) avail_len); my_req[proc].lens[l] = (int) avail_len; my_req[proc].count++; } diff -ubr mpich2-1.2.1/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c mpich2-1.2.1-new/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c --- mpich2-1.2.1/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c 2009-07-02 09:19:27.000000000 -0600 +++ mpich2-1.2.1-new/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c 2010-01-04 08:44:56.000000000 -0700 @@ -21,7 +21,7 @@ ADIO_Offset *len_list, int contig_access_count, int *striping_info, - int *buf_idx, int *error_code); + int **buf_idx, int *error_code); static void ADIOI_LUSTRE_Fill_send_buffer(ADIO_File fd, void *buf, ADIOI_Flatlist_node *flat_buf, char **send_buf, @@ -83,7 +83,7 @@ ADIO_Offset orig_fp, start_offset, end_offset, off; ADIO_Offset *offset_list = NULL, *st_offsets = NULL, *end_offsets = NULL; ADIO_Offset *len_list = NULL; - int *buf_idx = NULL, *striping_info = NULL; + int **buf_idx = NULL, *striping_info = NULL; int old_error, tmp_error; MPI_Comm_size(fd->comm, &nprocs); @@ -153,7 +153,7 @@ ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig); if (buftype_is_contig && filetype_is_contig) { if (file_ptr_type == ADIO_EXPLICIT_OFFSET) { - off = fd->disp + (fd->etype_size) * offset; + off = fd->disp + (ADIO_Offset)(fd->etype_size) * offset; ADIO_WriteContig(fd, buf, count, datatype, ADIO_EXPLICIT_OFFSET, off, status, error_code); @@ -175,7 +175,8 @@ */ ADIOI_LUSTRE_Calc_my_req(fd, offset_list, len_list, contig_access_count, striping_info, nprocs, &count_my_req_procs, - &count_my_req_per_proc, &my_req, &buf_idx); + &count_my_req_per_proc, &my_req, + &buf_idx); /* based on everyone's my_req, calculate what requests of other processes * will be accessed by this process. @@ -192,9 +193,9 @@ /* exchange data and write in sizes of no more than stripe_size. */ ADIOI_LUSTRE_Exch_and_write(fd, buf, datatype, nprocs, myrank, - others_req, my_req, - offset_list, len_list, contig_access_count, - striping_info, buf_idx, error_code); + others_req, my_req, offset_list, len_list, + contig_access_count, striping_info, + buf_idx, error_code); /* If this collective write is followed by an independent write, * it's possible to have those subsequent writes on other processes @@ -253,6 +254,9 @@ } } ADIOI_Free(my_req); + for (i = 0; i < nprocs; i++) { + ADIOI_Free(buf_idx[i]); + } ADIOI_Free(buf_idx); ADIOI_Free(offset_list); ADIOI_Free(len_list); @@ -286,7 +290,7 @@ ADIO_Offset *offset_list, ADIO_Offset *len_list, int contig_access_count, - int *striping_info, int *buf_idx, + int *striping_info, int **buf_idx, int *error_code) { /* Send data to appropriate processes and write in sizes of no more @@ -308,6 +312,7 @@ int *send_curr_offlen_ptr, *send_size; int *partial_recv, *sent_to_proc, *recv_start_pos; int *send_buf_idx, *curr_to_proc, *done_to_proc; + int *this_buf_idx; char *write_buf = NULL; MPI_Status status; ADIOI_Flatlist_node *flat_buf = NULL; @@ -355,7 +360,9 @@ * and ntimes=whole_file_portion/step_size */ step_size = (ADIO_Offset) avail_cb_nodes * stripe_size; - max_ntimes = (int)((max_end_loc - min_st_loc) / step_size + 1); + max_ntimes = (max_end_loc - min_st_loc + 1) / step_size + + (((max_end_loc - min_st_loc + 1) % step_size) ? 1 : 0); +/* max_ntimes = (int)((max_end_loc - min_st_loc) / step_size + 1); */ if (ntimes) write_buf = (char *) ADIOI_Malloc(stripe_size); @@ -395,6 +402,8 @@ done_to_proc = (int *) ADIOI_Malloc(nprocs * sizeof(int)); /* Above three are used in ADIOI_Fill_send_buffer */ + this_buf_idx = (int *) ADIOI_Malloc(nprocs * sizeof(int)); + recv_start_pos = (int *) ADIOI_Malloc(nprocs * sizeof(int)); /* used to store the starting value of recv_curr_offlen_ptr[i] in this iteration */ @@ -461,11 +470,13 @@ off = off_list[m]; max_size = ADIOI_MIN(step_size, max_end_loc - iter_st_off + 1); - real_size = (int) ADIOI_MIN((off / stripe_size + 1) * stripe_size - off, + real_size = (int) ADIOI_MIN((off / stripe_size + 1) * stripe_size - + off, end_loc - off + 1); for (i = 0; i < nprocs; i++) { if (my_req[i].count) { + this_buf_idx[i] = buf_idx[i][send_curr_offlen_ptr[i]]; for (j = send_curr_offlen_ptr[i]; j < my_req[i].count; j++) { send_off = my_req[i].offsets[j]; send_len = my_req[i].lens[j]; @@ -484,6 +495,7 @@ req_len = others_req[i].lens[j]; if (req_off < iter_st_off + max_size) { recv_count[i]++; + ADIOI_Assert((((ADIO_Offset)(MPIR_Upint)write_buf)+req_off-off) == (ADIO_Offset)(MPIR_Upint)(write_buf+req_off-off)); MPI_Address(write_buf + req_off - off, &(others_req[i].mem_ptrs[j])); recv_size[i] += req_len; @@ -503,7 +515,7 @@ buftype_is_contig, contig_access_count, striping_info, others_req, send_buf_idx, curr_to_proc, done_to_proc, &hole, m, - buftype_extent, buf_idx, error_code); + buftype_extent, this_buf_idx, error_code); if (*error_code != MPI_SUCCESS) goto over; @@ -564,6 +576,7 @@ ADIOI_Free(send_buf_idx); ADIOI_Free(curr_to_proc); ADIOI_Free(done_to_proc); + ADIOI_Free(this_buf_idx); ADIOI_Free(off_list); } @@ -714,13 +727,14 @@ j = 0; for (i = 0; i < nprocs; i++) if (send_size[i]) { + ADIOI_Assert(buf_idx[i] != -1); MPI_Isend(((char *) buf) + buf_idx[i], send_size[i], MPI_BYTE, i, myrank + i + 100 * iter, fd->comm, send_req + j); j++; - buf_idx[i] += send_size[i]; } - } else if (nprocs_send) { + } else + if (nprocs_send) { /* buftype is not contig */ send_buf = (char **) ADIOI_Malloc(nprocs * sizeof(char *)); for (i = 0; i < nprocs; i++) @@ -803,7 +817,7 @@ n_buftypes++; \ } \ user_buf_idx = flat_buf->indices[flat_buf_idx] + \ - n_buftypes*buftype_extent; \ + (ADIO_Offset)n_buftypes*(ADIO_Offset)buftype_extent; \ flat_buf_sz = flat_buf->blocklens[flat_buf_idx]; \ } \ buf_incr -= size_in_buf; \ @@ -815,6 +829,8 @@ { \ while (size) { \ size_in_buf = ADIOI_MIN(size, flat_buf_sz); \ + ADIOI_Assert((((ADIO_Offset)(MPIR_Upint)buf) + user_buf_idx) == (ADIO_Offset)(MPIR_Upint)((MPIR_Upint)buf + user_buf_idx)); \ + ADIOI_Assert(size_in_buf == (size_t)size_in_buf); \ memcpy(&(send_buf[p][send_buf_idx[p]]), \ ((char *) buf) + user_buf_idx, size_in_buf); \ send_buf_idx[p] += size_in_buf; \ @@ -827,7 +843,7 @@ n_buftypes++; \ } \ user_buf_idx = flat_buf->indices[flat_buf_idx] + \ - n_buftypes*buftype_extent; \ + (ADIO_Offset)n_buftypes*(ADIO_Offset)buftype_extent; \ flat_buf_sz = flat_buf->blocklens[flat_buf_idx]; \ } \ size -= size_in_buf; \ @@ -900,14 +916,17 @@ send_buf_idx[p]); buf_incr = done_to_proc[p] - curr_to_proc[p]; ADIOI_BUF_INCR + ADIOI_Assert((curr_to_proc[p] + len - done_to_proc[p]) == (unsigned)(curr_to_proc[p] + len - done_to_proc[p])); buf_incr = (int) (curr_to_proc[p] + len - done_to_proc[p]); + ADIOI_Assert((done_to_proc[p] + size) == (unsigned)(done_to_proc[p] + size)); curr_to_proc[p] = done_to_proc[p] + size; ADIOI_BUF_COPY } else { size = (int) ADIOI_MIN(len, send_size[p] - send_buf_idx[p]); buf_incr = (int) len; + ADIOI_Assert((curr_to_proc[p] + size) == (unsigned)((ADIO_Offset)curr_to_proc[p] + size)); curr_to_proc[p] += size; ADIOI_BUF_COPY } @@ -918,6 +937,7 @@ jj++; } } else { + ADIOI_Assert((curr_to_proc[p] + len) == (unsigned)((ADIO_Offset)curr_to_proc[p] + len)); curr_to_proc[p] += (int) len; buf_incr = (int) len; ADIOI_BUF_INCR diff -ubr mpich2-1.2.1/src/mpi/romio/adio/ad_lustre/ad_lustre_wrstr.c mpich2-1.2.1-new/src/mpi/romio/adio/ad_lustre/ad_lustre_wrstr.c --- mpich2-1.2.1/src/mpi/romio/adio/ad_lustre/ad_lustre_wrstr.c 2009-03-13 09:30:30.000000000 -0600 +++ mpich2-1.2.1-new/src/mpi/romio/adio/ad_lustre/ad_lustre_wrstr.c 2010-01-04 08:50:51.000000000 -0700 @@ -16,12 +16,14 @@ if (req_off >= writebuf_off + writebuf_len) { \ if (writebuf_len) { \ ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \ - ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \ + ADIO_EXPLICIT_OFFSET, writebuf_off, \ + &status1, error_code); \ if (!(fd->atomicity)) \ ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \ if (*error_code != MPI_SUCCESS) { \ *error_code = MPIO_Err_create_code(*error_code, \ - MPIR_ERR_RECOVERABLE, myname, \ + MPIR_ERR_RECOVERABLE, \ + myname, \ __LINE__, MPI_ERR_IO, \ "**iowswc", 0); \ ADIOI_Free(writebuf); \ @@ -30,25 +32,30 @@ } \ writebuf_off = req_off; \ /* stripe_size alignment */ \ - writebuf_len = (int) ADIOI_MIN(end_offset - writebuf_off + 1, \ + writebuf_len = (unsigned) ADIOI_MIN(end_offset - writebuf_off + 1, \ (writebuf_off / stripe_size + 1) * \ - stripe_size - writebuf_off);\ + stripe_size - writebuf_off); \ if (!(fd->atomicity)) \ ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \ - ADIO_ReadContig(fd, writebuf, writebuf_len, MPI_BYTE, ADIO_EXPLICIT_OFFSET,\ + ADIO_ReadContig(fd, writebuf, writebuf_len, MPI_BYTE, \ + ADIO_EXPLICIT_OFFSET, \ writebuf_off, &status1, error_code); \ if (*error_code != MPI_SUCCESS) { \ *error_code = MPIO_Err_create_code(*error_code, \ - MPIR_ERR_RECOVERABLE, myname, \ + MPIR_ERR_RECOVERABLE, \ + myname, \ __LINE__, MPI_ERR_IO, \ "**iowsrc", 0); \ ADIOI_Free(writebuf); \ return; \ } \ } \ - write_sz = (int) ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off); \ - memcpy(writebuf + req_off - writebuf_off, (char *)buf + userbuf_off, write_sz);\ - while (write_sz != req_len) {\ + write_sz = (unsigned) (ADIOI_MIN(req_len, \ + writebuf_off + writebuf_len - req_off)); \ + ADIOI_Assert((ADIO_Offset)write_sz == \ + ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \ + memcpy(writebuf + req_off - writebuf_off, (char *)buf +userbuf_off, write_sz); \ + while (write_sz != req_len) { \ ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \ ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \ if (!(fd->atomicity)) \ @@ -65,12 +72,13 @@ userbuf_off += write_sz; \ writebuf_off += writebuf_len; \ /* stripe_size alignment */ \ - writebuf_len = (int) ADIOI_MIN(end_offset - writebuf_off + 1, \ + writebuf_len = (unsigned) ADIOI_MIN(end_offset - writebuf_off + 1, \ (writebuf_off / stripe_size + 1) * \ - stripe_size - writebuf_off);\ + stripe_size - writebuf_off); \ if (!(fd->atomicity)) \ ADIOI_WRITE_LOCK(fd, writebuf_off, SEEK_SET, writebuf_len); \ - ADIO_ReadContig(fd, writebuf, writebuf_len, MPI_BYTE, ADIO_EXPLICIT_OFFSET,\ + ADIO_ReadContig(fd, writebuf, writebuf_len, MPI_BYTE, \ + ADIO_EXPLICIT_OFFSET, \ writebuf_off, &status1, error_code); \ if (*error_code != MPI_SUCCESS) { \ *error_code = MPIO_Err_create_code(*error_code, \ @@ -81,7 +89,7 @@ return; \ } \ write_sz = ADIOI_MIN(req_len, writebuf_len); \ - memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\ + memcpy(writebuf, (char *)buf + userbuf_off, write_sz); \ } \ } @@ -91,15 +99,29 @@ #define ADIOI_BUFFERED_WRITE_WITHOUT_READ \ { \ if (req_off >= writebuf_off + writebuf_len) { \ + ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \ + ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, \ + error_code); \ + if (*error_code != MPI_SUCCESS) { \ + *error_code = MPIO_Err_create_code(*error_code, \ + MPIR_ERR_RECOVERABLE, \ + myname, \ + __LINE__, MPI_ERR_IO, \ + "**iowswc", 0); \ + ADIOI_Free(writebuf); \ + return; \ + } \ writebuf_off = req_off; \ /* stripe_size alignment */ \ - writebuf_len = (int) ADIOI_MIN(end_offset - writebuf_off + 1, \ + writebuf_len = (unsigned) ADIOI_MIN(end_offset - writebuf_off + 1, \ (writebuf_off / stripe_size + 1) * \ - stripe_size - writebuf_off);\ + stripe_size - writebuf_off); \ } \ - write_sz = (int) ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off); \ - memcpy(writebuf + req_off - writebuf_off, (char *)buf + userbuf_off, write_sz);\ - while (req_len) { \ + write_sz = (unsigned) ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off); \ + ADIOI_Assert((ADIO_Offset)write_sz == ADIOI_MIN(req_len, writebuf_off + writebuf_len - req_off)); \ + memcpy(writebuf + req_off - writebuf_off, \ + (char *)buf + userbuf_off, write_sz); \ + while (write_sz != req_len) { \ ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, \ ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); \ if (*error_code != MPI_SUCCESS) { \ @@ -114,11 +136,11 @@ userbuf_off += write_sz; \ writebuf_off += writebuf_len; \ /* stripe_size alignment */ \ - writebuf_len = (int) ADIOI_MIN(end_offset - writebuf_off + 1, \ + writebuf_len = (unsigned) ADIOI_MIN(end_offset - writebuf_off + 1, \ (writebuf_off / stripe_size + 1) * \ - stripe_size - writebuf_off);\ + stripe_size - writebuf_off); \ write_sz = ADIOI_MIN(req_len, writebuf_len); \ - memcpy(writebuf, (char *)buf + userbuf_off, write_sz);\ + memcpy(writebuf, (char *)buf + userbuf_off, write_sz); \ } \ } @@ -129,23 +151,22 @@ { /* offset is in units of etype relative to the filetype. */ ADIOI_Flatlist_node *flat_buf, *flat_file; - int i, j, k, bwr_size, fwr_size = 0, st_index = 0; - int bufsize, num, size, sum, n_etypes_in_filetype, size_in_filetype; - int n_filetypes, etype_in_filetype; - ADIO_Offset abs_off_in_filetype = 0; - int filetype_size, etype_size, buftype_size, req_len; + ADIO_Offset i_offset, sum, size_in_filetype; + int i, j, k, st_index=0; + int n_etypes_in_filetype; + ADIO_Offset num, size, n_filetypes, etype_in_filetype, st_n_filetypes; + ADIO_Offset abs_off_in_filetype=0; + int filetype_size, etype_size, buftype_size; MPI_Aint filetype_extent, buftype_extent; int buf_count, buftype_is_contig, filetype_is_contig; ADIO_Offset userbuf_off; - ADIO_Offset off, req_off, disp, end_offset = 0, writebuf_off, start_off; + ADIO_Offset off, req_off, disp, end_offset=0, writebuf_off, start_off; char *writebuf; - int flag, st_fwr_size, st_n_filetypes, writebuf_len, write_sz; + unsigned bufsize, writebuf_len, write_sz; ADIO_Status status1; - int new_bwr_size, new_fwr_size; + ADIO_Offset new_bwr_size, new_fwr_size, st_fwr_size, fwr_size=0, bwr_size, req_len; int stripe_size; static char myname[] = "ADIOI_LUSTRE_WriteStrided"; - int myrank; - MPI_Comm_rank(fd->comm, &myrank); if (fd->hints->ds_write == ADIOI_HINT_DISABLE) { /* if user has disabled data sieving on writes, use naive @@ -176,6 +197,7 @@ MPI_Type_extent(datatype, &buftype_extent); etype_size = fd->etype_size; + ADIOI_Assert((buftype_size * count) == ((ADIO_Offset)(unsigned)buftype_size * (ADIO_Offset)count)); bufsize = buftype_size * count; /* get striping info */ @@ -190,16 +212,14 @@ flat_buf = flat_buf->next; off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind : - fd->disp + etype_size * offset; + fd->disp + (ADIO_Offset)etype_size * offset; start_off = off; end_offset = start_off + bufsize - 1; - writebuf_off = start_off; /* write stripe size buffer each time */ writebuf = (char *) ADIOI_Malloc(ADIOI_MIN(bufsize, stripe_size)); - writebuf_len = (int) ADIOI_MIN(bufsize, - (writebuf_off / stripe_size + 1) * - stripe_size - writebuf_off); + writebuf_off = 0; + writebuf_len = 0; /* if atomicity is true, lock the region to be accessed */ if (fd->atomicity) @@ -207,7 +227,8 @@ for (j = 0; j < count; j++) { for (i = 0; i < flat_buf->count; i++) { - userbuf_off = j * buftype_extent + flat_buf->indices[i]; + userbuf_off = (ADIO_Offset)j * (ADIO_Offset)buftype_extent + + flat_buf->indices[i]; req_off = off; req_len = flat_buf->blocklens[i]; ADIOI_BUFFERED_WRITE_WITHOUT_READ @@ -238,30 +259,36 @@ disp = fd->disp; if (file_ptr_type == ADIO_INDIVIDUAL) { - offset = fd->fp_ind; /* in bytes */ - n_filetypes = -1; - flag = 0; - while (!flag) { - n_filetypes++; - for (i = 0; i < flat_file->count; i++) { - if (disp + flat_file->indices[i] + - (ADIO_Offset) n_filetypes * filetype_extent + - flat_file->blocklens[i] >= offset) { - st_index = i; - fwr_size = (int) (disp + flat_file->indices[i] + - (ADIO_Offset) n_filetypes * - filetype_extent + - flat_file->blocklens[i] - - offset); - flag = 1; + /* Wei-keng reworked type processing to be a bit more efficient */ + offset = fd->fp_ind - disp; + n_filetypes = (offset - flat_file->indices[0]) / filetype_extent; + offset -= (ADIO_Offset)n_filetypes * filetype_extent; + /* now offset is local to this extent */ + + /* find the block where offset is located, skip blocklens[i]==0 */ + for (i=0; icount; i++) { + ADIO_Offset dist; + if (flat_file->blocklens[i] == 0) continue; + dist = flat_file->indices[i] + flat_file->blocklens[i] - offset; + /* fwr_size is from offset to the end of block i */ + if (dist == 0) { + i++; + offset = flat_file->indices[i]; + fwr_size = flat_file->blocklens[i]; break; } + if (dist > 0) { + fwr_size = dist; + break; } } - } else { - n_etypes_in_filetype = filetype_size / etype_size; - n_filetypes = (int) (offset / n_etypes_in_filetype); - etype_in_filetype = (int) (offset % n_etypes_in_filetype); + st_index = i; /* starting index in flat_file->indices[] */ + offset += disp + (ADIO_Offset)n_filetypes*filetype_extent; + } + else { + n_etypes_in_filetype = filetype_size/etype_size; + n_filetypes = offset / n_etypes_in_filetype; + etype_in_filetype = offset % n_etypes_in_filetype; size_in_filetype = etype_in_filetype * etype_size; sum = 0; @@ -283,8 +310,11 @@ start_off = offset; - /* If the file bytes is actually contiguous, we do not need data sieve at all */ - if (bufsize <= fwr_size) { + /* Wei-keng Liao:write request is within single flat_file + * contig block*/ + /* this could happen, for example, with subarray types that are + * actually fairly contiguous */ + if (buftype_is_contig && bufsize <= fwr_size) { req_off = start_off; req_len = bufsize; end_offset = start_off + bufsize - 1; @@ -294,90 +324,122 @@ writebuf_len = 0; userbuf_off = 0; ADIOI_BUFFERED_WRITE_WITHOUT_READ - } else { + /* write the buffer out finally */ + ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, + ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, + error_code); + + if (file_ptr_type == ADIO_INDIVIDUAL) { + /* update MPI-IO file pointer to point to the first byte + * that can be accessed in the fileview. */ + fd->fp_ind = offset + bufsize; + if (bufsize == fwr_size) { + do { + st_index++; + if (st_index == flat_file->count) { + st_index = 0; + n_filetypes++; + } + } while (flat_file->blocklens[st_index] == 0); + fd->fp_ind = disp + flat_file->indices[st_index] + + (ADIO_Offset)n_filetypes*filetype_extent; + } + } + fd->fp_sys_posn = -1; /* set it to null. */ +#ifdef HAVE_STATUS_SET_BYTES + MPIR_Status_set_bytes(status, datatype, bufsize); +#endif + ADIOI_Free(writebuf); + return; + } + /* Calculate end_offset, the last byte-offset that will be accessed. - e.g., if start_offset=0 and 100 bytes to be write, end_offset=99 */ + e.g., if start_offset=0 and 100 bytes to be write, end_offset=99*/ + st_fwr_size = fwr_size; st_n_filetypes = n_filetypes; - i = 0; + i_offset = 0; j = st_index; off = offset; fwr_size = ADIOI_MIN(st_fwr_size, bufsize); - while (i < bufsize) { - i += fwr_size; + while (i_offset < bufsize) { + i_offset += fwr_size; end_offset = off + fwr_size - 1; - if (j < (flat_file->count - 1)) - j++; - else { - j = 0; - n_filetypes++; + j = (j+1) % flat_file->count; + n_filetypes += (j == 0) ? 1 : 0; + while (flat_file->blocklens[j]==0) { + j = (j+1) % flat_file->count; + n_filetypes += (j == 0) ? 1 : 0; } off = disp + flat_file->indices[j] + - (ADIO_Offset) n_filetypes * filetype_extent; - fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize - i); + n_filetypes*(ADIO_Offset)filetype_extent; + fwr_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i_offset); } +/* if atomicity is true, lock the region to be accessed */ + if (fd->atomicity) + ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1); + writebuf_off = 0; writebuf_len = 0; writebuf = (char *) ADIOI_Malloc(stripe_size); memset(writebuf, -1, stripe_size); - /* if atomicity is true, lock the region to be accessed */ - if (fd->atomicity) - ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, bufsize); if (buftype_is_contig && !filetype_is_contig) { - /* contiguous in memory, noncontiguous in file. should be the most + +/* contiguous in memory, noncontiguous in file. should be the most common case. */ - i = 0; + + i_offset = 0; j = st_index; off = offset; n_filetypes = st_n_filetypes; fwr_size = ADIOI_MIN(st_fwr_size, bufsize); - while (i < bufsize) { + while (i_offset < bufsize) { if (fwr_size) { /* TYPE_UB and TYPE_LB can result in fwr_size = 0. save system call in such cases */ - /* - lseek(fd->fd_sys, off, SEEK_SET); - err = write(fd->fd_sys, ((char *) buf) + i, fwr_size); - */ + /* lseek(fd->fd_sys, off, SEEK_SET); + err = write(fd->fd_sys, ((char *) buf) + i_offset, fwr_size);*/ + req_off = off; req_len = fwr_size; - userbuf_off = i; + userbuf_off = i_offset; ADIOI_BUFFERED_WRITE } - i += fwr_size; + i_offset += fwr_size; if (off + fwr_size < disp + flat_file->indices[j] + flat_file->blocklens[j] + - (ADIO_Offset) n_filetypes * filetype_extent) + n_filetypes*(ADIO_Offset)filetype_extent) off += fwr_size; /* did not reach end of contiguous block in filetype. no more I/O needed. off is incremented by fwr_size. */ else { - if (j < (flat_file->count - 1)) - j++; - else { - j = 0; - n_filetypes++; + j = (j+1) % flat_file->count; + n_filetypes += (j == 0) ? 1 : 0; + while (flat_file->blocklens[j]==0) { + j = (j+1) % flat_file->count; + n_filetypes += (j == 0) ? 1 : 0; } off = disp + flat_file->indices[j] + - (ADIO_Offset) n_filetypes * filetype_extent; + n_filetypes*(ADIO_Offset)filetype_extent; fwr_size = ADIOI_MIN(flat_file->blocklens[j], - bufsize - i); + bufsize-i_offset); } } - } else { - /* noncontiguous in memory as well as in file */ + } + else { +/* noncontiguous in memory as well as in file */ + ADIOI_Flatten_datatype(datatype); flat_buf = ADIOI_Flatlist; - while (flat_buf->type != datatype) - flat_buf = flat_buf->next; + while (flat_buf->type != datatype) flat_buf = flat_buf->next; k = num = buf_count = 0; - i = (int) (flat_buf->indices[0]); + i_offset = flat_buf->indices[0]; j = st_index; off = offset; n_filetypes = st_n_filetypes; @@ -387,13 +449,12 @@ while (num < bufsize) { size = ADIOI_MIN(fwr_size, bwr_size); if (size) { - /* - lseek(fd->fd_sys, off, SEEK_SET); - err = write(fd->fd_sys, ((char *) buf) + i, size); - */ + /* lseek(fd->fd_sys, off, SEEK_SET); + err = write(fd->fd_sys, ((char *) buf) + i_offset, size); */ + req_off = off; req_len = size; - userbuf_off = i; + userbuf_off = i_offset; ADIOI_BUFFERED_WRITE } @@ -401,28 +462,32 @@ new_bwr_size = bwr_size; if (size == fwr_size) { - /* reached end of contiguous block in file */ - if (j < (flat_file->count - 1)) { - j++; - } else { - j = 0; - n_filetypes++; +/* reached end of contiguous block in file */ + j = (j+1) % flat_file->count; + n_filetypes += (j == 0) ? 1 : 0; + while (flat_file->blocklens[j]==0) { + j = (j+1) % flat_file->count; + n_filetypes += (j == 0) ? 1 : 0; } + off = disp + flat_file->indices[j] + - (ADIO_Offset) n_filetypes * filetype_extent; + n_filetypes*(ADIO_Offset)filetype_extent; + new_fwr_size = flat_file->blocklens[j]; if (size != bwr_size) { - i += size; + i_offset += size; new_bwr_size -= size; } } + if (size == bwr_size) { - /* reached end of contiguous block in memory */ - k = (k + 1) % flat_buf->count; +/* reached end of contiguous block in memory */ + + k = (k + 1)%flat_buf->count; buf_count++; - i = (int) (buftype_extent * - (buf_count / flat_buf->count) + - flat_buf->indices[k]); + i_offset = (ADIO_Offset)buftype_extent * + (ADIO_Offset)(buf_count/flat_buf->count) + + flat_buf->indices[k]; new_bwr_size = flat_buf->blocklens[k]; if (size != fwr_size) { off += size; @@ -437,28 +502,26 @@ /* write the buffer out finally */ if (writebuf_len) { - ADIO_WriteContig(fd, writebuf, writebuf_len, - MPI_BYTE, ADIO_EXPLICIT_OFFSET, + ADIO_WriteContig(fd, writebuf, writebuf_len, MPI_BYTE, + ADIO_EXPLICIT_OFFSET, writebuf_off, &status1, error_code); if (!(fd->atomicity)) ADIOI_UNLOCK(fd, writebuf_off, SEEK_SET, writebuf_len); - if (*error_code != MPI_SUCCESS) { - ADIOI_Free(writebuf); - return; - } + if (*error_code != MPI_SUCCESS) return; } if (fd->atomicity) - ADIOI_UNLOCK(fd, start_off, SEEK_SET, bufsize); - } + ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1); + ADIOI_Free(writebuf); - if (file_ptr_type == ADIO_INDIVIDUAL) - fd->fp_ind = off; + + if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off; } + fd->fp_sys_posn = -1; /* set it to null. */ #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, datatype, bufsize); - /* This is a temporary way of filling in status. The right way is to +/* This is a temporary way of filling in status. The right way is to keep track of how much data was actually written by ADIOI_BUFFERED_WRITE. */ #endif diff -ubr mpich2-1.2.1/src/mpi/romio/adio/common/ad_fstype.c mpich2-1.2.1-new/src/mpi/romio/adio/common/ad_fstype.c --- mpich2-1.2.1/src/mpi/romio/adio/common/ad_fstype.c 2009-06-01 16:57:33.000000000 -0600 +++ mpich2-1.2.1-new/src/mpi/romio/adio/common/ad_fstype.c 2009-12-29 13:20:21.000000000 -0700 @@ -346,18 +346,13 @@ } # endif -/*#if defined(LINUX) && defined(ROMIO_LUSTRE)*/ -#if 0 - /* disable lustre auto-detection until we figure out why collective i/o - * broken */ -#ifdef ROMIO_LUSTRE -#define LL_SUPER_MAGIC 0x0BD00BD0 +# ifdef ROMIO_LUSTRE +# define LL_SUPER_MAGIC 0x0BD00BD0 if (fsbuf.f_type == LL_SUPER_MAGIC) { *fstype = ADIO_LUSTRE; return; } # endif -#endif # ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) {