first stab at re-adding nc_def_var_szip()

This commit is contained in:
Edward Hartnett 2020-01-03 11:38:45 -07:00
parent 808a0e2be9
commit e703a7678c
3 changed files with 115 additions and 5 deletions

View File

@ -210,7 +210,7 @@ typedef struct NC_VAR_INFO
nc_bool_t dimscale; /**< True if var is a dimscale */
nc_bool_t *dimscale_attached; /**< Array of flags that are true if dimscale is attached for that dim index */
nc_bool_t deflate; /**< True if var has deflate filter applied */
int deflate_level;
int deflate_level; /**< If deflate is true, this is the deflate level, between 1 and 9. */
nc_bool_t shuffle; /**< True if var has shuffle filter applied */
nc_bool_t fletcher32; /**< True if var has fletcher32 filter applied */
size_t chunk_cache_size, chunk_cache_nelems;

View File

@ -317,6 +317,9 @@ there. */
#define NC_MIN_DEFLATE_LEVEL 0 /**< Minimum deflate level. */
#define NC_MAX_DEFLATE_LEVEL 9 /**< Maximum deflate level. */
#define NC_SZIP_EC 4 /**< Selects entropy coding method for szip. */
#define NC_SZIP_NN 32 /**< Selects nearest neighbor coding method for szip. */
/** The netcdf version 3 functions all return integer error status.
* These are the possible values, in addition to certain values from
* the system errno.h.
@ -850,6 +853,10 @@ EXTERNL int
nc_inq_var_deflate(int ncid, int varid, int *shufflep,
int *deflatep, int *deflate_levelp);
/* Set szip compression for a variable. */
EXTERNL int
nc_def_var_szip(int ncid, int varid, int options_mask, int pixels_per_block);
/* Find out szip settings of a var. */
EXTERNL int
nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp);

View File

@ -25,6 +25,12 @@
/** Number of bytes in 64 KB. */
#define SIXTY_FOUR_KB (65536)
/** Number of parameters needed when turning on szip filter. */
#define NUM_SZIP_PARAM 2
/** The HDF5 ID for the szip filter. */
#define HDF5_FILTER_SZIP 4
#ifdef LOGGING
/**
* Report the chunksizes selected for a variable.
@ -661,8 +667,7 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
return NC_ENOTVAR;
assert(var && var->hdr.id == varid);
/* Can't turn on parallel and deflate/fletcher32/szip/shuffle
* before HDF5 1.10.2. */
/* Can't turn on parallel and any filters before HDF5 1.10.2. */
#ifndef HDF5_SUPPORTS_PAR_FILTERS
if (h5->parallel == NC_TRUE)
if (deflate || fletcher32 || shuffle)
@ -872,8 +877,8 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
}
/**
* @internal Set compression settings on a variable. This is called by
* nc_def_var_deflate().
* @internal Set zlib compression settings on a variable. This is
* called by nc_def_var_deflate().
*
* @param ncid File ID.
* @param varid Variable ID.
@ -900,6 +905,104 @@ NC4_def_var_deflate(int ncid, int varid, int shuffle, int deflate,
&deflate_level, NULL, NULL, NULL, NULL, NULL, NULL);
}
/**
* Set szip compression settings on a variable. Szip is an
* implementation of the extended-Rice lossless compression
* algorithm. Szip is reported to provide fast and effective
* compression.
*
* SZIP compression cannot be applied to variables with any
* user-defined type.
*
* @note The options_mask parameter may be either NC_SZIP_EC (entropy
* coding) or NC_SZIP_NN (nearest neighbor):
* * The entropy coding method is best suited for data that has been
* processed. The EC method works best for small numbers.
* * The nearest neighbor coding method preprocesses the data then the
* applies EC method as above.
*
* @param ncid File ID.
* @param varid Variable ID.
* @param options_mask The options mask. Can be NC_SZIP_EC or
* NC_SZIP_NN.
* @param pixels_per_block Pixels per block. Must be even and not
* greater than 32, with typical values being 8, 10, 16, or 32. This
* parameter affects compression ratio; the more pixel values vary,
* the smaller this number should be to achieve better performance. If
* pixels_per_block is bigger than the total number of elements in a
* dataset chunk, H5Pset_szip will succeed but the subsequent call to
* H5Dcreate will fail; the conflict can be detected only when the
* property list is used.
*
* @returns ::NC_NOERR No error.
* @returns ::NC_ENOTBUILT This HDF5 install was not built with szip.
* @returns ::NC_EBADID Bad ncid.
* @returns ::NC_ENOTVAR Invalid variable ID.
* @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is
* not netCDF-4/HDF5.
* @returns ::NC_ELATEDEF Too late to change settings for this variable.
* @returns ::NC_ENOTINDEFINE Not in define mode.
* @returns ::NC_EINVAL Invalid input
* @author Ed Hartnett
*/
int
nc_def_var_szip(int ncid, int varid, int options_mask, int pixels_per_block)
{
NC_GRP_INFO_T *grp;
NC_FILE_INFO_T *h5;
NC_VAR_INFO_T *var;
unsigned int szip_params[NUM_SZIP_PARAM]; /* [0]=options_mask [1]=pixels_per_block */
int built = 0;
int ret;
LOG((2, "%s: ncid 0x%x varid %d", __func__, ncid, varid));
/* If HDF5 was not built with szip, then return error. */
#ifdef HAVE_H5Z_SZIP
built = 1;
#endif /* HAVE_H5Z_SZIP */
if (!built)
return NC_ENOTBUILT;
/* Find info for this file and group, and set pointer to each. */
if ((ret = nc4_find_nc_grp_h5(ncid, NULL, &grp, &h5)))
return ret;
assert(grp && h5);
/* Trying to write to a read-only file? No way, Jose! */
if (h5->no_write)
return NC_EPERM;
/* Can't turn on parallel and szip before HDF5 1.10.2. */
#ifdef USE_PARALLEL
#ifndef HDF5_SUPPORTS_PAR_FILTERS
if (h5->parallel == NC_TRUE)
return NC_EINVAL;
#endif /* HDF5_SUPPORTS_PAR_FILTERS */
#endif /* USE_PARALLEL */
/* Find the var. */
if (!(var = (NC_VAR_INFO_T *)ncindexith(grp->vars, varid)))
return NC_ENOTVAR;
assert(var && var->hdr.id == varid);
#ifdef USE_PARALLEL
/* Switch to collective access. HDF5 requires collevtive access
* for filter use with parallel I/O. */
if (h5->parallel)
var->parallel_access = NC_COLLECTIVE;
#endif /* USE_PARALLEL */
/* This will cause H5Pset_szip to be called when the var is created. */
szip_params[0] = options_mask == NC_SZIP_EC ? H5_SZIP_EC_OPTION_MASK:
H5_SZIP_NN_OPTION_MASK;
szip_params[1] = pixels_per_block;
if ((ret = nc_def_var_filter(ncid, varid, HDF5_FILTER_SZIP, 2, szip_params)))
return ret;
return NC_NOERR;
}
/**
* @internal Set checksum on a variable. This is called by
* nc_def_var_fletcher32().