/* * ADIOI_Cache_alloc - allocate space in the local file system for the cache file */ void ADIOI_Cache_alloc(ADIO_File fd, ADIO_Offset off, ADIO_Offset len, int *error_code) { int ret; char myname[] = "ADIOI_CACHE_ALLOC"; *error_code = MPI_SUCCESS; ret = fallocate(fd->fd_sys, 0, (off_t)off, (off_t)len); if (ret == -1) if (errno == ENOSPC) *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SPACE, "**filenospace", "**filenospace %s", strerror(errno)); else if (errno == EBADF) *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ACCESS, "**fileaccess", "**fileaccess %s", strerror(errno)); else if (errno == EIO) *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); /* if the system call is not supported proceed as if * the allocation was successfull. We do this since * it would take much more time to write zeros to the * file */ /* else if( errno == ENOSYS ) */ }
/*@ MPI_File_set_size - Sets the file size Input Parameters: . fh - file handle (handle) . size - size to truncate or expand file (nonnegative integer) .N fortran @*/ int MPI_File_set_size(MPI_File mpi_fh, MPI_Offset size) { int error_code; ADIO_File fh; static char myname[] = "MPI_FILE_SET_SIZE"; MPI_Offset tmp_sz; #ifdef MPI_hpux int fl_xmpi; HPMP_IO_START(fl_xmpi, BLKMPIFILESETSIZE, TRDTBLOCK, fh, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ MPID_CS_ENTER(); MPIR_Nest_incr(); fh = MPIO_File_resolve(mpi_fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(fh, myname, error_code); if (size < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadsize", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ tmp_sz = size; MPI_Bcast(&tmp_sz, 1, ADIO_OFFSET, 0, fh->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_sz != size) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**notsame", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ ADIOI_TEST_DEFERRED(fh, "MPI_File_set_size", &error_code); ADIO_Resize(fh, size, &error_code); /* TODO: what to do with error code? */ #ifdef MPI_hpux HPMP_IO_END(fl_xmpi, fh, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ fn_exit: MPIR_Nest_decr(); MPID_CS_EXIT(); return error_code; }
/* Wait for completion of one of the outstanding AIO requests */ int ADIOI_NTFS_aio_wait_fn(int count, void **array_of_states, double timeout, MPI_Status *status) { int i, mpi_errno = MPI_SUCCESS; ADIOI_AIO_Request **aio_reqlist; LPHANDLE lpHandles; DWORD retObject=0; /* FIXME: Validate the args -- has it already been done by the caller ? */ aio_reqlist = (ADIOI_AIO_Request **)array_of_states; lpHandles = (LPHANDLE) ADIOI_Calloc(count, sizeof(HANDLE)); if (lpHandles == NULL) { mpi_errno = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "ADIOI_NTFS_aio_wait_fn", __LINE__, MPI_ERR_IO, "**nomem", "**nomem %s", "Event handles"); return mpi_errno; } /* XXX: set-up arrays of outstanding requests */ for(i=0; i<count; i++){ lpHandles[i] = (aio_reqlist[i])->lpOvl->hEvent; } /* XXX: wait for one request to complete */ /* FIXME: Is the timeout in seconds ? */ timeout = (timeout <= 0) ? INFINITE : (timeout * 1000); if((retObject = WaitForMultipleObjects(count, lpHandles, FALSE, timeout)) != WAIT_FAILED){ retObject = retObject - WAIT_OBJECT_0; if(GetOverlappedResult( aio_reqlist[retObject]->fd, aio_reqlist[retObject]->lpOvl, &(aio_reqlist[retObject]->nbytes), FALSE)){ /* XXX: mark completed requests as 'done'*/ mpi_errno = MPI_Grequest_complete(aio_reqlist[retObject]->req); if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "ADIOI_NTFS_aio_wait_fn", __LINE__, MPI_ERR_IO, "**mpi_grequest_complete", 0); } }else{ if(GetLastError() == ERROR_IO_INCOMPLETE){ /* IO in progress */ /* TODO: need to diddle with status somehow */ }else{ /* Error occured */ /* TODO: not sure how to handle this */ } } }else{ /* TODO: How to handle error while waiting ? */ } ADIOI_Free(lpHandles); return mpi_errno; }
int MPIOI_File_read_all_begin(MPI_File mpi_fh, MPI_Offset offset, int file_ptr_type, void *buf, int count, MPI_Datatype datatype, char *myname) { int error_code, datatype_size; ADIO_File fh; MPID_CS_ENTER(); MPIR_Nest_incr(); fh = MPIO_File_resolve(mpi_fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(fh, myname, error_code); MPIO_CHECK_COUNT(fh, count, myname, error_code); MPIO_CHECK_DATATYPE(fh, datatype, myname, error_code); if (file_ptr_type == ADIO_EXPLICIT_OFFSET && offset < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadoffset", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ MPI_Type_size(datatype, &datatype_size); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_INTEGRAL_ETYPE(fh, count, datatype_size, myname, error_code); MPIO_CHECK_READABLE(fh, myname, error_code); MPIO_CHECK_NOT_SEQUENTIAL_MODE(fh, myname, error_code); if (fh->split_coll_count) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**iosplitcoll", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ fh->split_coll_count = 1; ADIO_ReadStridedColl(fh, buf, count, datatype, file_ptr_type, offset, &fh->split_status, &error_code); fn_exit: MPIR_Nest_decr(); MPID_CS_EXIT(); return error_code; }
static int build_cb_config_list(ADIO_File fd, MPI_Comm orig_comm, MPI_Comm comm, int rank, int procs, int *error_code) { ADIO_cb_name_array array; int *tmp_ranklist; int rank_ct; char *value; static char myname[] = "ADIO_OPEN cb_config_list"; /* gather the processor name array if we don't already have it */ /* this has to be done early in ADIO_Open so that we can cache the name * array in both the dup'd communicator (in case we want it later) and the * original communicator */ ADIOI_cb_gather_name_array(orig_comm, comm, &array); /* parse the cb_config_list and create a rank map on rank 0 */ if (rank == 0) { tmp_ranklist = (int *) ADIOI_Malloc(sizeof(int) * procs); if (tmp_ranklist == NULL) { *error_code = MPIO_Err_create_code(*error_code, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_OTHER, "**nomem2",0); return 0; } rank_ct = ADIOI_cb_config_list_parse(fd->hints->cb_config_list, array, tmp_ranklist, fd->hints->cb_nodes); /* store the ranklist using the minimum amount of memory */ if (rank_ct > 0) { fd->hints->ranklist = (int *) ADIOI_Malloc(sizeof(int) * rank_ct); memcpy(fd->hints->ranklist, tmp_ranklist, sizeof(int) * rank_ct); } ADIOI_Free(tmp_ranklist); fd->hints->cb_nodes = rank_ct; /* TEMPORARY -- REMOVE WHEN NO LONGER UPDATING INFO FOR FS-INDEP. */ value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char)); MPL_snprintf(value, MPI_MAX_INFO_VAL+1, "%d", rank_ct); ADIOI_Info_set(fd->info, "cb_nodes", value); ADIOI_Free(value); } ADIOI_cb_bcast_rank_map(fd); if (fd->hints->cb_nodes <= 0) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**ioagnomatch", 0); fd = ADIO_FILE_NULL; } return 0; }
void ADIOI_PANFS_ReadContig(ADIO_File fd, void *buf, int count, MPI_Datatype datatype, int file_ptr_type, ADIO_Offset offset, ADIO_Status *status, int *error_code) { MPI_Count err = -1, datatype_size, len; static char myname[] = "ADIOI_PANFS_READCONTIG"; MPI_Type_size_x(datatype, &datatype_size); len = datatype_size * count; if (file_ptr_type == ADIO_INDIVIDUAL) { offset = fd->fp_ind; } if (fd->fp_sys_posn != offset) { err = lseek(fd->fd_sys, offset, SEEK_SET); /* --BEGIN ERROR HANDLING-- */ if (err == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); fd->fp_sys_posn = -1; return; } /* --END ERROR HANDLING-- */ } AD_PANFS_RETRY(read(fd->fd_sys, buf, len),err) /* --BEGIN ERROR HANDLING-- */ if (err == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); fd->fp_sys_posn = -1; return; } /* --END ERROR HANDLING-- */ fd->fp_sys_posn = offset + err; if (file_ptr_type == ADIO_INDIVIDUAL) { fd->fp_ind += err; } #ifdef HAVE_STATUS_SET_BYTES if (err != -1) MPIR_Status_set_bytes(status, datatype, err); #endif *error_code = MPI_SUCCESS; }
void ADIOI_PVFS2_Delete(const char *filename, int *error_code) { PVFS_credentials credentials; PVFS_sysresp_getparent resp_getparent; int ret; PVFS_fs_id cur_fs; static char myname[] = "ADIOI_PVFS2_DELETE"; char pvfs_path[PVFS_NAME_MAX] = {0}; ADIOI_PVFS2_Init(error_code); /* --BEGIN ERROR HANDLING-- */ if (*error_code != MPI_SUCCESS) { /* ADIOI_PVFS2_INIT handles creating error codes itself */ return; } /* --END ERROR HANDLING-- */ /* in most cases we'll store the credentials in the fs struct, but we don't * have one of those in Delete */ ADIOI_PVFS2_makecredentials(&credentials); /* given the filename, figure out which pvfs filesystem it is on */ ret = PVFS_util_resolve(filename, &cur_fs, pvfs_path, PVFS_NAME_MAX); /* --BEGIN ERROR HANDLING-- */ if (ret != 0) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, ADIOI_PVFS2_error_convert(ret), "Error in PVFS_util_resolve", 0); return; } /* --END ERROR HANDLING-- */ ret = PVFS_sys_getparent(cur_fs, pvfs_path, &credentials, &resp_getparent); ret = PVFS_sys_remove(resp_getparent.basename, resp_getparent.parent_ref, &credentials); /* --BEGIN ERROR HANDLING-- */ if (ret != 0) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, ADIOI_PVFS2_error_convert(ret), "Error in PVFS_sys_remove", 0); return; } /* --END ERROR HANDLING-- */ *error_code = MPI_SUCCESS; return; }
void ADIOI_PVFS_Fcntl(ADIO_File fd, int flag, ADIO_Fcntl_t *fcntl_struct, int *error_code) { static char myname[] = "ADIOI_PVFS_FCNTL"; switch(flag) { case ADIO_FCNTL_GET_FSIZE: fcntl_struct->fsize = pvfs_lseek64(fd->fd_sys, 0, SEEK_END); if (fd->fp_sys_posn != -1) pvfs_lseek64(fd->fd_sys, fd->fp_sys_posn, SEEK_SET); if (fcntl_struct->fsize == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); } else *error_code = MPI_SUCCESS; break; case ADIO_FCNTL_SET_DISKSPACE: ADIOI_GEN_Prealloc(fd, fcntl_struct->diskspace, error_code); break; case ADIO_FCNTL_SET_ATOMICITY: fd->atomicity = 0; /* --BEGIN ERROR HANDLING-- */ if (fcntl_struct->atomicity != 0) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_UNSUPPORTED_OPERATION, "PVFS does not support atomic mode", 0); return; } /* --END ERROR HANDLING-- */ break; default: /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**flag", "**flag %d", flag); return; /* --END ERROR HANDLING-- */ } }
void ADIOI_GEN_Fcntl(ADIO_File fd, int flag, ADIO_Fcntl_t * fcntl_struct, int *error_code) { static char myname[] = "ADIOI_GEN_FCNTL"; switch (flag) { case ADIO_FCNTL_GET_FSIZE: #ifdef ADIOI_MPE_LOGGING MPE_Log_event(ADIOI_MPE_lseek_a, 0, NULL); #endif fcntl_struct->fsize = lseek(fd->fd_sys, 0, SEEK_END); #ifdef ADIOI_MPE_LOGGING MPE_Log_event(ADIOI_MPE_lseek_b, 0, NULL); #endif if (fd->fp_sys_posn != -1) { #ifdef ADIOI_MPE_LOGGING MPE_Log_event(ADIOI_MPE_lseek_a, 0, NULL); #endif lseek(fd->fd_sys, fd->fp_sys_posn, SEEK_SET); #ifdef ADIOI_MPE_LOGGING MPE_Log_event(ADIOI_MPE_lseek_b, 0, NULL); #endif } if (fcntl_struct->fsize == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); } else *error_code = MPI_SUCCESS; break; case ADIO_FCNTL_SET_DISKSPACE: ADIOI_GEN_Prealloc(fd, fcntl_struct->diskspace, error_code); break; case ADIO_FCNTL_SET_ATOMICITY: fd->atomicity = (fcntl_struct->atomicity == 0) ? 0 : 1; *error_code = MPI_SUCCESS; break; /* --BEGIN ERROR HANDLING-- */ default: *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**flag", "**flag %d", flag); /* --END ERROR HANDLING-- */ } }
void ADIOI_BGL_Set_shared_fp(ADIO_File fd, ADIO_Offset offset, int *error_code) { int err; MPI_Comm dupcommself; static char myname[] = "ADIOI_BGL_SET_SHARED_FP"; if (fd->shared_fp_fd == ADIO_FILE_NULL) { MPI_Comm_dup(MPI_COMM_SELF, &dupcommself); fd->shared_fp_fd = ADIO_Open(MPI_COMM_SELF, dupcommself, fd->shared_fp_fname, fd->file_system, fd->fns, ADIO_CREATE | ADIO_RDWR | ADIO_DELETE_ON_CLOSE, 0, MPI_BYTE, MPI_BYTE, MPI_INFO_NULL, ADIO_PERM_NULL, error_code); } if (*error_code != MPI_SUCCESS) return; ADIOI_WRITE_LOCK(fd->shared_fp_fd, 0, SEEK_SET, sizeof(ADIO_Offset)); lseek(fd->shared_fp_fd->fd_sys, 0, SEEK_SET); err = write(fd->shared_fp_fd->fd_sys, &offset, sizeof(ADIO_Offset)); ADIOI_UNLOCK(fd->shared_fp_fd, 0, SEEK_SET, sizeof(ADIO_Offset)); if (err == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); } else *error_code = MPI_SUCCESS; }
void ADIOI_PVFS2_Flush(ADIO_File fd, int *error_code) { int ret, rank, dummy=0, dummy_in=0; ADIOI_PVFS2_fs *pvfs_fs; static char myname[] = "ADIOI_PVFS2_FLUSH"; *error_code = MPI_SUCCESS; pvfs_fs = (ADIOI_PVFS2_fs*)fd->fs_ptr; MPI_Comm_rank(fd->comm, &rank); /* unlike ADIOI_PVFS2_Resize, MPI_File_sync() does not perform any * syncronization */ MPI_Reduce(&dummy_in, &dummy, 1, MPI_INT, MPI_SUM, fd->hints->ranklist[0], fd->comm); /* io_worker computed in ADIO_Open */ if (rank == fd->hints->ranklist[0]) { ret = PVFS_sys_flush(pvfs_fs->object_ref, &(pvfs_fs->credentials)); MPI_Bcast(&ret, 1, MPI_INT, 0, fd->comm); } else { MPI_Bcast(&ret, 1, MPI_INT, 0, fd->comm); } /* --BEGIN ERROR HANDLING-- */ if (ret != 0) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, ADIOI_PVFS2_error_convert(ret), "Error in PVFS_sys_flush", 0); } /* --END ERROR HANDLING-- */ }
/* generic POSIX aio completion test routine */ int ADIOI_GEN_aio_poll_fn(void *extra_state, MPI_Status *status) { ADIOI_AIO_Request *aio_req; int errcode=MPI_SUCCESS; aio_req = (ADIOI_AIO_Request *)extra_state; /* aio_error returns an ERRNO value */ errno = aio_error(aio_req->aiocbp); if (errno == EINPROGRESS) { /* TODO: need to diddle with status somehow */ } else if (errno == ECANCELED) { /* TODO: unsure how to handle this */ } else if (errno == 0) { ssize_t n = aio_return(aio_req->aiocbp); aio_req->nbytes = n; errcode = MPI_Grequest_complete(aio_req->req); /* --BEGIN ERROR HANDLING-- */ if (errcode != MPI_SUCCESS) { errcode = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "ADIOI_GEN_aio_poll_fn", __LINE__, MPI_ERR_IO, "**mpi_grequest_complete", 0); } /* --END ERROR HANDLING-- */ } return errcode; }
/* poll for completion of a single outstanding AIO request */ int ADIOI_NTFS_aio_poll_fn(void *extra_state, MPI_Status *status) { ADIOI_AIO_Request *aio_req; int mpi_errno = MPI_SUCCESS; /* FIXME: Validate the args -- has it already been done by the caller ? */ aio_req = (ADIOI_AIO_Request *)extra_state; /* XXX: test for AIO completion here */ if(!GetOverlappedResult( aio_req->fd, aio_req->lpOvl, &(aio_req->nbytes), FALSE)){ if(GetLastError() == ERROR_IO_INCOMPLETE){ /* IO in progress */ /* TODO: need to diddle with status somehow */ }else{ /* Error occured */ /* TODO: unsure how to handle this */ } }else{ mpi_errno = MPI_Grequest_complete(aio_req->req); if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "ADIOI_NTFS_aio_poll_fn", __LINE__, MPI_ERR_IO, "**mpi_grequest_complete", 0); } } return mpi_errno; }
void ADIOI_NTFS_IwriteContig(ADIO_File fd, void *buf, int count, MPI_Datatype datatype, int file_ptr_type, ADIO_Offset offset, ADIO_Request *request, int *error_code) { int len, typesize; int err; static char myname[] = "ADIOI_NTFS_IwriteContig"; MPI_Type_size(datatype, &typesize); len = count * typesize; if (file_ptr_type == ADIO_INDIVIDUAL) { offset = fd->fp_ind; } err = ADIOI_NTFS_aio(fd, buf, len, offset, 1, request); if (file_ptr_type == ADIO_INDIVIDUAL) { fd->fp_ind += len; } /* --BEGIN ERROR HANDLING-- */ if (err != MPI_SUCCESS) { *error_code = MPIO_Err_create_code(err, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", 0); return; } /* --END ERROR HANDLING-- */ *error_code = MPI_SUCCESS; fd->fp_sys_posn = -1; /* set it to null. */ }
void ADIOI_ZOIDFS_Delete(char *filename, int *error_code) { int ret; static char myname[] = "ADIOI_ZOIDFS_DELETE"; ADIOI_ZOIDFS_Init(0, error_code); /* --BEGIN ERROR HANDLING-- */ if (*error_code != MPI_SUCCESS) { /* ADIOI_ZOIDFS_INIT handles creating error codes itself */ return; } /* --END ERROR HANDLING-- */ ret = zoidfs_remove(NULL, NULL, filename, NULL, ZOIDFS_NO_OP_HINT); /* --BEGIN ERROR HANDLING-- */ if (ret != ZFS_OK) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, ADIOI_ZOIDFS_error_convert(ret), "Error in zoidfs_remove", 0); return; } /* --END ERROR HANDLING-- */ *error_code = MPI_SUCCESS; return; }
/* ADIOI_cb_bcast_rank_map() - broadcast the rank array * * Parameters: * fd - ADIO_File for which update is occurring. cb_nodes and ranklist * parameters must be up-to-date on rank 0 of the fd->comm. * * should probably be a void fn. */ int ADIOI_cb_bcast_rank_map(ADIO_File fd) { int my_rank; char *value; int error_code = MPI_SUCCESS; static char myname[] = "ADIOI_cb_bcast_rank_map"; MPI_Bcast(&(fd->hints->cb_nodes), 1, MPI_INT, 0, fd->comm); if (fd->hints->cb_nodes > 0) { MPI_Comm_rank(fd->comm, &my_rank); if (my_rank != 0) { fd->hints->ranklist = ADIOI_Malloc(fd->hints->cb_nodes*sizeof(int)); if (fd->hints->ranklist == NULL) { error_code = MPIO_Err_create_code(error_code, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_OTHER, "**nomem2",0); return error_code; } } MPI_Bcast(fd->hints->ranklist, fd->hints->cb_nodes, MPI_INT, 0, fd->comm); } /* TEMPORARY -- REMOVE WHEN NO LONGER UPDATING INFO FOR * FS-INDEP. */ value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char)); ADIOI_Snprintf(value, MPI_MAX_INFO_VAL+1, "%d", fd->hints->cb_nodes); ADIOI_Info_set(fd->info, "cb_nodes", value); ADIOI_Free(value); return 0; }
void ADIOI_ZOIDFS_Flush(ADIO_File fd, int *error_code) { int ret, rank, dummy=0, dummy_in=0; ADIOI_ZOIDFS_object *zoidfs_obj_ptr; static char myname[] = "ADIOI_ZOIDFS_FLUSH"; *error_code = MPI_SUCCESS; zoidfs_obj_ptr = (ADIOI_ZOIDFS_object*)fd->fs_ptr; MPI_Comm_rank(fd->comm, &rank); /* collective call to ensure no outstanding write requests. reduce is * slightly less expensvie than barrier */ MPI_Reduce(&dummy_in, &dummy, 1, MPI_INT, MPI_SUM, fd->hints->ranklist[0], fd->comm); if (rank == fd->hints->ranklist[0]) { ret = zoidfs_commit(zoidfs_obj_ptr, ZOIDFS_NO_OP_HINT); } MPI_Bcast(&ret, 1, MPI_INT, fd->hints->ranklist[0], fd->comm); /* --BEGIN ERROR HANDLING-- */ if (ret != 0) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, ADIOI_ZOIDFS_error_convert(ret), "Error in zoidfs_commit", 0); } /* --END ERROR HANDLING-- */ }
/* wait for multiple requests to complete */ static int ADIOI_GEN_irc_wait_fn(int count, void **array_of_states, double timeout, MPI_Status *status) { int i, errcode = MPI_SUCCESS; double starttime; ADIOI_NBC_Request **nbc_reqlist; nbc_reqlist = (ADIOI_NBC_Request **)array_of_states; starttime = MPI_Wtime(); for (i = 0; i < count ; i++) { while (nbc_reqlist[i]->data.rd.state != ADIOI_IRC_STATE_COMPLETE) { errcode = ADIOI_GEN_irc_poll_fn(nbc_reqlist[i], MPI_STATUS_IGNORE); /* --BEGIN ERROR HANDLING-- */ if (errcode != MPI_SUCCESS) { errcode = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "ADIOI_GEN_irc_wait_fn", __LINE__, MPI_ERR_IO, "**mpi_grequest_complete", 0); } /* --END ERROR HANDLING-- */ if ((timeout > 0) && (timeout < (MPI_Wtime() - starttime))) goto fn_exit; } } fn_exit: return errcode; }
/*@ MPI_File_get_byte_offset - Returns the absolute byte position in the file corresponding to "offset" etypes relative to the current view Input Parameters: . fh - file handle (handle) . offset - offset (nonnegative integer) Output Parameters: . disp - absolute byte position of offset (nonnegative integer) .N fortran @*/ int MPI_File_get_byte_offset(MPI_File fh, MPI_Offset offset, MPI_Offset *disp) { int error_code; ADIO_File adio_fh; static char myname[] = "MPI_FILE_GET_BYTE_OFFSET"; adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); if (offset < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadoffset", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } MPIO_CHECK_NOT_SEQUENTIAL_MODE(adio_fh, myname, error_code); /* --END ERROR HANDLING-- */ ADIOI_Get_byte_offset(adio_fh, offset, disp); fn_exit: return MPI_SUCCESS; }
void MPIR_MPIOInit(int * error_code) { int flag; char myname[] = "MPIR_MPIOInit"; /* first check if ADIO has been initialized. If not, initialize it */ if (ADIO_Init_keyval == MPI_KEYVAL_INVALID) { MPI_Initialized(&flag); /* --BEGIN ERROR HANDLING-- */ if (!flag) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_OTHER, "**initialized", 0); *error_code = MPIO_Err_return_file(MPI_FILE_NULL, *error_code); return; } /* --END ERROR HANDLING-- */ MPI_Keyval_create(MPI_NULL_COPY_FN, ADIOI_End_call, &ADIO_Init_keyval, (void *) 0); /* put a dummy attribute on MPI_COMM_SELF, because we want the delete function to be called when MPI_COMM_SELF is freed. Clarified in MPI-2 section 4.8, the standard mandates that attributes on MPI_COMM_SELF get cleaned up early in MPI_Finalize */ MPI_Attr_put(MPI_COMM_SELF, ADIO_Init_keyval, (void *) 0); /* initialize ADIO */ ADIO_Init( (int *)0, (char ***)0, error_code); } *error_code = MPI_SUCCESS; }
/*@ MPI_File_get_errhandler - Returns the error handler for a file Input Parameters: . fh - file handle (handle) Output Parameters: . errhandler - error handler (handle) .N fortran @*/ int MPI_File_get_errhandler(MPI_File mpi_fh, MPI_Errhandler *errhandler) { int error_code = MPI_SUCCESS; ADIO_File fh; static char myname[] = "MPI_FILE_GET_ERRHANDLER"; MPID_THREADPRIV_DECL; if (mpi_fh == MPI_FILE_NULL) { *errhandler = ADIOI_DFLT_ERR_HANDLER; } else { fh = MPIO_File_resolve(mpi_fh); /* --BEGIN ERROR HANDLING-- */ if ((fh <= (MPI_File) 0) || ((fh)->cookie != ADIOI_FILE_COOKIE)) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadfh", 0); error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ *errhandler = fh->err_handler; } fn_exit: return MPI_SUCCESS; }
/* this used to be implemented in every file system as an fcntl, but the code * is identical for all file systems without a real "preallocate" system call. * This naive approach will get the job done, but not in a terribly efficient * manner. */ void ADIOI_GEN_Prealloc(ADIO_File fd, ADIO_Offset diskspace, int *error_code) { ADIO_Offset curr_fsize, alloc_size, size, len, done; ADIO_Status status; int i, ntimes; char *buf; static char myname[] = "ADIOI_GEN_PREALLOC"; /* will be called by one process only */ /* On file systems with no preallocation function, we have to explicitly write to allocate space. Since there could be holes in the file, we need to read up to the current file size, write it back, and then write beyond that depending on how much preallocation is needed. read/write in sizes of no more than ADIOI_PREALLOC_BUFSZ */ curr_fsize = fd->fp_ind; alloc_size = diskspace; size = ADIOI_MIN(curr_fsize, alloc_size); ntimes = (size + ADIOI_PREALLOC_BUFSZ - 1)/ADIOI_PREALLOC_BUFSZ; buf = (char *) ADIOI_Malloc(ADIOI_PREALLOC_BUFSZ); done = 0; for (i=0; i<ntimes; i++) { len = ADIOI_MIN(size-done, ADIOI_PREALLOC_BUFSZ); ADIO_ReadContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET, done, &status, error_code); if (*error_code != MPI_SUCCESS) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**iopreallocrdwr", 0); return; } ADIO_WriteContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET, done, &status, error_code); if (*error_code != MPI_SUCCESS) return; done += len; } if (alloc_size > curr_fsize) { memset(buf, 0, ADIOI_PREALLOC_BUFSZ); size = alloc_size - curr_fsize; ntimes = (size + ADIOI_PREALLOC_BUFSZ - 1)/ADIOI_PREALLOC_BUFSZ; for (i=0; i<ntimes; i++) { len = ADIOI_MIN(alloc_size-done, ADIOI_PREALLOC_BUFSZ); ADIO_WriteContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET, done, &status, error_code); if (*error_code != MPI_SUCCESS) return; done += len; } } ADIOI_Free(buf); *error_code = MPI_SUCCESS; }
int MPIOI_File_read_all_end(MPI_File fh, void *buf, char *myname, MPI_Status *status) { int error_code = MPI_SUCCESS; ADIO_File adio_fh; MPIU_UNREFERENCED_ARG(buf); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); if (!(adio_fh->split_coll_count)) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**iosplitcollnone", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ #ifdef HAVE_STATUS_SET_BYTES if (status != MPI_STATUS_IGNORE) *status = adio_fh->split_status; #endif adio_fh->split_coll_count = 0; fn_exit: return error_code; }
void ADIOI_NFS_WriteContig(ADIO_File fd, const void *buf, int count, MPI_Datatype datatype, int file_ptr_type, ADIO_Offset offset, ADIO_Status *status, int *error_code) { ssize_t err=-1; MPI_Count datatype_size, len; ADIO_Offset bytes_xfered=0; size_t wr_count; static char myname[] = "ADIOI_NFS_WRITECONTIG"; char *p; MPI_Type_size_x(datatype, &datatype_size); len = datatype_size * (ADIO_Offset)count; if (file_ptr_type == ADIO_INDIVIDUAL) { offset = fd->fp_ind; } p = (char *)buf; while (bytes_xfered < len) { #ifdef ADIOI_MPE_LOGGING MPE_Log_event( ADIOI_MPE_write_a, 0, NULL ); #endif wr_count = len - bytes_xfered; /* work around FreeBSD and OS X defects*/ if (wr_count > INT_MAX) wr_count = INT_MAX; ADIOI_WRITE_LOCK(fd, offset+bytes_xfered, SEEK_SET, wr_count); err = pwrite(fd->fd_sys, p, wr_count, offset+bytes_xfered); /* --BEGIN ERROR HANDLING-- */ if (err == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); fd->fp_sys_posn = -1; return; } /* --END ERROR HANDLING-- */ #ifdef ADIOI_MPE_LOGGING MPE_Log_event( ADIOI_MPE_write_b, 0, NULL ); #endif ADIOI_UNLOCK(fd, offset+bytes_xfered, SEEK_SET, wr_count); bytes_xfered += err; p += err; } fd->fp_sys_posn = offset + bytes_xfered; if (file_ptr_type == ADIO_INDIVIDUAL) { fd->fp_ind += bytes_xfered; } #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, datatype, bytes_xfered); #endif *error_code = MPI_SUCCESS; }
void ADIOI_XFS_ReadComplete(ADIO_Request *request, ADIO_Status *status, int *error_code) { int err; static char myname[] = "ADIOI_XFS_READCOMPLETE"; if (*request == ADIO_REQUEST_NULL) { *error_code = MPI_SUCCESS; return; } if ((*request)->queued) { do { err = aio_suspend64((const aiocb64_t **) &((*request)->handle), 1, 0); } while ((err == -1) && (errno == EINTR)); if (err != -1) { err = aio_return64((aiocb64_t *) (*request)->handle); (*request)->nbytes = err; errno = aio_error64((aiocb64_t *) (*request)->handle); } else (*request)->nbytes = -1; if (err == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); } else *error_code = MPI_SUCCESS; } /* if ((*request)->queued) */ else *error_code = MPI_SUCCESS; #ifdef HAVE_STATUS_SET_BYTES if ((*request)->nbytes != -1) MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif if ((*request)->queued != -1) { /* queued = -1 is an internal hack used when the request must be completed, but the request object should not be freed. This is used in ADIOI_Complete_async, because the user will call MPI_Wait later, which would require status to be filled. Ugly but works. queued = -1 should be used only in ADIOI_Complete_async. This should not affect the user in any way. */ /* if request is still queued in the system, it is also there on ADIOI_Async_list. Delete it from there. */ if ((*request)->queued) ADIOI_Del_req_from_list(request); (*request)->fd->async_count--; if ((*request)->handle) ADIOI_Free((*request)->handle); ADIOI_Free_request((ADIOI_Req_node *) (*request)); *request = ADIO_REQUEST_NULL; } }
void ADIOI_ZOIDFS_Fcntl(ADIO_File fd, int flag, ADIO_Fcntl_t *fcntl_struct, int *error_code) { int ret; zoidfs_attr_t attr; ADIOI_ZOIDFS_object *zoidfs_obj_ptr; static char myname[] = "ADIOI_ZOIDFS_FCNTL"; zoidfs_obj_ptr = (ADIOI_ZOIDFS_object*)fd->fs_ptr; switch(flag) { case ADIO_FCNTL_GET_FSIZE: attr.mask = ZOIDFS_ATTR_SIZE; NO_STALE(ret, fd, zoidfs_obj_ptr, zoidfs_getattr(zoidfs_obj_ptr, &attr, ZOIDFS_NO_OP_HINT)); if ( !(attr.mask & ZOIDFS_ATTR_SIZE) || (ret != ZFS_OK ) ) { /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, ADIOI_ZOIDFS_error_convert(ret), "Error in zoidfs_getattr", 0); /* --END ERROR HANDLING-- */ } else { *error_code = MPI_SUCCESS; } fcntl_struct->fsize = attr.size; return; case ADIO_FCNTL_SET_DISKSPACE: ADIOI_GEN_Prealloc(fd, fcntl_struct->diskspace, error_code); break; /* --BEGIN ERROR HANDLING-- */ case ADIO_FCNTL_SET_ATOMICITY: default: *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**flag", "**flag %d", flag); /* --END ERROR HANDLING-- */ } }
/*@ MPI_File_get_view - Returns the file view Input Parameters: . fh - file handle (handle) Output Parameters: . disp - displacement (nonnegative integer) . etype - elementary datatype (handle) . filetype - filetype (handle) . datarep - data representation (string) .N fortran @*/ int MPI_File_get_view(MPI_File fh, MPI_Offset * disp, MPI_Datatype * etype, MPI_Datatype * filetype, char *datarep) { int error_code; ADIO_File adio_fh; static char myname[] = "MPI_FILE_GET_VIEW"; int i, j, k, combiner; MPI_Datatype copy_etype, copy_filetype; ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); if (datarep == NULL) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iodatarepnomem", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ *disp = adio_fh->disp; ADIOI_Strncpy(datarep, (adio_fh->is_external32 ? "external32" : "native"), MPI_MAX_DATAREP_STRING); MPI_Type_get_envelope(adio_fh->etype, &i, &j, &k, &combiner); if (combiner == MPI_COMBINER_NAMED) *etype = adio_fh->etype; else { /* FIXME: It is wrong to use MPI_Type_contiguous; the user could choose to * re-implement MPI_Type_contiguous in an unexpected way. Either use * MPID_Barrier as in MPICH or PMPI_Type_contiguous */ MPI_Type_contiguous(1, adio_fh->etype, ©_etype); /* FIXME: Ditto for MPI_Type_commit - use NMPI or PMPI */ MPI_Type_commit(©_etype); *etype = copy_etype; } /* FIXME: Ditto for MPI_Type_xxx - use NMPI or PMPI */ MPI_Type_get_envelope(adio_fh->filetype, &i, &j, &k, &combiner); if (combiner == MPI_COMBINER_NAMED) *filetype = adio_fh->filetype; else { MPI_Type_contiguous(1, adio_fh->filetype, ©_filetype); MPI_Type_commit(©_filetype); *filetype = copy_filetype; } fn_exit: ROMIO_THREAD_CS_EXIT(); return MPI_SUCCESS; }
void ADIOI_PVFS2_Fcntl(ADIO_File fd, int flag, ADIO_Fcntl_t *fcntl_struct, int *error_code) { int ret; ADIOI_PVFS2_fs *pvfs_fs; PVFS_sysresp_getattr resp_getattr; static char myname[] = "ADIOI_PVFS2_FCNTL"; pvfs_fs = (ADIOI_PVFS2_fs*)fd->fs_ptr; switch(flag) { case ADIO_FCNTL_GET_FSIZE: ret = PVFS_sys_getattr(pvfs_fs->object_ref, PVFS_ATTR_SYS_SIZE, &(pvfs_fs->credentials), &resp_getattr); if (ret != 0 ) { /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, ADIOI_PVFS2_error_convert(ret), "Error in PVFS_sys_getattr", 0); /* --END ERROR HANDLING-- */ } else { *error_code = MPI_SUCCESS; } fcntl_struct->fsize = resp_getattr.attr.size; return; case ADIO_FCNTL_SET_DISKSPACE: ADIOI_GEN_Prealloc(fd, fcntl_struct->diskspace, error_code); break; /* --BEGIN ERROR HANDLING-- */ case ADIO_FCNTL_SET_ATOMICITY: default: *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**flag", "**flag %d", flag); /* --END ERROR HANDLING-- */ } }
/*@ MPI_File_set_atomicity - Sets the atomicity mode Input Parameters: . fh - file handle (handle) . flag - true to set atomic mode, false to set nonatomic mode (logical) .N fortran @*/ int MPI_File_set_atomicity(MPI_File fh, int flag) { int error_code, tmp_flag; static char myname[] = "MPI_FILE_SET_ATOMICITY"; ADIO_Fcntl_t *fcntl_struct; ADIO_File adio_fh; MPIU_THREAD_CS_ENTER(ALLFUNC,); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); /* --END ERROR HANDLING-- */ ADIOI_TEST_DEFERRED(adio_fh, myname, &error_code); if (flag) flag = 1; /* take care of non-one values! */ /* check if flag is the same on all processes */ tmp_flag = flag; MPI_Bcast(&tmp_flag, 1, MPI_INT, 0, adio_fh->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_flag != flag) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**notsame", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ if (adio_fh->atomicity == flag){ error_code = MPI_SUCCESS; goto fn_exit; } fcntl_struct = (ADIO_Fcntl_t *) ADIOI_Malloc(sizeof(ADIO_Fcntl_t)); fcntl_struct->atomicity = flag; ADIO_Fcntl(adio_fh, ADIO_FCNTL_SET_ATOMICITY, fcntl_struct, &error_code); /* TODO: what do we do with this error code? */ /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ ADIOI_Free(fcntl_struct); fn_exit: MPIU_THREAD_CS_EXIT(ALLFUNC,); return error_code; }
void ADIOI_NTFS_Resize(ADIO_File fd, ADIO_Offset size, int *error_code) { LONG dwTemp; DWORD err; BOOL result; static char myname[] = "ADIOI_NTFS_Resize"; dwTemp = DWORDHIGH(size); err = SetFilePointer(fd->fd_sys, DWORDLOW(size), &dwTemp, FILE_BEGIN); /* --BEGIN ERROR HANDLING-- */ if (err == INVALID_SET_FILE_POINTER) { err = GetLastError(); if (err != NO_ERROR) { char errMsg[ADIOI_NTFS_ERR_MSG_MAX]; ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", errMsg); return; } } /*printf("setting file length to %d\n", size);fflush(stdout);*/ /* --END ERROR HANDLING-- */ result = SetEndOfFile(fd->fd_sys); /* --BEGIN ERROR HANDLING-- */ if (result == FALSE) { char errMsg[ADIOI_NTFS_ERR_MSG_MAX]; err = GetLastError(); ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", errMsg); return; } /* --END ERROR HANDLING-- */ *error_code = MPI_SUCCESS; }