1/*
2  Copyright 2007, UCAR/Unidata
3  See COPYRIGHT file for copying and redistribution conditions.
4
5  This is part of netCDF.
6
7  This program tests for a bug discovered with nofill mode that failed
8  only on file systems with block size in a particular range.  It fails
9  when invoked with the blksize argument between 2091953 and 2150032,
10  inclusive, and succeeds for other blksizes.
11
12  $Id: tst_nofill.c 2792 2014-10-27 06:02:59Z wkliao $
13*/
14
15#include <config.h>
16#include <nc_tests.h>
17#include "err_macros.h"
18#include <stdio.h>
19#include <limits.h>
20#include <stdlib.h>
21#include <errno.h>
22#include <netcdf.h>
23
24#define FILE_NAME1 "tst_fill1.nc"
25#define FILE_NAME2 "tst_fill2.nc"
26
27void
28check_err(const int stat, const int line, const char *file) {
29    if (stat != NC_NOERR) {
30 (void) fprintf(stderr, "line %d of %s: %s\n", linefilenc_strerror(stat));
31        fflush(stderr);
32 exit(1);
33    }
34}
35
36#define LON_LEN 240
37#define LAT_LEN 121
38#define LVL_LEN 31
39#define TIME_LEN 1
40
41int
42create_file(char *file_name, int fill_mode, size_t* sizehintp)
43{
44   int i;
45   int  stat; /* return status */
46   int  ncid; /* netCDF id */
47
48   /* dimension ids */
49   int lon_dim;
50   int lat_dim;
51   int lvl_dim;
52   int time_dim;
53
54   /* dimension lengths */
55   size_t lon_len = LON_LEN;
56   size_t lat_len = LAT_LEN;
57   size_t lvl_len = LVL_LEN;
58   size_t time_len = TIME_LEN;
59
60   /* variable ids */
61   int time_id;
62   int lat_id;
63   int lon_id;
64   int lvl_id;
65   int sfc_pres_id;
66   int temp_scrn_id;
67   int qsair_scrn_id;
68   int topog_id;
69   int mslp_id;
70   int sfc_temp_id;
71   int zonal_wnd_id;
72
73   /* rank (number of dimensions) for each variable */
74#  define RANK_time 1
75#  define RANK_lat 1
76#  define RANK_lon 1
77#  define RANK_lvl 1
78#  define RANK_sfc_pres 3
79#  define RANK_temp_scrn 3
80#  define RANK_qsair_scrn 3
81#  define RANK_topog 3
82#  define RANK_mslp 3
83#  define RANK_sfc_temp 3
84#  define RANK_zonal_wnd 4
85
86   /* variable shapes */
87   int time_dims[RANK_time];
88   int lat_dims[RANK_lat];
89   int lon_dims[RANK_lon];
90   int lvl_dims[RANK_lvl];
91   int sfc_pres_dims[RANK_sfc_pres];
92   int temp_scrn_dims[RANK_temp_scrn];
93   int qsair_scrn_dims[RANK_qsair_scrn];
94   int topog_dims[RANK_topog];
95   int mslp_dims[RANK_mslp];
96   int sfc_temp_dims[RANK_sfc_temp];
97   int zonal_wnd_dims[RANK_zonal_wnd];
98
99   size_t zonal_wnd_start[RANK_zonal_wnd];
100   size_t zonal_wnd_count[RANK_zonal_wnd];
101   float zonal_wnd[LON_LEN*LAT_LEN*TIME_LEN];
102   int ii;
103
104   int old_fill_mode;
105   size_t default_initialsize = 0;
106
107   /* To test bug on filesystem without large block size, we can get
108    * the same effect by providing the desired value as sizehint to
109    * nc__create() instead of calling nc_create() and getting the
110    * block size reported by fstat */
111#ifdef USE_PNETCDF
112   stat = nc_create_par(file_nameNC_CLOBBER|NC_PNETCDFMPI_COMM_WORLDMPI_INFO_NULL, &ncid);
113   /* PnetCDF does not support fill mode */
114#else
115   stat = nc__create(file_nameNC_CLOBBERdefault_initialsizesizehintp, &ncid);
116   check_err(stat,__LINE__,__FILE__);
117   stat = nc_set_fill(ncidfill_mode, &old_fill_mode);
118#endif
119   check_err(stat,__LINE__,__FILE__);
120
121   /* define dimensions */
122   stat = nc_def_dim(ncid, "lon", lon_len, &lon_dim);
123   check_err(stat,__LINE__,__FILE__);
124   stat = nc_def_dim(ncid, "lat", lat_len, &lat_dim);
125   check_err(stat,__LINE__,__FILE__);
126   stat = nc_def_dim(ncid, "lvl", lvl_len, &lvl_dim);
127   check_err(stat,__LINE__,__FILE__);
128   stat = nc_def_dim(ncid, "time", time_len, &time_dim);
129   check_err(stat,__LINE__,__FILE__);
130
131   /* define variables */
132   time_dims[0] = time_dim;
133   stat = nc_def_var(ncid, "time", NC_DOUBLERANK_timetime_dims, &time_id);
134   check_err(stat,__LINE__,__FILE__);
135
136   lat_dims[0] = lat_dim;
137   stat = nc_def_var(ncid, "lat", NC_FLOATRANK_latlat_dims, &lat_id);
138   check_err(stat,__LINE__,__FILE__);
139
140   lon_dims[0] = lon_dim;
141   stat = nc_def_var(ncid, "lon", NC_FLOATRANK_lonlon_dims, &lon_id);
142   check_err(stat,__LINE__,__FILE__);
143
144   lvl_dims[0] = lvl_dim;
145   stat = nc_def_var(ncid, "lvl", NC_FLOATRANK_lvllvl_dims, &lvl_id);
146   check_err(stat,__LINE__,__FILE__);
147
148   sfc_pres_dims[0] = time_dim;
149   sfc_pres_dims[1] = lat_dim;
150   sfc_pres_dims[2] = lon_dim;
151   stat = nc_def_var(ncid, "sfc_pres", NC_FLOATRANK_sfc_pressfc_pres_dims, &sfc_pres_id);
152   check_err(stat,__LINE__,__FILE__);
153
154   temp_scrn_dims[0] = time_dim;
155   temp_scrn_dims[1] = lat_dim;
156   temp_scrn_dims[2] = lon_dim;
157   stat = nc_def_var(ncid, "temp_scrn", NC_FLOATRANK_temp_scrntemp_scrn_dims, &temp_scrn_id);
158   check_err(stat,__LINE__,__FILE__);
159
160   qsair_scrn_dims[0] = time_dim;
161   qsair_scrn_dims[1] = lat_dim;
162   qsair_scrn_dims[2] = lon_dim;
163   stat = nc_def_var(ncid, "qsair_scrn", NC_FLOATRANK_qsair_scrnqsair_scrn_dims, &qsair_scrn_id);
164   check_err(stat,__LINE__,__FILE__);
165
166   topog_dims[0] = time_dim;
167   topog_dims[1] = lat_dim;
168   topog_dims[2] = lon_dim;
169   stat = nc_def_var(ncid, "topog", NC_FLOATRANK_topogtopog_dims, &topog_id);
170   check_err(stat,__LINE__,__FILE__);
171
172   mslp_dims[0] = time_dim;
173   mslp_dims[1] = lat_dim;
174   mslp_dims[2] = lon_dim;
175   stat = nc_def_var(ncid, "mslp", NC_FLOATRANK_mslpmslp_dims, &mslp_id);
176   check_err(stat,__LINE__,__FILE__);
177
178   sfc_temp_dims[0] = time_dim;
179   sfc_temp_dims[1] = lat_dim;
180   sfc_temp_dims[2] = lon_dim;
181   stat = nc_def_var(ncid, "sfc_temp", NC_FLOATRANK_sfc_tempsfc_temp_dims, &sfc_temp_id);
182   check_err(stat,__LINE__,__FILE__);
183
184   zonal_wnd_dims[0] = time_dim;
185   zonal_wnd_dims[1] = lvl_dim;
186   zonal_wnd_dims[2] = lat_dim;
187   zonal_wnd_dims[3] = lon_dim;
188   stat = nc_def_var(ncid, "zonal_wnd", NC_FLOATRANK_zonal_wndzonal_wnd_dims, &zonal_wnd_id);
189   check_err(stat,__LINE__,__FILE__);
190
191   /* leave define mode */
192   stat = nc_enddef (ncid);
193   check_err(stat,__LINE__,__FILE__);
194
195   { /* store time */
196       size_t time_start[RANK_time];
197       size_t time_count[RANK_time];
198       double time[TIME_LEN] = {1.};
199       time_len = 1;
200       time_start[0] = 0;
201       time_count[0] = time_len;
202       stat = nc_put_vara_double(ncidtime_idtime_starttime_count, time);
203       check_err(stat,__LINE__,__FILE__);
204   }
205
206   { /* store lat */
207       float lat[] = {90, 88.5, 87, 85.5, 84, 82.5, 81, 79.5, 78, 76.5, 75, 73.5, 72, 70.5, 69, 67.5, 66, 64.5, 63, 61.5, 60, 58.5, 57, 55.5, 54, 52.5, 51, 49.5, 48, 46.5, 45, 43.5, 42, 40.5, 39, 37.5, 36, 34.5, 33, 31.5, 30, 28.5, 27, 25.5, 24, 22.5, 21, 19.5, 18, 16.5, 15, 13.5, 12, 10.5, 9, 7.5, 6, 4.5, 3, 1.5, 0, -1.5, -3, -4.5, -6, -7.5, -9, -10.5, -12, -13.5, -15, -16.5, -18, -19.5, -21, -22.5, -24, -25.5, -27, -28.5, -30, -31.5, -33, -34.5, -36, -37.5, -39, -40.5, -42, -43.5, -45, -46.5, -48, -49.5, -51, -52.5, -54, -55.5, -57, -58.5, -60, -61.5, -63, -64.5, -66, -67.5, -69, -70.5, -72, -73.5, -75, -76.5, -78, -79.5, -81, -82.5, -84, -85.5, -87, -88.5, -90};
208       stat = nc_put_var_float(ncidlat_idlat);
209       check_err(stat,__LINE__,__FILE__);
210   }
211
212   { /* store lon */
213       float lon[] = {0, 1.5, 3, 4.5, 6, 7.5, 9, 10.5, 12, 13.5, 15, 16.5, 18, 19.5, 21, 22.5, 24, 25.5, 27, 28.5, 30, 31.5, 33, 34.5, 36, 37.5, 39, 40.5, 42, 43.5, 45, 46.5, 48, 49.5, 51, 52.5, 54, 55.5, 57, 58.5, 60, 61.5, 63, 64.5, 66, 67.5, 69, 70.5, 72, 73.5, 75, 76.5, 78, 79.5, 81, 82.5, 84, 85.5, 87, 88.5, 90, 91.5, 93, 94.5, 96, 97.5, 99, 100.5, 102, 103.5, 105, 106.5, 108, 109.5, 111, 112.5, 114, 115.5, 117, 118.5, 120, 121.5, 123, 124.5, 126, 127.5, 129, 130.5, 132, 133.5, 135, 136.5, 138, 139.5, 141, 142.5, 144, 145.5, 147, 148.5, 150, 151.5, 153, 154.5, 156, 157.5, 159, 160.5, 162, 163.5, 165, 166.5, 168, 169.5, 171, 172.5, 174, 175.5, 177, 178.5, 180, 181.5, 183, 184.5, 186, 187.5, 189, 190.5, 192, 193.5, 195, 196.5, 198, 199.5, 201, 202.5, 204, 205.5, 207, 208.5, 210, 211.5, 213, 214.5, 216, 217.5, 219, 220.5, 222, 223.5, 225, 226.5, 228, 229.5, 231, 232.5, 234, 235.5, 237, 238.5, 240, 241.5, 243, 244.5, 246, 247.5, 249, 250.5, 252, 253.5, 255, 256.5, 258, 259.5, 261, 262.5, 264, 265.5, 267, 268.5, 270, 271.5, 273, 274.5, 276, 277.5, 279, 280.5, 282, 283.5, 285, 286.5, 288, 289.5, 291, 292.5, 294, 295.5, 297, 298.5, 300, 301.5, 303, 304.5, 306, 307.5, 309, 310.5, 312, 313.5, 315, 316.5, 318, 319.5, 321, 322.5, 324, 325.5, 327, 328.5, 330, 331.5, 333, 334.5, 336, 337.5, 339, 340.5, 342, 343.5, 345, 346.5, 348, 349.5, 351, 352.5, 354, 355.5, 357, 358.5};
214       stat = nc_put_var_float(ncidlon_idlon);
215       check_err(stat,__LINE__,__FILE__);
216   }
217
218   { /* store lvl */
219       float lvl[] = {1000, 995, 990, 985, 975, 950, 925, 900, 875, 850, 800, 750, 700, 600, 500, 450, 400, 350, 300, 275, 250, 225, 200, 175, 150, 100, 70, 50, 30, 20, 10};
220       stat = nc_put_var_float(ncidlvl_idlvl);
221       check_err(stat,__LINE__,__FILE__);
222   }
223
224   { /* store sfc_pres */
225       size_t sfc_pres_start[RANK_sfc_pres];
226       size_t sfc_pres_count[RANK_sfc_pres];
227       float sfc_pres[LON_LEN*LAT_LEN];
228
229       for(ii = 0; ii < LAT_LEN * LON_LENii++) {
230    sfc_pres[ii] = 6;
231       }
232       sfc_pres_start[0] = 0;
233       sfc_pres_start[1] = 0;
234       sfc_pres_start[2] = 0;
235       sfc_pres_count[0] = time_len;
236       sfc_pres_count[1] = lat_len;
237       sfc_pres_count[2] = lon_len;
238       stat = nc_put_vara_float(ncidsfc_pres_idsfc_pres_startsfc_pres_countsfc_pres);
239       check_err(stat,__LINE__,__FILE__);
240   }
241
242   { /* store temp_scrn */
243       size_t temp_scrn_start[RANK_temp_scrn];
244       size_t temp_scrn_count[RANK_temp_scrn];
245       float temp_scrn[LON_LEN*LAT_LEN];
246
247       for(ii = 0; ii < LAT_LEN * LON_LENii++) {
248    temp_scrn[ii] = 11;
249       }
250       temp_scrn_start[0] = 0;
251       temp_scrn_start[1] = 0;
252       temp_scrn_start[2] = 0;
253       temp_scrn_count[0] = time_len;
254       temp_scrn_count[1] = lat_len;
255       temp_scrn_count[2] = lon_len;
256       stat = nc_put_vara_float(ncidtemp_scrn_idtemp_scrn_starttemp_scrn_counttemp_scrn);
257       check_err(stat,__LINE__,__FILE__);
258   }
259
260   { /* store qsair_scrn */
261       size_t qsair_scrn_start[RANK_qsair_scrn];
262       size_t qsair_scrn_count[RANK_qsair_scrn];
263       float qsair_scrn[LON_LEN*LAT_LEN];
264
265       for(ii = 0; ii < LAT_LEN * LON_LENii++) {
266    qsair_scrn[ii] = 22;
267       }
268       qsair_scrn_start[0] = 0;
269       qsair_scrn_start[1] = 0;
270       qsair_scrn_start[2] = 0;
271       qsair_scrn_count[0] = time_len;
272       qsair_scrn_count[1] = lat_len;
273       qsair_scrn_count[2] = lon_len;
274       stat = nc_put_vara_float(ncidqsair_scrn_idqsair_scrn_startqsair_scrn_countqsair_scrn);
275       check_err(stat,__LINE__,__FILE__);
276   }
277
278   { /* store topog */
279       size_t topog_start[RANK_topog];
280       size_t topog_count[RANK_topog];
281       float topog[LON_LEN*LAT_LEN];
282
283       for(ii = 0; ii < LAT_LEN * LON_LENii++) {
284    topog[ii] = 33;
285       }
286       topog_start[0] = 0;
287       topog_start[1] = 0;
288       topog_start[2] = 0;
289       topog_count[0] = time_len;
290       topog_count[1] = lat_len;
291       topog_count[2] = lon_len;
292       stat = nc_put_vara_float(ncidtopog_idtopog_starttopog_counttopog);
293       check_err(stat,__LINE__,__FILE__);
294   }
295
296   { /* store mslp */
297       size_t mslp_start[RANK_mslp];
298       size_t mslp_count[RANK_mslp];
299       float mslp[LON_LEN*LAT_LEN];
300
301       for(ii = 0; ii < LAT_LEN * LON_LENii++) {
302    mslp[ii] = 44;
303       }
304       mslp_start[0] = 0;
305       mslp_start[1] = 0;
306       mslp_start[2] = 0;
307       mslp_count[0] = time_len;
308       mslp_count[1] = lat_len;
309       mslp_count[2] = lon_len;
310       stat = nc_put_vara_float(ncidmslp_idmslp_startmslp_countmslp);
311       check_err(stat,__LINE__,__FILE__);
312   }
313
314   { /* store sfc_temp */
315       size_t sfc_temp_start[RANK_sfc_temp];
316       size_t sfc_temp_count[RANK_sfc_temp];
317       float sfc_temp[LON_LEN*LAT_LEN];
318
319       for(ii = 0; ii < LAT_LEN * LON_LENii++) {
320    sfc_temp[ii] = 55;
321       }
322       sfc_temp_start[0] = 0;
323       sfc_temp_start[1] = 0;
324       sfc_temp_start[2] = 0;
325       sfc_temp_count[0] = time_len;
326       sfc_temp_count[1] = lat_len;
327       sfc_temp_count[2] = lon_len;
328       stat = nc_put_vara_float(ncidsfc_temp_idsfc_temp_startsfc_temp_countsfc_temp);
329       check_err(stat,__LINE__,__FILE__);
330   }
331
332   {       /* store zonal_wnd */
333       /* Bug exposed when written in reverse order. */
334       for(i = LVL_LEN - 1; i>=0; i--)
335       /* for(i = 0; i < LVL_LEN; i++) */
336       {
337    int izw;
338    for(izw = 0; izw < TIME_LEN * LAT_LEN * LON_LENizw++) {
339        zonal_wnd[izw] = 100 + i;
340    }
341    zonal_wnd_start[0] = 0;
342    zonal_wnd_start[1] = i;
343    zonal_wnd_start[2] = 0;
344    zonal_wnd_start[3] = 0;
345    zonal_wnd_count[0] = time_len;
346    zonal_wnd_count[1] = 1;
347    zonal_wnd_count[2] = lat_len;
348    zonal_wnd_count[3] = lon_len;
349    stat = nc_put_vara_float(ncidzonal_wnd_idzonal_wnd_startzonal_wnd_countzonal_wnd);
350    check_err(stat,__LINE__,__FILE__);
351       }
352   }
353   stat = nc_close(ncid);
354   check_err(stat,__LINE__,__FILE__);
355   return 0;
356}
357
358int
359main(int argc, char **argv)
360{
361    size_t sizehint = 2100000; /* default if not set on command line,
362  * exposes bug.  It turns out any
363  * value between 2091953 and 2150032
364  * triggers bug, whereas all other
365  * values work fine. */
366#ifdef USE_PNETCDF
367    MPI_Init(&argc, &argv);
368#endif
369
370    if (argc > 1) {
371 char *endptr, *str = argv[1];
372 errno = 0;
373 sizehint = strtol(str, &endptr, 0);
374 /* check for various possible errors */
375 if ((errno == ERANGE && (sizehint == LONG_MAX || sizehint == LONG_MIN))
376                   || (errno != 0 && sizehint == 0)) {
377               perror("strtol");
378               exit(EXIT_FAILURE);
379 }
380 if (endptr == str) {
381     fprintf(stderr, "No digits were found\n");
382     exit(EXIT_FAILURE);
383 }
384    }
385   printf("\n*** Testing nofill mode.\n");
386   {
387       printf("*** Create file in nofill mode, writing all values...");
388       if (create_file(FILE_NAME1NC_NOFILL, &sizehint)) ERR;
389       SUMMARIZE_ERR;
390   }
391   {
392       printf("*** Create file with same data in fill mode, writing all values...");
393       if (create_file(FILE_NAME2NC_FILL, &sizehint)) ERR;
394       SUMMARIZE_ERR;
395   }
396   {
397       int ncid1ncid2;
398       int nvars1nvars2;
399       int varid;
400       int badvars;
401
402       printf("*** Compare values in nofill mode and fill mode files...");
403       /* compare data in two files created with nofill mode and fill
404 * mode, which should be identical if all the data were written */
405#ifdef USE_PNETCDF
406       if (nc_open_par(FILE_NAME1NC_NOWRITE|NC_PNETCDFMPI_COMM_WORLDMPI_INFO_NULL, &ncid1)) ERR;
407       if (nc_open_par(FILE_NAME2NC_NOWRITE|NC_PNETCDFMPI_COMM_WORLDMPI_INFO_NULL, &ncid2)) ERR;
408#else
409       if (nc_open(FILE_NAME1NC_NOWRITE, &ncid1)) ERR;
410       if (nc_open(FILE_NAME2NC_NOWRITE, &ncid2)) ERR;
411#endif
412       if (nc_inq_nvars(ncid1, &nvars1)) ERR;
413       if (nc_inq_nvars(ncid2, &nvars2)) ERR;
414       if (nvars1 != nvars2ERR;
415       badvars = 0;
416       for(varid = 0; varid < nvars1varid++) {
417    size_t nvalsnn;
418    int ndims, *dimidsdim;
419    nc_type vtype;
420    char varname1[NC_MAX_NAME];
421    char varname2[NC_MAX_NAME];
422    /* How many values in this variable to compare? */
423    if (nc_inq_varndims(ncid1varid, &ndims)) ERR;
424    dimids = malloc((ndims + 1) * sizeof(int));
425    if (!dimidsERR;
426    if (nc_inq_vardimid (ncid1variddimids)) ERR;
427    nvals = 1;
428    for(dim = 0; dim < ndimsdim++) {
429        size_t len;
430        if (nc_inq_dimlen(ncid1dimids[dim], &len)) ERR;
431        nvals *= len;
432    }
433    if (nc_inq_vartype(ncid1varid, &vtype)) ERR;
434    if (nc_inq_varname(ncid1varidvarname1)) ERR;
435    if (nc_inq_varname(ncid1varidvarname2)) ERR;
436
437    if (vtype != NC_CHAR) {  /* numeric data, just read in as doubles */
438        double *data1, *data2;
439        /* Allocate space to hold values in both files */
440        data1 = malloc((nvals + 1) * sizeof(double));
441        if (!data1ERR;
442        data2 = malloc((nvals + 1) * sizeof(double));
443        if (!data2ERR;
444        /* Read in values */
445        if (nc_get_var_double(ncid1variddata1)) ERR;
446        if (nc_get_var_double(ncid2variddata2)) ERR;
447        /* Compare values */
448        for(nn = 0; nn < nvalsnn++) {
449    if (data1[nn] != data2[nn]) {
450        badvars++;
451        fprintf(stderr,
452        "\tFrom nofill file, %s[%lu] = %.15g\tFrom fill file, %s[%lu] = %.15g\n",
453        varname1, (unsigned long)nndata1[nn], varname2, (unsigned long)nndata2[nn]);
454        break;
455    };
456        }
457        free(data1);
458        free(data2);
459    } else { /* character data */
460        char *data1, *data2;
461        /* Allocate space to hold values in both files */
462        data1 = malloc((nvals + 1) * sizeof(char));
463        if (!data1ERR;
464        data2 = malloc((nvals + 1) * sizeof(char));
465        if (!data2ERR;
466        /* Read in values */
467        if (nc_get_var_text(ncid1variddata1)) ERR;
468        if (nc_get_var_text(ncid2variddata2)) ERR;
469        /* Compare values */
470        for(nn = 0; nn < nvalsnn++) {
471    if (data1[nn] != data2[nn]) {
472        badvars++;
473        fprintf(stderr,
474        "\tFrom nofill file, %s[%lu] = %d\tFrom fill file, %s[%lu] = %d\n",
475        varname1, (unsigned long)nndata1[nn], varname2, (unsigned long)nndata2[nn]);
476        break;
477    };
478        }
479        free(data1);
480        free(data2);
481    }
482    free(dimids);
483       }
484       if(badvars > 0) ERR;
485       if (nc_close(ncid1)) ERR;
486       if (nc_close(ncid2)) ERR;
487       SUMMARIZE_ERR;
488   }
489   FINAL_RESULTS;
490#ifdef USE_PNETCDF
491   MPI_Finalize();
492#endif
493}


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed