|
NEP 2.7.0
NetCDF Extension Pack
|
Demonstrates how SZIP options_mask and pixels_per_block affect NetCDF-4 compression ratio and I/O throughput. More...
#include <netcdf.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <sys/time.h>Macros | |
| #define | NZ 500 |
| #define | NY 180 |
| #define | NX 360 |
| #define | TMP_FILE "szip_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 | N_PPB 5 |
Functions | |
| static double | get_time (void) |
| Return current wall-clock time in seconds. | |
| static int | run_one (float *data, int pixels_per_block) |
| Run one SZIP combination and print a CSV row. | |
| int | main (void) |
| Main entry point. | |
Variables | |
| static const int | PPB_VALUES [] = {2, 6, 10, 18, 30} |
Demonstrates how SZIP options_mask and pixels_per_block affect NetCDF-4 compression ratio and I/O throughput.
SZIP (Lossless Scientific Data Compression) is a lossless compression algorithm developed at JPL for scientific floating-point data and integrated into HDF5 as filter ID 4. NetCDF-4 exposes it via nc_def_var_szip().
SZIP supports two coding methods: nearest-neighbor (NC_SZIP_NN) and entropy coding (NC_SZIP_EC). However, NC_SZIP_EC requires integer data with a defined bit depth and does not work with NC_FLOAT. This program therefore uses NC_SZIP_NN exclusively, which is the correct and commonly used mode for floating-point scientific data.
The pixels_per_block parameter (even values 2 to NC_MAX_PIXELS_PER_BLOCK = 32) controls the block size used by the SZIP encoder. Larger values give the encoder more context and often improve ratio, at some increase in CPU cost. For chunked storage, pixels_per_block must divide the chunk's fastest-varying dimension (CHUNK_X). With CHUNK_X=90, valid values are 2 (90/2=45) and any divisor of 90.
This program iterates 5 pixels_per_block values over a 500x180x360 NC_FLOAT temperature dataset (~129 MB uncompressed) and reports:
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: CHUNK_X=90 is divisible by all tested pixels_per_block values {2, 6, 10, 18, 30}: the even divisors of 90 up to NC_MAX_PIXELS_PER_BLOCK. pixels_per_block must be even and divide CHUNK_X for NC_SZIP_NN.
| #define ERR | ( | e | ) | {printf("Error: %s\n", nc_strerror(e)); exit(ERRCODE);} |
| #define ERRCODE 2 |
| #define N_PPB 5 |
| #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 "szip_tmp.nc" |
Temporary NetCDF file created and removed for each measurement.
| #define UNCOMPRESSED_BYTES ((double)NVALS * sizeof(float)) |
Uncompressed size in bytes.
|
static |
Return current wall-clock time in seconds.
| int main | ( | void | ) |
Main entry point.
Allocates a 500x180x360 NC_FLOAT buffer with synthetic temperature data, then iterates 5 pixels_per_block values (5 rows total), printing one CSV row per value. All rows use NC_SZIP_NN coding.
|
static |
Run one SZIP combination and print a CSV row.
Creates szip_tmp.nc with the given options_mask and pixels_per_block, writes a 500x180x360 NC_FLOAT temperature variable, stats the file to obtain the compressed size, reads the variable back, then removes the file.
| data | Pre-allocated buffer of NVALS floats (synthetic data). |
| pixels_per_block | Value that divides CHUNK_X=90. |
|
static |
pixels_per_block values to test: even divisors of CHUNK_X=90.