From dc86a890adef656b0f0eddd4b6cdfa4b73378b69 Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Fri, 1 Jun 2007 14:28:10 -0500 Subject: [svn-r13828] Some systems (only SGI Altix ProPack 4 discovered so far) doesn't return correct file size from MPI_File_get_size. Bypass this problem by replacing it with stat. Add an option --disable-mpi-size in configure to indicate this function doesn't work properly. Add a test in testpar/t_mpi.c, too. If it returns wrong file size, print out a warning. Tested on kagiso(parallel), cobalt, copper, and sol. --- configure | 44 +++++++++++++++++++++++++++++++++++++++----- configure.in | 32 +++++++++++++++++++++++++++++++- src/H5FDmpio.c | 14 +++++++++++++- src/H5config.h.in | 3 +++ testpar/t_chunk_alloc.c | 14 ++++++++++++++ testpar/t_mpi.c | 40 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 140 insertions(+), 7 deletions(-) diff --git a/configure b/configure index d031c19..3c1008b 100755 --- a/configure +++ b/configure @@ -868,6 +868,7 @@ TRACE_API INSTRUMENT_LIBRARY CLEARFILEBUF MPE +MPI_GET_SIZE FILTERS USE_FILTER_SHUFFLE USE_FILTER_FLETCHER32 @@ -1507,6 +1508,11 @@ Optional Features: Securely clear file buffers before writing to file. Default=yes. --enable-parallel Search for MPI-IO and MPI support files + --enable-mpi-size Some systems (only SGI Altix Propack 4 so far) + return wrong value from MPI_File_get_size. By + disabling this function, the library will replace it + with stat to get the correct file size. + [default=yes] --enable-stream-vfd Build the Stream Virtual File Driver [default=yes] --enable-filters=all Turn on all internal I/O filters. One may also specify a comma-separated list of filters or the @@ -5305,7 +5311,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes case $host in *-*-irix6*) # Find out which ABI we are using. - echo '#line 5308 "configure"' > conftest.$ac_ext + echo '#line 5314 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -5862,7 +5868,7 @@ chmod -w . save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" compiler_c_o=no -if { (eval echo configure:5865: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then +if { (eval echo configure:5871: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings if test -s out/conftest.err; then @@ -7737,7 +7743,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&6; } echo "${ECHO_T}no" >&6; } fi +# Check whether --enable-mpi-size was given. +if test "${enable_mpi_size+set}" = set; then + enableval=$enable_mpi_size; MPI_GET_SIZE=$enableval +fi + + +{ echo "$as_me:$LINENO: checking if MPI_File_get_size is enabled" >&5 +echo $ECHO_N "checking if MPI_File_get_size is enabled... $ECHO_C" >&6; } + + +case "X-$MPI_GET_SIZE" in + X-no) + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + MPI_GET_SIZE=no + ;; + X-yes|*) + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + MPI_GET_SIZE=yes + +cat >>confdefs.h <<\_ACEOF +#define HAVE_MPI_GET_SIZE 1 +_ACEOF + + ;; +esac { echo "$as_me:$LINENO: checking if irregular hyperslab optimization code works inside MPI-IO" >&5 echo $ECHO_N "checking if irregular hyperslab optimization code works inside MPI-IO... $ECHO_C" >&6; } @@ -37627,6 +37660,7 @@ TRACE_API!$TRACE_API$ac_delim INSTRUMENT_LIBRARY!$INSTRUMENT_LIBRARY$ac_delim CLEARFILEBUF!$CLEARFILEBUF$ac_delim MPE!$MPE$ac_delim +MPI_GET_SIZE!$MPI_GET_SIZE$ac_delim FILTERS!$FILTERS$ac_delim USE_FILTER_SHUFFLE!$USE_FILTER_SHUFFLE$ac_delim USE_FILTER_FLETCHER32!$USE_FILTER_FLETCHER32$ac_delim @@ -37646,7 +37680,7 @@ LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 21; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 22; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/configure.in b/configure.in index 23f4101..ead1448 100644 --- a/configure.in +++ b/configure.in @@ -2117,7 +2117,37 @@ if test -n "$PARALLEL"; then else AC_MSG_RESULT([no]) fi - + +dnl ---------------------------------------------------------------------- +dnl Set the flag to indicate that the MPI_File_get_size() function +dnl works. The default is enabled unless the user knows the function +dnl doesn't work on the system and disables it. (This flag should be set +dnl for all machines except for SGI Altix Propack 4 where the function +dnl doesn't return correct file size.) +dnl +AC_ARG_ENABLE([mpi-size], + [AC_HELP_STRING([--enable-mpi-size], + [Some systems (only SGI Altix Propack 4 so far) return wrong value + from MPI_File_get_size. By disabling this function, the library + will replace it with stat to get the correct file size. + [default=yes]])], + [MPI_GET_SIZE=$enableval]) + +AC_MSG_CHECKING([if MPI_File_get_size is enabled]) + +AC_SUBST(MPI_GET_SIZE) +case "X-$MPI_GET_SIZE" in + X-no) + AC_MSG_RESULT([no]) + MPI_GET_SIZE=no + ;; + X-yes|*) + AC_MSG_RESULT([yes]) + MPI_GET_SIZE=yes + AC_DEFINE([HAVE_MPI_GET_SIZE], [1], + [Define if MPI_File_get_size works correctly]) + ;; +esac dnl ---------------------------------------------------------------------- dnl Check to see whether the complicate MPI derived datatype works. diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 8d0479f..4f348d5 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -742,6 +742,9 @@ H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id, MPI_Comm comm_dup=MPI_COMM_NULL; MPI_Info info_dup=MPI_INFO_NULL; H5FD_t *ret_value; /* Return value */ +#ifndef H5_HAVE_MPI_GET_SIZE + struct stat stat_buf; +#endif FUNC_ENTER_NOAPI(H5FD_mpio_open, NULL) @@ -816,9 +819,18 @@ H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id, /* Only processor p0 will get the filesize and broadcast it. */ if (mpi_rank == 0) { - /* Get current file size */ + /* Get current file size. If MPI_File_get_size is disabled in configuration + * because it doesn't return correct value (SGI Altix Propack 4), + * use stat to get the file size. */ +#ifdef H5_HAVE_MPI_GET_SIZE if (MPI_SUCCESS != (mpi_code=MPI_File_get_size(fh, &size))) HMPI_GOTO_ERROR(NULL, "MPI_File_get_size failed", mpi_code) +#else + if((mpi_code=HDstat(name, &stat_buf))<0) + HMPI_GOTO_ERROR(NULL, "stat failed", mpi_code) + /* Hopefully this casting is safe */ + size = (MPI_Offset)(stat_buf.st_size); +#endif } /* end if */ /* Broadcast file size */ diff --git a/src/H5config.h.in b/src/H5config.h.in index 4d4685b..c34a7c0 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -219,6 +219,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MPE_H +/* Define if MPI_File_get_size works correctly */ +#undef HAVE_MPI_GET_SIZE + /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H diff --git a/testpar/t_chunk_alloc.c b/testpar/t_chunk_alloc.c index 4c0154f..9d3ef4b 100644 --- a/testpar/t_chunk_alloc.c +++ b/testpar/t_chunk_alloc.c @@ -36,7 +36,11 @@ get_filesize(const char *filename) int mpierr; MPI_File fd; MPI_Offset filesize; +#ifndef H5_HAVE_MPI_GET_SIZE + struct stat stat_buf; +#endif +#ifdef H5_HAVE_MPI_GET_SIZE mpierr = MPI_File_open(MPI_COMM_SELF, (char*)filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fd); VRFY((mpierr == MPI_SUCCESS), ""); @@ -46,6 +50,16 @@ get_filesize(const char *filename) mpierr = MPI_File_close(&fd); VRFY((mpierr == MPI_SUCCESS), ""); +#else + /* Some systems (only SGI Altix Propack 4 so far) doesn't return correct + * file size for MPI_File_get_size. Use stat instead. + */ + if((mpierr=stat(filename, &stat_buf))<0) + VRFY((mpierr == MPI_SUCCESS), ""); + + /* Hopefully this casting is safe */ + filesize = (MPI_Offset)(stat_buf.st_size); +#endif return(filesize); } diff --git a/testpar/t_mpi.c b/testpar/t_mpi.c index 6973230..5b92673 100644 --- a/testpar/t_mpi.c +++ b/testpar/t_mpi.c @@ -202,9 +202,11 @@ test_mpio_gb_file(char *filename) int ntimes; /* how many times */ char *buf = NULL; char expected; + MPI_Offset size; MPI_Offset mpi_off; MPI_Offset mpi_off_old; MPI_Status mpi_stat; + struct stat stat_buf; int is_signed, sizeof_mpi_offset; nerrs = 0; @@ -376,6 +378,44 @@ test_mpio_gb_file(char *filename) */ mrc = MPI_Barrier(MPI_COMM_WORLD); VRFY((mrc==MPI_SUCCESS), "Sync before leaving test"); + + /* + * Check if MPI_File_get_size works correctly. Some systems (only SGI Altix + * Propack 4 so far) return wrong file size. It can be avoided by reconfiguring + * with "--disable-mpi-size". + */ +#ifdef H5_HAVE_MPI_GET_SIZE + printf("Test if MPI_File_get_size works correctly with %s\n", filename); + + mrc = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, info, &fh); + VRFY((mrc==MPI_SUCCESS), ""); + + if (MAINPROCESS){ /* only process 0 needs to check it*/ + mrc = MPI_File_get_size(fh, &size); + VRFY((mrc==MPI_SUCCESS), ""); + + mrc=stat(filename, &stat_buf); + VRFY((mrc==0), ""); + + /* Hopefully this casting is safe */ + if(size != (MPI_Offset)(stat_buf.st_size)) { + printf("Warning: MPI_File_get_size doesn't return correct file size. To avoid using it in the library, reconfigure and rebuild the library with --disable-mpi-size.\n"); + } + } + + /* close file and free the communicator */ + mrc = MPI_File_close(&fh); + VRFY((mrc==MPI_SUCCESS), "MPI_FILE_CLOSE"); + + /* + * one more sync to ensure all processes have done reading + * before ending this test. + */ + mrc = MPI_Barrier(MPI_COMM_WORLD); + VRFY((mrc==MPI_SUCCESS), "Sync before leaving test"); +#else + printf("Skipped testing MPI_File_get_size because it's disabled\n"); +#endif } finish: -- cgit v0.12