|
NEP 2.7.0
NetCDF Extension Pack
|
Demonstrates how lossy quantization pre-filters interact with lossless compression to affect compression ratio, I/O throughput, and precision loss on a realistic scientific dataset. More...
#include <netcdf.h>#include <netcdf_filter.h>#include "nep.h"#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <sys/time.h>Data Structures | |
| struct | filter_config_t |
Macros | |
| #define | NZ 500 |
| #define | NY 180 |
| #define | NX 360 |
| #define | TMP_FILE "quantize_tmp.nc" |
| #define | CHUNK_Z 10 |
| #define | CHUNK_Y 45 |
| #define | CHUNK_X 90 |
| #define | NVALS ((size_t)NZ * NY * NX) |
| #define | UNCOMPRESSED_BYTES ((double)NVALS * sizeof(float)) |
| #define | ERRCODE 2 |
| #define | ERR(e) {printf("Error: %s\n", nc_strerror(e)); exit(ERRCODE);} |
| #define | NSD_MIN 1 |
| #define | NSD_MAX 6 |
| #define | N_NSB 6 |
| #define | NUM_FILTERS (sizeof(filters) / sizeof(filters[0])) |
Functions | |
| static double | get_time (void) |
| Return current wall-clock time in seconds. | |
| static int | apply_filter (int ncid, int varid, const filter_config_t *filter) |
| Apply the specified lossless filter to the variable. | |
| static int | run_one (float *orig, float *read_buf, const char *q_alg, int quantize_mode, int nsd_or_nsb, const filter_config_t *filter) |
| Run one quantize × lossless filter combination and print a CSV row. | |
| int | main (void) |
| Main entry point. | |
Variables | |
| static const int | nsb_values [] = {3, 6, 9, 13, 16, 19} |
| static const filter_config_t | filters [] |
Demonstrates how lossy quantization pre-filters interact with lossless compression to affect compression ratio, I/O throughput, and precision loss on a realistic scientific dataset.
Quantization is a lossy pre-filter that zeroes excess bits of the IEEE 754 floating-point significand before a lossless compression step. Because adjacent quantized values share identical trailing bits, lossless compressors achieve substantially higher compression ratios. Unlike the shuffle filter, quantization introduces a bounded but irreversible precision loss.
Three quantization algorithms are tested:
Each quantize algorithm × NSD/NSB level is paired with all five lossless filters at their sprint-10 optimal settings (all with shuffle enabled). Baseline rows (lossless only, no quantization) are printed first.
The program measures max absolute error by reading back written data and comparing element-wise to the original array. Baseline rows report 0.000000.
Call order: shuffle → lossless filter → nc_def_var_quantize() → nc_enddef()
Output: CSV printed to stdout with columns:
Typical workflow:
Learning Objectives:
Key Concepts:
Prerequisites:
Related Examples:
Key API functions:
| #define CHUNK_X 90 |
| #define CHUNK_Y 45 |
| #define CHUNK_Z 10 |
Chunk shape: matches all v1.10.0 performance examples for consistency.
| #define ERR | ( | e | ) | {printf("Error: %s\n", nc_strerror(e)); exit(ERRCODE);} |
| #define ERRCODE 2 |
| #define N_NSB 6 |
| #define NSD_MAX 6 |
| #define NSD_MIN 1 |
NSD range for BitGroom and GranularBitRound (decimal digits). NC_FLOAT has ~6.92 significant decimal digits (23-bit significand). NC_QUANTIZE_MAX_FLOAT_NSD is 7, but NSD=7 triggers a boundary condition in BitGroom where bits_to_zero=0 and the alternating mask produces NaN on odd indices. Cap at 6 to stay within meaningful float precision.
| #define NX 360 |
Longitude dimension: 360 degrees.
| #define NY 180 |
Latitude dimension: 180 degrees.
| #define NZ 500 |
Time dimension: 500 time steps.
| #define TMP_FILE "quantize_tmp.nc" |
Temporary NetCDF file created and removed for each measurement.
| #define UNCOMPRESSED_BYTES ((double)NVALS * sizeof(float)) |
Uncompressed size in bytes.
|
static |
Apply the specified lossless filter to the variable.
For DEFLATE, shuffle is embedded in nc_def_var_deflate(). For all other filters, the caller has already applied the shuffle-only call before invoking this function.
| ncid | NetCDF file ID. |
| varid | Variable ID. |
| filter | Lossless filter configuration. |
|
static |
Return current wall-clock time in seconds.
| int main | ( | void | ) |
Main entry point.
Allocates two 500×180×360 NC_FLOAT buffers (original data and read-back buffer), then iterates:
Total: 110 CSV data rows + 1 header row.
|
static |
Run one quantize × lossless filter combination and print a CSV row.
Creates quantize_tmp.nc with shuffle + lossless filter + (optionally) quantization, writes a 500×180×360 NC_FLOAT temperature variable, stats the file to obtain the compressed size, reads the variable back to compute max absolute error, then removes the file.
When quantize_mode is -1 (baseline), no quantization is applied and max_abs_err is reported as 0.000000.
| orig | Pre-allocated buffer of NVALS floats (original data). |
| read_buf | Pre-allocated buffer of NVALS floats (read-back buffer). |
| q_alg | Quantize algorithm name for CSV ("none", "bitgroom", "granularbr", or "bitround"). |
| quantize_mode | NC_QUANTIZE_BITGROOM, NC_QUANTIZE_GRANULARBR, NC_QUANTIZE_BITROUND, or -1 for no quantization. |
| nsd_or_nsb | NSD (BitGroom/GranularBitRound) or NSB (BitRound) value; 0 when quantize_mode is -1. |
| filter | Lossless filter configuration. |
|
static |
Optimal lossless filter configurations (from sprint 10).
|
static |
NSB values for BitRound, equivalent in decimal precision to NSD 1–6. NSB=23 (NSD=7 equivalent) is excluded for NC_FLOAT: it retains all 23 significand bits and is indistinguishable from no quantization.