Skip to content

Commit 8071689

Browse files
authored
Merge pull request #612 from E3SM-Project/dqwu/fix_pio_set_buffer_size_limit
This PR fixes two major issues with the pio_set_buffer_size_limit interface: [Legacy Fortran library compatibility] Update the legacy Fortran interface to include an optional second argument to align with the newer interface used in E3SM/SCREAM, resolving confirmed build errors. [Allow 0 as a valid buffer size limit] Update the handling of buffer size limit to allow 0 as a valid value and also fix calls to PnetCDF API ncmpi_buffer_attach. Fixes #611
2 parents 65af970 + 1c44692 commit 8071689

File tree

5 files changed

+36
-7
lines changed

5 files changed

+36
-7
lines changed

ctest/CTestEnvironment-anlgce.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,8 @@ if (DEFINED ENV{ENABLE_HDF5})
126126
endif ()
127127
endif ()
128128
endif ()
129+
130+
# If USE_FORTRAN_LEGACY_LIB environment variable is set, then use the legacy Fortran library
131+
if (DEFINED ENV{USE_FORTRAN_LEGACY_LIB})
132+
set (CTEST_CONFIGURE_OPTIONS "${CTEST_CONFIGURE_OPTIONS} -DPIO_USE_FORTRAN_LEGACY_LIB=ON")
133+
endif ()

src/clib/pio_darray.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ PIO_Offset PIOc_set_buffer_size_limit_impl(PIO_Offset limit)
4949
PIO_Offset oldsize = pio_buffer_size_limit;
5050

5151
/* If the user passed a valid size, use it. */
52-
if (limit > 0)
52+
if (limit >= 0)
5353
pio_buffer_size_limit = limit;
5454

5555
return oldsize;

src/clib/pioc_support.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3411,7 +3411,18 @@ int spio_createfile_int(int iosysid, int *ncidp, const int *iotype, const char *
34113411

34123412
ierr = ncmpi_create(ios->io_comm, filename, file->mode, ios->info, &file->fh);
34133413
if (!ierr)
3414-
ierr = ncmpi_buffer_attach(file->fh, pio_buffer_size_limit);
3414+
{
3415+
/* When using buffered put APIs in PnetCDF, we must explicitly specify the size of the internal buffer.
3416+
To avoid potential failures, we ensure a minimum buffer size (16 MiB) when pio_buffer_size_limit is
3417+
0 or too small. If pio_buffer_size_limit is set to 0, this workaround prevents a direct failure of
3418+
the ncmpi_buffer_attach call (NULL buffer error). Additionally, if pio_buffer_size_limit is too small,
3419+
using the larger minimum size reduces the likelihood of potential NC_EINSUFFBUF errors. As recommended
3420+
by PnetCDF documentation, users should make sure that the internal buffer size is sufficiently large
3421+
for buffered put operations.
3422+
*/
3423+
const PIO_Offset min_bufsize = 16777216; /* Minimum buffer size (16 MiB) for buffered put APIs in PnetCDF */
3424+
ierr = ncmpi_buffer_attach(file->fh, (pio_buffer_size_limit > min_bufsize)? pio_buffer_size_limit : min_bufsize);
3425+
}
34153426
break;
34163427
#endif
34173428
#ifdef _HDF5
@@ -4998,7 +5009,12 @@ int PIOc_openfile_retry_impl(int iosysid, int *ncidp, int *iotype, const char *f
49985009
{
49995010
if (ios->iomaster == MPI_ROOT)
50005011
LOG((2, "%d Setting IO buffer %ld", __LINE__, pio_buffer_size_limit));
5001-
ierr = ncmpi_buffer_attach(file->fh, pio_buffer_size_limit);
5012+
5013+
/* Please refer to a previous related comment for why we ensure a minimum buffer size (16 MiB) for
5014+
buffered put APIs in PnetCDF.
5015+
*/
5016+
const PIO_Offset min_bufsize = 16777216; /* Minimum buffer size (16 MiB) for buffered put APIs in PnetCDF */
5017+
ierr = ncmpi_buffer_attach(file->fh, (pio_buffer_size_limit > min_bufsize)? pio_buffer_size_limit : min_bufsize);
50025018
}
50035019
LOG((2, "ncmpi_open(%s) : fd = %d", filename, file->fh));
50045020
break;

src/flib_legacy/piodarray.F90.in

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ end interface
9393

9494
contains
9595

96-
subroutine pio_set_buffer_size_limit(limit)
96+
subroutine pio_set_buffer_size_limit(limit, prev_limit)
9797
integer(PIO_OFFSET_KIND), intent(in) :: limit
98+
integer(PIO_OFFSET_KIND), intent(out), optional :: prev_limit
9899
integer(PIO_OFFSET_KIND) :: oldval
99100
interface
100101
integer(C_LONG_LONG) function PIOc_set_buffer_size_limit(limit) &
@@ -103,10 +104,10 @@ contains
103104
integer(C_LONG_LONG), value :: limit
104105
end function PIOc_set_buffer_size_limit
105106
end interface
106-
if(limit<0) then
107-
call piodie(__PIO_FILE__,__LINE__,' bad value to buffer_size_limit: ',int(limit))
108-
end if
109107
oldval = PIOc_set_buffer_size_limit(limit)
108+
if(present(prev_limit)) then
109+
prev_limit = oldval
110+
end if
110111

111112
end subroutine pio_set_buffer_size_limit
112113

tests/general/pio_buf_lim_tests.F90.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ PIO_TF_AUTO_TEST_SUB_BEGIN nc_wr_buf_limit_zero
3333
implicit none
3434
integer, parameter :: VEC_LOCAL_SZ = 7
3535
integer(kind=pio_offset_kind), parameter :: PIO_BUFFER_SZ_ZERO = 0
36+
integer(kind=pio_offset_kind), parameter :: PIO_BUFFER_SZ_NEG = -1
37+
integer(kind=pio_offset_kind) :: cur_buf_sz_limit
3638
type(var_desc_t) :: pio_var
3739
type(file_desc_t) :: pio_file
3840
character(len=PIO_TF_MAX_STR_LEN) :: filename
@@ -76,6 +78,11 @@ PIO_TF_AUTO_TEST_SUB_BEGIN nc_wr_buf_limit_zero
7678

7779
call pio_set_buffer_size_limit(PIO_BUFFER_SZ_ZERO)
7880

81+
! Query the current buffer size limit by passing a negative value for the
82+
! new limit, which will be ignored by pio_set_buffer_size_limit
83+
call pio_set_buffer_size_limit(PIO_BUFFER_SZ_NEG, prev_limit=cur_buf_sz_limit)
84+
PIO_TF_PASSERT(cur_buf_sz_limit == PIO_BUFFER_SZ_ZERO, "Current buffer size limit should equal the previously set zero limit")
85+
7986
! Write the variable out
8087
call PIO_write_darray(pio_file, pio_var, iodesc, wbuf, ierr)
8188
PIO_TF_CHECK_ERR(ierr, "Failed to write darray : " // trim(filename))

0 commit comments

Comments
 (0)