1 /*********************************************************************
2  *
3  *  Copyright (C) 2016, Northwestern University and Argonne National Laboratory
4  *  See COPYRIGHT notice in top-level directory.
5  *
6  *********************************************************************/
7 /* $Id$ */
8 
9 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
10  *
11  * This program is to test CDF-1, CDF-2 file formats using the allowable
12  * maximal dimension size
13  *
14  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h> /* strcpy() */
19 #include <libgen.h> /* basename() */
20 #include <limits.h>
21 #include <mpi.h>
22 #include <pnetcdf.h>
23 #include <testutils.h>
24 
25 #define FOUR_G 4294967296
26 #define TWO_G  2147483648
27 #define ONE_G  1073741824
28 
29 #define NZ 4
30 #define NY 10
31 #define NX TWO_G
32 
33 #define ERR if (err!=NC_NOERR) {printf("Error at line %d: err=%s (%s)\n", __LINE__,nc_err_code_name(err),ncmpi_strerror(err)); nerrs++;}
34 
35 #define ERR_EXPECT(exp) if (err!=exp) {printf("Error at line %d: expect error %s but got %s\n", __LINE__,nc_err_code_name(exp),nc_err_code_name(err)); nerrs++;}
36 
main(int argc,char ** argv)37 int main(int argc, char** argv)
38 {
39     char filename[256];
40     int rank, nprocs, err, nerrs=0;
41     int ncid, cmode, varid, dimid[3];
42 
43     MPI_Init(&argc, &argv);
44     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
45     MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
46 
47     /* get command-line arguments */
48     if (argc > 2) {
49         if (!rank) printf("Usage: %s [filename]\n",argv[0]);
50         MPI_Finalize();
51         return 0;
52     }
53     if (argc == 2) snprintf(filename, 256, "%s", argv[1]);
54     else           strcpy(filename, "testfile.nc");
55     MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
56 
57     if (rank == 0) {
58         char *cmd_str = (char*)malloc(strlen(argv[0]) + 256);
59         sprintf(cmd_str, "*** TESTING C   %s for defining dim in CDF-1/2 format ", basename(argv[0]));
60         printf("%-66s ------ ", cmd_str); fflush(stdout);
61         free(cmd_str);
62     }
63 
64     /* create a new CDF-1 file ----------------------------------------------*/
65     cmode = NC_CLOBBER;
66 
67     /* max dimension size for CDF-2 file is 2^31-3 = 2147483647 - 3 */
68     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
69     err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]);
70     ERR_EXPECT(NC_EDIMSIZE)
71     err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); ERR
72     err = ncmpi_close(ncid); ERR
73     err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
74     err = ncmpi_close(ncid); ERR
75 
76     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
77     err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); ERR
78     err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, dimid, &varid); ERR
79     err = ncmpi_close(ncid); ERR
80     err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
81     err = ncmpi_close(ncid); ERR
82 
83     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
84     err = ncmpi_def_dim(ncid, "Y", INT_MAX-3,  &dimid[0]); ERR
85     err = ncmpi_def_dim(ncid, "X", 2,          &dimid[1]); ERR
86     err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); ERR
87     err = ncmpi_def_var(ncid, "var1", NC_INT,  1, &dimid[1], &varid); ERR
88     err = ncmpi_close(ncid);
89     ERR_EXPECT(NC_EVARSIZE)
90 
91     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
92     err = ncmpi_def_dim(ncid, "Y", INT_MAX-1024,  &dimid[0]); ERR
93     err = ncmpi_def_dim(ncid, "X", 2,             &dimid[1]); ERR
94     err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); ERR
95     err = ncmpi_def_var(ncid, "var1", NC_INT,  1, &dimid[1], &varid); ERR
96     err = ncmpi_close(ncid); ERR
97     err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
98     err = ncmpi_close(ncid); ERR
99 
100     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
101     err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); ERR
102     err = ncmpi_def_dim(ncid, "X", 2,         &dimid[1]); ERR
103     err = ncmpi_def_var(ncid, "var0", NC_SHORT, 1, &dimid[0], &varid); ERR
104     err = ncmpi_def_var(ncid, "var1", NC_CHAR,  1, &dimid[1], &varid); ERR
105     err = ncmpi_close(ncid);
106     ERR_EXPECT(NC_EVARSIZE)
107 
108     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
109     err = ncmpi_def_dim(ncid, "Y", INT_MAX-3-512-8, &dimid[0]); ERR
110     err = ncmpi_def_dim(ncid, "X", 2,       &dimid[1]); ERR
111     err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); ERR
112     err = ncmpi_def_var(ncid, "var1", NC_INT,  1, &dimid[1], &varid); ERR
113     err = ncmpi_close(ncid); ERR
114 
115     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
116     err = ncmpi_def_dim(ncid, "Y", INT_MAX/2+1, &dimid[0]); ERR
117     err = ncmpi_def_dim(ncid, "X", 2,           &dimid[1]); ERR
118     err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); ERR
119     err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
120     err = ncmpi_close(ncid);
121     ERR_EXPECT(NC_EVARSIZE)
122 
123     /* create a new CDF-2 file ----------------------------------------------*/
124     cmode = NC_CLOBBER;
125     cmode = NC_CLOBBER | NC_64BIT_OFFSET;
126 
127     /* max dimension size for CDF-2 file is 2^32-3 = 4294967295 - 3 */
128     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
129     err = ncmpi_def_dim(ncid, "Y", UINT_MAX, &dimid[0]);
130     ERR_EXPECT(NC_EDIMSIZE)
131     err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); ERR
132     err = ncmpi_close(ncid); ERR
133     err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
134     err = ncmpi_close(ncid); ERR
135 
136     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
137     err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); ERR
138     err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, dimid, &varid); ERR
139     err = ncmpi_close(ncid); ERR
140     err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
141     err = ncmpi_close(ncid); ERR
142 
143     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
144     err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); ERR
145     err = ncmpi_def_dim(ncid, "X", 2,          &dimid[1]); ERR
146     err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); ERR
147     err = ncmpi_def_var(ncid, "var1", NC_INT,  1, &dimid[1], &varid); ERR
148     err = ncmpi_close(ncid); ERR
149     err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
150     err = ncmpi_close(ncid); ERR
151 
152     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
153     err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); ERR
154     err = ncmpi_def_dim(ncid, "X", 2,          &dimid[1]); ERR
155     err = ncmpi_def_var(ncid, "var0", NC_SHORT, 1, &dimid[0], &varid); ERR
156     err = ncmpi_def_var(ncid, "var1", NC_INT,   1, &dimid[1], &varid); ERR
157     err = ncmpi_close(ncid);
158     ERR_EXPECT(NC_EVARSIZE)
159 
160     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
161     err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); ERR
162     err = ncmpi_def_dim(ncid, "X", 2,       &dimid[1]); ERR
163     err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); ERR
164     err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
165     err = ncmpi_close(ncid);
166     ERR_EXPECT(NC_EVARSIZE)
167 
168     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
169     err = ncmpi_def_dim(ncid, "Y", INT_MAX/2+1, &dimid[0]); ERR
170     err = ncmpi_def_dim(ncid, "X", 2,           &dimid[1]); ERR
171     err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); ERR
172     err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
173     err = ncmpi_close(ncid);
174     ERR_EXPECT(NC_EVARSIZE)
175 
176     err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
177     err = ncmpi_def_dim(ncid, "Y", INT_MAX/2, &dimid[0]); ERR
178     err = ncmpi_def_dim(ncid, "X", 2,         &dimid[1]); ERR
179     err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); ERR
180     err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
181     err = ncmpi_close(ncid); ERR
182     err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
183     err = ncmpi_close(ncid); ERR
184 
185     /* check if PnetCDF freed all internal malloc */
186     MPI_Offset malloc_size, sum_size;
187     err = ncmpi_inq_malloc_size(&malloc_size);
188     if (err == NC_NOERR) {
189         MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
190         if (rank == 0 && sum_size > 0)
191             printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
192                    sum_size);
193     }
194 
195     MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
196     if (rank == 0) {
197         if (nerrs) printf(FAIL_STR,nerrs);
198         else       printf(PASS_STR);
199     }
200 
201     MPI_Finalize();
202     return (nerrs) ? 2 : 0;
203 }
204 
205