Skip to content

Commit

Permalink
Merge pull request ESMCI#1327 from NCAR/ejh_dumb_null_bug
Browse files Browse the repository at this point in the history
Fix NULL bug
  • Loading branch information
edhartnett authored Feb 6, 2019
2 parents 130c564 + ee30e09 commit d77683e
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 49 deletions.
6 changes: 3 additions & 3 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
## Ed Hartnett 8/16/17

# Initialize autoconf and automake.
AC_INIT(pio, 2.3.1)
AC_INIT(pio, 2.4.0)
AC_CONFIG_SRCDIR(src/clib/pio_darray.c)
AM_INIT_AUTOMAKE([foreign serial-tests])

Expand Down Expand Up @@ -46,8 +46,8 @@ AC_DEFINE([_NETCDF], [1], [netCDF classic library available])

# The PIO version, again.
AC_DEFINE([PIO_VERSION_MAJOR], [2], [PIO major version])
AC_DEFINE([PIO_VERSION_MINOR], [3], [PIO minor version])
AC_DEFINE([PIO_VERSION_PATCH], [1], [PIO patch version])
AC_DEFINE([PIO_VERSION_MINOR], [4], [PIO minor version])
AC_DEFINE([PIO_VERSION_PATCH], [0], [PIO patch version])

# ???
AC_DEFINE([CPRGNU], [1], [defined by CMake build])
Expand Down
128 changes: 86 additions & 42 deletions src/clib/pio_getput_int.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,8 @@ int PIOc_get_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Off
char start_present = start ? true : false;
char count_present = count ? true : false;
char stride_present = stride ? true : false;
PIO_Offset one = 1; /* For fake_stride. */
PIO_Offset *fake_stride = &one; /* Needed for NULL stride bug in netcdf-4.6.2. */
int mpierr = MPI_SUCCESS, mpierr2; /* Return code from MPI function codes. */
int ierr; /* Return code. */

Expand Down Expand Up @@ -601,12 +603,29 @@ int PIOc_get_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Off
check_mpi(file, mpierr, __FILE__, __LINE__);
if ((mpierr = MPI_Bcast(&xtype, 1, MPI_INT, ios->comproot, ios->my_comm)))
check_mpi(file, mpierr, __FILE__, __LINE__);
if ((mpierr = MPI_Bcast(&ndims, 1, MPI_INT, ios->comproot, ios->my_comm)))
check_mpi(file, mpierr, __FILE__, __LINE__);
}

if (ndims)
{
if (!stride_present)
{
LOG((2, "stride not present "));
if (!(fake_stride = malloc(ndims * sizeof(PIO_Offset))))
return pio_err(ios, file, PIO_ENOMEM, __FILE__, __LINE__);
for (int d = 0; d < ndims; d++)
fake_stride[d] = 1;
}
else
fake_stride = (PIO_Offset *)stride;
}

