diff options
author | Albert Cheng <acheng@hdfgroup.org> | 2003-04-18 03:04:56 (GMT) |
---|---|---|
committer | Albert Cheng <acheng@hdfgroup.org> | 2003-04-18 03:04:56 (GMT) |
commit | 49fa61246edc571924884c9cd9a112cec53ade2a (patch) | |
tree | f8fab274e42a41d3fc8de914a16dce20a207b6cf | |
parent | 3585f15d915ad6c28abbfc45961db274dccf1684 (diff) | |
download | hdf5-49fa61246edc571924884c9cd9a112cec53ade2a.zip hdf5-49fa61246edc571924884c9cd9a112cec53ade2a.tar.gz hdf5-49fa61246edc571924884c9cd9a112cec53ade2a.tar.bz2 |
[svn-r6709] Purpose:
Bug fixes/API changes
Description:
Previously, the Communicator and Info object arguments supplied
to H5Pset_fapl_mpio() are stored in the property with its handle
values. This meant changes to the communicator or the Info object
after calling H5Pset_fapl_mpio would affect the how the property
list function. This was also the case when H5Fopen/create operated.
They just stored the handle value. This is not according to the
MPI-2 defined behavior of how Info objects should be handled. (MPI-2
defines Info objects must be parsed when called.)
The old design was trying to avoid numerous duplicates of the same
information (e.g., every property object holds one version, every
file opened holds another version, when all of them are referring to
the same original version.) Nevertheless it is safer to implement
it according to MPI-2 definition.
Futhermore, the library often needs to do message passing using the
supplied communicator. Using the same communicator as the application
version may result in some messages mix up.
Solution:
H5Pset_fapl_mpio now stores a duplicate of each of the communicator
and Info object.
H5Pget_fapl_mpio returns a duplicate of its stored communicator and
Info object. It is now the responsibility of the applications to free
those objects when done.
H5Fopen/create also stores a duplicate of the communicator and Info
object supplied by the File Access Property list.
H5Fclose frees those duplicates.
There are a few more internal VFL call back functions that they
follow this "make duplicates" requirement.
Platforms tested:
"h5committested".
What other platforms/configurations were tested?
Eirene (mpicc), sol(mpicc), copper(parallel)
Misc. update:
Need to update MANIFEST for the added t_ph5basic.c which tests the
correctness of duplicated communicator and INFO object.
-rw-r--r-- | testpar/Makefile.in | 8 | ||||
-rw-r--r-- | testpar/t_ph5basic.c | 188 | ||||
-rw-r--r-- | testpar/testphdf5.c | 12 |
3 files changed, 202 insertions, 6 deletions
diff --git a/testpar/Makefile.in b/testpar/Makefile.in index e28feae..15cf109 100644 --- a/testpar/Makefile.in +++ b/testpar/Makefile.in @@ -1,6 +1,5 @@ ## hdf5 Parallel Library Test Makefile(.in) ## -## ## Copyright by the Board of Trustees of the University of Illinois. ## All rights reserved. ## @@ -29,7 +28,7 @@ RUNTEST=$(RUNPARALLEL) ## Test programs and scripts. ## -TEST_PROGS_PARA=t_mpi +TEST_PROGS_PARA=t_mpi t_fphdf5 TEST_SCRIPTS=testph5.sh ## These are our main targets @@ -40,7 +39,7 @@ MOSTLYCLEAN=ParaEg[123].h5f DISTCLEAN=go Makefile testph5.sh ## Test source files -TEST_PHDF5_SRC=testphdf5.c t_dset.c t_file.c t_mdset.c +TEST_PHDF5_SRC=testphdf5.c t_dset.c t_file.c t_mdset.c t_ph5basic.c TEST_PHDF5_OBJ=$(TEST_PHDF5_SRC:.c=.lo) TEST_SRC=t_mpi.c $(TEST_PHDF5_SRC) TEST_OBJ=$(TEST_SRC:.c=.lo) @@ -51,6 +50,9 @@ $(PROGS): $(LIBHDF5) $(LIBH5TEST) $(TEST_OBJ): $(TEST_HDR) +t_fphdf5: t_fphdf5.lo + @$(LT_LINK_EXE) $(CFLAGS) -o $@ t_fphdf5.lo $(LIBH5TEST) $(LIBHDF5) $(LDFLAGS) $(LIBS) + t_mpi: t_mpi.lo @$(LT_LINK_EXE) $(CFLAGS) -o $@ t_mpi.lo $(LIBH5TEST) $(LIBHDF5) $(LDFLAGS) $(LIBS) diff --git a/testpar/t_ph5basic.c b/testpar/t_ph5basic.c new file mode 100644 index 0000000..75cbc60 --- /dev/null +++ b/testpar/t_ph5basic.c @@ -0,0 +1,188 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* $Id$ */ + +/* + * Test parallel HDF5 basic components + */ + +#include "testphdf5.h" + + +/*------------------------------------------------------------------------- + * Function: test_comm_info_delete + * + * Purpose: Test if communicator and INFO object can be safely deleted + * after calling H5Pset_fapl_mpio. + * + * Return: Success: None + * + * Failure: Abort + * + * Programmer: Albert Cheng + * January 9, 2003 + * + * Modifications: + *------------------------------------------------------------------------- + */ +void +test_comm_info_delete(void) +{ + int mpi_size, mpi_rank; + MPI_Comm comm, comm_tmp; + int mpi_size_old, mpi_rank_old; + int mpi_size_tmp, mpi_rank_tmp; + MPI_Info info = MPI_INFO_NULL; + MPI_Info info_tmp = MPI_INFO_NULL; + int mrc; /* MPI return value */ + hid_t acc_pl; /* File access properties */ + herr_t ret; /* hdf5 return value */ + int nkeys, nkeys_tmp; + + if (verbose) + printf("Delete communicator and INFO object\n"); + + /* set up MPI parameters */ + MPI_Comm_size(MPI_COMM_WORLD,&mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank); + + /* Create a new communicator that has the same processes as MPI_COMM_WORLD. + * Use MPI_Comm_split because it is simplier than MPI_Comm_create + */ + mrc = MPI_Comm_split(MPI_COMM_WORLD, 0, 0, &comm); + VRFY((mrc==MPI_SUCCESS), "MPI_Comm_split"); + MPI_Comm_size(comm,&mpi_size_old); + MPI_Comm_rank(comm,&mpi_rank_old); + if (verbose) + printf("rank/size of comm are %d/%d\n", mpi_rank_old, mpi_size_old); + + /* create a new INFO object with some trivial information. */ + mrc = MPI_Info_create(&info); + VRFY((mrc==MPI_SUCCESS), "MPI_Info_create"); + mrc = MPI_Info_set(info, "hdf_info_name", "XYZ"); + VRFY((mrc==MPI_SUCCESS), "MPI_Info_set"); + if (MPI_INFO_NULL != info){ + mrc=MPI_Info_get_nkeys(info, &nkeys); + VRFY((mrc==MPI_SUCCESS), "MPI_Info_get_nkeys"); + } + if (verbose) + h5_dump_info_object(info); + + acc_pl = H5Pcreate (H5P_FILE_ACCESS); + VRFY((acc_pl >= 0), "H5P_FILE_ACCESS"); + + ret = H5Pset_fapl_mpio(acc_pl, comm, info); + VRFY((ret >= 0), ""); + + /* Case 1: + * Free the created communicator and INFO object. + * Check if the access property list is still valid and can return + * valid communicator and INFO object. + */ + mrc = MPI_Comm_free(&comm); + VRFY((mrc==MPI_SUCCESS), "MPI_Comm_free"); + if (MPI_INFO_NULL!=info){ + mrc = MPI_Info_free(&info); + VRFY((mrc==MPI_SUCCESS), "MPI_Info_free"); + } + + ret = H5Pget_fapl_mpio(acc_pl, &comm_tmp, &info_tmp); + VRFY((ret >= 0), "H5Pget_fapl_mpio"); + MPI_Comm_size(comm_tmp,&mpi_size_tmp); + MPI_Comm_rank(comm_tmp,&mpi_rank_tmp); + if (verbose) + printf("After H5Pget_fapl_mpio: rank/size of comm are %d/%d\n", + mpi_rank_tmp, mpi_size_tmp); + VRFY((mpi_size_tmp==mpi_size), "MPI_Comm_size"); + VRFY((mpi_rank_tmp==mpi_rank), "MPI_Comm_rank"); + if (MPI_INFO_NULL != info_tmp){ + mrc=MPI_Info_get_nkeys(info_tmp, &nkeys_tmp); + VRFY((mrc==MPI_SUCCESS), "MPI_Info_get_nkeys"); + VRFY((nkeys_tmp==nkeys), "new and old nkeys equal"); + } + if (verbose) + h5_dump_info_object(info_tmp); + + /* Case 2: + * Free the retrieved communicator and INFO object. + * Check if the access property list is still valid and can return + * valid communicator and INFO object. + * Also verify the NULL argument option. + */ + mrc = MPI_Comm_free(&comm_tmp); + VRFY((mrc==MPI_SUCCESS), "MPI_Comm_free"); + if (MPI_INFO_NULL!=info_tmp){ + mrc = MPI_Info_free(&info_tmp); + VRFY((mrc==MPI_SUCCESS), "MPI_Info_free"); + } + + /* check NULL argument options. */ + ret = H5Pget_fapl_mpio(acc_pl, &comm_tmp, NULL); + VRFY((ret >= 0), "H5Pget_fapl_mpio Comm only"); + mrc = MPI_Comm_free(&comm_tmp); + VRFY((mrc==MPI_SUCCESS), "MPI_Comm_free"); + + ret = H5Pget_fapl_mpio(acc_pl, NULL, &info_tmp); + VRFY((ret >= 0), "H5Pget_fapl_mpio Info only"); + if (MPI_INFO_NULL!=info_tmp){ + mrc = MPI_Info_free(&info_tmp); + VRFY((mrc==MPI_SUCCESS), "MPI_Info_free"); + } + + ret = H5Pget_fapl_mpio(acc_pl, NULL, NULL); + VRFY((ret >= 0), "H5Pget_fapl_mpio neither"); + + /* now get both and check validity too. */ + ret = H5Pget_fapl_mpio(acc_pl, &comm_tmp, &info_tmp); + VRFY((ret >= 0), "H5Pget_fapl_mpio"); + MPI_Comm_size(comm_tmp,&mpi_size_tmp); + MPI_Comm_rank(comm_tmp,&mpi_rank_tmp); + if (verbose) + printf("After second H5Pget_fapl_mpio: rank/size of comm are %d/%d\n", + mpi_rank_tmp, mpi_size_tmp); + VRFY((mpi_size_tmp==mpi_size), "MPI_Comm_size"); + VRFY((mpi_rank_tmp==mpi_rank), "MPI_Comm_rank"); + if (MPI_INFO_NULL != info_tmp){ + mrc=MPI_Info_get_nkeys(info_tmp, &nkeys_tmp); + VRFY((mrc==MPI_SUCCESS), "MPI_Info_get_nkeys"); + VRFY((nkeys_tmp==nkeys), "new and old nkeys equal"); + } + if (verbose) + h5_dump_info_object(info_tmp); + + /* Case 3: + * Close the property list and verify the retrieved communicator and INFO + * object are still valid. + */ + H5Pclose(acc_pl); + MPI_Comm_size(comm_tmp,&mpi_size_tmp); + MPI_Comm_rank(comm_tmp,&mpi_rank_tmp); + if (verbose) + printf("After Property list closed: rank/size of comm are %d/%d\n", + mpi_rank_tmp, mpi_size_tmp); + if (MPI_INFO_NULL != info_tmp){ + mrc=MPI_Info_get_nkeys(info_tmp, &nkeys_tmp); + VRFY((mrc==MPI_SUCCESS), "MPI_Info_get_nkeys"); + } + if (verbose) + h5_dump_info_object(info_tmp); + + /* clean up */ + mrc = MPI_Comm_free(&comm_tmp); + VRFY((mrc==MPI_SUCCESS), "MPI_Comm_free"); + if (MPI_INFO_NULL!=info_tmp){ + mrc = MPI_Info_free(&info_tmp); + VRFY((mrc==MPI_SUCCESS), "MPI_Info_free"); + } +} diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c index f7846d7..98d394a 100644 --- a/testpar/testphdf5.c +++ b/testpar/testphdf5.c @@ -343,6 +343,7 @@ int main(int argc, char **argv) printf("PHDF5 TESTS START\n"); printf("===================================\n"); } + H5open(); h5_show_hostname(); fapl = H5Pcreate (H5P_FILE_ACCESS); @@ -354,6 +355,9 @@ int main(int argc, char **argv) goto finish; } + MPI_BANNER("test_comm_info_delete..."); + test_comm_info_delete(); + if (ndatasets){ MPI_BANNER("multiple datasets write ..."); multiple_dset_write(filenames[3], ndatasets); @@ -431,6 +435,10 @@ int main(int argc, char **argv) } finish: + /* make sure all processes are finished before final report, cleanup + * and exit. + */ + MPI_Barrier(MPI_COMM_WORLD); if (MAINPROCESS){ /* only process 0 reports */ printf("===================================\n"); if (nerrors){ @@ -441,9 +449,6 @@ finish: } printf("===================================\n"); } - - /* make sure all processes are finished before starting cleanup and exit */ - MPI_Barrier(MPI_COMM_WORLD); if (dowrite){ h5_cleanup(FILENAME, fapl); } else { @@ -453,6 +458,7 @@ finish: /* close HDF5 library */ H5close(); + /* MPI_Finalize must be called AFTER H5close which may use MPI calls */ MPI_Finalize(); return(nerrors); |