/* Return size of chunk in bytes for a variable varid in a group igrp, or 0 if * layout is contiguous */ static int inq_var_chunksize(int igrp, int varid, size_t* chunksizep) { int stat = NC_NOERR; int ndims; size_t *chunksizes; int dim; int contig = 1; nc_type vartype; size_t value_size; size_t prod; NC_CHECK(nc_inq_vartype(igrp, varid, &vartype)); /* from type, get size in memory needed for each value */ NC_CHECK(nc_inq_type(igrp, vartype, NULL, &value_size)); prod = value_size; NC_CHECK(nc_inq_varndims(igrp, varid, &ndims)); chunksizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t)); if(ndims > 0) { NC_CHECK(nc_inq_var_chunking(igrp, varid, &contig, NULL)); } if(contig == 1) { *chunksizep = 0; } else { NC_CHECK(nc_inq_var_chunking(igrp, varid, &contig, chunksizes)); for(dim = 0; dim < ndims; dim++) { prod *= chunksizes[dim]; } *chunksizep = prod; } free(chunksizes); return stat; }
/* Initialize iteration for a variable. Just a wrapper for * nc_blkio_init() that makes the netCDF calls needed to initialize * lower-level iterator. */ int nc_get_iter(int ncid, int varid, size_t bufsize, /* size in bytes of memory buffer */ nciter_t **iterpp /* returned opaque iteration state */) { int stat = NC_NOERR; nciter_t *iterp; nc_type vartype; size_t value_size = 0; /* size in bytes of each variable element */ int ndims; /* number of dimensions for variable */ int *dimids; long long nvalues = 1; int dim; int chunked = 0; /* Caller should free this by calling nc_free_iter(iterp) */ iterp = (nciter_t *) emalloc(sizeof(nciter_t)); memset((void*)iterp,0,sizeof(nciter_t)); /* make sure it is initialized */ NC_CHECK(nc_inq_varndims(ncid, varid, &ndims)); dimids = (int *) emalloc((ndims + 1) * sizeof(int)); iterp->dimsizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t)); iterp->chunksizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t)); NC_CHECK(nc_inq_vardimid (ncid, varid, dimids)); for(dim = 0; dim < ndims; dim++) { size_t len; NC_CHECK(nc_inq_dimlen(ncid, dimids[dim], &len)); nvalues *= len; iterp->dimsizes[dim] = len; } NC_CHECK(nc_inq_vartype(ncid, varid, &vartype)); NC_CHECK(inq_value_size(ncid, vartype, &value_size)); #ifdef USE_NETCDF4 { int contig = 1; if(ndims > 0) { NC_CHECK(nc_inq_var_chunking(ncid, varid, &contig, NULL)); } if(contig == 0) { /* chunked */ NC_CHECK(nc_inq_var_chunking(ncid, varid, &contig, iterp->chunksizes)); chunked = 1; } } #endif /* USE_NETCDF4 */ NC_CHECK(nc_blkio_init(bufsize, value_size, ndims, chunked, iterp)); iterp->to_get = 0; free(dimids); *iterpp = iterp; return stat; }
/* Initialize iteration for a variable. Just a wrapper for * nc_blkio_init() that makes the netCDF calls needed to initialize * lower-level iterator. */ int nc_get_iter(Symbol* vsym, size_t bufsize, /* size in bytes of memory buffer */ nciter_t *iterp /* returned opaque iteration state */) { int stat = NC_NOERR; Symbol* vartype; size_t value_size; /* size in bytes of each variable element */ int ndims; /* number of dimensions for variable */ size_t dimsizes[NC_MAX_VAR_DIMS]; /* variable dimension sizes */ size_t chunksizes[NC_MAX_VAR_DIMS]; /* corresponding chunk sizes */ long long nvalues = 1; int dim; int chunked = 0; memset((void*)iterp,0,sizeof(nciter_t)); /* make sure it is initialized */ stat = nciter_ndims(vsym, &ndims); CHECK(stat, nciter_ndims); stat = nciter_dimlens(vsym,dimsizes); /* compute total # elements */ nvalues=1; for(dim = 0; dim < ndims; dim++) { nvalues *= dimsizes[dim]; } stat = nciter_vartype(vsym, &vartype); CHECK(stat, nciter_vartype); stat = nciter_valuesize(vartype,&value_size); CHECK(stat, nciter_valuesize); #ifdef USE_NETCDF4 #ifdef DOCHUNK { int contig = 1; if(ndims > 0) { stat = nc_inq_var_chunking(ncid, varid, &contig, NULL); CHECK(stat, nc_inq_var_chunking); } if(contig == 0) { /* chunked */ stat = nc_inq_var_chunking(ncid, varid, &contig, chunksizes); CHECK(stat, nc_inq_var_chunking); chunked = 1; } } #else chunked = 0; #endif #endif /* USE_NETCDF4 */ stat = nc_blkio_init(bufsize, value_size, ndims, dimsizes, chunked, chunksizes, iterp); CHECK(stat, nc_blkio_init); iterp->to_get = 0; return stat; }
/* Inputs: root_id: netcdfID of the root group varid: var ID to set the deflate params for ndims: number of dims in the variable Outputs: storage: either 1 for NC_CONTIGUOUS or 2 for NC_CHUNKED chunksizesp: pointer to array indicating chunk sizes along each dimension. NOTE: THIS MUST BE ALLOCATED BEFORE CALLING THIS ROUTINE!! Returned values are in C order (which is opposite R order) ierr: 0 on success, otherwise an error was encountered */ void R_nc4_inq_var_chunking( int *root_id, int *varid, int *ndims, int *storage, int *chunksizesp, int *ierr ) { int stor_param, i; size_t sizet_chunkparam[MAX_NC_DIMS]; *ierr = nc_inq_var_chunking( *root_id, *varid, &stor_param, sizet_chunkparam ); if( *ierr != NC_NOERR ) { Rprintf( "Error in R_nc4_inq_var_chunking: %s\n", nc_strerror(*ierr) ); return; } if( stor_param == NC_CONTIGUOUS ) *storage = 1; else if( stor_param == NC_CHUNKED ) *storage = 2; else { Rprintf( "Error in R_nc4_inq_var_chunking: obtained value of storage is neither NC_CONTIGUOUS nor NC_CHUNKED! Value=%d\n", stor_param ); *ierr = -1; return; } for( i=0; i<(*ndims); i++ ) chunksizesp[i] = (int)(sizet_chunkparam[i]); }
static int verifychunks(void) { int i; int store = -1; size_t localchunks[MAXDIMS]; memset(localchunks,0,sizeof(localchunks)); CHECK(nc_inq_var_chunking(ncid, varid, &store, localchunks)); if(store != NC_CHUNKED) { fprintf(stderr,"bad chunk store\n"); return 0; } for(i=0;i<ndims;i++) { if(chunksize[i] != localchunks[i]) { fprintf(stderr,"bad chunk size: %d\n",i); return 0; } } return 1; }
static int verifychunks(void) { int i; int store = -1; size_t chunksizes[NDIMS]; memset(chunksizes,0,sizeof(chunksizes)); CHECK(nc_inq_var_chunking(ncid, varid, &store, chunksizes)); /* Storate must be chunked, not contiguous */ if(store != NC_CHUNKED) { fprintf(stderr,"bad chunk store\n"); return NC_ESTORAGE; } /* Chunk sizes must match our predefined set */ for(i=0;i<actualdims;i++) { if(chunksizes[i] != chunks[i]) { fprintf(stderr,"bad chunk size: %d\n",i); return NC_EBADCHUNK; } } return 1; }
int main(int argc, char **argv) { extern int optind; extern int opterr; extern char *optarg; int c, header = 0, verbose = 0, timeseries = 0; int ncid, varid, storage; char name_in[NC_MAX_NAME + 1]; size_t len; size_t cs[NDIMS3] = {0, 0, 0}; int cache = MEGABYTE; int ndims, dimid[NDIMS3]; float hor_data[LAT_LEN * LON_LEN]; int read_1_us, avg_read_us; float ts_data[TIME_LEN]; size_t start[NDIMS3], count[NDIMS3]; int deflate, shuffle, deflate_level; struct timeval start_time, end_time, diff_time; while ((c = getopt(argc, argv, "vhtc:")) != EOF) switch(c) { case 'v': verbose++; break; case 'h': header++; break; case 't': timeseries++; break; case 'c': sscanf(optarg, "%d", &cache); break; case '?': usage(); return 1; } argc -= optind; argv += optind; /* If no file arguments left, report and exit */ if (argc < 1) { printf("no file specified\n"); return 0; } /* Print the header if desired. */ if (header) { printf("cs[0]\tcs[1]\tcs[2]\tcache(MB)\tdeflate\tshuffle"); if (timeseries) printf("\t1st_read_ser(us)\tavg_read_ser(us)\n"); else printf("\t1st_read_hor(us)\tavg_read_hor(us)\n"); } #define PREEMPTION .75 /* Also tried NELEMS of 2500009*/ #define NELEMS 7919 if (nc_set_chunk_cache(cache, NELEMS, PREEMPTION)) ERR; if (nc_open(argv[0], 0, &ncid)) ERR; /* Check to make sure that all the dimension information is * correct. */ if (nc_inq_varid(ncid, DATA_VAR_NAME, &varid)) ERR; if (nc_inq_dim(ncid, LON_DIMID, name_in, &len)) ERR; if (strcmp(name_in, "lon") || len != LON_LEN) ERR; if (nc_inq_dim(ncid, LAT_DIMID, name_in, &len)) ERR; if (strcmp(name_in, "lat") || len != LAT_LEN) ERR; if (nc_inq_dim(ncid, BNDS_DIMID, name_in, &len)) ERR; if (strcmp(name_in, "bnds") || len != BNDS_LEN) ERR; if (nc_inq_dim(ncid, TIME_DIMID, name_in, &len)) ERR; if (strcmp(name_in, "time") || len != TIME_LEN) ERR; if (nc_inq_var(ncid, varid, NULL, NULL, &ndims, dimid, NULL)) ERR; if (ndims != NDIMS3 || dimid[0] != TIME_DIMID || dimid[1] != LAT_DIMID || dimid[2] != LON_DIMID) ERR; /* Get info about the main data var. */ if (nc_inq_var_chunking(ncid, varid, &storage, cs)) ERR; if (nc_inq_var_deflate(ncid, varid, &shuffle, &deflate, &deflate_level)) ERR; if (timeseries) { /* Read the var as a time series. */ start[0] = 0; start[1] = 0; start[2] = 0; count[0] = TIME_LEN; count[1] = 1; count[2] = 1; /* Read the first timeseries. */ if (gettimeofday(&start_time, NULL)) ERR; if (nc_get_vara_float(ncid, varid, start, count, ts_data)) ERR_RET; if (gettimeofday(&end_time, NULL)) ERR; if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR; read_1_us = (int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec; /* Read all the rest. */ if (gettimeofday(&start_time, NULL)) ERR; for (start[1] = 0; start[1] < LAT_LEN; start[1]++) for (start[2] = 1; start[2] < LON_LEN; start[2]++) if (nc_get_vara_float(ncid, varid, start, count, ts_data)) ERR_RET; if (gettimeofday(&end_time, NULL)) ERR; if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR; avg_read_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec + read_1_us) / (LAT_LEN * LON_LEN); } else { /* Read the data variable in horizontal slices. */ start[0] = 0; start[1] = 0; start[2] = 0; count[0] = 1; count[1] = LAT_LEN; count[2] = LON_LEN; /* Read (and time) the first one. */ if (gettimeofday(&start_time, NULL)) ERR; if (nc_get_vara_float(ncid, varid, start, count, hor_data)) ERR_RET; if (gettimeofday(&end_time, NULL)) ERR; if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR; read_1_us = (int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec; /* Read (and time) all the rest. */ if (gettimeofday(&start_time, NULL)) ERR; for (start[0] = 1; start[0] < TIME_LEN; start[0]++) if (nc_get_vara_float(ncid, varid, start, count, hor_data)) ERR_RET; if (gettimeofday(&end_time, NULL)) ERR; if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR; avg_read_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec + read_1_us) / TIME_LEN; } /* Close file. */ if (nc_close(ncid)) ERR; /* Print results. */ printf("%d\t%d\t%d\t%.1f\t\t%d\t%d\t\t", (int)cs[0], (int)cs[1], (int)cs[2], (storage == NC_CHUNKED) ? (cache/(float)MEGABYTE) : 0, deflate, shuffle); if (timeseries) printf("%d\t\t%d\n", (int)read_1_us, (int)avg_read_us); else printf("%d\t\t%d\n", (int)read_1_us, (int)avg_read_us); return 0; }
int main(int argc, char **argv) { printf("\n*** Testing netcdf-4 variable chunking.\n"); printf("**** testing that fixed vars with filter end up being chunked, with good sizes..."); { int ncid; int nvars, ndims, ngatts, unlimdimid; int contig; int ndims_in, natts_in, dimids_in; int small_dimid, medium_dimid, large_dimid; int small_varid, medium_varid, large_varid; char var_name_in[NC_MAX_NAME + 1]; size_t chunksize_in[NDIMS1]; nc_type xtype_in; /* Create a netcdf-4 file with three dimensions. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, D_SMALL, D_SMALL_LEN, &small_dimid)) ERR; if (nc_def_dim(ncid, D_MEDIUM, D_MEDIUM_LEN, &medium_dimid)) ERR; if (nc_def_dim(ncid, D_LARGE, D_LARGE_LEN, &large_dimid)) ERR; /* Add three vars, with filters to force chunking. */ if (nc_def_var(ncid, V_SMALL, NC_INT64, NDIMS1, &small_dimid, &small_varid)) ERR; if (nc_def_var_deflate(ncid, small_varid, 0, 1, 4)) ERR; if (nc_def_var(ncid, V_MEDIUM, NC_INT64, NDIMS1, &medium_dimid, &medium_varid)) ERR; if (nc_def_var_deflate(ncid, medium_varid, 1, 0, 0)) ERR; if (nc_def_var(ncid, V_LARGE, NC_INT64, NDIMS1, &large_dimid, &large_varid)) ERR; if (nc_def_var_fletcher32(ncid, large_varid, 1)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR; if (nvars != 3 || ndims != 3 || ngatts != 0 || unlimdimid != -1) ERR; if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, &dimids_in, &natts_in)) ERR; if (strcmp(var_name_in, V_SMALL) || xtype_in != NC_INT64 || ndims_in != 1 || natts_in != 0) ERR; /* Make sure chunking sizes are what we expect. */ if (nc_inq_var_chunking(ncid, small_varid, &contig, chunksize_in)) ERR; if (contig || chunksize_in[0] != D_SMALL_LEN) ERR; if (nc_inq_var_chunking(ncid, medium_varid, &contig, chunksize_in)) ERR; if (contig || chunksize_in[0] * sizeof(long long) > DEFAULT_CHUNK_SIZE) ERR; if (nc_inq_var_chunking(ncid, large_varid, &contig, chunksize_in)) ERR; if (contig || chunksize_in[0] * sizeof(long long) > DEFAULT_CHUNK_SIZE) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing default chunksizes..."); { int nvars, ndims, ngatts, unlimdimid; int contig; #define NUM_DIM 4 #define NUM_TYPE 2 int ncid; int dim_len[NUM_DIM] = {NC_UNLIMITED, 100, 1000, 2000}; size_t chunksize_in[NUM_DIM]; int type_id[NUM_TYPE] = {NC_BYTE, NC_INT}; int dimid[NUM_DIM], varid[NUM_TYPE]; char dim_name[NC_MAX_NAME + 1], var_name[NC_MAX_NAME + 1]; int d, t; /* Create a netcdf-4 file with NUM_DIM dimensions. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; for (d = 0; d < NUM_DIM; d++) { sprintf(dim_name, "dim_%d", dim_len[d]); #ifdef PRINT_DEFAULT_CHUNKSIZE_TABLE printf("creating dim %s\n", dim_name); #endif if (nc_def_dim(ncid, dim_name, dim_len[d], &dimid[d])) ERR; } for (t = 0; t < NUM_TYPE; t++) { sprintf(var_name, "var_%d", type_id[t]); if (nc_def_var(ncid, var_name, type_id[t], NUM_DIM, dimid, &varid[t])) ERR; if (nc_inq_var_chunking(ncid, varid[t], &contig, chunksize_in)) ERR; #ifdef PRINT_DEFAULT_CHUNKSIZE_TABLE printf("chunksizes for %d x %d x %d x %d var: %d x %d x %d x %d (=%d)\n", dim_len[0], dim_len[1], dim_len[2], dim_len[3], (int)chunksize_in[0], (int)chunksize_in[1], (int)chunksize_in[2], (int)chunksize_in[3], (int)(chunksize_in[0] * chunksize_in[1] * chunksize_in[2] * chunksize_in[3])); #endif } if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR; if (nvars != NUM_TYPE || ndims != NUM_DIM || ngatts != 0 || unlimdimid != 0) ERR; for (t = 0; t < NUM_TYPE; t++) { sprintf(var_name, "var_%d", type_id[t]); if (nc_inq_var_chunking(ncid, varid[t], &contig, chunksize_in)) ERR; if (contig) ERR; #ifdef PRINT_DEFAULT_CHUNKSIZE_TABLE printf("chunksizes for %d x %d x %d x %d var: %d x %d x %d x %d (=%d)\n", dim_len[0], dim_len[1], dim_len[2], dim_len[3], (int)chunksize_in[0], (int)chunksize_in[1], (int)chunksize_in[2], (int)chunksize_in[3], (int)(chunksize_in[0] * chunksize_in[1] * chunksize_in[2] * chunksize_in[3])); #endif } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing that chunking works on classic mode files..."); { #define D_SMALL_LEN2 66 int ncid; int nvars, ndims, ngatts, unlimdimid; int contig; int ndims_in, natts_in, dimids_in; int small_dimid, medium_dimid, large_dimid; int small_varid, medium_varid, large_varid; char var_name_in[NC_MAX_NAME + 1]; size_t chunks[1], chunksize_in; nc_type xtype_in; /* Create a netcdf-4 file with three dimensions. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, D_SMALL, D_SMALL_LEN2, &small_dimid)) ERR; if (nc_def_dim(ncid, D_MEDIUM, D_MEDIUM_LEN, &medium_dimid)) ERR; if (nc_def_dim(ncid, D_LARGE, D_LARGE_LEN, &large_dimid)) ERR; /* Add three vars. */ if (nc_def_var(ncid, V_SMALL, NC_INT64, NDIMS1, &small_dimid, &small_varid)) ERR; if (nc_def_var_chunking(ncid, small_varid, 1, NULL)) ERR; if (nc_def_var(ncid, V_MEDIUM, NC_INT64, NDIMS1, &medium_dimid, &medium_varid)) ERR; chunks[0] = D_MEDIUM_LEN / 100; if (nc_def_var_chunking(ncid, medium_varid, 0, chunks)) ERR; if (nc_def_var_deflate(ncid, medium_varid, 1, 0, 0)) ERR; if (nc_def_var(ncid, V_LARGE, NC_INT64, NDIMS1, &large_dimid, &large_varid)) ERR; chunks[0] = D_LARGE_LEN / 1000; if (nc_def_var_chunking(ncid, large_varid, 0, chunks)) ERR; if (nc_def_var_fletcher32(ncid, large_varid, 1)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR; if (nvars != 3 || ndims != 3 || ngatts != 0 || unlimdimid != -1) ERR; if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, &dimids_in, &natts_in)) ERR; if (strcmp(var_name_in, V_SMALL) || xtype_in != NC_INT64 || ndims_in != 1 || natts_in != 0) ERR; /* Make sure chunking settings are what we expect. */ if (nc_inq_var_chunking(ncid, small_varid, &contig, &chunksize_in)) ERR; if (!contig) ERR; if (nc_inq_var_chunking(ncid, medium_varid, &contig, &chunksize_in)) ERR; if (contig || chunksize_in != D_MEDIUM_LEN / 100) ERR; if (nc_inq_var_chunking(ncid, large_varid, &contig, &chunksize_in)) ERR; if (contig || chunksize_in != D_LARGE_LEN / 1000) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing many chunking and contiguous variables..."); { #define NDIMS_3 3 #define NUM_PLANS 30 #define D_SNEAKINESS "sneakiness" #define D_SNEAKINESS_LEN 5 #define D_CLEVERNESS "clevernesss" #define D_CLEVERNESS_LEN 3 #define D_EFFECTIVENESS "effectiveness" #define D_EFFECTIVENESS_LEN 2 int ncid, dimids[NDIMS_3], varid[NUM_PLANS]; size_t chunksize[NDIMS_3] = {D_SNEAKINESS_LEN, D_CLEVERNESS_LEN, D_EFFECTIVENESS_LEN}; char plan_name[NC_MAX_NAME + 1]; int contig; size_t chunksize_in[NDIMS_3]; int i, j; /* Create a netcdf-4 file with three dimensions. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, D_SNEAKINESS, D_SNEAKINESS_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, D_CLEVERNESS, D_CLEVERNESS_LEN, &dimids[1])) ERR; if (nc_def_dim(ncid, D_EFFECTIVENESS, D_EFFECTIVENESS_LEN, &dimids[2])) ERR; /* Oh that tricky Cardinal Richelieu, he had many plans! */ for (i = 0; i < NUM_PLANS; i++) { sprintf(plan_name, "Richelieu_sneaky_plan_%d", i); if (nc_def_var(ncid, plan_name, i % (NC_STRING - 1) + 1, NDIMS_3, dimids, &varid[i])) ERR; if (i % 2 && nc_def_var_chunking(ncid, varid[i], 0, chunksize)) ERR; } /* Check the chunking. */ for (i = 0; i < NUM_PLANS; i++) { if (nc_inq_var_chunking(ncid, varid[i], &contig, chunksize_in)) ERR; if (i % 2) { for (j = 0; j < NDIMS_3; j++) if (chunksize_in[j] != chunksize[j]) ERR; } else if (!contig) ERR; } if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; /* Check the chunking. */ for (i = 0; i < NUM_PLANS; i++) { if (nc_inq_var_chunking(ncid, varid[i], &contig, chunksize_in)) ERR; if (i % 2) { for (j = 0; j < NDIMS_3; j++) if (chunksize_in[j] != chunksize[j]) ERR; } else if (!contig) ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing that too large chunksizes fail..."); { #define D_SMALL_LEN2 66 int stat = NC_NOERR; int ncid; int nvars, ndims, ngatts, unlimdimid; int contig; int ndims_in, natts_in, dimids_in; int small_dimid, medium_dimid, large_dimid; int small_varid; char var_name_in[NC_MAX_NAME + 1]; size_t chunks[1], chunksize_in; nc_type xtype_in; /* Create a netcdf-4 file with three dimensions. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, D_SMALL, D_SMALL_LEN2, &small_dimid)) ERR; /* Add one var. */ if (nc_def_var(ncid, V_SMALL, NC_INT64, NDIMS1, &small_dimid, &small_varid)) ERR; /* Attempt to set too large chunksizes */ chunks[0] = D_SMALL_LEN2 + 1; stat = nc_def_var_chunking(ncid, small_varid, NC_CHUNKED, chunks); if(stat != NC_EBADCHUNK) { printf("Return code is '%s', expected NC_BADCHUNK",nc_strerror(stat)); ERR; } /* try agains with proper chunksize */ chunks[0] = D_SMALL_LEN2; stat = nc_def_var_chunking(ncid, small_varid, NC_CHUNKED, chunks); if(stat != NC_NOERR) { printf("Return code is '%s', expected NC_NOERR",nc_strerror(stat)); ERR; } if (nc_abort(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }
int main(int argc, char **argv) { int ncid; int varid; int rank; int d; int storage; size_t chunksizes[NC_MAX_VAR_DIMS]; const char* srcdir = "."; printf("\n*** Testing HDF4/NetCDF-4 chunking API: chunked...\n"); { /* Open with netCDF */ if (nc_open(CHUNKEDFILE, NC_NOWRITE, &ncid)) ERR; /* Get a variable id */ if(nc_inq_varid(ncid,CHUNKEDVAR,&varid)) ERR; /* get rank */ if(nc_inq_varndims(ncid,varid,&rank)) ERR; /* get chunk info */ memset(chunksizes,0,sizeof(chunksizes)); if(nc_inq_var_chunking(ncid,varid,&storage,chunksizes)) ERR; if(storage == NC_CONTIGUOUS) { fprintf(stderr,"nc_inq_var_chunking did not return CHUNKED\n"); ERR; } for(d=0;d<rank;d++) { if(EXPECTED_CHUNKSIZES[d] != chunksizes[d]) { fprintf(stderr,"chunk size mismatch: [%d] %ld :: %ld\n",d,chunksizes[d],EXPECTED_CHUNKSIZES[d]); ERR; } } if (nc_close(ncid)) ERR; } printf("\n*** Testing HDF4/NetCDF-4 chunking API: contiguous...\n"); { /* Open with netCDF */ if (nc_open(CONTIGFILE, NC_NOWRITE, &ncid)) ERR; /* Get a variable id */ if(nc_inq_varid(ncid,CONTIGVAR,&varid)) ERR; /* get rank */ if(nc_inq_varndims(ncid,varid,&rank)) ERR; /* get chunk info */ memset(chunksizes,0,sizeof(chunksizes)); if(nc_inq_var_chunking(ncid,varid,&storage,chunksizes)) ERR; if(storage != NC_CONTIGUOUS) { fprintf(stderr,"nc_inq_var_chunking did not return CONTIGUOUS\n"); ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }
/*********************************************************************** * * HANDLE_NC_INQ_VAR_CHUNKING: * * code for handling the nc_inq_var_chunking routine. * * [storage,chunksize,status] = mexnc('inq_var_chunking',ncid,varid); * **********************************************************************/ void handle_nc_inq_var_chunking ( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[], op *nc_op ) { int ncid; int varid; int storage; size_t chunksize[NC_MAX_DIMS]; /* * Pointer shortcut to matrix data. * */ double *pr; mwSize mxsize[2]; /* Size of chunking matrix. */ int status, j; /* * Number of dimensions (inferred from length of chunk argument) * */ int ndims; /* * File format. * */ int format; /* * Make sure that the inputs are the right type. * */ check_numeric_argument_type ( prhs, nc_op->opname, 1 ); check_numeric_argument_type ( prhs, nc_op->opname, 2 ); pr = mxGetData ( prhs[1] ); ncid = (int)(pr[0]); pr = mxGetData ( prhs[2] ); varid = (int)(pr[0]); status = nc_inq_format(ncid,&format); if ( status != NC_NOERR ) { sprintf ( error_message, "Internal call to nc_inq_format failed, operation \"%s\", line %d file \"%s\"\n", nc_op->opname, __LINE__, __FILE__ ); mexErrMsgTxt ( error_message ); return; } switch(format){ case NC_FORMAT_CLASSIC: case NC_FORMAT_64BIT: plhs[0] = mxCreateString ( "contiguous" ); plhs[1] = mxCreateNumericArray(0,0, mxDOUBLE_CLASS, mxREAL ); plhs[2] = mxCreateNumericArray(0,0, mxDOUBLE_CLASS, mxREAL ); return; } status = nc_inq_varndims(ncid,varid,&ndims); if ( status != NC_NOERR ) { sprintf ( error_message, "Internal call to nc_inq_varndims failed, operation \"%s\", line %d file \"%s\"\n", nc_op->opname, __LINE__, __FILE__ ); mexErrMsgTxt ( error_message ); return; } status = nc_inq_var_chunking ( ncid, varid, &storage, chunksize ); plhs[2] = mexncCreateDoubleScalar ( status ); if ( storage == NC_CONTIGUOUS ) { plhs[0] = mxCreateString ( "contiguous" ); /* * Return [] for the chunksize * */ mxsize[0] = 0; mxsize[1] = 0; plhs[1] = mxCreateNumericArray ( 2, mxsize, mxDOUBLE_CLASS, mxREAL ); return; } plhs[0] = mxCreateString ( "chunked" ); mxsize[0] = 1; mxsize[1] = ndims; plhs[1] = mxCreateNumericArray ( 2, mxsize, mxDOUBLE_CLASS, mxREAL ); pr = mxGetData ( plhs[1] ); for ( j = 0; j < ndims; ++j ) { pr[j] = chunksize[j]; } return; }
int main(int argc, char **argv) { int ncid, dimids[NUM_DIMS]; int varid; int nvars_in, varids_in[NUM_DIMS]; signed char fill_value = 42, fill_value_in; nc_type xtype_in; size_t len_in; char name_in[NC_MAX_NAME + 1]; int attnum_in; int cnum; #ifdef USE_PARALLEL MPI_Init(&argc, &argv); #endif printf("\n*** Testing netcdf-4 variable functions, even more.\n"); for (cnum = 0; cnum < MAX_CNUM; cnum++) { int cmode; switch(cnum) { case 0: printf("*** Testing with classic format:\n"); cmode = 0; break; case 1: printf("*** Testing with 64-bit offset format:\n"); cmode = NC_64BIT_OFFSET; break; case 2: printf("*** Testing with HDF5:\n"); cmode = NC_NETCDF4|NC_CLOBBER; break; case 3: printf("*** Testing with HDF5, netCDF Classic Model:\n"); cmode = NC_CLASSIC_MODEL | NC_NETCDF4; } printf("**** testing simple fill value attribute creation..."); { /* Create a netcdf-4 file with one scalar var. Add fill * value. */ if (nc_create(FILE_NAME, cmode, &ncid)) ERR; if (nc_def_var(ncid, VAR_NAME, NC_BYTE, 0, NULL, &varid)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_put_att_schar(ncid, varid, _FillValue, NC_BYTE, 1, &fill_value)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR; if (nvars_in != 1 || varids_in[0] != 0) ERR; if (nc_inq_varname(ncid, 0, name_in)) ERR; if (strcmp(name_in, VAR_NAME)) ERR; if (nc_inq_att(ncid, varid, _FillValue, &xtype_in, &len_in)) ERR; if (xtype_in != NC_BYTE || len_in != 1) ERR; if (nc_get_att(ncid, varid, _FillValue, &fill_value_in)) ERR; if (fill_value_in != fill_value) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing simple fill value with data read..."); { size_t start[NUM_DIMS], count[NUM_DIMS]; signed char data = 99, data_in; /* Create a netcdf-4 file with one unlimited dim and one * var. Add fill value. */ if (nc_create(FILE_NAME, cmode, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_var(ncid, VAR_NAME, NC_BYTE, NUM_DIMS, dimids, &varid)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_put_att_schar(ncid, varid, _FillValue, NC_BYTE, 1, &fill_value)) ERR; if (nc_enddef(ncid)) ERR; /* Write the second record. */ start[0] = 1; count[0] = 1; if (nc_put_vara_schar(ncid, varid, start, count, &data)) ERR; /* Read the first record, it should be the fill value. */ start[0] = 0; if (nc_get_vara_schar(ncid, varid, start, count, &data_in)) ERR; if (data_in != fill_value) ERR; /* Read the second record, it should be the value we just wrote * there. */ start[0] = 1; if (nc_get_vara_schar(ncid, varid, start, count, &data_in)) ERR; if (data_in != data) ERR; /* Close up. */ if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Check metadata. */ if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR; if (nvars_in != 1 || varids_in[0] != 0) ERR; if (nc_inq_varname(ncid, 0, name_in)) ERR; if (strcmp(name_in, VAR_NAME)) ERR; /* Check fill value att. */ if (nc_inq_att(ncid, varid, _FillValue, &xtype_in, &len_in)) ERR; if (xtype_in != NC_BYTE || len_in != 1) ERR; if (nc_get_att(ncid, varid, _FillValue, &fill_value_in)) ERR; if (fill_value_in != fill_value) ERR; /* Read the first record, it should be the fill value. */ start[0] = 0; if (nc_get_vara_schar(ncid, varid, start, count, &data_in)) ERR; if (data_in != fill_value) ERR; /* Read the second record, it should be the value we just wrote * there. */ start[0] = 1; if (nc_get_vara_schar(ncid, varid, start, count, &data_in)) ERR; if (data_in != data) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing fill value with one other attribute..."); { int losses_value = 192, losses_value_in; /* Create a netcdf-4 file with one dim and one var. Add another * attribute, then fill value. */ if (nc_create(FILE_NAME, cmode, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_var(ncid, VAR_NAME, NC_BYTE, NUM_DIMS, dimids, &varid)) ERR; if (nc_put_att_int(ncid, varid, LOSSES_NAME, NC_INT, 1, &losses_value)) ERR; if (nc_put_att_schar(ncid, varid, _FillValue, NC_BYTE, 1, &fill_value)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_att(ncid, 0, LOSSES_NAME, &xtype_in, &len_in)) ERR; if (xtype_in != NC_INT || len_in != 1) ERR; if (nc_get_att(ncid, 0, LOSSES_NAME, &losses_value_in)) ERR; if (losses_value_in != losses_value) ERR; if (nc_inq_att(ncid, 0, _FillValue, &xtype_in, &len_in)) ERR; if (xtype_in != NC_BYTE || len_in != 1) ERR; if (nc_get_att(ncid, 0, _FillValue, &fill_value_in)) ERR; if (fill_value_in != fill_value) ERR; if (nc_inq_attid(ncid, 0, LOSSES_NAME, &attnum_in)) ERR; if (attnum_in != 0) ERR; if (nc_inq_attid(ncid, 0, _FillValue, &attnum_in)) ERR; if (attnum_in != 1) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing fill value with three other attributes..."); { #define NUM_LEADERS 3 char leader[NUM_LEADERS][NC_MAX_NAME + 1] = {"hair_length_of_strategoi", "hair_length_of_Miltiades", "hair_length_of_Darius_I"}; short hair_length[NUM_LEADERS] = {3, 11, 4}; short short_in; int a; /* Create a netcdf file with one dim and one var. Add 3 * attributes, then fill value. */ if (nc_create(FILE_NAME, cmode, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_var(ncid, VAR_NAME, NC_BYTE, NUM_DIMS, dimids, &varid)) ERR; for (a = 0; a < NUM_LEADERS; a++) if (nc_put_att_short(ncid, varid, leader[a], NC_SHORT, 1, &hair_length[a])) ERR; if (nc_put_att_schar(ncid, varid, _FillValue, NC_BYTE, 1, &fill_value)) ERR; if (nc_close(ncid)) ERR; /* Open the file. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Check our three hair-related attributes. */ for (a = 0; a < NUM_LEADERS; a++) { if (nc_inq_att(ncid, 0, leader[a], &xtype_in, &len_in)) ERR; if (xtype_in != NC_SHORT || len_in != 1) ERR; if (nc_get_att(ncid, 0, leader[a], &short_in)) ERR; if (short_in != hair_length[a]) ERR; if (nc_inq_attid(ncid, 0, leader[a], &attnum_in)) ERR; if (attnum_in != a) ERR; } /* Check our fill value attribute. */ if (nc_inq_att(ncid, 0, _FillValue, &xtype_in, &len_in)) ERR; if (xtype_in != NC_BYTE || len_in != 1) ERR; if (nc_get_att(ncid, 0, _FillValue, &fill_value_in)) ERR; if (fill_value_in != fill_value) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing fill value with simple example..."); { /* Dims stuff. */ #define NDIMS 3 #define VAR_DIMS 3 #define DIM_A "dim1" #define DIM_A_LEN 4 #define DIM_B "dim2" #define DIM_B_LEN 3 #define DIM_C "dim3" #define DIM_C_LEN NC_UNLIMITED /* Var stuff. */ #define CXX_VAR_NAME "P" /* Att stuff. */ #define NUM_ATTS 4 #define LONG_NAME "long_name" #define PRES_MAX_WIND "pressure at maximum wind" #define UNITS "units" #define HECTOPASCALS "hectopascals" int dimid[NDIMS], var_dimids[VAR_DIMS] = {2, 1, 0}; float fill_value = -9999.0f; char long_name[] = PRES_MAX_WIND; if (nc_create(FILE_NAME, cmode, &ncid)) ERR; /* Create dims. */ if (nc_def_dim(ncid, DIM_A, DIM_A_LEN, &dimid[0])) ERR; if (nc_def_dim (ncid, DIM_B, DIM_B_LEN, &dimid[1])) ERR; if (nc_def_dim(ncid, DIM_C, DIM_C_LEN, &dimid[2])) ERR; /* Create var. */ if (nc_def_var(ncid, CXX_VAR_NAME, NC_FLOAT, VAR_DIMS, var_dimids, &varid)) ERR; if (varid) ERR; if (nc_put_att(ncid, varid, LONG_NAME, NC_CHAR, strlen(long_name) + 1, long_name)) ERR; if (nc_put_att(ncid, varid, UNITS, NC_CHAR, strlen(UNITS) + 1, UNITS)) ERR; /* Check to ensure the atts have their expected attnums. */ if (nc_inq_attid(ncid, 0, LONG_NAME, &attnum_in)) ERR; if (attnum_in != 0) ERR; if (nc_inq_attid(ncid, 0, UNITS, &attnum_in)) ERR; if (attnum_in != 1) ERR; /* Now add a fill value. This will acutually cause HDF5 to * destroy the dataset and recreate it, recreating also the * three attributes that are attached to it. */ if (nc_put_att(ncid, varid, _FillValue, NC_FLOAT, 1, &fill_value)) ERR; /* Check to ensure the atts have their expected attnums. */ if (nc_inq_attid(ncid, 0, LONG_NAME, &attnum_in)) ERR; if (attnum_in != 0) ERR; if (nc_inq_attid(ncid, 0, UNITS, &attnum_in)) ERR; if (attnum_in != 1) ERR; if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_inq_attid(ncid, 0, LONG_NAME, &attnum_in)) ERR; if (attnum_in != 0) ERR; if (nc_inq_attid(ncid, 0, UNITS, &attnum_in)) ERR; if (attnum_in != 1) ERR; if (nc_inq_attid(ncid, 0, _FillValue, &attnum_in)) ERR; if (attnum_in != 2) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; #ifndef NO_NETCDF_2 /* The following test is an attempt to recreate a problem occuring in the cxx tests. The file is created in c++ in nctsts.cpp. */ printf("**** testing fill value with example from cxx tests in v2 api..."); { /* Dims stuff. */ #define NDIMS_1 4 #define VAR_DIMS 3 #define LAT "lat" #define LAT_LEN 4 #define LON "lon" #define LON_LEN 3 #define FRTIMED "frtimed" #define FRTIMED_LEN NC_UNLIMITED #define TIMELEN "timelen" #define TIMELEN_LEN 20 /* Var stuff. */ #define CXX_VAR_NAME "P" /* Att stuff. */ #define NUM_ATTS 4 #define LONG_NAME "long_name" #define UNITS "units" int dimid[NDIMS_1], var_dimids[VAR_DIMS] = {2, 0, 1}; float fill_value = -9999.0f; char long_name[] = PRES_MAX_WIND; int i, attid[NUM_ATTS]; ncid = nccreate(FILE_NAME, NC_NETCDF4); /* Create dims. */ dimid[0] = ncdimdef(ncid, LAT, LAT_LEN); dimid[1] = ncdimdef(ncid, LON, LON_LEN); dimid[2] = ncdimdef(ncid, FRTIMED, FRTIMED_LEN); dimid[3] = ncdimdef(ncid, TIMELEN, TIMELEN_LEN); /* Just check our dimids to see that they are correct. */ for (i = 0; i < NDIMS_1; i++) if (dimid[i] != i) ERR; /* Create var. */ varid = ncvardef(ncid, CXX_VAR_NAME, NC_FLOAT, VAR_DIMS, var_dimids); if (varid) ERR; /* Add three atts to the var, long_name, units, and * valid_range. */ if (nc_put_att(ncid, varid, LONG_NAME, NC_CHAR, strlen(long_name) + 1, long_name)) ERR; if (nc_put_att(ncid, varid, UNITS, NC_CHAR, strlen(UNITS) + 1, UNITS)) ERR; /* Check to ensure the atts have their expected attnums. */ if (nc_inq_attid(ncid, 0, LONG_NAME, &attnum_in)) ERR; if (attnum_in != 0) ERR; if (nc_inq_attid(ncid, 0, UNITS, &attnum_in)) ERR; if (attnum_in != 1) ERR; /* Now add a fill value. This will acutually cause HDF5 to * destroy the dataset and recreate it, recreating also the * three attributes that are attached to it. */ attid[3] = ncattput(ncid, varid, _FillValue, NC_FLOAT, 1, &fill_value); /* Check to ensure the atts have their expected attnums. */ if (nc_inq_attid(ncid, 0, LONG_NAME, &attnum_in)) ERR; if (attnum_in != 0) ERR; if (nc_inq_attid(ncid, 0, UNITS, &attnum_in)) ERR; if (attnum_in != 1) ERR; ncclose(ncid); /* Open the file and check. */ ncid = ncopen(FILE_NAME, 0); if (nc_inq_attid(ncid, 0, LONG_NAME, &attnum_in)) ERR; if (attnum_in != 0) ERR; if (nc_inq_attid(ncid, 0, UNITS, &attnum_in)) ERR; if (attnum_in != 1) ERR; if (nc_inq_attid(ncid, 0, _FillValue, &attnum_in)) ERR; if (attnum_in != 2) ERR; ncclose(ncid); } SUMMARIZE_ERR; #endif /* NO_NETCDF_2 */ } printf("**** testing create order varids..."); #define UNITS "units" #define DIMNAME "x" #define VARNAME "data" { /* This test contributed by Jeff Whitaker of NOAA - Thanks Jeff! */ int ncid, dimid, varid, xvarid; char units[] = "zlotys"; if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_def_dim(ncid, DIMNAME, 1, &dimid)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_def_var(ncid, DIMNAME, NC_INT, 1, &dimid, &xvarid)) ERR; if (nc_put_att_text(ncid, xvarid, UNITS, strlen(units), units)) ERR; if (nc_def_var(ncid, VARNAME, NC_INT, 1, &dimid, &varid)) ERR; if (nc_close(ncid)) ERR; if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; #define RANK_wind 1 printf("**** testing simple variable renaming..."); { /* This test contributed by Jeff Whitaker of NOAA - Thanks Jeff! */ int ncid, lat_dim, time_dim, lon_dim, wind_id; size_t lat_len = 73, time_len = 10, lon_len = 145; int cdf_goober[1]; /* if (nc_set_default_format(NC_FORMAT_NETCDF4, NULL)) ERR;*/ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; /* define dimensions */ if (nc_def_dim(ncid, "a", lon_len, &lon_dim)) ERR; if (nc_def_dim(ncid, "b", lat_len, &lat_dim)) ERR; if (nc_def_dim(ncid, "c", time_len, &time_dim)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, "a", 3, "bar")) ERR; cdf_goober[0] = 2; if (nc_put_att_int(ncid, NC_GLOBAL, "b", NC_INT, 1, cdf_goober)) ERR; /* define variables */ if (nc_def_var(ncid, "aa", NC_FLOAT, RANK_wind, &lon_dim, &wind_id)) ERR; if (nc_close(ncid)) ERR; if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_rename_var(ncid, 0, "az")) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing dimension and variable renaming..."); { /* This test contributed by Jeff Whitaker of NOAA - Thanks Jeff! */ int ncid, lat_dim, time_dim, lon_dim, wind_id; size_t lat_len = 73, time_len = 10, lon_len = 145; int wind_dims[RANK_wind], wind_slobber[1], cdf_goober[1]; if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; /* define dimensions */ if (nc_def_dim(ncid, "lon", lon_len, &lon_dim)) ERR; if (nc_def_dim(ncid, "lat", lat_len, &lat_dim)) ERR; if (nc_def_dim(ncid, "time", time_len, &time_dim)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, "foo", 3, "bar")) ERR; cdf_goober[0] = 2; if (nc_put_att_int(ncid, NC_GLOBAL, "goober", NC_INT, 1, cdf_goober)) ERR; /* define variables */ wind_dims[0] = lon_dim; if (nc_def_var(ncid, "temp", NC_FLOAT, RANK_wind, wind_dims, &wind_id)) ERR; if (nc_put_att_text(ncid, wind_id, "bar", 3, "foo")) ERR; wind_slobber[0] = 3; if (nc_put_att_int(ncid, wind_id, "slobber", NC_INT, 1, wind_slobber)) ERR; if (nc_close(ncid)) ERR; /* re-open dataset*/ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_dimid(ncid, "lon", &lon_dim)) ERR; /* rename dimension */ if (nc_rename_dim(ncid, lon_dim, "longitude")) ERR; if (nc_inq_varid(ncid, "temp", &wind_id)) ERR; /* rename variable */ if (nc_rename_var(ncid, wind_id, "wind")) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; /* printf("*** testing 2D array of NC_CHAR..."); */ /* { */ /* int dimid[NDIMS_1], var_dimids[VAR_DIMS] = {2, 0, 1}; */ /* float fill_value = -9999.0f; */ /* char long_name[] = PRES_MAX_WIND; */ /* int i, attid[NUM_ATTS]; */ /* ncid = nccreate(FILE_NAME, NC_NETCDF4); */ /* /\* Create dims. *\/ */ /* dimid[0] = ncdimdef(ncid, LAT, LAT_LEN); */ /* dimid[1] = ncdimdef(ncid, LON, LON_LEN); */ /* /\* Create var. *\/ */ /* varid = ncvardef(ncid, CXX_VAR_NAME, NC_FLOAT, VAR_DIMS, var_dimids); */ /* if (varid) ERR; */ /* ncclose(ncid); */ /* /\* Open the file and check. *\/ */ /* ncid = ncopen(FILE_NAME, 0); */ /* ncclose(ncid); */ /* } */ /* SUMMARIZE_ERR; */ #define NDIMS 3 #define NNAMES 4 #define NLINES 13 /* printf("**** testing funny names for netCDF-4..."); */ /* { */ /* int ncid, wind_id; */ /* size_t len[NDIMS] = {7, 3, 1}; */ /* int dimids[NDIMS], dimids_in[NDIMS], ndims_in; */ /* char funny_name[NNAMES][NC_MAX_NAME] = {"\a\t", "\f\n", "\r\v", "\b"}; */ /* char name_in[NC_MAX_NAME + 1]; */ /* char *speech[NLINES] = {"who would fardels bear, ", */ /* "To grunt and sweat under a weary life, ", */ /* "But that the dread of something after death, ", */ /* "The undiscover'd country from whose bourn ", */ /* "No traveller returns, puzzles the will ", */ /* "And makes us rather bear those ills we have ", */ /* "Than fly to others that we know not of? ", */ /* "Thus conscience does make cowards of us all; ", */ /* "And thus the native hue of resolution ", */ /* "Is sicklied o'er with the pale cast of thought, ", */ /* "And enterprises of great pith and moment ", */ /* "With this regard their currents turn awry, ", */ /* "And lose the name of action."}; */ /* char *speech_in[NLINES]; */ /* int i; */ /* unsigned short nlines = NLINES; */ /* unsigned int nlines_in; */ /* if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; */ /* /\* Define dimensions. *\/ */ /* for (i = 0; i < NDIMS; i++) */ /* if (nc_def_dim(ncid, funny_name[i], len[i], &dimids[i])) ERR; */ /* /\* Write some global atts. *\/ */ /* if (nc_put_att_string(ncid, NC_GLOBAL, funny_name[0], NLINES, */ /* (const char **)speech)) ERR; */ /* if (nc_put_att_ushort(ncid, NC_GLOBAL, funny_name[1], NC_UINT, 1, &nlines)) ERR; */ /* /\* Define variables. *\/ */ /* if (nc_def_var(ncid, funny_name[3], NC_INT64, NDIMS, dimids, &wind_id)) ERR; */ /* if (nc_close(ncid)) ERR; */ /* /\* Open the file and check. *\/ */ /* if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; */ /* if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; */ /* if (ndims_in != NDIMS) ERR; */ /* for (i = 0; i < NDIMS; i++) */ /* { */ /* if (dimids_in[i] != i) ERR; */ /* if (nc_inq_dimname(ncid, i, name_in)) ERR; */ /* if (strcmp(name_in, funny_name[i])) ERR; */ /* } */ /* if (nc_get_att_string(ncid, NC_GLOBAL, funny_name[0], (char **)speech_in)) ERR; */ /* for (i = 0; i < NLINES; i++) */ /* if (strcmp(speech_in[i], speech[i])) ERR; */ /* if (nc_get_att_uint(ncid, NC_GLOBAL, funny_name[1], &nlines_in)) ERR; */ /* if (nlines_in != NLINES) ERR; */ /* if (nc_free_string(NLINES, (char **)speech_in)) ERR; */ /* if (nc_inq_varname(ncid, 0, name_in)) ERR; */ /* if (strcmp(name_in, funny_name[3])) ERR; */ /* if (nc_close(ncid)) ERR; */ /* } */ /* SUMMARIZE_ERR; */ printf("**** testing endianness..."); #define NDIMS4 1 #define DIM4_NAME "Joe" #define VAR_NAME4 "Ed" #define DIM4_LEN 10 { int dimids[NDIMS4], dimids_in[NDIMS4]; int varid; int ndims, nvars, natts, unlimdimid; nc_type xtype_in; char name_in[NC_MAX_NAME + 1]; int data[DIM4_LEN], data_in[DIM4_LEN]; int endian_in; int i; for (i = 0; i < DIM4_LEN; i++) data[i] = i; /* Create a netcdf-4 file with one dim and one var. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM4_NAME, DIM4_LEN, &dimids[0])) ERR; if (dimids[0] != 0) ERR; if (nc_def_var(ncid, VAR_NAME4, NC_INT, NDIMS4, dimids, &varid)) ERR; if (nc_def_var_endian(ncid, varid, NC_ENDIAN_BIG)) ERR; if (varid != 0) ERR; if (nc_put_var_int(ncid, varid, data)) ERR; /* Check stuff. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS4 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != 1) ERR; if (varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR_NAME4) || xtype_in != NC_INT || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_endian(ncid, 0, &endian_in)) ERR; if (endian_in != NC_ENDIAN_BIG) ERR; if (nc_close(ncid)) ERR; /* Open the file and check the same stuff. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS4 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != 1) ERR; if (varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR_NAME4) || xtype_in != NC_INT || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_endian(ncid, 0, &endian_in)) ERR; if (endian_in != NC_ENDIAN_BIG) ERR; if (nc_get_var_int(ncid, varid, data_in)) ERR; for (i = 0; i < DIM4_LEN; i++) if (data[i] != data_in[i]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing chunking..."); { #define NDIMS5 1 #define DIM5_NAME "D5" #define VAR_NAME5 "V5" #define DIM5_LEN 1000 int dimids[NDIMS5], dimids_in[NDIMS5]; int varid; int ndims, nvars, natts, unlimdimid; nc_type xtype_in; char name_in[NC_MAX_NAME + 1]; int data[DIM5_LEN], data_in[DIM5_LEN]; int chunksize[NDIMS5] = {5}; int chunksize_in[NDIMS5]; int contiguous_in; int i, d; for (i = 0; i < DIM5_LEN; i++) data[i] = i; /* Create a netcdf-4 file with one dim and one var. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimids[0])) ERR; if (dimids[0] != 0) ERR; if (nc_def_var(ncid, VAR_NAME5, NC_INT, NDIMS5, dimids, &varid)) ERR; if (nc_def_var_chunking(ncid, varid, 0, chunksize)) ERR; if (nc_put_var_int(ncid, varid, data)) ERR; /* Check stuff. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS5 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != 1) ERR; if (varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR_NAME5) || xtype_in != NC_INT || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_chunking(ncid, 0, &contiguous_in, chunksize_in)) ERR; for (d = 0; d < NDIMS5; d++) if (chunksize[d] != chunksize_in[d]) ERR; if (contiguous_in != 0) ERR; if (nc_get_var_int(ncid, varid, data_in)) ERR; for (i = 0; i < DIM5_LEN; i++) if (data[i] != data_in[i]) ERR_RET; if (nc_close(ncid)) ERR; /* Open the file and check the same stuff. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Check stuff. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS5 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != 1) ERR; if (varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR_NAME5) || xtype_in != NC_INT || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_chunking(ncid, 0, &contiguous_in, chunksize_in)) ERR; for (d = 0; d < NDIMS5; d++) if (chunksize[d] != chunksize_in[d]) ERR; if (contiguous_in != 0) ERR; if (nc_get_var_int(ncid, varid, data_in)) ERR; for (i = 0; i < DIM5_LEN; i++) if (data[i] != data_in[i]) ERR_RET; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing contiguous storage..."); { #define NDIMS6 1 #define DIM6_NAME "D5" #define VAR_NAME6 "V5" #define DIM6_LEN 100 int dimids[NDIMS6], dimids_in[NDIMS6]; int varid; int ndims, nvars, natts, unlimdimid; nc_type xtype_in; char name_in[NC_MAX_NAME + 1]; int data[DIM6_LEN], data_in[DIM6_LEN]; int chunksize_in[NDIMS6]; int contiguous_in; int i, d; for (i = 0; i < DIM6_LEN; i++) data[i] = i; /* Create a netcdf-4 file with one dim and one var. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM6_NAME, DIM6_LEN, &dimids[0])) ERR; if (dimids[0] != 0) ERR; if (nc_def_var(ncid, VAR_NAME6, NC_INT, NDIMS6, dimids, &varid)) ERR; if (nc_def_var_chunking(ncid, varid, 1, NULL)) ERR; if (nc_put_var_int(ncid, varid, data)) ERR; /* Check stuff. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS6 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != 1) ERR; if (varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR_NAME6) || xtype_in != NC_INT || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_chunking(ncid, 0, &contiguous_in, chunksize_in)) ERR; for (d = 0; d < NDIMS6; d++) if (chunksize_in[d] != 0) ERR; if (!contiguous_in) ERR; if (nc_get_var_int(ncid, varid, data_in)) ERR; for (i = 0; i < DIM6_LEN; i++) if (data_in[i] != data[i]) ERR_RET; if (nc_close(ncid)) ERR; /* Open the file and check the same stuff. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Check stuff. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS6 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != 1) ERR; if (varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR_NAME6) || xtype_in != NC_INT || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_chunking(ncid, 0, &contiguous_in, chunksize_in)) ERR; for (d = 0; d < NDIMS6; d++) if (chunksize_in[d] != 0) ERR; if (!contiguous_in) ERR; if (nc_get_var_int(ncid, varid, data_in)) ERR; for (i = 0; i < DIM6_LEN; i++) if (data[i] != data_in[i]) ERR_RET; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing extreme numbers dude..."); { #define VAR_NAME7 "V5" #define DIM6_LEN 100 int varid; int ndims, nvars, natts, unlimdimid; nc_type xtype_in; char name_in[NC_MAX_NAME + 1]; /* unsigned long long data = 9223372036854775807ull, data_in;*/ unsigned long long data = 9223372036854775817ull, data_in; /* Create a netcdf-4 file with scalar var. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_var(ncid, VAR_NAME7, NC_UINT64, 0, NULL, &varid)) ERR; if (nc_put_var_ulonglong(ncid, varid, &data)) ERR; /* Check stuff. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 0 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != 1 || varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, NULL, &natts)) ERR; if (strcmp(name_in, VAR_NAME7) || xtype_in != NC_UINT64 || ndims != 0 || natts != 0) ERR; if (nc_get_var_ulonglong(ncid, varid, &data_in)) ERR; if (data_in != data) ERR; if (nc_close(ncid)) ERR; /* Open the file and check the same stuff. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 0 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != 1 || varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, NULL, &natts)) ERR; if (strcmp(name_in, VAR_NAME7) || xtype_in != NC_UINT64 || ndims != 0 || natts != 0) ERR; if (nc_get_var_ulonglong(ncid, varid, &data_in)) ERR; if (data_in != data) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing error codes for name clashes..."); { #define GENERIC_NAME "bob" int ncid, varid, numgrps, ntypes; /* Create a netcdf-4 file with one var. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_var(ncid, GENERIC_NAME, NC_BYTE, 0, NULL, &varid)) ERR; /* These don'e work, becuase the name is already in use. Make * sure the correct error is returned. */ if (nc_def_grp(ncid, GENERIC_NAME, NULL) != NC_ENAMEINUSE) ERR; if (nc_def_opaque(ncid, 1, GENERIC_NAME, NULL) != NC_ENAMEINUSE) ERR; /* Close it. */ if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR; if (nvars_in != 1 || varids_in[0] != 0) ERR; if (nc_inq_varname(ncid, 0, name_in)) ERR; if (strcmp(name_in, GENERIC_NAME)) ERR; if (nc_inq_grps(ncid, &numgrps, NULL)) ERR; if (numgrps) ERR; if (nc_inq_typeids(ncid, &ntypes, NULL)) ERR; if (ntypes) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing error codes for name clashes some more..."); { #define GENERIC_NAME "bob" int ncid, varid, numgrps, ntypes; /* Create a netcdf-4 file with one type. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_opaque(ncid, 1, GENERIC_NAME, NULL)) ERR; /* These don'e work, becuase the name is already in use. Make * sure the correct error is returned. */ if (nc_def_grp(ncid, GENERIC_NAME, NULL) != NC_ENAMEINUSE) ERR; if (nc_def_var(ncid, GENERIC_NAME, NC_BYTE, 0, NULL, &varid) != NC_ENAMEINUSE) ERR; /* Close it. */ if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR; if (nvars_in) ERR; if (nc_inq_grps(ncid, &numgrps, NULL)) ERR; if (numgrps) ERR; if (nc_inq_typeids(ncid, &ntypes, NULL)) ERR; if (ntypes != 1) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing error codes for name clashes even more..."); { #define GENERIC_NAME "bob" int ncid, varid, numgrps, ntypes; /* Create a netcdf-4 file with one group. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_grp(ncid, GENERIC_NAME, NULL)) ERR; /* These don'e work, becuase the name is already in use. Make * sure the correct error is returned. */ if (nc_def_opaque(ncid, 1, GENERIC_NAME, NULL) != NC_ENAMEINUSE) ERR; if (nc_def_var(ncid, GENERIC_NAME, NC_BYTE, 0, NULL, &varid) != NC_ENAMEINUSE) ERR; /* Close it. */ if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR; if (nvars_in) ERR; if (nc_inq_grps(ncid, &numgrps, NULL)) ERR; if (numgrps != 1) ERR; if (nc_inq_typeids(ncid, &ntypes, NULL)) ERR; if (ntypes) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing error code for too-large chunks..."); { #define NDIMS17 2 #define DIM17_NAME "personality" #define DIM17_NAME_2 "good_looks" #define VAR_NAME17 "ed" #define DIM17_LEN 2147483644 /* max dimension size - 2GB - 4. */ #define DIM17_2_LEN 1000 int dimids[NDIMS17], dimids_in[NDIMS17]; int varid; int ndims, nvars, natts, unlimdimid; nc_type xtype_in; char name_in[NC_MAX_NAME + 1]; int chunksize[NDIMS17] = {5, 5}; int bad_chunksize[NDIMS17] = {5, DIM17_LEN}; int chunksize_in[NDIMS17]; int contiguous_in; int d; /* Create a netcdf-4 file with two dims and one var. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM17_NAME, DIM17_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, DIM17_NAME_2, DIM17_2_LEN, &dimids[1])) ERR; if (dimids[0] != 0 || dimids[1] != 1) ERR; if (nc_def_var(ncid, VAR_NAME17, NC_UINT64, NDIMS17, dimids, &varid)) ERR; if (nc_def_var_chunking(ncid, varid, 0, bad_chunksize) != NC_EBADCHUNK) ERR; if (nc_def_var_chunking(ncid, varid, 0, chunksize)) ERR; /* Check stuff. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS17 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != 1) ERR; if (varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR_NAME17) || xtype_in != NC_UINT64 || ndims != 2 || natts != 0 || dimids_in[0] != 0 || dimids_in[1] != 1) ERR; if (nc_inq_var_chunking(ncid, 0, &contiguous_in, chunksize_in)) ERR; for (d = 0; d < NDIMS17; d++) if (chunksize[d] != chunksize_in[d]) ERR; if (contiguous_in != 0) ERR; if (nc_close(ncid)) ERR; /* Open the file and check the same stuff. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Check stuff. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS17 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != 1) ERR; if (varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR_NAME17) || xtype_in != NC_UINT64 || ndims != 2 || natts != 0 || dimids_in[0] != 0 || dimids_in[1] != 1) ERR; if (nc_inq_var_chunking(ncid, 0, &contiguous_in, chunksize_in)) ERR; for (d = 0; d < NDIMS17; d++) if (chunksize[d] != chunksize_in[d]) ERR; if (contiguous_in != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; #ifdef USE_PARALLEL MPI_Finalize(); #endif }
/** * @ingroup PIO_inq_var * Inquire about chunksizes for a variable. * * This function only applies to netCDF-4 files. When used with netCDF * classic files, the error PIO_ENOTNC4 will be returned. * * See the <a * href="http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html">netCDF * variable documentation</a> for details about the operation of this * function. * * @param ncid the ncid of the open file. * @param varid the ID of the variable to set chunksizes for. * @param storagep pointer to int which will be set to either * NC_CONTIGUOUS or NC_CHUNKED. * @param chunksizep pointer to memory where chunksizes will be * set. There are the same number of chunksizes as there are * dimensions. * * @return PIO_NOERR for success, otherwise an error code. */ int PIOc_inq_var_chunking(int ncid, int varid, int *storagep, PIO_Offset *chunksizesp) { int ierr; int msg; int mpierr; iosystem_desc_t *ios; file_desc_t *file; char *errstr; int ndims; errstr = NULL; ierr = PIO_NOERR; if (!(file = pio_get_file_from_id(ncid))) return PIO_EBADID; ios = file->iosystem; msg = PIO_MSG_INQ_VAR_CHUNKING; if (ios->async_interface && ! ios->ioproc) { if (ios->compmaster) mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); } if (ios->ioproc) { switch (file->iotype) { #ifdef _NETCDF #ifdef _NETCDF4 case PIO_IOTYPE_NETCDF4P: ierr = nc_inq_var_chunking(file->fh, varid, storagep, chunksizesp); break; case PIO_IOTYPE_NETCDF4C: if (ios->io_rank == 0) { if ((ierr = nc_inq_var_chunking(file->fh, varid, storagep, chunksizesp))) return ierr; if ((ierr = nc_inq_varndims(file->fh, varid, &ndims))) return ierr; } break; #endif case PIO_IOTYPE_NETCDF: return PIO_ENOTNC4; break; #endif #ifdef _PNETCDF case PIO_IOTYPE_PNETCDF: return PIO_ENOTNC4; break; #endif default: ierr = iotype_error(file->iotype,__FILE__,__LINE__); } } /* If there is an error, allocate space for the error string. */ if (ierr != PIO_NOERR) { errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); sprintf(errstr,"in file %s",__FILE__); } /* Check the netCDF return code, and broadcast it to all tasks. */ ierr = check_netcdf(file, ierr, errstr,__LINE__); /* Free the error stringif it was allocated. */ if (errstr != NULL) free(errstr); /* Broadcast results to all tasks. */ ierr = MPI_Bcast(&ndims, 1, MPI_INT, ios->ioroot, ios->my_comm); if (storagep) ierr = MPI_Bcast(storagep, 1, MPI_INT, ios->ioroot, ios->my_comm); if (chunksizesp) ierr = MPI_Bcast(chunksizesp, ndims, MPI_OFFSET, ios->ioroot, ios->my_comm); return ierr; }
int main(int argc, char **argv) { printf("\n*** Testing netcdf-4 file functions, some more.\n"); last_sbrk = sbrk(0); printf("*** testing lots of open files...\n"); { #define NUM_TRIES 6 int *ncid_in; int mem_used, mem_used2; /* int mem_per_file; */ int num_files[NUM_TRIES] = {1, 5, 10, 20, 35, 50}; char file_name[NUM_TRIES][NC_MAX_NAME + 1]; int num_vars[NUM_TRIES]; size_t cache_size[NUM_TRIES]; int mode[NUM_TRIES]; char mode_name[NUM_TRIES][8]; int ndims[NUM_TRIES]; int dim_len[NUM_TRIES][MAX_DIMS]; int dim_4d[MAX_DIMS] = {NC_UNLIMITED, 10, 100, 100}; char dimstr[30]; char chunkstr[30]; int num_recs[NUM_TRIES] = {1, 1, 1, 1, 1, 1}; struct timeval start_time, end_time, diff_time; struct timeval close_start_time, close_end_time, close_diff_time; int open_us, close_us, create_us; size_t chunksize[MAX_DIMS]; int storage; int d, f, t; printf("dims\t\tchunks\t\tformat\tnum_files\tcache(kb)\tnum_vars\tmem(kb)\t" "open_time(us/file)\tclose_time(us/file)\tcreate_time(us/file)\n"); for (t = 0; t < NUM_TRIES; t++) { strcpy(mode_name[t], "netcdf4"); mode[t] = NC_NETCDF4; cache_size[t] = 16000000; num_vars[t] = 10; ndims[t] = 4; for (d = 0; d < ndims[t]; d++) dim_len[t][d] = dim_4d[d]; /* Create sample files. */ if (gettimeofday(&start_time, NULL)) ERR; for (f = 0; f < num_files[t]; f++) { /* Set up filename. */ sprintf(file_name[t], "tst_files2_%d_%d.nc", t, f); if (create_sample_file(file_name[t], ndims[t], dim_len[t], num_vars[t], mode[t], num_recs[t])) ERR; /* How long did it take? */ if (gettimeofday(&end_time, NULL)) ERR; if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR; create_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec) / num_files[t]; } /* /\* Change the cache settings. *\/ */ /* if (nc_set_chunk_cache(cache_size[t], 20000, .75)) ERR; */ /* We need storage for an array of ncids. */ if (!(ncid_in = malloc(num_files[t] * sizeof(int)))) ERR; /* How much memory is in use now? */ if (get_mem_used1(&mem_used)) ERR; /* Open the first file to get chunksizes. */ if (gettimeofday(&start_time, NULL)) ERR; if (nc_open(file_name[t], 0, &ncid_in[0])) ERR; if (nc_inq_var_chunking(ncid_in[0], 0, &storage, chunksize)) ERR; /* Now reopen this file a large number of times. */ for (f = 1; f < num_files[t]; f++) if (nc_open(file_name[t], 0, &ncid_in[f])) ERR_RET; /* How long did it take per file? */ if (gettimeofday(&end_time, NULL)) ERR; if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR; open_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec) / num_files[t]; /* How much memory is in use by this process now? */ if (get_mem_used1(&mem_used2)) ERR; /* Close all netcdf files. */ if (gettimeofday(&close_start_time, NULL)) ERR; for (f = 0; f < num_files[t]; f++) if (nc_close(ncid_in[f])) ERR_RET; /* How long did it take to close all files? */ if (gettimeofday(&close_end_time, NULL)) ERR; if (nc4_timeval_subtract(&close_diff_time, &close_end_time, &close_start_time)) ERR; close_us = ((int)close_diff_time.tv_sec * MILLION + (int)close_diff_time.tv_usec) / num_files[t]; /* We're done with this. */ free(ncid_in); /* How much memory was used for each open file? */ /* mem_per_file = mem_used2/num_files[t]; */ /* Prepare the dimensions string. */ if (ndims[t] == MAX_DIMS) sprintf(dimstr, "%dx%dx%dx%d", dim_len[t][0], dim_len[t][1], dim_len[t][2], dim_len[t][3]); else sprintf(dimstr, "%dx%dx%d", dim_len[t][0], dim_len[t][1], dim_len[t][2]); /* Prepare the chunksize string. */ if (storage == NC_CHUNKED) { if (ndims[t] == MAX_DIMS) sprintf(chunkstr, "%dx%dx%dx%d", (int)chunksize[0], (int)chunksize[1], (int)chunksize[2], (int)chunksize[3]); else sprintf(chunkstr, "%dx%dx%d", (int)chunksize[0], (int)chunksize[1], (int)chunksize[2]); } else strcpy(chunkstr, "contig "); /* Output results. */ printf("%s\t%s\t%s\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n", dimstr, chunkstr, mode_name[t], num_files[t], (int)(cache_size[t]/1024), num_vars[t], mem_used2, open_us, close_us, create_us); } } SUMMARIZE_ERR; printf("Test for memory consumption...\n"); { #define NUM_TRIES_100 100 int ncid, i; int mem_used, mem_used1, mem_used2; get_mem_used2(&mem_used); mem_used1 = mem_used; mem_used2 = mem_used; printf("start: memuse= %d\t%d\t%d \n",mem_used, mem_used1, mem_used2); printf("bef_open\taft_open\taft_close\tused_open\tused_closed\n"); for (i=0; i < NUM_TRIES_100; i++) { /* Open the file. NC_NOWRITE tells netCDF we want read-only access * to the file.*/ get_mem_used2(&mem_used); nc_set_chunk_cache(10,10,.5); if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; get_mem_used2(&mem_used1); /* Close the file, freeing all resources. ???? */ if (nc_close(ncid)) ERR; get_mem_used2(&mem_used2); if (mem_used2 - mem_used) printf("try %d - %d\t\t%d\t\t%d\t\t%d\t\t%d \n", i, mem_used, mem_used1, mem_used2, mem_used1 - mem_used, mem_used2 - mem_used); } } SUMMARIZE_ERR; FINAL_RESULTS; }