1 /*
2 * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
3 * See COPYRIGHT notice in top-level directory.
4 *
5 * $Id: one_record.c 2744 2016-12-28 16:25:22Z wkliao $
6 */
7
8 /*
9 * This program tests the special case of ONLY one record variable is defined
10 * and the record size is not aligned with the 4-byte boundary. As defined in
11 * CDF-1 and CDF-2 format specifications:
12 * "A special case: Where there is exactly one record variable, we drop the
13 * requirement that each record be four-byte aligned, so in this case there
14 * is no record padding."
15 *
16 */
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <libgen.h> /* basename() */
22 #include <pnetcdf.h>
23
24 #include <testutils.h>
25
26 #define ERRCODE 2
27 #define ERR if (err != NC_NOERR) {printf("Error at line %d: err=%d %s\n", __LINE__, err, ncmpi_strerror(err));}
28
29 #define STR_LEN 19
30 #define NUM_VALS 2
31
32 /*----< main() >------------------------------------------------------------*/
main(int argc,char ** argv)33 int main(int argc, char **argv)
34 {
35 char filename[256];
36 int i, err, nerrs=0, rank, nprocs, cmode;
37 int ncid, dimids[2], varid;
38 char data[NUM_VALS][STR_LEN + 1], data_in[NUM_VALS*STR_LEN];
39 MPI_Offset start[2];
40 MPI_Offset count[2];
41
42 MPI_Init(&argc, &argv);
43 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
44 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
45
46 if (argc > 2) {
47 if (!rank) printf("Usage: %s [filename]\n",argv[0]);
48 MPI_Finalize();
49 return 0;
50 }
51 if (argc == 2) snprintf(filename, 256, "%s", argv[1]);
52 else strcpy(filename, "testfile.nc");
53
54 if (rank == 0) {
55 char *cmd_str = (char*)malloc(strlen(argv[0]) + 256);
56 sprintf(cmd_str, "*** TESTING C %s for only one record variable ", basename(argv[0]));
57 printf("%-66s ------ ", cmd_str); fflush(stdout);
58 free(cmd_str);
59 }
60
61 strcpy(data[0], "2005-04-11_12:00:00"); /* 19 bytes not a multiply of 4 */
62 strcpy(data[1], "2005-04-11_13:00:00");
63
64 cmode = NC_CLOBBER;
65 err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
66
67 err = ncmpi_def_dim(ncid, "time", NC_UNLIMITED, dimids); ERR
68 err = ncmpi_def_dim(ncid, "text_dim", STR_LEN, &dimids[1]); ERR
69
70 /* create ONLY one record variable of type NC_CHAR and make sure each
71 * record is of size not aligned with 4-byte boundary.
72 */
73 err = ncmpi_def_var(ncid, "text_var", NC_CHAR, 2, dimids, &varid); ERR
74 err = ncmpi_enddef(ncid); ERR
75
76 /* Write some records of var data. */
77 count[0] = 1;
78 count[1] = STR_LEN;
79 start[0] = 0;
80 start[1] = 0;
81 for (i=0; i<NUM_VALS; i++) {
82 err = ncmpi_put_vara_text_all(ncid, varid, start, count, data[start[0]]);
83 ERR
84 start[0]++;
85 }
86
87 /* read the entire data back */
88 err = ncmpi_get_var_text_all(ncid, varid, data_in); ERR
89
90 /* check the contents */
91 for (i=0; i<NUM_VALS; i++)
92 if (strncmp(data[i], data_in+i*STR_LEN, STR_LEN)) {
93 printf("Error: expecting %s but got %s\n", data[i],data_in+i*STR_LEN);
94 nerrs++;
95 }
96
97 err = ncmpi_close(ncid);
98 ERR
99
100 /* check if PnetCDF freed all internal malloc */
101 MPI_Offset malloc_size, sum_size;
102 err = ncmpi_inq_malloc_size(&malloc_size);
103 if (err == NC_NOERR) {
104 MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
105 if (rank == 0 && sum_size > 0)
106 printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
107 sum_size);
108 }
109
110 MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
111 if (rank == 0) {
112 if (nerrs) printf(FAIL_STR,nerrs);
113 else printf(PASS_STR);
114 }
115
116 MPI_Finalize();
117
118 return nerrs;
119 }
120
121