From 87a20ce36139611b4eb5438b1bfbef6a20609d49 Mon Sep 17 00:00:00 2001 From: wkliao Date: Sun, 17 Mar 2024 14:17:35 -0500 Subject: [PATCH] Check MPI_Get_count_c, use it if available --- configure.ac | 1 + src/drivers/ncmpio/ncmpio_enddef.c | 35 ++++++++++++------- src/drivers/ncmpio/ncmpio_file_io.c | 48 ++++++++++++++++++++------ src/drivers/ncmpio/ncmpio_header_put.c | 23 +++++++----- src/drivers/ncmpio/ncmpio_sync.c | 17 +++++---- 5 files changed, 88 insertions(+), 36 deletions(-) diff --git a/configure.ac b/configure.ac index 371788d13..e8e0eadf8 100644 --- a/configure.ac +++ b/configure.ac @@ -1326,6 +1326,7 @@ AC_CHECK_FUNCS([MPI_Type_create_subarray_c \ MPI_Type_vector_c \ MPI_Type_size_c \ MPI_Type_get_true_extent_c \ + MPI_Get_count_c \ MPI_Pack_c \ MPI_Unpack_c], [], [have_mpi_large_count_apis=no]) # If one of the above APIs is not available, have_mpi_large_count_apis will be diff --git a/src/drivers/ncmpio/ncmpio_enddef.c b/src/drivers/ncmpio/ncmpio_enddef.c index f16a5b932..eb1804ec3 100644 --- a/src/drivers/ncmpio/ncmpio_enddef.c +++ b/src/drivers/ncmpio/ncmpio_enddef.c @@ -133,14 +133,14 @@ move_file_block(NC *ncp, * bufcount for write. Note that the latter will write the variables * that have not been written before. Below uses the former option. */ -#ifdef _USE_MPI_GET_COUNT + /* explicitly initialize mpistatus object to 0. For zero-length read, * MPI_Get_count may report incorrect result for some MPICH version, * due to the uninitialized MPI_Status object passed to MPI-IO calls. * Thus we initialize it above to work around. */ memset(&mpistatus, 0, sizeof(MPI_Status)); -#endif + TRACE_IO(MPI_File_write_at_all)(ncp->collective_fh, to+nbytes+rank*chunk_size, buf, get_size /* bufcount */, @@ -150,12 +150,18 @@ move_file_block(NC *ncp, if (err == NC_EFILE) DEBUG_ASSIGN_ERROR(status, NC_EWRITE) } else { -#ifdef _USE_MPI_GET_COUNT - int put_size; - MPI_Get_count(&mpistatus, MPI_BYTE, &put_size); + /* update the number of bytes written since file open */ +#ifdef HAVE_MPI_GET_COUNT_C + MPI_Count put_size; + MPI_Get_count_c(&mpistatus, MPI_BYTE, &put_size); ncp->put_size += put_size; #else - ncp->put_size += get_size; /* or bufcount */ + int put_size; + mpireturn = MPI_Get_count(&mpistatus, MPI_BYTE, &put_size); + if (mpireturn != MPI_SUCCESS || put_size == MPI_UNDEFINED) + ncp->put_size += get_size; /* or bufcount */ + else + ncp->put_size += put_size; #endif } TRACE_COMM(MPI_Allreduce)(&status, &min_st, 1, MPI_INT, MPI_MIN, ncp->comm); @@ -520,14 +526,13 @@ write_NC(NC *ncp) /* rank 0's fileview already includes the file header */ -#ifdef _USE_MPI_GET_COUNT /* explicitly initialize mpistatus object to 0. For zero-length read, * MPI_Get_count may report incorrect result for some MPICH version, * due to the uninitialized MPI_Status object passed to MPI-IO calls. * Thus we initialize it above to work around. */ memset(&mpistatus, 0, sizeof(MPI_Status)); -#endif + /* write the header in chunks */ remain = header_wlen; for (i=0; iput_size += put_size; #else - ncp->put_size += header_wlen; + int put_size; + mpireturn = MPI_Get_count(&mpistatus, MPI_BYTE, &put_size); + if (mpireturn != MPI_SUCCESS || put_size == MPI_UNDEFINED) + ncp->put_size += header_wlen; + else + ncp->put_size += put_size; #endif } remain -= NC_MAX_INT; diff --git a/src/drivers/ncmpio/ncmpio_file_io.c b/src/drivers/ncmpio/ncmpio_file_io.c index bad56345b..e3912c50c 100644 --- a/src/drivers/ncmpio/ncmpio_file_io.c +++ b/src/drivers/ncmpio/ncmpio_file_io.c @@ -66,14 +66,12 @@ ncmpio_read_write(NC *ncp, /* request size in bytes, may be > NC_MAX_INT */ req_size = (MPI_Offset)btype_size * buf_count; -#ifdef _USE_MPI_GET_COUNT /* explicitly initialize mpistatus object to 0. For zero-length read, * MPI_Get_count may report incorrect result for some MPICH version, * due to the uninitialized MPI_Status object passed to MPI-IO calls. * Thus we initialize it above to work around. */ memset(&mpistatus, 0, sizeof(MPI_Status)); -#endif if (coll_indep == NC_REQ_COLL) fh = ncp->collective_fh; @@ -141,12 +139,27 @@ ncmpio_read_write(NC *ncp, } if (mpireturn == MPI_SUCCESS) { /* update the number of bytes read since file open */ -#ifdef _USE_MPI_GET_COUNT - int get_size; - MPI_Get_count(&mpistatus, MPI_BYTE, &get_size); +#ifdef HAVE_MPI_GET_COUNT_C + MPI_Count get_size; + MPI_Get_count_c(&mpistatus, MPI_BYTE, &get_size); ncp->get_size += get_size; #else - ncp->get_size += req_size; + int get_size; + mpireturn = MPI_Get_count(&mpistatus, xbuf_type, &get_size); + if (mpireturn != MPI_SUCCESS || get_size == MPI_UNDEFINED) + ncp->get_size += req_size; + else { +#ifdef HAVE_MPI_TYPE_SIZE_X + /* MPI_Type_size_x is introduced in MPI 3.0 */ + mpireturn = MPI_Type_size_x(xbuf_type, &btype_size); +#else + mpireturn = MPI_Type_size(xbuf_type, &btype_size); +#endif + if (mpireturn != MPI_SUCCESS || get_size == MPI_UNDEFINED) + ncp->get_size += req_size; + else + ncp->get_size += btype_size * get_size; + } #endif } if (xbuf != buf) { /* unpack contiguous xbuf to noncontiguous buf */ @@ -237,12 +250,27 @@ ncmpio_read_write(NC *ncp, } if (mpireturn == MPI_SUCCESS) { /* update the number of bytes written since file open */ -#ifdef _USE_MPI_GET_COUNT - int put_size; - MPI_Get_count(&mpistatus, MPI_BYTE, &put_size); +#ifdef HAVE_MPI_GET_COUNT_C + MPI_Count put_size; + MPI_Get_count_c(&mpistatus, MPI_BYTE, &put_size); ncp->put_size += put_size; #else - ncp->put_size += req_size; + int put_size; + mpireturn = MPI_Get_count(&mpistatus, xbuf_type, &put_size); + if (mpireturn != MPI_SUCCESS || put_size == MPI_UNDEFINED) + ncp->put_size += req_size; + else { +#ifdef HAVE_MPI_TYPE_SIZE_X + /* MPI_Type_size_x is introduced in MPI 3.0 */ + mpireturn = MPI_Type_size_x(xbuf_type, &btype_size); +#else + mpireturn = MPI_Type_size(xbuf_type, &btype_size); +#endif + if (mpireturn != MPI_SUCCESS || put_size == MPI_UNDEFINED) + ncp->put_size += req_size; + else + ncp->put_size += btype_size * put_size; + } #endif } if (xbuf != buf) NCI_Free(xbuf); diff --git a/src/drivers/ncmpio/ncmpio_header_put.c b/src/drivers/ncmpio/ncmpio_header_put.c index 0dac72b63..f88937262 100644 --- a/src/drivers/ncmpio/ncmpio_header_put.c +++ b/src/drivers/ncmpio/ncmpio_header_put.c @@ -544,18 +544,19 @@ int ncmpio_write_header(NC *ncp) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) } -#ifdef _USE_MPI_GET_COUNT /* explicitly initialize mpistatus object to 0. For zero-length read, * MPI_Get_count may report incorrect result for some MPICH version, * due to the uninitialized MPI_Status object passed to MPI-IO calls. * Thus we initialize it above to work around. */ memset(&mpistatus, 0, sizeof(MPI_Status)); -#endif + if (fIsSet(ncp->flags, NC_HCOLL)) /* collective write */ - TRACE_IO(MPI_File_write_at_all)(fh, 0, buf, (int)ncp->xsz, MPI_BYTE, &mpistatus); + TRACE_IO(MPI_File_write_at_all)(fh, 0, buf, (int)ncp->xsz, + MPI_BYTE, &mpistatus); else - TRACE_IO(MPI_File_write_at)(fh, 0, buf, (int)ncp->xsz, MPI_BYTE, &mpistatus); + TRACE_IO(MPI_File_write_at)(fh, 0, buf, (int)ncp->xsz, + MPI_BYTE, &mpistatus); if (mpireturn != MPI_SUCCESS) { err = ncmpii_error_mpi2nc(mpireturn, "MPI_File_write_at"); @@ -565,12 +566,18 @@ int ncmpio_write_header(NC *ncp) } } else { -#ifdef _USE_MPI_GET_COUNT - int put_size; - MPI_Get_count(&mpistatus, MPI_BYTE, &put_size); + /* update the number of bytes written since file open */ +#ifdef HAVE_MPI_GET_COUNT_C + MPI_Count put_size; + MPI_Get_count_c(&mpistatus, MPI_BYTE, &put_size); ncp->put_size += put_size; #else - ncp->put_size += ncp->xsz; + int put_size; + mpireturn = MPI_Get_count(&mpistatus, MPI_BYTE, &put_size); + if (mpireturn != MPI_SUCCESS || put_size == MPI_UNDEFINED) + ncp->put_size += ncp->xsz; + else + ncp->put_size += put_size; #endif } NCI_Free(buf); diff --git a/src/drivers/ncmpio/ncmpio_sync.c b/src/drivers/ncmpio/ncmpio_sync.c index 59f0f92cf..eae730b38 100644 --- a/src/drivers/ncmpio/ncmpio_sync.c +++ b/src/drivers/ncmpio/ncmpio_sync.c @@ -107,14 +107,13 @@ ncmpio_write_numrecs(NC *ncp, } /* ncmpix_put_xxx advances the 1st argument with size len */ -#ifdef _USE_MPI_GET_COUNT /* explicitly initialize mpistatus object to 0. For zero-length read, * MPI_Get_count may report incorrect result for some MPICH version, * due to the uninitialized MPI_Status object passed to MPI-IO calls. * Thus we initialize it above to work around. */ memset(&mpistatus, 0, sizeof(MPI_Status)); -#endif + /* root's file view always includes the entire file header */ if (fIsSet(ncp->flags, NC_HCOLL)) TRACE_IO(MPI_File_write_at_all)(fh, NC_NUMRECS_OFFSET, (void*)pos, @@ -127,12 +126,18 @@ ncmpio_write_numrecs(NC *ncp, if (err == NC_EFILE) DEBUG_RETURN_ERROR(NC_EWRITE) } else { -#ifdef _USE_MPI_GET_COUNT - int put_size; - MPI_Get_count(&mpistatus, MPI_BYTE, &put_size); + /* update the number of bytes written since file open */ +#ifdef HAVE_MPI_GET_COUNT_C + MPI_Count put_size; + MPI_Get_count_c(&mpistatus, MPI_BYTE, &put_size); ncp->put_size += put_size; #else - ncp->put_size += len; + int put_size; + mpireturn = MPI_Get_count(&mpistatus, MPI_BYTE, &put_size); + if (mpireturn != MPI_SUCCESS || put_size == MPI_UNDEFINED) + ncp->put_size += len; + else + ncp->put_size += put_size; #endif } }