Closed czender closed 2 years ago
This is somewhat similar to #1691
In the case of nc_inq_var_deflate() and nc_inq_var_szip() the idea of supporting them for classic files was that zlib and szip can conceivably be used in other, future dispatch layers. Therefore it make sense to allow them to report no compression with classic files, instead of error.
Are filters the same?
I would argue yes.
I was working with the filters on the CCR project and they are actually very general. They just process a stream of bytes and yield a stream of bytes. It's easy to imagine a future dispatch layer that allowed the use of existing HDF5 filters, even if that dispatch layer doesn't use HDF5.
I now agree. I need to check how inq_var_filter functions operate.
I guess ideally instead of the NOTNC4 versions of the generic functions we provide for the dispacth layers, we should have a SHOWOFF version of the inq function which shows the values as off (i.e. no compression, no filter, etc.) and then dispatch layers that don't implement filters can use the SHOWIOFF versions instead of the NOTNC4 versions.
Or we could just change the NOITNC4 versions to do the same, and that would be easy.
Are there other features for which we should be doing this? Chunking, etc.
FWIW, NCO uses wrappers that treats netCDF4 and netCDF3 datasets as similarly as possible, e.g.,
int nco_inq_var_chunking
(const int nc_id, /* [ID] netCDF ID */
const int var_id, /* [ID] Variable ID */
int * const srg_typ, /* [enm] Storage type */
size_t * const cnk_sz) /* [nbr] Chunk sizes */
{
/* Purpose: Wrapper for nc_inq_var_chunking() */
/* NB: netCDF chunking inquire function only works on netCDF4 files
NCO wrapper works on netCDF3 and netCDF4 files */
int rcd;
int fl_fmt; /* [enm] Input file format */
rcd=nco_inq_format(nc_id,&fl_fmt);
if(fl_fmt == NC_FORMAT_NETCDF4 || fl_fmt == NC_FORMAT_NETCDF4_CLASSIC){
rcd=nc_inq_var_chunking(nc_id,var_id,srg_typ,cnk_sz);
}else{ /* !netCDF4 */
/* Defensive programming */
*srg_typ=NC_CONTIGUOUS;
} /* !netCDF4 */
if(rcd != NC_NOERR) nco_err_exit(rcd,"nco_inq_var_chunking()");
return rcd;
} /* end nco_inq_var_chunking() */
It's nice to be able to use the netCDF4 API and get reasonable answers when applied to netCDF3 files. Of course this exact approach may not be suitable for libnetcdf, just letting you know how some of userspace works around these issues.
OK, I have a test that demonstrates that nc_inq_var_chunking() works fine on all formats (returning NC_CONTIGUOUS for all classic formats, as it should).
I am going to leave nc_inq_var_filter() to @DennisHeimbigner since it is your code. This issue clearly involved nc_inq_var_filter().
In terms of implementing a SHOWOFF in addition to a NOTNC4 version of some dispatch functions, that is complicated by the fact that the classic dispatch table does not even include the netCDF-4 functions. I'm not sure how that works actually. Do we just count on the code to never call a netcdf-4 function for a classic file? I believe that is the answer.
In that case, I don't know how to handle nc_inq_var_deflate() using the dispatch table. I believe the answer is that nc3dispatch.h should be changed so classic files have a full dispatch table, instead of an abbreviated one, and that we use the NOTNC4 and SHOWOFF functions in that case. But that is beyond the scope of this issue, perhaps.
I will submit a PR which tests nc_inq_var_chunking(), demonstrating that it is working correctly.
Interesting. You may recall that that old issue about fixing the dispatch table had removing the netcdf4 dependency as a task. In fact I thought we had done this. I am going to create a PR to do this, then we can use the SHOWOFF (or perhaps IGNORE) dispatch table entries.
I take it back. Apparently this was done some time ago. So for example, the libsrc dispatch table has entries for e.g. def_var_deflate.
FYI I just implmented an NCO workaround to this nc_inq_var_filter()
backwards-incompatibility in netCDF 4.7.4 and in netCDF 4.8.0-development. I would be happy to remove the NCO workaround for 4.8.0-development should its behavior be reverted to the pre-4.7.4 behavior. Please LMK if/when the 4.8.0-development behavior of nc_inq_var_filter()
changes.
If I'm not mistaken this behavior has been reverted in master.
I believe this issue can be closed.
Hola compadres,
I am trying to identify and workaround a backward-incompatible behavior change in 4.7.4. Please correct me if I am wrong about the following, @DennisHeimbigner and others. As of 4.7.4,
nc_inq_var_filter()
called on a chunked and shuffled though not compressed variable in a netCDF4 dataset (CDL below) returns error -136, "NetCDF: Filter error: filter not defined for variable". Prior to 4.7.4,nc_inq_var_filter()
returns NC_NOERR on this variable, and sets the filter ID to 0. This new behavior in 4.7.4 breaks the strategy that NCO uses to identify which filters are used on a variable. Currently NCO usesnc_inq_var_filter()
on all chunked variables to assess whether any filters have been employed on them. If the returned filter ID != 0 then NCO delves deeper into the filter. As this example points out, that strategy no longer works on variables that are chunked and shuffled but not compressed. What is the recommended strategy to learn whether a variable has had a filter applied?This also serves as notice of the backwards incompatibility. I am happy to modify NCO to make calls that depend on the netCDF library version if necessary, though I would prefer one strategy that works with all netCDF libraries (greater than 4.6.0, when
nc_inq_var_filter()
was introduced, in this particular case).Interrogating this file with NCO using netCDF 4.7.3:
Interrogate this file with NCO using netCDF 4.7.4: