/* ADIOI_cb_delete_name_array() - attribute destructor */ int ADIOI_cb_delete_name_array(MPI_Comm comm, int keyval, void *attr_val, void *extra) { ADIO_cb_name_array array; ADIOI_UNREFERENCED_ARG(comm); ADIOI_UNREFERENCED_ARG(extra); array = (ADIO_cb_name_array) attr_val; ADIOI_Assert(array != NULL); array->refct--; if (array->refct <= 0) { /* time to free the structures (names, array of ptrs to names, struct) */ if (array->namect) { /* Note that array->names[i], where i > 0, * are just pointers into the allocated region array->names[0] */ ADIOI_Free(array->names[0]); } if (array->names != NULL) ADIOI_Free(array->names); ADIOI_Free(array); } return MPI_SUCCESS; }
int ADIOI_End_call(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state) { int error_code; ADIOI_UNREFERENCED_ARG(comm); ADIOI_UNREFERENCED_ARG(keyval); ADIOI_UNREFERENCED_ARG(attribute_val); ADIOI_UNREFERENCED_ARG(extra_state); ADIO_End(&error_code); return error_code; }
/* TODO: still needs to handle partial datatypes and situations where the mpi * implementation fills status with something other than bytes (globus2 might * do this) */ int MPIR_Status_set_bytes(MPI_Status *status, MPI_Datatype datatype, int nbytes) { ADIOI_UNREFERENCED_ARG(datatype); /* it's ok that ROMIO stores number-of-bytes in status, not * count-of-copies, as long as MPI_GET_COUNT knows what to do */ if (status != MPI_STATUS_IGNORE) MPI_Status_set_elements(status, MPI_BYTE, nbytes); return MPI_SUCCESS; }
int ADIOI_End_call(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state) { int error_code; ADIOI_UNREFERENCED_ARG(comm); ADIOI_UNREFERENCED_ARG(attribute_val); ADIOI_UNREFERENCED_ARG(extra_state); MPI_Keyval_free(&keyval); /* The end call will be called after all possible uses of this keyval, even * if a file was opened with MPI_COMM_SELF. Note, this assumes LIFO * MPI_COMM_SELF attribute destruction behavior mandated by MPI-2.2. */ if (ADIOI_cb_config_list_keyval != MPI_KEYVAL_INVALID) MPI_Keyval_free(&ADIOI_cb_config_list_keyval); ADIO_End(&error_code); return error_code; }
/* ADIOI_Calc_aggregator() * * The intention here is to implement a function which provides basically * the same functionality as in Rajeev's original version of * ADIOI_Calc_my_req(). He used a ceiling division approach to assign the * file domains, and we use the same approach here when calculating the * location of an offset/len in a specific file domain. Further we assume * this same distribution when calculating the rank_index, which is later * used to map to a specific process rank in charge of the file domain. * * A better (i.e. more general) approach would be to use the list of file * domains only. This would be slower in the case where the * original ceiling division was used, but it would allow for arbitrary * distributions of regions to aggregators. We'd need to know the * nprocs_for_coll in that case though, which we don't have now. * * Note a significant difference between this function and Rajeev's old code: * this code doesn't necessarily return a rank in the range * 0..nprocs_for_coll; instead you get something in 0..nprocs. This is a * result of the rank mapping; any set of ranks in the communicator could be * used now. * * Returns an integer representing a rank in the collective I/O communicator. * * The "len" parameter is also modified to indicate the amount of data * actually available in this file domain. */ int ADIOI_Calc_aggregator(ADIO_File fd, ADIO_Offset off, ADIO_Offset min_off, ADIO_Offset *len, ADIO_Offset fd_size, ADIO_Offset *fd_start, ADIO_Offset *fd_end) { int rank_index, rank; ADIO_Offset avail_bytes; ADIOI_UNREFERENCED_ARG(fd_start); /* get an index into our array of aggregators */ rank_index = (int) ((off - min_off + fd_size)/ fd_size - 1); if (fd->hints->striping_unit > 0) { /* wkliao: implementation for file domain alignment fd_start[] and fd_end[] have been aligned with file lock boundaries when returned from ADIOI_Calc_file_domains() so cannot just use simple arithmatic as above */ rank_index = 0; while (off > fd_end[rank_index]) rank_index++; } /* we index into fd_end with rank_index, and fd_end was allocated to be no * bigger than fd->hins->cb_nodes. If we ever violate that, we're * overrunning arrays. Obviously, we should never ever hit this abort */ if (rank_index >= fd->hints->cb_nodes || rank_index < 0) { FPRINTF(stderr, "Error in ADIOI_Calc_aggregator(): rank_index(%d) >= fd->hints->cb_nodes (%d) fd_size=%lld off=%lld\n", rank_index,fd->hints->cb_nodes,fd_size,off); MPI_Abort(MPI_COMM_WORLD, 1); } /* remember here that even in Rajeev's original code it was the case that * different aggregators could end up with different amounts of data to * aggregate. here we use fd_end[] to make sure that we know how much * data this aggregator is working with. * * the +1 is to take into account the end vs. length issue. */ avail_bytes = fd_end[rank_index] + 1 - off; if (avail_bytes < *len) { /* this file domain only has part of the requested contig. region */ *len = avail_bytes; } /* map our index to a rank */ /* NOTE: FOR NOW WE DON'T HAVE A MAPPING...JUST DO 0..NPROCS_FOR_COLL */ rank = fd->hints->ranklist[rank_index]; return rank; }
/* ADIOI_cb_copy_name_array() - attribute copy routine */ int ADIOI_cb_copy_name_array(MPI_Comm comm, int keyval, void *extra, void *attr_in, void **attr_out, int *flag) { ADIO_cb_name_array array; ADIOI_UNREFERENCED_ARG(comm); ADIOI_UNREFERENCED_ARG(keyval); ADIOI_UNREFERENCED_ARG(extra); array = (ADIO_cb_name_array) attr_in; if (array != NULL) array->refct++; *attr_out = attr_in; *flag = 1; /* make a copy in the new communicator */ return MPI_SUCCESS; }
/* ADIO_FileSysType_fncall - determines the file system type for a given file using a system-dependent function call Input Parameters: . filename - pointer to file name character array Output Parameters: . fstype - location in which to store file system type (ADIO_XXX) . error_code - location in which to store error code MPI_SUCCESS is stored in the location pointed to by error_code on success. This function is used by MPI_File_open() and MPI_File_delete() to determine file system type. Most other functions use the type which is stored when the file is opened. */ static void ADIO_FileSysType_fncall(const char *filename, int *fstype, int *error_code) { #if defined (ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE) || defined (HAVE_STRUCT_STATFS) || defined (ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE) int err; #endif #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE struct statvfs vfsbuf; #endif #ifdef HAVE_STRUCT_STATFS struct statfs fsbuf; #endif #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE struct stat sbuf; #endif static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL"; /* NFS can get stuck and end up returing ESTALE "forever" */ #define MAX_ESTALE_RETRY 10000 int retry_cnt; *error_code = MPI_SUCCESS; #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE /* rare: old solaris machines */ retry_cnt=0; do { err = statvfs(filename, &vfsbuf); } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); if (err) { /* ENOENT may be returned in two cases: * 1) no directory entry for "filename" * 2) "filename" is a dangling symbolic link * * ADIO_FileSysType_parentdir tries to deal with both cases. */ if (errno == ENOENT) { char *dir; ADIO_FileSysType_parentdir(filename, &dir); err = statvfs(dir, &vfsbuf); ADIOI_Free(dir); } else { *error_code = ADIOI_Err_create_code(myname, filename, errno); if(*error_code != MPI_SUCCESS) return; } } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */ if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) { *fstype = ADIO_NFS; return; } if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) { *fstype = ADIO_XFS; return; } # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATVFS APPROACH */ #if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS) /* common automagic fs-detection logic for any modern POSX-compliant * environment */ retry_cnt = 0; do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); if (err) { if(errno == ENOENT) { char *dir; ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); ADIOI_Free(dir); } else { *error_code = ADIOI_Err_create_code(myname, filename, errno); if(*error_code != MPI_SUCCESS) return; } } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ # ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME /* uncommon: maybe only on Darwin ? */ if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) { *fstype = ADIO_NFS; return; } # endif #ifdef ROMIO_GPFS if (fsbuf.f_type == GPFS_SUPER_MAGIC) { *fstype = ADIO_GPFS; return; } #endif /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/ # ifdef NFS_SUPER_MAGIC if (fsbuf.f_type == NFS_SUPER_MAGIC) { *fstype = ADIO_NFS; return; } # endif #ifdef ROMIO_LUSTRE # ifndef LL_SUPER_MAGIC # define LL_SUPER_MAGIC 0x0BD00BD0 # endif if (fsbuf.f_type == LL_SUPER_MAGIC) { *fstype = ADIO_LUSTRE; return; } #endif # ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) { *fstype = ADIO_PANFS; return; } # endif # ifdef MOUNT_NFS if (fsbuf.f_type == MOUNT_NFS) { *fstype = ADIO_NFS; return; } # endif # ifdef MOUNT_PFS if (fsbuf.f_type == MOUNT_PFS) { *fstype = ADIO_PFS; return; } # endif # ifdef PVFS_SUPER_MAGIC if (fsbuf.f_type == PVFS_SUPER_MAGIC) { *fstype = ADIO_PVFS; return; } # endif # ifdef PVFS2_SUPER_MAGIC if (fsbuf.f_type == PVFS2_SUPER_MAGIC) { *fstype = ADIO_PVFS2; return; } # endif # ifdef XFS_SUPER_MAGIC if (fsbuf.f_type == XFS_SUPER_MAGIC) { *fstype = ADIO_XFS; return; } # endif # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATFS APPROACH */ #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE /* rare: maybe old NEC SX or SGI IRIX machines */ retry_cnt = 0; do { err = stat(filename, &sbuf); } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); if (err) { if(errno == ENOENT) { char *dir; ADIO_FileSysType_parentdir(filename, &dir); err = stat(dir, &sbuf); ADIOI_Free(dir); } else{ *error_code = ADIOI_Err_create_code(myname, filename, errno); if(*error_code != MPI_SUCCESS) return; } } if (err) { /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ return; } else { if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS; else *fstype = ADIO_SFS; /* assuming SX4 for now */ } #endif /* STAT APPROACH */ #ifdef ROMIO_NTFS ADIOI_UNREFERENCED_ARG(filename); ADIOI_UNREFERENCED_ARG(error_code); *fstype = ADIO_NTFS; /* only supported FS on Windows */ #elif defined(ROMIO_NFS) *fstype = ADIO_NFS; #elif defined(ROMIO_UFS) *fstype = ADIO_UFS; #else /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif }
/* ADIO_FileSysType_fncall - determines the file system type for a given file using a system-dependent function call Input Parameters: . filename - pointer to file name character array Output Parameters: . fstype - location in which to store file system type (ADIO_XXX) . error_code - location in which to store error code MPI_SUCCESS is stored in the location pointed to by error_code on success. This function is used by MPI_File_open() and MPI_File_delete() to determine file system type. Most other functions use the type which is stored when the file is opened. */ static void ADIO_FileSysType_fncall(char *filename, int *fstype, int *error_code) { #ifndef ROMIO_NTFS char *dir; int err; #endif #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE struct statvfs vfsbuf; #endif #ifdef HAVE_STRUCT_STATFS struct statfs fsbuf; #endif #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE struct stat sbuf; #endif static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL"; *error_code = MPI_SUCCESS; #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE do { err = statvfs(filename, &vfsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { /* ENOENT may be returned in two cases: * 1) no directory entry for "filename" * 2) "filename" is a dangling symbolic link * * ADIO_FileSysType_parentdir tries to deal with both cases. */ ADIO_FileSysType_parentdir(filename, &dir); err = statvfs(dir, &vfsbuf); ADIOI_Free(dir); } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */ if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) { *fstype = ADIO_NFS; return; } if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) { *fstype = ADIO_XFS; return; } # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATVFS APPROACH */ #if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS) do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); ADIOI_Free(dir); } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ # ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) { *fstype = ADIO_NFS; return; } # endif # ifdef ROMIO_BGL /* BlueGene is a special case: all file systems are AD_BGL, except for * certain exceptions */ *fstype = ADIO_BGL; check_for_lockless_exceptions(fsbuf.f_type, fstype); *error_code = MPI_SUCCESS; return; # endif /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/ # ifdef NFS_SUPER_MAGIC if (fsbuf.f_type == NFS_SUPER_MAGIC) { *fstype = ADIO_NFS; return; } # endif /*#if defined(LINUX) && defined(ROMIO_LUSTRE)*/ #ifdef ROMIO_LUSTRE #define LL_SUPER_MAGIC 0x0BD00BD0 if (fsbuf.f_type == LL_SUPER_MAGIC) { *fstype = ADIO_LUSTRE; return; } # endif # ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) { *fstype = ADIO_PANFS; return; } # endif # ifdef MOUNT_NFS if (fsbuf.f_type == MOUNT_NFS) { *fstype = ADIO_NFS; return; } # endif # ifdef MOUNT_PFS if (fsbuf.f_type == MOUNT_PFS) { *fstype = ADIO_PFS; return; } # endif # ifdef PVFS_SUPER_MAGIC if (fsbuf.f_type == PVFS_SUPER_MAGIC) { *fstype = ADIO_PVFS; return; } # endif # ifdef PVFS2_SUPER_MAGIC if (fsbuf.f_type == PVFS2_SUPER_MAGIC) { *fstype = ADIO_PVFS2; return; } # endif # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATFS APPROACH */ #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE do { err = stat(filename, &sbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = stat(dir, &sbuf); ADIOI_Free(dir); } if (err) { /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ return; } else { if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS; else *fstype = ADIO_SFS; /* assuming SX4 for now */ } #endif /* STAT APPROACH */ #ifdef ROMIO_NTFS ADIOI_UNREFERENCED_ARG(filename); ADIOI_UNREFERENCED_ARG(error_code); *fstype = ADIO_NTFS; /* only supported FS on Windows */ #elif defined(ROMIO_NFS) *fstype = ADIO_NFS; #elif defined(ROMIO_UFS) *fstype = ADIO_UFS; #else /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif }
ADIO_Offset ADIOI_GEN_SeekIndividual(ADIO_File fd, ADIO_Offset offset, int whence, int *error_code) { /* implemented for whence=SEEK_SET only. SEEK_CUR and SEEK_END must be converted to the equivalent with SEEK_SET before calling this routine. */ /* offset is in units of etype relative to the filetype */ ADIO_Offset off; ADIOI_Flatlist_node *flat_file; int i; ADIO_Offset n_etypes_in_filetype, n_filetypes, etype_in_filetype; ADIO_Offset abs_off_in_filetype=0; ADIO_Offset size_in_filetype, sum; unsigned filetype_size; int etype_size, filetype_is_contig; MPI_Aint filetype_extent; ADIOI_UNREFERENCED_ARG(whence); ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig); etype_size = fd->etype_size; if (filetype_is_contig) off = fd->disp + (ADIO_Offset)etype_size * offset; else { flat_file = ADIOI_Flatlist; while (flat_file->type != fd->filetype) flat_file = flat_file->next; MPI_Type_extent(fd->filetype, &filetype_extent); MPI_Type_size(fd->filetype, (int*)&filetype_size); if ( ! filetype_size ) { /* Since offset relative to the filetype size, we can't do compute the offset when that result is zero. Return zero for the offset for now */ *error_code = MPI_SUCCESS; return 0; } 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; for (i=0; i<flat_file->count; i++) { sum += flat_file->blocklens[i]; if (sum > size_in_filetype) { abs_off_in_filetype = flat_file->indices[i] + size_in_filetype - (sum - flat_file->blocklens[i]); break; } } /* abs. offset in bytes in the file */ off = fd->disp + n_filetypes * filetype_extent + abs_off_in_filetype; } /* * we used to call lseek here and update both fp_ind and fp_sys_posn, but now * we don't seek and only update fp_ind (ROMIO's idea of where we are in the * file). We leave the system file descriptor and fp_sys_posn alone. * The fs-specifc ReadContig and WriteContig will seek to the correct place in * the file before reading/writing if the 'offset' parameter doesn't match * fp_sys_posn */ fd->fp_ind = off; *error_code = MPI_SUCCESS; return off; }
void ADIOI_Fill_user_buffer(ADIO_File fd, void *buf, ADIOI_Flatlist_node *flat_buf, char **recv_buf, ADIO_Offset *offset_list, ADIO_Offset *len_list, unsigned *recv_size, MPI_Request *requests, MPI_Status *statuses, int *recd_from_proc, int nprocs, int contig_access_count, ADIO_Offset min_st_offset, ADIO_Offset fd_size, ADIO_Offset *fd_start, ADIO_Offset *fd_end, MPI_Aint buftype_extent) { /* this function is only called if buftype is not contig */ int i, p, flat_buf_idx; ADIO_Offset flat_buf_sz, size_in_buf, buf_incr, size; int n_buftypes; ADIO_Offset off, len, rem_len, user_buf_idx; /* Not sure unsigned is necessary, but it makes the math safer */ unsigned *curr_from_proc, *done_from_proc, *recv_buf_idx; ADIOI_UNREFERENCED_ARG(requests); ADIOI_UNREFERENCED_ARG(statuses); /* curr_from_proc[p] = amount of data recd from proc. p that has already been accounted for so far done_from_proc[p] = amount of data already recd from proc. p and filled into user buffer in previous iterations user_buf_idx = current location in user buffer recv_buf_idx[p] = current location in recv_buf of proc. p */ curr_from_proc = (unsigned *) ADIOI_Malloc(nprocs * sizeof(unsigned)); done_from_proc = (unsigned *) ADIOI_Malloc(nprocs * sizeof(unsigned)); recv_buf_idx = (unsigned *) ADIOI_Malloc(nprocs * sizeof(unsigned)); for (i=0; i < nprocs; i++) { recv_buf_idx[i] = curr_from_proc[i] = 0; done_from_proc[i] = recd_from_proc[i]; } user_buf_idx = flat_buf->indices[0]; flat_buf_idx = 0; n_buftypes = 0; flat_buf_sz = flat_buf->blocklens[0]; /* flat_buf_idx = current index into flattened buftype flat_buf_sz = size of current contiguous component in flattened buf */ for (i=0; i<contig_access_count; i++) { off = offset_list[i]; rem_len = len_list[i]; /* this request may span the file domains of more than one process */ while (rem_len != 0) { len = rem_len; /* NOTE: len value is modified by ADIOI_Calc_aggregator() to be no * longer than the single region that processor "p" is responsible * for. */ p = ADIOI_Calc_aggregator(fd, off, min_st_offset, &len, fd_size, fd_start, fd_end); if (recv_buf_idx[p] < recv_size[p]) { if (curr_from_proc[p]+len > done_from_proc[p]) { if (done_from_proc[p] > curr_from_proc[p]) { size = ADIOI_MIN(curr_from_proc[p] + len - done_from_proc[p], recv_size[p]-recv_buf_idx[p]); buf_incr = done_from_proc[p] - curr_from_proc[p]; ADIOI_BUF_INCR buf_incr = curr_from_proc[p]+len-done_from_proc[p]; ADIOI_Assert((done_from_proc[p] + size) == (unsigned)((ADIO_Offset)done_from_proc[p] + size)); curr_from_proc[p] = done_from_proc[p] + size; ADIOI_BUF_COPY } else { size = ADIOI_MIN(len,recv_size[p]-recv_buf_idx[p]); buf_incr = len; ADIOI_Assert((curr_from_proc[p] + size) == (unsigned)((ADIO_Offset)curr_from_proc[p] + size)); curr_from_proc[p] += (unsigned) size; ADIOI_BUF_COPY } } else { ADIOI_Assert((curr_from_proc[p] + len) == (unsigned)((ADIO_Offset)curr_from_proc[p] + len)); curr_from_proc[p] += (unsigned) len; buf_incr = len; ADIOI_BUF_INCR } }
void ADIO_Init(int *argc, char ***argv, int *error_code) { #if defined(ROMIO_XFS) || defined(ROMIO_LUSTRE) char *c; #endif ADIOI_UNREFERENCED_ARG(argc); ADIOI_UNREFERENCED_ARG(argv); /* initialize the linked list containing flattened datatypes */ ADIOI_Flatlist = (ADIOI_Flatlist_node *) ADIOI_Malloc(sizeof(ADIOI_Flatlist_node)); ADIOI_Flatlist->type = MPI_DATATYPE_NULL; ADIOI_Flatlist->next = NULL; ADIOI_Flatlist->blocklens = NULL; ADIOI_Flatlist->indices = NULL; #if defined(ROMIO_XFS) || defined(ROMIO_LUSTRE) c = getenv("MPIO_DIRECT_READ"); if (c && (!strcmp(c, "true") || !strcmp(c, "TRUE"))) ADIOI_Direct_read = 1; else ADIOI_Direct_read = 0; c = getenv("MPIO_DIRECT_WRITE"); if (c && (!strcmp(c, "true") || !strcmp(c, "TRUE"))) ADIOI_Direct_write = 1; else ADIOI_Direct_write = 0; #endif /* Assume system-wide hints won't change between runs: move hint processing * from ADIO_Open to here */ /* FIXME should be checking error code from MPI_Info_create here */ MPI_Info_create(&ADIOI_syshints); ADIOI_process_system_hints(ADIOI_syshints); #ifdef ADIOI_MPE_LOGGING { MPE_Log_get_state_eventIDs( &ADIOI_MPE_open_a, &ADIOI_MPE_open_b ); MPE_Log_get_state_eventIDs( &ADIOI_MPE_read_a, &ADIOI_MPE_read_b ); MPE_Log_get_state_eventIDs( &ADIOI_MPE_write_a, &ADIOI_MPE_write_b ); MPE_Log_get_state_eventIDs( &ADIOI_MPE_lseek_a, &ADIOI_MPE_lseek_b ); MPE_Log_get_state_eventIDs( &ADIOI_MPE_close_a, &ADIOI_MPE_close_b ); MPE_Log_get_state_eventIDs( &ADIOI_MPE_writelock_a, &ADIOI_MPE_writelock_b ); MPE_Log_get_state_eventIDs( &ADIOI_MPE_readlock_a, &ADIOI_MPE_readlock_b ); MPE_Log_get_state_eventIDs( &ADIOI_MPE_unlock_a, &ADIOI_MPE_unlock_b ); MPE_Log_get_state_eventIDs( &ADIOI_MPE_postwrite_a, &ADIOI_MPE_postwrite_b ); MPE_Log_get_state_eventIDs( &ADIOI_MPE_openinternal_a, &ADIOI_MPE_openinternal_b); MPE_Log_get_state_eventIDs( &ADIOI_MPE_stat_a, &ADIOI_MPE_stat_b); MPE_Log_get_state_eventIDs( &ADIOI_MPE_iread_a, &ADIOI_MPE_iread_b); MPE_Log_get_state_eventIDs( &ADIOI_MPE_iwrite_a, &ADIOI_MPE_iwrite_b); int comm_world_rank; MPI_Comm_rank( MPI_COMM_WORLD, &comm_world_rank ); if ( comm_world_rank == 0 ) { MPE_Describe_state( ADIOI_MPE_open_a, ADIOI_MPE_open_b, "open", "orange" ); MPE_Describe_state( ADIOI_MPE_read_a, ADIOI_MPE_read_b, "read", "green" ); MPE_Describe_state( ADIOI_MPE_write_a, ADIOI_MPE_write_b, "write", "blue" ); MPE_Describe_state( ADIOI_MPE_lseek_a, ADIOI_MPE_lseek_b, "lseek", "red" ); MPE_Describe_state( ADIOI_MPE_close_a, ADIOI_MPE_close_b, "close", "grey" ); MPE_Describe_state( ADIOI_MPE_writelock_a, ADIOI_MPE_writelock_b, "writelock", "plum" ); MPE_Describe_state( ADIOI_MPE_readlock_a, ADIOI_MPE_readlock_b, "readlock", "magenta" ); MPE_Describe_state( ADIOI_MPE_unlock_a, ADIOI_MPE_unlock_b, "unlock", "purple" ); MPE_Describe_state( ADIOI_MPE_postwrite_a, ADIOI_MPE_postwrite_b, "postwrite", "ivory" ); MPE_Describe_state( ADIOI_MPE_openinternal_a, ADIOI_MPE_openinternal_b, "open system", "blue"); MPE_Describe_state( ADIOI_MPE_stat_a, ADIOI_MPE_stat_b, "stat", "purple"); MPE_Describe_state( ADIOI_MPE_iread_a, ADIOI_MPE_iread_b, "iread", "purple"); MPE_Describe_state( ADIOI_MPE_iwrite_a, ADIOI_MPE_iwrite_b, "iwrite", "purple"); } } #endif *error_code = MPI_SUCCESS; MPI_Op_create(my_consensus, 1, &ADIO_same_amode); }