diff --git a/src/clib/pio_getput_int.c b/src/clib/pio_getput_int.c index d7d1e5184d8..158ebe295c3 100644 --- a/src/clib/pio_getput_int.c +++ b/src/clib/pio_getput_int.c @@ -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. */ @@ -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) { @@ -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__); @@ -1012,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) { @@ -1069,17 +1123,6 @@ int PIOc_put_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Off 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))) @@ -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 */ @@ -1144,56 +1184,56 @@ 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: @@ -1201,6 +1241,10 @@ int PIOc_put_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Off } 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. */ diff --git a/tests/cunit/Makefile.am b/tests/cunit/Makefile.am index f0af769c98e..399114fa786 100644 --- a/tests/cunit/Makefile.am +++ b/tests/cunit/Makefile.am @@ -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 \