summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5FDmpio.c379
-rw-r--r--src/H5FDprivate.h8
-rw-r--r--src/H5Fmpi.c11
-rw-r--r--src/H5Fprivate.h4
-rw-r--r--src/H5Pfapl.c544
-rw-r--r--src/H5Ppublic.h2
-rw-r--r--src/H5mpi.c229
-rw-r--r--src/H5private.h2
8 files changed, 843 insertions, 336 deletions
diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c
index 6ca7aa4..13efcff 100644
--- a/src/H5FDmpio.c
+++ b/src/H5FDmpio.c
@@ -58,27 +58,24 @@ static char H5FD_mpi_native_g[] = "native";
* driver doesn't bother to keep it updated since it's an expensive operation.
*/
typedef struct H5FD_mpio_t {
- H5FD_t pub; /*public stuff, must be first */
- MPI_File f; /*MPIO file handle */
- MPI_Comm comm; /*communicator */
- MPI_Info info; /*file information */
- int mpi_rank; /* This process's rank */
- int mpi_size; /* Total number of processes */
- haddr_t eof; /*end-of-file marker */
- haddr_t eoa; /*end-of-address marker */
- haddr_t last_eoa; /* Last known end-of-address marker */
- haddr_t local_eof; /* Local end-of-file address for each process */
+ H5FD_t pub; /* Public stuff, must be first */
+ MPI_File f; /* MPIO file handle */
+ MPI_Comm comm; /* MPI Communicator */
+ MPI_Info info; /* MPI info object */
+ int mpi_rank; /* This process's rank */
+ int mpi_size; /* Total number of processes */
+ haddr_t eof; /* End-of-file marker */
+ haddr_t eoa; /* End-of-address marker */
+ haddr_t last_eoa; /* Last known end-of-address marker */
+ haddr_t local_eof; /* Local end-of-file address for each process */
} H5FD_mpio_t;
/* Private Prototypes */
/* Callbacks */
static herr_t H5FD__mpio_term(void);
-static void *H5FD__mpio_fapl_get(H5FD_t *_file);
-static void *H5FD__mpio_fapl_copy(const void *_old_fa);
-static herr_t H5FD__mpio_fapl_free(void *_fa);
static H5FD_t *H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id,
- haddr_t maxaddr);
+ haddr_t maxaddr);
static herr_t H5FD__mpio_close(H5FD_t *_file);
static herr_t H5FD__mpio_query(const H5FD_t *_f1, unsigned long *flags);
static haddr_t H5FD__mpio_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
@@ -106,10 +103,10 @@ static const H5FD_class_mpi_t H5FD_mpio_g = {
NULL, /*sb_size */
NULL, /*sb_encode */
NULL, /*sb_decode */
- sizeof(H5FD_mpio_fapl_t), /*fapl_size */
- H5FD__mpio_fapl_get, /*fapl_get */
- H5FD__mpio_fapl_copy, /*fapl_copy */
- H5FD__mpio_fapl_free, /*fapl_free */
+ 0, /*fapl_size */
+ NULL, /*fapl_get */
+ NULL, /*fapl_copy */
+ NULL, /*fapl_free */
0, /*dxpl_size */
NULL, /*dxpl_copy */
NULL, /*dxpl_free */
@@ -306,7 +303,6 @@ H5FD__mpio_term(void)
herr_t
H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info)
{
- H5FD_mpio_fapl_t fa;
H5P_genplist_t *plist; /* Property list pointer */
herr_t ret_value;
@@ -319,15 +315,16 @@ H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info)
if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a file access list")
if(MPI_COMM_NULL == comm)
- HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a valid communicator")
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "MPI_COMM_NULL is not a valid communicator")
- /* Initialize driver specific properties */
- HDmemset(&fa, 0, sizeof(H5FD_mpio_fapl_t));
- fa.comm = comm;
- fa.info = info;
+ /* Set the MPI communicator and info object */
+ if(H5P_set(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI communicator")
+ if(H5P_set(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI info object")
/* duplication is done during driver setting. */
- ret_value = H5P_set_driver(plist, H5FD_MPIO, &fa);
+ ret_value = H5P_set_driver(plist, H5FD_MPIO, NULL);
done:
FUNC_LEAVE_API(ret_value)
@@ -361,52 +358,43 @@ herr_t
H5Pget_fapl_mpio(hid_t fapl_id, MPI_Comm *comm/*out*/, MPI_Info *info/*out*/)
{
H5P_genplist_t *plist; /* Property list pointer */
- const H5FD_mpio_fapl_t *fa; /* MPIO fapl info */
- MPI_Comm comm_tmp = MPI_COMM_NULL;
- hbool_t comm_copied = FALSE; /* MPI Comm has been duplicated */
- int mpi_code; /* MPI return code */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE3("e", "ixx", fapl_id, comm, info);
+ /* Set comm and info in case we have problems */
+ if(comm)
+ *comm = MPI_COMM_NULL;
+ if(info)
+ *info = MPI_INFO_NULL;
+
/* Check arguments */
if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a file access list")
if(H5FD_MPIO != H5P_peek_driver(plist))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
- if(NULL == (fa = (const H5FD_mpio_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info")
-
- /* Store the duplicated communicator in a temporary variable for error */
- /* recovery in case the INFO duplication fails. */
- if(comm) {
- if(MPI_SUCCESS != (mpi_code = MPI_Comm_dup(fa->comm, &comm_tmp)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code)
- comm_copied = TRUE;
- } /* end if */
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "VFL driver is not MPI-I/O")
- if(info) {
- if(MPI_INFO_NULL != fa->info) {
- if(MPI_SUCCESS != (mpi_code = MPI_Info_dup(fa->info, info)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Info_dup failed", mpi_code)
- } /* end if */
- else
- /* do not dup it */
- *info = MPI_INFO_NULL;
- } /* end if */
-
- /* Store the copied communicator, now that the Info object has been
- * successfully copied.
- */
+ /* Get the MPI communicator and info object */
if(comm)
- *comm = comm_tmp;
+ if(H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, comm) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI communicator")
+ if(info)
+ if(H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI info object")
done:
- if(ret_value < 0)
- /* need to free anything created here */
- if(comm_copied)
- MPI_Comm_free(&comm_tmp);
+ /* Clean up anything duplicated on errors. The free calls will set
+ * the output values to MPI_COMM|INFO_NULL.
+ */
+ if(ret_value != SUCCEED) {
+ if(comm)
+ if(H5_mpi_comm_free(comm) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "unable to free MPI communicator")
+ if(info)
+ if(H5_mpi_info_free(info) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "unable to free MPI info object")
+ }
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_fapl_mpio() */
@@ -667,161 +655,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD__mpio_fapl_get
- *
- * Purpose: Returns a file access property list which could be used to
- * create another file the same as this one.
- *
- * Return: Success: Ptr to new file access property list with all
- * fields copied from the file pointer.
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * Friday, August 13, 1999
- *
- *-------------------------------------------------------------------------
- */
-static void *
-H5FD__mpio_fapl_get(H5FD_t *_file)
-{
- H5FD_mpio_t *file = (H5FD_mpio_t*)_file;
- H5FD_mpio_fapl_t *fa = NULL;
- void *ret_value = NULL; /* Return value */
-
- FUNC_ENTER_STATIC
-
- /* Sanity checks */
- HDassert(file);
- HDassert(H5FD_MPIO == file->pub.driver_id);
-
- /* Check arguments */
- if(NULL == (fa = (H5FD_mpio_fapl_t *)H5MM_calloc(sizeof(H5FD_mpio_fapl_t))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- fa->comm = MPI_COMM_NULL;
- fa->info = MPI_INFO_NULL;
-
- /* Duplicate MPI communicator and info */
- if(FAIL == H5_mpi_comm_dup(file->comm, &fa->comm))
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "communicator duplicate failed")
- if(FAIL == H5_mpi_info_dup(file->info, &fa->info))
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "info duplicate failed")
-
- /* Set return value */
- ret_value = fa;
-
-done:
- /* Clean up badness if we're failing */
- if(NULL == ret_value && fa) {
- H5_mpi_comm_free(&fa->comm);
- H5_mpi_info_free(&fa->info);
- H5MM_xfree(fa);
- }
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD__mpio_fapl_get() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD__mpio_fapl_copy
- *
- * Purpose: Copies the mpio-specific file access properties.
- *
- * Return: Success: Ptr to a new property list
- * Failure: NULL
- *
- * Programmer: Albert Cheng
- * Jan 8, 2003
- *
- *-------------------------------------------------------------------------
- */
-static void *
-H5FD__mpio_fapl_copy(const void *_old_fa)
-{
- const H5FD_mpio_fapl_t *old_fa = (const H5FD_mpio_fapl_t*)_old_fa;
- H5FD_mpio_fapl_t *new_fa = NULL;
- void *ret_value = NULL;
-
- FUNC_ENTER_STATIC
-
-#ifdef H5FDmpio_DEBUG
-if(H5FD_mpio_Debug[(int)'t'])
- HDfprintf(stderr, "%s: entering\n", FUNC);
-#endif
-
- if(NULL == (new_fa = (H5FD_mpio_fapl_t *)H5MM_malloc(sizeof(H5FD_mpio_fapl_t))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* Copy the general information */
- H5MM_memcpy(new_fa, old_fa, sizeof(H5FD_mpio_fapl_t));
-
- /* Duplicate MPI communicator and info */
- if(H5_mpi_comm_dup(old_fa->comm, &new_fa->comm) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "communicator duplicate failed")
- if(H5_mpi_info_dup(old_fa->info, &new_fa->info) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "info duplicate failed")
-
- /* Set return value */
- ret_value = new_fa;
-
-done:
- /* Clean up badness if we're failing */
- if(NULL == ret_value && new_fa) {
- H5_mpi_comm_free(&new_fa->comm);
- H5_mpi_info_free(&new_fa->info);
- H5MM_xfree(new_fa);
- }
-
-#ifdef H5FDmpio_DEBUG
-if(H5FD_mpio_Debug[(int)'t'])
- HDfprintf(stderr, "%s: leaving\n", FUNC);
-#endif
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD__mpio_fapl_copy() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD__mpio_fapl_free
- *
- * Purpose: Frees the mpio-specific file access properties.
- *
- * Return: SUCCEED/FAIL
- *
- * Programmer: Albert Cheng
- * Jan 8, 2003
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD__mpio_fapl_free(void *_fa)
-{
- H5FD_mpio_fapl_t *fa = (H5FD_mpio_fapl_t*)_fa;
-
- FUNC_ENTER_STATIC_NOERR
-
-#ifdef H5FDmpio_DEBUG
-if(H5FD_mpio_Debug[(int)'t'])
- HDfprintf(stderr, "%s: Entering\n", FUNC);
-#endif
-
- /* Sanity checks */
- HDassert(fa);
-
- /* Free the internal communicator and INFO object */
- HDassert(MPI_COMM_NULL != fa->comm);
- H5_mpi_comm_free(&fa->comm);
- H5_mpi_info_free(&fa->info);
- H5MM_xfree(fa);
-
-#ifdef H5FDmpio_DEBUG
-if(H5FD_mpio_Debug[(int)'t'])
- HDfprintf(stderr, "%s: leaving\n", FUNC);
-#endif
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5FD__mpio_fapl_free() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5FD_set_mpio_atomicity
*
* Purpose: Sets the atomicity mode
@@ -935,20 +768,18 @@ static H5FD_t *
H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id,
haddr_t H5_ATTR_UNUSED maxaddr)
{
- H5FD_mpio_t *file = NULL;
- MPI_File fh;
- unsigned file_opened = 0; /* Flag to indicate that the file was successfully opened */
- int mpi_amode;
- int mpi_rank; /* MPI rank of this process */
- int mpi_size; /* Total number of MPI processes */
- int mpi_code; /* mpi return code */
- MPI_Offset size;
- const H5FD_mpio_fapl_t *fa = NULL;
- H5FD_mpio_fapl_t _fa;
+ H5FD_mpio_t *file = NULL;
+ MPI_File fh;
+ hbool_t file_opened = FALSE; /* Flag to indicate that the file was successfully opened */
+ int mpi_amode;
+ int mpi_rank; /* MPI rank of this process */
+ int mpi_size; /* Total number of MPI processes */
+ int mpi_code; /* MPI return code */
+ MPI_Offset size;
H5P_genplist_t *plist; /* Property list pointer */
- MPI_Comm comm_dup = MPI_COMM_NULL;
- MPI_Info info_dup = MPI_INFO_NULL;
- H5FD_t *ret_value = NULL; /* Return value */
+ MPI_Comm comm = MPI_COMM_NULL;
+ MPI_Info info = MPI_INFO_NULL;
+ H5FD_t *ret_value = NULL; /* Return value */
FUNC_ENTER_STATIC
@@ -957,26 +788,27 @@ H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id,
HDfprintf(stdout, "%s: Entering - name = \"%s\", flags = 0x%x, fapl_id = %d, maxaddr = %lu\n", FUNC, name, flags, (int)fapl_id, (unsigned long)maxaddr);
#endif
- /* Obtain a pointer to mpio-specific file access properties */
+ /* Get a pointer to the fapl */
if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- if(H5P_FILE_ACCESS_DEFAULT == fapl_id || H5FD_MPIO != H5P_peek_driver(plist)) {
- _fa.comm = MPI_COMM_SELF; /*default*/
- _fa.info = MPI_INFO_NULL; /*default*/
- fa = &_fa;
- } /* end if */
- else
- if(NULL == (fa = (const H5FD_mpio_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info")
- /* Duplicate MPI communicator and info */
- if(FAIL == H5_mpi_comm_dup(fa->comm, &comm_dup))
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "communicator duplicate failed")
- if(FAIL == H5_mpi_info_dup(fa->info, &info_dup))
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "info duplicate failed")
+ /* Set MPI communicator and info object */
+ if(H5P_FILE_ACCESS_DEFAULT == fapl_id || H5FD_MPIO != H5P_peek_driver(plist)) {
+ /* Non-parallel defaults */
+ if(FAIL == H5_mpi_comm_dup(MPI_COMM_SELF, &comm))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "communicator duplicate failed")
+ info = MPI_INFO_NULL;
+ }
+ else {
+ /* Get the MPI communicator and info object from the property list */
+ if(H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator")
+ if(H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object")
+ }
- /* convert HDF5 flags to MPI-IO flags */
- /* some combinations are illegal; let MPI-IO figure it out */
+ /* Convert HDF5 flags to MPI-IO flags */
+ /* Some combinations are illegal; let MPI-IO figure it out */
mpi_amode = (flags & H5F_ACC_RDWR) ? MPI_MODE_RDWR : MPI_MODE_RDONLY;
if(flags & H5F_ACC_CREAT)
mpi_amode |= MPI_MODE_CREATE;
@@ -985,11 +817,11 @@ H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id,
#ifdef H5FDmpio_DEBUG
/* Check for debug commands in the info parameter */
- if(MPI_INFO_NULL != info_dup) {
+ if(MPI_INFO_NULL != info) {
char debug_str[128];
int flag;
- MPI_Info_get(fa->info, H5F_MPIO_DEBUG_KEY, sizeof(debug_str) - 1, debug_str, &flag);
+ MPI_Info_get(info, H5F_MPIO_DEBUG_KEY, sizeof(debug_str) - 1, debug_str, &flag);
if(flag) {
int i;
@@ -1000,22 +832,22 @@ H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id,
} /* end if */
#endif
- if(MPI_SUCCESS != (mpi_code = MPI_File_open(comm_dup, name, mpi_amode, info_dup, &fh)))
+ if(MPI_SUCCESS != (mpi_code = MPI_File_open(comm, name, mpi_amode, info, &fh)))
HMPI_GOTO_ERROR(NULL, "MPI_File_open failed", mpi_code)
- file_opened=1;
+ file_opened = TRUE;
/* Get the MPI rank of this process and the total number of processes */
- if (MPI_SUCCESS != (mpi_code=MPI_Comm_rank (comm_dup, &mpi_rank)))
+ if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank (comm, &mpi_rank)))
HMPI_GOTO_ERROR(NULL, "MPI_Comm_rank failed", mpi_code)
- if (MPI_SUCCESS != (mpi_code=MPI_Comm_size (comm_dup, &mpi_size)))
+ if (MPI_SUCCESS != (mpi_code = MPI_Comm_size (comm, &mpi_size)))
HMPI_GOTO_ERROR(NULL, "MPI_Comm_size failed", mpi_code)
/* Build the return value and initialize it */
if(NULL == (file = (H5FD_mpio_t *)H5MM_calloc(sizeof(H5FD_mpio_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
file->f = fh;
- file->comm = comm_dup;
- file->info = info_dup;
+ file->comm = comm;
+ file->info = info;
file->mpi_rank = mpi_rank;
file->mpi_size = mpi_size;
@@ -1026,7 +858,7 @@ H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id,
} /* end if */
/* Broadcast file size */
- if(MPI_SUCCESS != (mpi_code = MPI_Bcast(&size, (int)sizeof(MPI_Offset), MPI_BYTE, 0, comm_dup)))
+ if(MPI_SUCCESS != (mpi_code = MPI_Bcast(&size, (int)sizeof(MPI_Offset), MPI_BYTE, 0, comm)))
HMPI_GOTO_ERROR(NULL, "MPI_Bcast failed", mpi_code)
/* Determine if the file should be truncated */
@@ -1035,7 +867,7 @@ H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id,
HMPI_GOTO_ERROR(NULL, "MPI_File_set_size failed", mpi_code)
/* Don't let any proc return until all have truncated the file. */
- if (MPI_SUCCESS!= (mpi_code=MPI_Barrier(comm_dup)))
+ if (MPI_SUCCESS != (mpi_code = MPI_Barrier(comm)))
HMPI_GOTO_ERROR(NULL, "MPI_Barrier failed", mpi_code)
/* File is zero size now */
@@ -1053,8 +885,10 @@ done:
if(ret_value == NULL) {
if(file_opened)
MPI_File_close(&fh);
- MPI_Comm_free(&comm_dup);
- MPI_Info_free(&info_dup);
+ if(H5_mpi_comm_free(&comm) < 0)
+ HDONE_ERROR(H5E_VFL, H5E_CANTFREE, NULL, "unable to free MPI communicator")
+ if(H5_mpi_info_free(&info) < 0)
+ HDONE_ERROR(H5E_VFL, H5E_CANTFREE, NULL, "unable to free MPI info object")
if(file)
H5MM_xfree(file);
} /* end if */
@@ -1282,37 +1116,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_mpio_get_info
- *
- * Purpose: Returns the file info of MPIO file driver.
- *
- * Returns: SUCCEED/FAIL
- *
- * Programmer: John Mainzer
- * April 4, 2017
- *
- *-------------------------------------------------------------------------
-*/
-static herr_t
-H5FD_mpio_get_info(H5FD_t *_file, void** mpi_info)
-{
- H5FD_mpio_t *file = (H5FD_mpio_t *)_file;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT
-
- if(!mpi_info)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mpi info not valid")
-
- *mpi_info = &(file->info);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-
-} /* H5FD_mpio_get_info() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5FD__mpio_read
*
* Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR
@@ -1697,7 +1500,7 @@ H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id,
io_size = type_size * size_i;
/* Check for write failure */
- if(bytes_written != io_size)
+ if(bytes_written != io_size || bytes_written < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
/* Each process will keep track of its perceived EOF value locally, and
@@ -1708,8 +1511,8 @@ H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id,
* potentially be wrong.) */
file->eof = HADDR_UNDEF;
- if(bytes_written && ((bytes_written + addr) > file->local_eof))
- file->local_eof = addr + bytes_written;
+ if(bytes_written && (((haddr_t)bytes_written + addr) > file->local_eof))
+ file->local_eof = addr + (haddr_t)bytes_written;
done:
#ifdef H5FDmpio_DEBUG
diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h
index 0db66af..ac08f7f 100644
--- a/src/H5FDprivate.h
+++ b/src/H5FDprivate.h
@@ -95,14 +95,6 @@ typedef struct {
const void *driver_info; /* Driver info, for open callbacks */
} H5FD_driver_prop_t;
-#ifdef H5_HAVE_PARALLEL
-/* MPIO-specific file access properties */
-typedef struct H5FD_mpio_fapl_t {
- MPI_Comm comm; /*communicator */
- MPI_Info info; /*file information */
-} H5FD_mpio_fapl_t;
-#endif /* H5_HAVE_PARALLEL */
-
/*****************************/
/* Library Private Variables */
diff --git a/src/H5Fmpi.c b/src/H5Fmpi.c
index 470241b..bb422ac 100644
--- a/src/H5Fmpi.c
+++ b/src/H5Fmpi.c
@@ -368,14 +368,9 @@ H5F_mpi_retrieve_comm(hid_t loc_id, hid_t acspl_id, MPI_Comm *mpi_comm)
if(NULL == (plist = H5P_object_verify(acspl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a file access list")
- if(H5FD_MPIO == H5P_peek_driver(plist)) {
- const H5FD_mpio_fapl_t *fa; /* MPIO fapl info */
-
- if(NULL == (fa = (const H5FD_mpio_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad VFL driver info")
-
- *mpi_comm = fa->comm;
- }
+ if(H5FD_MPIO == H5P_peek_driver(plist))
+ if(H5P_peek(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, mpi_comm) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MPI communicator")
}
done:
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 867db84..0a7daa0 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -513,6 +513,10 @@ typedef struct H5F_t H5F_t;
#define H5F_ACS_PAGE_BUFFER_SIZE_NAME "page_buffer_size" /* the maximum size for the page buffer cache */
#define H5F_ACS_PAGE_BUFFER_MIN_META_PERC_NAME "page_buffer_min_meta_perc" /* the min metadata percentage for the page buffer cache */
#define H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_NAME "page_buffer_min_raw_perc" /* the min raw data percentage for the page buffer cache */
+#ifdef H5_HAVE_PARALLEL
+#define H5F_ACS_MPI_PARAMS_COMM_NAME "mpi_params_comm" /* the MPI communicator */
+#define H5F_ACS_MPI_PARAMS_INFO_NAME "mpi_params_info" /* the MPI info struct */
+#endif /* H5_HAVE_PARALLEL */
/* ======================== File Mount properties ====================*/
#define H5F_MNT_SYM_LOCAL_NAME "local" /* Whether absolute symlinks local to file. */
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index 8bb2b12..22252d3 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -30,22 +30,22 @@
/***********/
/* Headers */
/***********/
-#include "H5private.h" /* Generic Functions */
-#include "H5ACprivate.h" /* Metadata cache */
-#include "H5Dprivate.h" /* Datasets */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Fprivate.h" /* Files */
-#include "H5FDprivate.h" /* File drivers */
-#include "H5Iprivate.h" /* IDs */
-#include "H5MMprivate.h" /* Memory Management */
-#include "H5Ppkg.h" /* Property lists */
-#include "H5VLprivate.h" /* Virtual Object Layer */
+#include "H5private.h" /* Generic Functions */
+#include "H5ACprivate.h" /* Metadata cache */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* Files */
+#include "H5FDprivate.h" /* File drivers */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory Management */
+#include "H5Ppkg.h" /* Property lists */
+#include "H5VLprivate.h" /* Virtual Object Layer */
+#include "H5VMprivate.h" /* Vector Functions */
/* Includes needed to set default file driver */
-#include "H5FDsec2.h" /* POSIX unbuffered I/O */
-#include "H5FDstdio.h" /* Standard C buffered I/O */
+#include "H5FDsec2.h" /* POSIX unbuffered I/O */
+#include "H5FDstdio.h" /* Standard C buffered I/O */
#ifdef H5_HAVE_WINDOWS
-#include "H5FDwindows.h" /* Win32 I/O */
+#include "H5FDwindows.h" /* Win32 I/O */
#endif
/* Includes needed to set default VOL connector */
@@ -111,7 +111,7 @@
#define H5F_ACS_GARBG_COLCT_REF_DEF 0
#define H5F_ACS_GARBG_COLCT_REF_ENC H5P__encode_unsigned
#define H5F_ACS_GARBG_COLCT_REF_DEC H5P__decode_unsigned
-/* Definition for file driver ID & info*/
+/* Definition for file driver ID & info */
#define H5F_ACS_FILE_DRV_SIZE sizeof(H5FD_driver_prop_t)
#define H5F_ACS_FILE_DRV_DEF {H5_DEFAULT_VFD, NULL}
#define H5F_ACS_FILE_DRV_CRT H5P__facc_file_driver_create
@@ -231,6 +231,24 @@
#define H5F_ACS_COLL_MD_WRITE_FLAG_DEF FALSE
#define H5F_ACS_COLL_MD_WRITE_FLAG_ENC H5P__encode_hbool_t
#define H5F_ACS_COLL_MD_WRITE_FLAG_DEC H5P__decode_hbool_t
+/* Definition for the file's MPI communicator */
+#define H5F_ACS_MPI_PARAMS_COMM_SIZE sizeof(MPI_Comm)
+#define H5F_ACS_MPI_PARAMS_COMM_DEF MPI_COMM_NULL
+#define H5F_ACS_MPI_PARAMS_COMM_SET H5P__facc_mpi_comm_set
+#define H5F_ACS_MPI_PARAMS_COMM_GET H5P__facc_mpi_comm_get
+#define H5F_ACS_MPI_PARAMS_COMM_DEL H5P__facc_mpi_comm_del
+#define H5F_ACS_MPI_PARAMS_COMM_COPY H5P__facc_mpi_comm_copy
+#define H5F_ACS_MPI_PARAMS_COMM_CMP H5P__facc_mpi_comm_cmp
+#define H5F_ACS_MPI_PARAMS_COMM_CLOSE H5P__facc_mpi_comm_close
+/* Definition for the file's MPI info */
+#define H5F_ACS_MPI_PARAMS_INFO_SIZE sizeof(MPI_Info)
+#define H5F_ACS_MPI_PARAMS_INFO_DEF MPI_INFO_NULL
+#define H5F_ACS_MPI_PARAMS_INFO_SET H5P__facc_mpi_info_set
+#define H5F_ACS_MPI_PARAMS_INFO_GET H5P__facc_mpi_info_get
+#define H5F_ACS_MPI_PARAMS_INFO_DEL H5P__facc_mpi_info_del
+#define H5F_ACS_MPI_PARAMS_INFO_COPY H5P__facc_mpi_info_copy
+#define H5F_ACS_MPI_PARAMS_INFO_CMP H5P__facc_mpi_info_cmp
+#define H5F_ACS_MPI_PARAMS_INFO_CLOSE H5P__facc_mpi_info_close
#endif /* H5_HAVE_PARALLEL */
/* Definitions for the initial metadata cache image configuration */
#define H5F_ACS_META_CACHE_INIT_IMAGE_CONFIG_SIZE sizeof(H5AC_cache_image_config_t)
@@ -334,6 +352,24 @@ static herr_t H5P__facc_vol_copy(const char *name, size_t size, void *value);
static int H5P__facc_vol_cmp(const void *value1, const void *value2, size_t size);
static herr_t H5P__facc_vol_close(const char *name, size_t size, void *value);
+#ifdef H5_HAVE_PARALLEL
+/* MPI communicator callbacks */
+static herr_t H5P__facc_mpi_comm_set(hid_t prop_id, const char *name, size_t size, void *value);
+static herr_t H5P__facc_mpi_comm_get(hid_t prop_id, const char *name, size_t size, void *value);
+static herr_t H5P__facc_mpi_comm_del(hid_t prop_id, const char *name, size_t size, void *value);
+static herr_t H5P__facc_mpi_comm_copy(const char *name, size_t size, void *value);
+static int H5P__facc_mpi_comm_cmp(const void *value1, const void *value2, size_t size);
+static herr_t H5P__facc_mpi_comm_close(const char *name, size_t size, void *value);
+
+/* MPI info callbacks */
+static herr_t H5P__facc_mpi_info_set(hid_t prop_id, const char *name, size_t size, void *value);
+static herr_t H5P__facc_mpi_info_get(hid_t prop_id, const char *name, size_t size, void *value);
+static herr_t H5P__facc_mpi_info_del(hid_t prop_id, const char *name, size_t size, void *value);
+static herr_t H5P__facc_mpi_info_copy(const char *name, size_t size, void *value);
+static int H5P__facc_mpi_info_cmp(const void *value1, const void *value2, size_t size);
+static herr_t H5P__facc_mpi_info_close(const char *name, size_t size, void *value);
+#endif /* H5_HAVE_PARALLEL */
+
/*********************/
/* Package Variables */
@@ -404,6 +440,8 @@ static const hbool_t H5F_def_evict_on_close_flag_g = H5F_ACS_EVICT_ON_CLOSE_FLAG
#ifdef H5_HAVE_PARALLEL
static const H5P_coll_md_read_flag_t H5F_def_coll_md_read_flag_g = H5F_ACS_COLL_MD_READ_FLAG_DEF; /* Default setting for the collective metedata read flag */
static const hbool_t H5F_def_coll_md_write_flag_g = H5F_ACS_COLL_MD_WRITE_FLAG_DEF; /* Default setting for the collective metedata write flag */
+static const MPI_Comm H5F_def_mpi_params_comm_g = H5F_ACS_MPI_PARAMS_COMM_DEF; /* Default MPI communicator */
+static const MPI_Info H5F_def_mpi_params_info_g = H5F_ACS_MPI_PARAMS_INFO_DEF; /* Default MPI info struct */
#endif /* H5_HAVE_PARALLEL */
static const H5AC_cache_image_config_t H5F_def_mdc_initCacheImageCfg_g = H5F_ACS_META_CACHE_INIT_IMAGE_CONFIG_DEF; /* Default metadata cache image settings */
static const size_t H5F_def_page_buf_size_g = H5F_ACS_PAGE_BUFFER_SIZE_DEF; /* Default page buffer size */
@@ -621,6 +659,19 @@ H5P__facc_reg_prop(H5P_genclass_t *pclass)
NULL, NULL, NULL, H5F_ACS_COLL_MD_WRITE_FLAG_ENC, H5F_ACS_COLL_MD_WRITE_FLAG_DEC,
NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register the MPI communicator */
+ if(H5P__register_real(pclass, H5F_ACS_MPI_PARAMS_COMM_NAME, H5F_ACS_MPI_PARAMS_COMM_SIZE, &H5F_def_mpi_params_comm_g,
+ NULL, H5F_ACS_MPI_PARAMS_COMM_SET, H5F_ACS_MPI_PARAMS_COMM_GET, NULL, NULL,
+ H5F_ACS_MPI_PARAMS_COMM_DEL, H5F_ACS_MPI_PARAMS_COMM_COPY, H5F_ACS_MPI_PARAMS_COMM_CMP, H5F_ACS_MPI_PARAMS_COMM_CLOSE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register the MPI info struct */
+ if(H5P__register_real(pclass, H5F_ACS_MPI_PARAMS_INFO_NAME, H5F_ACS_MPI_PARAMS_INFO_SIZE, &H5F_def_mpi_params_info_g,
+ NULL, H5F_ACS_MPI_PARAMS_INFO_SET, H5F_ACS_MPI_PARAMS_INFO_GET, NULL, NULL,
+ H5F_ACS_MPI_PARAMS_INFO_DEL, H5F_ACS_MPI_PARAMS_INFO_COPY, H5F_ACS_MPI_PARAMS_INFO_CMP, H5F_ACS_MPI_PARAMS_INFO_CLOSE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
#endif /* H5_HAVE_PARALLEL */
/* Register the initial metadata cache image configuration */
@@ -634,11 +685,13 @@ H5P__facc_reg_prop(H5P_genclass_t *pclass)
NULL, NULL, NULL, H5F_ACS_PAGE_BUFFER_SIZE_ENC, H5F_ACS_PAGE_BUFFER_SIZE_DEC,
NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
/* Register the size of the page buffer minimum metadata size */
if(H5P__register_real(pclass, H5F_ACS_PAGE_BUFFER_MIN_META_PERC_NAME, H5F_ACS_PAGE_BUFFER_MIN_META_PERC_SIZE, &H5F_def_page_buf_min_meta_perc_g,
NULL, NULL, NULL, H5F_ACS_PAGE_BUFFER_MIN_META_PERC_ENC, H5F_ACS_PAGE_BUFFER_MIN_META_PERC_DEC,
NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
/* Register the size of the page buffer minimum raw data size */
if(H5P__register_real(pclass, H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_NAME, H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_SIZE, &H5F_def_page_buf_min_raw_perc_g,
NULL, NULL, NULL, H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_ENC, H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_DEC,
@@ -4738,6 +4791,468 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Pget_mpi_params
+ *
+ * Purpose: Gets the MPI communicator and info stored in the fapl.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Dana Robinson
+ * August 2019
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_mpi_params(hid_t plist_id, MPI_Comm *comm, MPI_Info *info)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*Mc*Mi", plist_id, comm, info);
+
+ /* Make sure that the property list is a fapl */
+ if(TRUE != H5P_isa_class(plist_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property list is not a file access plist")
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(plist_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get the properties */
+ if(H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, comm) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI communicator from plist")
+ if(H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI info from plist")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_mpi_params() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_mpi_params
+ *
+ * Purpose: Set the MPI communicator and info
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Dana Robinson
+ * August 2019
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_mpi_params(hid_t plist_id, MPI_Comm comm, MPI_Info info)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iMcMi", plist_id, comm, info);
+
+ /* Make sure the MPI communicator is valid */
+ if(MPI_COMM_NULL == comm)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "not a valid argument")
+
+ /* Make sure that the property list is a fapl */
+ if(TRUE != H5P_isa_class(plist_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property list is not a file access plist")
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(plist_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Set values */
+ if(H5P_set(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI communicator")
+ if(H5P_set(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI info object")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_mpi_params() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_comm_set
+ *
+ * Purpose: Copies an MPI comminicator property when it's set for a property list
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_mpi_comm_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
+ size_t H5_ATTR_UNUSED size, void *value)
+{
+ MPI_Comm *comm = (MPI_Comm *)value;
+ MPI_Comm comm_tmp = MPI_COMM_NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Make a copy of the MPI communicator */
+ if(H5_mpi_comm_dup(*comm, &comm_tmp) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to duplicate MPI communicator")
+
+done:
+ /* Copy the communicator to the in/out parameter */
+ if(ret_value != SUCCEED)
+ *comm = MPI_COMM_NULL;
+ else
+ *comm = comm_tmp;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_comm_set() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_comm_get
+ *
+ * Purpose: Copies an MPI comminicator property when it's retrieved from a property list
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_mpi_comm_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
+ size_t H5_ATTR_UNUSED size, void *value)
+{
+ MPI_Comm *comm = (MPI_Comm *)value;
+ MPI_Comm comm_tmp = MPI_COMM_NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Make a copy of the MPI communicator */
+ if(H5_mpi_comm_dup(*comm, &comm_tmp) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to duplicate MPI communicator")
+
+done:
+ /* Copy the communicator to the out parameter */
+ if(ret_value != SUCCEED)
+ *comm = MPI_COMM_NULL;
+ else
+ *comm = comm_tmp;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_comm_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_comm_del
+ *
+ * Purpose: Frees an MPI communicator property
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_mpi_comm_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
+{
+ MPI_Comm *comm = (MPI_Comm *)value;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Free the MPI communicator */
+ if(H5_mpi_comm_free(comm) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "unable to free MPI communicator")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_comm_del() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_comm_copy
+ *
+ * Purpose: Copy callback for the MPI communicator property.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_mpi_comm_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
+{
+ MPI_Comm *comm = (MPI_Comm *)value;
+ MPI_Comm comm_tmp = MPI_COMM_NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Make a copy of the MPI communicator */
+ if(H5_mpi_comm_dup(*comm, &comm_tmp) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to duplicate MPI communicator")
+
+done:
+ /* Copy the communicator to the in/out parameter */
+ if(ret_value != SUCCEED)
+ *comm = MPI_COMM_NULL;
+ else
+ *comm = comm_tmp;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_comm_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_comm_cmp
+ *
+ * Purpose: Callback routine which is called whenever the MPI
+ * communicator property in the file access property list
+ * is compared.
+ *
+ * Return: positive if VALUE1 is greater than VALUE2, negative if
+ * VALUE2 is greater than VALUE1 and zero if VALUE1 and
+ * VALUE2 are equal.
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5P__facc_mpi_comm_cmp(const void *_comm1, const void *_comm2, size_t H5_ATTR_UNUSED size)
+{
+ const MPI_Comm *comm1 = (const MPI_Comm *)_comm1;
+ const MPI_Comm *comm2 = (const MPI_Comm *)_comm2;
+ int ret_value = 0;
+
+ FUNC_ENTER_STATIC
+
+ /* Compare the MPI communicators */
+ if(H5_mpi_comm_cmp(*comm1, *comm2, &ret_value) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, 0, "unable to compare MPI communicator")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_comm_cmp() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_comm_close
+ *
+ * Purpose: Close callback for the MPI communicator property.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_mpi_comm_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
+{
+ MPI_Comm *comm = (MPI_Comm *)value;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Free the MPI communicator */
+ if(H5_mpi_comm_free(comm) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "unable to free MPI communicator")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_comm_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_info_set
+ *
+ * Purpose: Copies an MPI info object property when it's set for a property list
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_mpi_info_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
+ size_t H5_ATTR_UNUSED size, void *value)
+{
+ MPI_Info *info = (MPI_Info *)value;
+ MPI_Info info_tmp = MPI_INFO_NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Make a copy of the MPI info object */
+ if(H5_mpi_info_dup(*info, &info_tmp) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to duplicate MPI info object")
+
+done:
+ /* Copy the info object to the in/out parameter */
+ if(ret_value != SUCCEED)
+ *info = MPI_INFO_NULL;
+ else
+ *info = info_tmp;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_info_set() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_info_get
+ *
+ * Purpose: Copies an MPI comminicator property when it's retrieved from a property list
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_mpi_info_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
+ size_t H5_ATTR_UNUSED size, void *value)
+{
+ MPI_Info *info = (MPI_Info *)value;
+ MPI_Info info_tmp = MPI_INFO_NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Make a copy of the MPI communicator */
+ if(H5_mpi_info_dup(*info, &info_tmp) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to duplicate MPI info object")
+
+done:
+ /* Copy the info object to the out parameter */
+ if(ret_value != SUCCEED)
+ *info = MPI_INFO_NULL;
+ else
+ *info = info_tmp;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_info_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_info_del
+ *
+ * Purpose: Frees an MPI info object property
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_mpi_info_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
+{
+ MPI_Info *info = (MPI_Info *)value;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Free the MPI info object */
+ if(H5_mpi_info_free(info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "unable to free MPI info object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_info_del() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_info_copy
+ *
+ * Purpose: Copy callback for the MPI info object property.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_mpi_info_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
+{
+ MPI_Info *info = (MPI_Info *)value;
+ MPI_Info info_tmp = MPI_INFO_NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Make a copy of the MPI info object */
+ if(H5_mpi_info_dup(*info, &info_tmp) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to duplicate MPI info object")
+
+done:
+ /* Copy the info object to the in/out parameter */
+ if(ret_value != SUCCEED)
+ *info = MPI_INFO_NULL;
+ else
+ *info = info_tmp;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_info_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_info_cmp
+ *
+ * Purpose: Callback routine which is called whenever the MPI
+ * info object property in the file access property list
+ * is compared.
+ *
+ * Return: positive if VALUE1 is greater than VALUE2, negative if
+ * VALUE2 is greater than VALUE1 and zero if VALUE1 and
+ * VALUE2 are equal.
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5P__facc_mpi_info_cmp(const void *_info1, const void *_info2, size_t H5_ATTR_UNUSED size)
+{
+ const MPI_Info *info1 = (const MPI_Info *)_info1;
+ const MPI_Info *info2 = (const MPI_Info *)_info2;
+ int ret_value = 0;
+
+ FUNC_ENTER_STATIC
+
+ /* Compare the MPI info objects */
+ if(H5_mpi_info_cmp(*info1, *info2, &ret_value) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, 0, "unable to compare MPI info objects")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_info_cmp() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_mpi_info_close
+ *
+ * Purpose: Close callback for the MPI info object property.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_mpi_info_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
+{
+ MPI_Info *info = (MPI_Info *)value;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Free the MPI info object */
+ if(H5_mpi_info_free(info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "unable to free MPI info object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_mpi_info_close() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Pget_coll_metadata_write
*
* Purpose: Gets information about collective metadata write mode.
@@ -5305,4 +5820,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P__facc_vol_close() */
-
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 43e477a..9f26b8b 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -381,6 +381,8 @@ H5_DLL herr_t H5Pset_all_coll_metadata_ops(hid_t plist_id, hbool_t is_collective
H5_DLL herr_t H5Pget_all_coll_metadata_ops(hid_t plist_id, hbool_t *is_collective);
H5_DLL herr_t H5Pset_coll_metadata_write(hid_t plist_id, hbool_t is_collective);
H5_DLL herr_t H5Pget_coll_metadata_write(hid_t plist_id, hbool_t *is_collective);
+H5_DLL herr_t H5Pget_mpi_params(hid_t fapl_id, MPI_Comm *comm, MPI_Info *info);
+H5_DLL herr_t H5Pset_mpi_params(hid_t fapl_id, MPI_Comm comm, MPI_Info info);
#endif /* H5_HAVE_PARALLEL */
H5_DLL herr_t H5Pset_mdc_image_config(hid_t plist_id, H5AC_cache_image_config_t *config_ptr);
H5_DLL herr_t H5Pget_mdc_image_config(hid_t plist_id, H5AC_cache_image_config_t *config_ptr /*out*/);
diff --git a/src/H5mpi.c b/src/H5mpi.c
index ea6b33f..aec1e03 100644
--- a/src/H5mpi.c
+++ b/src/H5mpi.c
@@ -16,14 +16,10 @@
*
*/
-
#include "H5private.h" /* Generic Functions */
-#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
-#include "H5Fprivate.h" /* File access */
-#include "H5FDprivate.h" /* File drivers */
-#include "H5FDmpi.h" /* Common MPI file driver */
-#include "H5Pprivate.h" /* Property lists */
+#include "H5MMprivate.h" /* Memory Management */
+
#ifdef H5_HAVE_PARALLEL
@@ -32,6 +28,9 @@
*
* Purpose: Duplicate an MPI communicator.
*
+ * Does not duplicate MPI_COMM_NULL. Instead, comm_new will
+ * be set to MPI_COMM_NULL directly.
+ *
* The new communicator is returned via the comm_new pointer.
*
* Return: SUCCEED/FAIL
@@ -50,19 +49,26 @@ H5_mpi_comm_dup(MPI_Comm comm, MPI_Comm *comm_new)
/* Check arguments */
if (!comm_new)
HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "comm_new cannot be NULL")
- if (MPI_COMM_NULL == comm)
- HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't duplicate MPI_COMM_NULL")
- /* Duplicate the MPI communicator */
- if (MPI_SUCCESS != (mpi_code = MPI_Comm_dup(comm, &comm_dup)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code)
+ /* Handle MPI_COMM_NULL separately */
+ if (MPI_COMM_NULL == comm) {
+ /* Don't duplicate MPI_COMM_NULL since that's an error in MPI */
+ comm_dup = MPI_COMM_NULL;
+ }
+ else {
- /* Set MPI_ERRORS_RETURN on comm_dup so that MPI failures are not fatal,
- * and return codes can be checked and handled.
- */
- if (MPI_SUCCESS != (mpi_code = MPI_Comm_set_errhandler(comm_dup, MPI_ERRORS_RETURN)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Errhandler_set failed", mpi_code)
+ /* Duplicate the MPI communicator */
+ if (MPI_SUCCESS != (mpi_code = MPI_Comm_dup(comm, &comm_dup)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code)
+
+ /* Set MPI_ERRORS_RETURN on comm_dup so that MPI failures are not fatal,
+ * and return codes can be checked and handled.
+ */
+ if (MPI_SUCCESS != (mpi_code = MPI_Comm_set_errhandler(comm_dup, MPI_ERRORS_RETURN)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Errhandler_set failed", mpi_code)
+ }
+
/* Copy the new communicator to the return argument */
*comm_new = comm_dup;
@@ -108,7 +114,7 @@ H5_mpi_info_dup(MPI_Info info, MPI_Info *info_new)
/* Duplicate the MPI info */
if (info == MPI_INFO_NULL) {
/* Don't duplicate MPI_INFO_NULL. Just copy it. */
- info_dup = info;
+ info_dup = MPI_INFO_NULL;
}
else {
/* Duplicate the info */
@@ -194,5 +200,194 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* End H5_mpi_info_free() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5_mpi_comm_cmp
+ *
+ * Purpose: Compares two MPI communicators.
+ *
+ * Note that passing MPI_COMM_NULL to this function will not
+ * throw errors, unlike MPI_Comm_compare().
+ *
+ * We consider MPI communicators to be the "same" when the
+ * groups are identical. We don't care about the context
+ * since that will always be different as we call MPI_Comm_dup
+ * when we store the communicator in the fapl.
+ *
+ * The out parameter is a value like strcmp. The value is
+ * undefined when the return value is FAIL.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5_mpi_comm_cmp(MPI_Comm comm1, MPI_Comm comm2, int *result)
+{
+ int mpi_code;
+ int mpi_result = MPI_IDENT;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check arguments */
+ if (!result)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "result cannot be NULL")
+
+ /* Set out parameter to something reasonable in case something goes wrong */
+ *result = 0;
+
+ /* Can't pass MPI_COMM_NULL to MPI_Comm_compare() so we have to handle
+ * it in special cases.
+ */
+ if (MPI_COMM_NULL == comm1 && MPI_COMM_NULL == comm2) {
+ /* Special case of both communicators being MPI_COMM_NULL */
+ *result = 0;
+ }
+ else if (MPI_COMM_NULL == comm1 || MPI_COMM_NULL == comm2) {
+
+ /* Special case of one communicator being MPI_COMM_NULL */
+ *result = (MPI_Datatype)comm1 < (MPI_Datatype)comm2 ? -1 : 1;
+ }
+ else {
+
+ /* Normal communicator compare */
+
+ /* Compare the MPI communicators */
+ if (MPI_SUCCESS != (mpi_code = MPI_Comm_compare(comm1, comm2, &mpi_result)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Comm_compare failed", mpi_code)
+
+ /* Set the result
+ *
+ * The else clause should work regardless of whether MPI_Datatype is
+ * fundamentally an integer or a pointer.
+ */
+ if (MPI_IDENT == mpi_result || MPI_CONGRUENT == mpi_result)
+ *result = 0;
+ else
+ *result = (MPI_Datatype)comm1 < (MPI_Datatype)comm2 ? -1 : 1;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5_mpi_comm_cmp() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5_mpi_info_cmp
+ *
+ * Purpose: Compares two MPI info objects.
+ *
+ * For our purposes, two mpi info objects are the "same" if
+ * they contain the same key-value pairs or are both
+ * MPI_INFO_NULL.
+ *
+ * The out parameter is a value like strcmp. The value is
+ * undefined when the return value is FAIL.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5_mpi_info_cmp(MPI_Info info1, MPI_Info info2, int *result)
+{
+ hbool_t same = FALSE;
+ char *key = NULL;
+ char *value1 = NULL;
+ char *value2 = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check arguments */
+ if (!result)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "result cannot be NULL")
+
+ /* Check for MPI_INFO_NULL */
+ if (MPI_INFO_NULL == info1 && MPI_INFO_NULL == info2) {
+ /* Special case of both info objects being MPI_INFO_NULL */
+ same = TRUE;
+ }
+ else if (MPI_INFO_NULL == info1 || MPI_INFO_NULL == info2) {
+
+ /* Special case of one info object being MPI_INFO_NULL */
+ same = FALSE;
+ }
+ else {
+ int mpi_code;
+ int nkeys_1;
+ int nkeys_2;
+
+ /* Check if the number of keys is the same */
+ if (MPI_SUCCESS != (mpi_code = MPI_Info_get_nkeys(info1, &nkeys_1)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Info_get_nkeys failed", mpi_code)
+ if (MPI_SUCCESS != (mpi_code = MPI_Info_get_nkeys(info2, &nkeys_2)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Info_get_nkeys failed", mpi_code)
+
+ if (nkeys_1 != nkeys_2)
+ same = FALSE;
+ else if (0 == nkeys_1 && 0 == nkeys_2)
+ same = TRUE;
+ else {
+ int i;
+ int flag1 = -1;
+ int flag2 = -1;
+
+ /* Allocate buffers for iteration */
+ if (NULL == (key = (char *)H5MM_malloc(MPI_MAX_INFO_KEY * sizeof(char))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if (NULL == (value1 = (char *)H5MM_malloc(MPI_MAX_INFO_VAL * sizeof(char))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if (NULL == (value2 = (char *)H5MM_malloc(MPI_MAX_INFO_VAL * sizeof(char))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Iterate over the keys, comparing them */
+ for (i = 0; i < nkeys_1; i++) {
+
+ same = TRUE;
+
+ /* Memset the buffers to zero */
+ HDmemset(key, 0, MPI_MAX_INFO_KEY);
+ HDmemset(value1, 0, MPI_MAX_INFO_VAL);
+ HDmemset(value2, 0, MPI_MAX_INFO_VAL);
+
+ /* Get the nth key */
+ if (MPI_SUCCESS != (mpi_code = MPI_Info_get_nthkey(info1, i, key)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Info_get_nthkey failed", mpi_code)
+
+ /* Get the values */
+ if (MPI_SUCCESS != (mpi_code = MPI_Info_get(info1, key, MPI_MAX_INFO_VAL, value1, &flag1)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Info_get failed", mpi_code)
+ if (MPI_SUCCESS != (mpi_code = MPI_Info_get(info2, key, MPI_MAX_INFO_VAL, value2, &flag2)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Info_get failed", mpi_code)
+
+ /* Compare values and flags */
+ if (!flag1 || !flag2 || HDmemcmp(value1, value2, MPI_MAX_INFO_VAL)) {
+ same = FALSE;
+ break;
+ }
+
+ } /* end for */
+ } /* end else */
+ } /* end else */
+
+ /* Set the output value */
+ if (same)
+ *result = 0;
+ else
+ *result = (MPI_Datatype)info1 < (MPI_Datatype)info2 ? -1 : 1;
+
+done:
+ if (key)
+ H5MM_xfree(key);
+ if (value1)
+ H5MM_xfree(value1);
+ if (value2)
+ H5MM_xfree(value2);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5_mpi_info_cmp() */
+
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5private.h b/src/H5private.h
index 18b52a0..bb2a2eb 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -2674,6 +2674,8 @@ H5_DLL herr_t H5_mpi_comm_dup(MPI_Comm comm, MPI_Comm *comm_new);
H5_DLL herr_t H5_mpi_info_dup(MPI_Info info, MPI_Info *info_new);
H5_DLL herr_t H5_mpi_comm_free(MPI_Comm *comm);
H5_DLL herr_t H5_mpi_info_free(MPI_Info *info);
+H5_DLL herr_t H5_mpi_comm_cmp(MPI_Comm comm1, MPI_Comm comm2, int *result);
+H5_DLL herr_t H5_mpi_info_cmp(MPI_Info info1, MPI_Info info2, int *result);
#endif /* H5_HAVE_PARALLEL */
/* Functions for debugging */