forked from Unidata/netcdf-c
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tst_large_cdf5.c
201 lines (173 loc) · 5.89 KB
/
tst_large_cdf5.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*
Copyright 2017, UCAR/Unidata
See COPYRIGHT file for copying and redistribution conditions.
This program tests the large file bug in netCDF 3.6.2,
creating byte and short variables larger than 4 GiB.
This program is based on tst_large.c, and tests against
CDF5.
$Id: tst_large.c,v 1.16 2010/05/18 20:20:01 russ Exp $
*/
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <nc_tests.h>
#include "err_macros.h"
#include <netcdf.h>
/* Test with both classic and 64-bit offset files. If netcdf-4 is
* included, test with both netCDF-4 format variants also. */
#ifdef USE_NETCDF4
#define NUM_FORMATS (4)
#else
#define NUM_FORMATS (2)
#endif
#define NUMDIMS 2 /* rank of each variable in tests */
#define DIM1 2048
#define DIM2 2097153 /* DIM1*DIM2*sizeof(char) > 2**32 */
#define DIM3 1024
#define DIM4 2097153 /* DIM3*DIM4*sizeof(short) > 2**32 */
/*
* In netCDF-3.6.2, a divide by zero occurs on 32-bit platforms when
* creating a variable for which the product of dimensions is exactly
* 2**32. Check that this bug has been fixed.
*/
static int
test_big_var(const char *testfile) {
int ncid, varid, dimids[NUMDIMS];
int cflag = NC_CLOBBER;
nc_type type = NC_BYTE;
size_t index[NUMDIMS];
signed char nval = 99;
int nval_in;
/* Define the file with one large variable. */
if (nc_create(testfile, cflag, &ncid)) ERR;
if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR;
if (nc_def_dim(ncid, "dim1", DIM1, &dimids[0])) ERR;
if (nc_def_dim(ncid, "dim2", DIM2 - 1, &dimids[1])) ERR;
if (nc_def_var(ncid, "var", type, NUMDIMS, dimids, &varid)) ERR;
if (nc_enddef(ncid)) ERR;
/* Write one datum, near the end of the variable. */
index[0] = DIM1 - 1;
index[1] = DIM2 - 2;
if (nc_put_var1_schar(ncid, varid, index, &nval)) ERR;
if (nc_close(ncid)) ERR;
/* Reopen the file and check that datum. */
if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR;
if (nc_inq_varid(ncid, "var", &varid)) ERR;
if (nc_get_var1_int(ncid, varid, index, &nval_in)) ERR;
if (nval != nval_in)
ERR;
if (nc_close(ncid)) ERR;
return 0;
}
static int
test_large_byte_var(const char *testfile) {
int ncid, varid, dimids[NUMDIMS];
size_t index[NUMDIMS] = {0, 0};
signed char vals[DIM2];
signed char char_val_in;
size_t start[NUMDIMS], count[NUMDIMS];
int j;
if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR;
if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR;
if (nc_def_dim(ncid, "dim1", DIM1, &dimids[0])) ERR;
if (nc_def_dim(ncid, "dim2", DIM2, &dimids[1])) ERR;
if (nc_def_var(ncid, "var", NC_BYTE, NUMDIMS, dimids, &varid)) ERR;
if (nc_enddef(ncid)) ERR;
for (j = 0; j < DIM2; j++) {
vals[j] = 9 * (j + 11); /* note vals[j] is 99 when j==0 */
}
start[1] = 0;
count[0] = 1;
count[1] = DIM2;
for (start[0] = 0; start[0] < DIM1; start[0]++) {
if (nc_put_vara_schar(ncid, varid, start, count, vals))
{
ERR;
break;
}
}
if (nc_close(ncid)) ERR;
if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR;
if (nc_inq_varid(ncid, "var", &varid)) ERR;
if (nc_get_var1_schar(ncid, varid, index, &char_val_in)) ERR;
if (char_val_in != 99) /* see above, the value written when start[0]==0, j==0 */
ERR;
if (nc_close(ncid)) ERR;
return 0;
}
static int
test_large_short_var(const char *testfile) {
int ncid, varid, dimids[NUMDIMS];
int int_val_in, int_val_out = 99;
size_t index[2];
int cflag = NC_CLOBBER;
if (nc_create(testfile, cflag, &ncid)) ERR;
if (nc_def_dim(ncid, "dim3", DIM3, &dimids[0])) ERR;
if (nc_def_dim(ncid, "dim4", DIM4, &dimids[1])) ERR;
if (nc_def_var(ncid, "var", NC_SHORT, NUMDIMS, dimids, &varid)) ERR;
if (nc_enddef(ncid)) ERR;
index[0] = 0;
index[1] = 1;
if (nc_put_var1_int(ncid, varid, index, &int_val_out)) ERR;
if (nc_close(ncid)) ERR;
if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR;
if (nc_inq_varid(ncid, "var", &varid)) ERR;
if (nc_get_var1_int(ncid, varid, index, &int_val_in)) ERR;
if (int_val_in != int_val_out)
ERR;
#ifndef NOFILL
index[0] = 1;
index[1] = 2;
if (nc_get_var1_int(ncid, varid, index, &int_val_in)) ERR;
if (int_val_in != NC_FILL_SHORT)
ERR;
#endif
if (nc_close(ncid)) ERR;
return 0;
}
#define FILE_NAME "tst_large_cdf5.nc"
int
main(int argc, char **argv) {
int i;
char testfile[NC_MAX_NAME + 1];
sprintf(testfile, "%s/%s", TEMP_LARGE, FILE_NAME);
printf("\n*** Testing fix for 3.6.2 large file bug in %s.\n",
testfile);
/* Go thru formats and run all tests for each of two (for netCDF-3
* only builds), or 4 (for netCDF-4 builds) different formats. */
for (i = NC_FORMAT_CLASSIC; i <= NUM_FORMATS; i++)
{
nc_set_default_format(i, NULL);
printf("*** testing format %d with a variable with 2**32 values...", i);
test_big_var(testfile);
(void) remove(testfile);
SUMMARIZE_ERR;
printf("*** testing format %d with a byte variable with > 2**32 values...", i);
test_large_byte_var(testfile);
(void) remove(testfile);
SUMMARIZE_ERR;
printf("*** testing format %d with a short variable with > 2**32 values...", i);
test_large_short_var(testfile);
(void) remove(testfile);
SUMMARIZE_ERR;
}
/* Test CDF5 */
{
i = NC_64BIT_DATA;
nc_set_default_format(i, NULL);
printf("*** testing format %d with a variable with 2**32 values...", i);
test_big_var(testfile);
(void) remove(testfile);
SUMMARIZE_ERR;
printf("*** testing format %d with a byte variable with > 2**32 values...", i);
test_large_byte_var(testfile);
(void) remove(testfile);
SUMMARIZE_ERR;
printf("*** testing format %d with a short variable with > 2**32 values...", i);
test_large_short_var(testfile);
(void) remove(testfile);
SUMMARIZE_ERR;
}
FINAL_RESULTS;
}