/* If this is an IO task, then call the netCDF function. */
if (ios->ioproc)
{
LOG((2, "file->iotype = %d xtype = %d file->do_io = %d", file->iotype, xtype, file->do_io));

LOG((2, "file->iotype = %d xtype = %d file->do_io = %d", file->iotype, xtype, file->do_io));
#ifdef _PNETCDF
if (file->iotype == PIO_IOTYPE_PNETCDF)
{
Expand Down Expand Up @@ -653,69 +672,90 @@ int PIOc_get_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Off
}
#endif /* _PNETCDF */

LOG((2, "duck ndims %d", ndims));
for (int d = 0; d < ndims; d++)
{
LOG((2, "start[%d] %d", d, start[d]));
LOG((2, "count[%d] %d", d, count[d]));
LOG((2, "fake_stride[%d] %d", d, fake_stride[d]));
}

if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io)
{
switch(xtype)
{
case NC_BYTE:
ierr = nc_get_vars_schar(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_CHAR:
ierr = nc_get_vars_text(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_SHORT:
ierr = nc_get_vars_short(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_INT:
ierr = nc_get_vars_int(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case PIO_LONG_INTERNAL:
ierr = nc_get_vars_long(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_FLOAT:
ierr = nc_get_vars_float(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_DOUBLE:
ierr = nc_get_vars_double(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
#ifdef _NETCDF4
case NC_UBYTE:
ierr = nc_get_vars_uchar(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_USHORT:
ierr = nc_get_vars_ushort(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_UINT:
ierr = nc_get_vars_uint(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_INT64:
LOG((3, "about to call nc_get_vars_longlong"));
ierr = nc_get_vars_longlong(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_UINT64:
ierr = nc_get_vars_ulonglong(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
/* case NC_STRING: */
/* ierr = nc_get_vars_string(file->fh, varid, (size_t *)start, (size_t *)count, */
/* (ptrdiff_t *)stride, (void *)buf); */
/* (ptrdiff_t *)fake_stride, (void *)buf); */
/* break; */
#endif /* _NETCDF4 */
default:
return pio_err(ios, file, PIO_EBADTYPE, __FILE__, __LINE__);
}
}

}

LOG((2, "howdy ndims %d", ndims));
for (int d = 0; d < ndims; d++)
{
LOG((2, "fake_stride[%d] %d", d, fake_stride[d]));
}

/* Free malloced resources. */
if (ndims && !stride_present)
free(fake_stride);

/* Broadcast and check the return code. */
if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm)))
return check_mpi(file, mpierr, __FILE__, __LINE__);
Expand Down Expand Up @@ -896,6 +936,7 @@ int PIOc_put_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Off
char count_present = count ? true : false; /* Is count non-NULL? */
char stride_present = stride ? true : false; /* Is stride non-NULL? */
nc_type vartype; /* The type of the var we are reading from. */
PIO_Offset *fake_stride;
int mpierr = MPI_SUCCESS, mpierr2; /* Return code from MPI function codes. */
int ierr; /* Return code from function calls. */

Expand Down Expand Up @@ -1011,6 +1052,20 @@ int PIOc_put_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Off
/* If this is an IO task, then call the netCDF function. */
if (ios->ioproc)
{
if (ndims)
{
if (!stride_present)
{
LOG((2, "stride not present"));
if (!(fake_stride = malloc(ndims * sizeof(PIO_Offset))))
return pio_err(ios, file, PIO_ENOMEM, __FILE__, __LINE__);
for (int d = 0; d < ndims; d++)
fake_stride[d] = 1;
}
else
fake_stride = (PIO_Offset *)stride;
}

#ifdef _PNETCDF
if (file->iotype == PIO_IOTYPE_PNETCDF)
{
Expand Down Expand Up @@ -1065,21 +1120,9 @@ int PIOc_put_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Off
else
{
/* This is not a scalar var. */
PIO_Offset *fake_stride;
var_desc_t *vdesc;
int *request;

if (!stride_present)
{
LOG((2, "stride not present"));
if (!(fake_stride = malloc(ndims * sizeof(PIO_Offset))))
return pio_err(ios, file, PIO_ENOMEM, __FILE__, __LINE__);
for (int d = 0; d < ndims; d++)
fake_stride[d] = 1;
}
else
fake_stride = (PIO_Offset *)stride;

LOG((2, "PIOc_put_vars_tc calling pnetcdf function"));
/*vdesc = &file->varlist[varid];*/
if ((ierr = get_var_desc(varid, &file->varlist, &vdesc)))
Expand Down Expand Up @@ -1129,9 +1172,6 @@ int PIOc_put_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Off
flush_output_buffer(file, false, 0);
LOG((2, "PIOc_put_vars_tc flushed output buffer"));

/* Free malloced resources. */
if (!stride_present)
free(fake_stride);
} /* endif ndims == 0 */
}
#endif /* _PNETCDF */
Expand All @@ -1144,63 +1184,67 @@ int PIOc_put_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Off
{
case NC_BYTE:
ierr = nc_put_vars_schar(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_CHAR:
ierr = nc_put_vars_text(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_SHORT:
ierr = nc_put_vars_short(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_INT:
ierr = nc_put_vars_int(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case PIO_LONG_INTERNAL:
ierr = nc_put_vars_long(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_FLOAT:
ierr = nc_put_vars_float(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_DOUBLE:
ierr = nc_put_vars_double(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
#ifdef _NETCDF4
case NC_UBYTE:
ierr = nc_put_vars_uchar(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_USHORT:
ierr = nc_put_vars_ushort(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_UINT:
ierr = nc_put_vars_uint(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_INT64:
ierr = nc_put_vars_longlong(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
case NC_UINT64:
ierr = nc_put_vars_ulonglong(file->fh, varid, (size_t *)start, (size_t *)count,
(ptrdiff_t *)stride, buf);
(ptrdiff_t *)fake_stride, buf);
break;
/* case NC_STRING: */
/* ierr = nc_put_vars_string(file->fh, varid, (size_t *)start, (size_t *)count, */
/* (ptrdiff_t *)stride, (void *)buf); */
/* (ptrdiff_t *)fake_stride, (void *)buf); */
/* break; */
#endif /* _NETCDF4 */
default:
return pio_err(ios, file, PIO_EBADTYPE, __FILE__, __LINE__);
}
LOG((2, "PIOc_put_vars_tc io_rank 0 done with netcdf call, ierr=%d", ierr));
}

/* Free malloced resources. */
if (ndims && !stride_present)
free(fake_stride);
}

/* Broadcast and check the return code. */
Expand Down
2 changes: 1 addition & 1 deletion tests/cunit/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# Link to our assembled library.
AM_LDFLAGS = ${top_builddir}/src/clib/libpio.la
AM_CPPFLAGS = -I$(top_srcdir)/src/clib

LDADD = ${top_builddir}/src/clib/libpio.la

# Build the tests for make check.
check_PROGRAMS = test_intercomm2 test_async_mpi test_spmd \
Expand Down
6 changes: 3 additions & 3 deletions tests/cunit/test_pioc.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,11 +539,11 @@ int test_iotypes(int my_rank)
*/
int check_strerror_netcdf(int my_rank)
{
#define NUM_NETCDF_TRIES 5
int errcode[NUM_NETCDF_TRIES] = {PIO_EBADID, NC4_LAST_ERROR - 1, 0, 1, -600};
#define NUM_NETCDF_TRIES 4
int errcode[NUM_NETCDF_TRIES] = {PIO_EBADID, NC4_LAST_ERROR - 1, 0, 1};
const char *expected[NUM_NETCDF_TRIES] = {"NetCDF: Not a valid ID",
"Unknown Error: Unrecognized error code", "No error",
nc_strerror(1), "Unknown Error: Unrecognized error code"};
nc_strerror(1)};
int ret;

if ((ret = check_error_strings(my_rank, NUM_NETCDF_TRIES, errcode, expected)))
Expand Down

0 comments on commit d77683e

Please sign in to comment.