Unidata / netcdf-c

Official GitHub repository for netCDF-C libraries and utilities.
BSD 3-Clause "New" or "Revised" License
511 stars 263 forks source link

NetCDF 4.9.0: nc_def_var_fletcher32(ncid, varid, NC_NOCHECKSUM) activates check sums #2401

Closed Alexander-Barth closed 2 years ago

Alexander-Barth commented 2 years ago

On Linux, when I call nc_def_var_fletcher32(ncid, varid, NC_NOCHECKSUM), a subsequent call to nc_inq_var_fletcher32 returns NC_FLETCHER32 . Apparently check summing is activated. Under NetCDF 4.8.1, nc_inq_var_fletcher32 returns NC_NOCHECKSUM as expected. This causes some test failures in my Julia package.

NetCDF 4.9.0

Ubuntu 18.04, gcc 7.5.0 with system HDF5 ( libhdf5-serial-dev ,1.10.0)

The program test_fletcher32.c (apated from examples/C/simple_xy_wr.c) shows this behavior:

$ gcc test_fletcher32.c  $(/home/abarth/opt/netcdf-4.9.0/bin/nc-config --cflags --libs )
$ LD_LIBRARY_PATH=/home/abarth/opt/netcdf-4.9.0/lib ./a.out 
mode 1
expected mode 0
*** SUCCESS writing example file simple_xy.nc!

$ gcc test_fletcher32.c  $(/home/abarth/opt/netcdf-4.8.1/bin/nc-config --cflags --libs )
$ LD_LIBRARY_PATH=/home/abarth/opt/netcdf-4.8.1/lib ./a.out 
mode 0
expected mode 0
*** SUCCESS writing example file simple_xy.nc!
Test program test_fletcher32.c ```c /*! \file An example program demonstrating a simple 2D write. Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 University Corporation for Atmospheric Research/Unidata. See netcdf-c/COPYRIGHT file for more info. */ #include #include #include /* This is the name of the data file we will create. */ #define FILE_NAME "simple_xy.nc" /* We are writing 2D data, a 6 x 12 grid. */ #define NDIMS 2 #define NX 6 #define NY 12 /* Handle errors by printing an error message and exiting with a * non-zero status. */ #define ERRCODE 2 #define ERR(e) {printf("Error: %s\n", nc_strerror(e)); exit(ERRCODE);} int main() { /* When we create netCDF variables and dimensions, we get back an * ID for each one. */ int ncid, x_dimid, y_dimid, varid; int dimids[NDIMS]; int fletcher32p; /* This is the data array we will write. It will be filled with a * progression of numbers for this example. */ int data_out[NX][NY]; /* Loop indexes, and error handling. */ int x, y, retval; /* Create some pretend data. If this wasn't an example program, we * would have some real data to write, for example, model * output. */ for (x = 0; x < NX; x++) for (y = 0; y < NY; y++) data_out[x][y] = x * NY + y; /* Always check the return code of every netCDF function call. In * this example program, any retval which is not equal to NC_NOERR * (0) will cause the program to print an error message and exit * with a non-zero return code. */ /* Create the file. The NC_CLOBBER parameter tells netCDF to * overwrite this file, if it already exists.*/ if ((retval = nc_create(FILE_NAME, NC_CLOBBER | NC_NETCDF4, &ncid))) ERR(retval); /* Define the dimensions. NetCDF will hand back an ID for each. */ if ((retval = nc_def_dim(ncid, "x", NX, &x_dimid))) ERR(retval); if ((retval = nc_def_dim(ncid, "y", NY, &y_dimid))) ERR(retval); /* The dimids array is used to pass the IDs of the dimensions of * the variable. */ dimids[0] = x_dimid; dimids[1] = y_dimid; /* Define the variable. The type of the variable in this case is * NC_INT (4-byte integer). */ if ((retval = nc_def_var(ncid, "data", NC_INT, NDIMS, dimids, &varid))) ERR(retval); if ((retval = nc_def_var_fletcher32(ncid, varid, NC_NOCHECKSUM))) ERR(retval); if ((nc_inq_var_fletcher32(ncid, varid, &fletcher32p))) ERR(retval); printf("mode %d\n",fletcher32p); printf("expected mode %d\n",NC_NOCHECKSUM); /* End define mode. This tells netCDF we are done defining * metadata. */ if ((retval = nc_enddef(ncid))) ERR(retval); /* Write the pretend data to the file. Although netCDF supports * reading and writing subsets of data, in this case we write all * the data in one operation. */ if ((retval = nc_put_var_int(ncid, varid, &data_out[0][0]))) ERR(retval); /* Close the file. This frees up any internal netCDF resources * associated with the file, and flushes any buffers. */ if ((retval = nc_close(ncid))) ERR(retval); printf("*** SUCCESS writing example file simple_xy.nc!\n"); return 0; } ```
output of `ncdump -s` of the file generated by NetCDF 4.9.0 ``` netcdf simple_xy { dimensions: x = 6 ; y = 12 ; variables: int data(x, y) ; data:_Storage = "chunked" ; data:_ChunkSizes = 6, 12 ; data:_Fletcher32 = "true" ; data:_Endianness = "little" ; // global attributes: :_NCProperties = "version=2,netcdf=4.9.0,hdf5=1.10.0" ; :_SuperblockVersion = 0 ; :_IsNetcdf4 = 1 ; :_Format = "netCDF-4" ; data: data = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71 ; } ```
DennisHeimbigner commented 2 years ago

It was a typo. I will put up a fix shortly, but you can test it by:

  1. edit libhdf5/hdf5var.c
  2. At about line 545 change:
    if (fletcher32 && fletcher32) {
    to
    if (fletcher32 && *fletcher32) {
Alexander-Barth commented 2 years ago

Thanks, indeed! Now it works.

$ LD_LIBRARY_PATH=/home/abarth/opt/netcdf-4.9.0/lib ./a.out 
mode 0
expected mode 0
*** SUCCESS writing example file simple_xy.nc!
Alexander-Barth commented 2 years ago

Thanks a lot for implementing this fix!