1 /*********************************************************************
2 *
3 * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
4 * See COPYRIGHT notice in top-level directory.
5 *
6 *********************************************************************/
7 /* $Id: test_bput.c 2744 2016-12-28 16:25:22Z wkliao $ */
8
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <libgen.h> /* basename() */
13 #include <assert.h>
14 #include <pnetcdf.h>
15
16 #include <testutils.h>
17
18 #define FILE_NAME "testfile.nc"
19
20 #define ERR if (err!=NC_NOERR) {printf("Error at line %d: err=%d %s\n", __LINE__, err, ncmpi_strerror(err)); nerrs++;}
21
22 /*----< main() >------------------------------------------------------------*/
main(int argc,char ** argv)23 int main(int argc, char **argv) {
24 int i, j, ncid, dimid[2], varid, err, nerrs=0, rank, nprocs;
25 int req[2], status[2];
26 float var[4][6];
27 char filename[256];
28 MPI_Offset bufsize, start[2], count[2], stride[2], imap[2];
29 MPI_Info info;
30
31 MPI_Init(&argc, &argv);
32 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
33 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
34
35 #ifdef DEBUG
36 if (nprocs > 1 && rank == 0)
37 printf("Warning: %s is designed to run on 1 process\n", argv[0]);
38 #endif
39
40 if (argc > 2) {
41 if (!rank) printf("Usage: %s [filename]\n",argv[0]);
42 MPI_Finalize();
43 return 0;
44 }
45 if (argc == 2) snprintf(filename, 256, "%s", argv[1]);
46 else strcpy(filename, "testfile.nc");
47
48 if (rank == 0) {
49 char *cmd_str = (char*)malloc(strlen(argv[0]) + 256);
50 sprintf(cmd_str, "*** TESTING C %s for bput API ", basename(argv[0]));
51 printf("%-66s ------ ", cmd_str);
52 free(cmd_str);
53 }
54
55 MPI_Info_create(&info);
56 /* MPI_Info_set(info, "romio_pvfs2_posix_write","enable"); */
57
58 err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER | NC_64BIT_DATA, info, &ncid); ERR
59 MPI_Info_free(&info);
60
61 /* define a variable of a 6 x 4 integer array in the nc file */
62 err = ncmpi_def_dim(ncid, "Y", 6, &dimid[0]); ERR
63 err = ncmpi_def_dim(ncid, "X", 4, &dimid[1]); ERR
64 err = ncmpi_def_var(ncid, "var", NC_INT64, 2, dimid, &varid); ERR
65 err = ncmpi_enddef(ncid); ERR
66
67 /* set the contents of the write buffer var, a 4 x 6 float array
68 50, 51, 52, 53, 54, 55,
69 56, 57, 58, 59, 60, 61,
70 62, 63, 64, 65, 66, 67,
71 68, 69, 70, 71, 72, 73
72 */
73 for (j=0; j<4; j++) for (i=0; i<6; i++) var[j][i] = 50.5 + j*6+i;
74
75 /* bufsize must be max of data type converted before and after */
76 bufsize = 4*6*sizeof(long long);
77 err = ncmpi_buffer_attach(ncid, bufsize); ERR
78
79 /* write var to the NC variable in the matrix transposed way */
80 count[0] = 6; count[1] = 2;
81 stride[0] = 1; stride[1] = 1;
82 imap[0] = 1; imap[1] = 6; /* would be {4, 1} if not transposing */
83
84 if (rank > 0) /* non-root processes just participate the call */
85 count[0] = count[1] = 0;
86
87 /* write the first two columns of the NC variable in the matrix transposed way */
88 start[0] = 0; start[1] = 0;
89 err = ncmpi_bput_varm_float(ncid, varid, start, count, stride, imap, &var[0][0], &req[0]); ERR
90
91 /* check if write buffer contents have been altered */
92 for (j=0; j<4; j++)
93 for (i=0; i<6; i++) {
94 if (var[j][i] != 50.5 + j*6+i) {
95 printf("Error: put buffer[%d][%d]=%f altered, should be %f\n",
96 j,i,var[j][i],50.5+j*6+i);
97 nerrs++;
98 }
99 }
100
101 /* write the second two columns of the NC variable in the matrix transposed way */
102 start[0] = 0; start[1] = 2;
103 err = ncmpi_bput_varm_float(ncid, varid, start, count, stride, imap, &var[2][0], &req[1]); ERR
104
105 /* check if write buffer contents have been altered */
106 for (j=0; j<4; j++)
107 for (i=0; i<6; i++) {
108 if (var[j][i] != 50.5 + j*6+i) {
109 printf("Error: put buffer[%d][%d]=%f altered, should be %f\n",
110 j,i,var[j][i],50.5+j*6+i);
111 nerrs++;
112 }
113 }
114
115 err = ncmpi_wait_all(ncid, 2, req, status); ERR
116
117 /* check each bput status */
118 for (i=0; i<2; i++)
119 if (status[i] != NC_NOERR) {
120 printf("Error at line %d: err=%d %s\n", __LINE__, status[i], ncmpi_strerror(err));
121 nerrs++;
122 }
123
124 err = ncmpi_buffer_detach(ncid); ERR
125
126 /* the output from command "ncmpidump -v var test.nc" should be:
127 var =
128 50, 56, 62, 68,
129 51, 57, 63, 69,
130 52, 58, 64, 70,
131 53, 59, 65, 71,
132 54, 60, 66, 72,
133 55, 61, 67, 73 ;
134 */
135
136 /* check if the contents of write buffer have been altered (should not be) */
137 for (j=0; j<4; j++) {
138 for (i=0; i<6; i++) {
139 if (var[j][i] != 50.5+j*6+i) {
140 /* this error is a pntecdf internal error, if occurs */
141 printf("Error: put buffer[%d][%d]=%f altered, should be %f\n",
142 j,i,var[j][i],50.5+j*6+i);
143 nerrs++;
144 break;
145 }
146 }
147 }
148 err = ncmpi_close(ncid); ERR
149
150 /* check if PnetCDF freed all internal malloc */
151 MPI_Offset malloc_size, sum_size;
152 err = ncmpi_inq_malloc_size(&malloc_size);
153 if (err == NC_NOERR) {
154 MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
155 if (rank == 0 && sum_size > 0)
156 printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
157 sum_size);
158 }
159
160 MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
161 if (rank == 0) {
162 if (nerrs) printf(FAIL_STR,nerrs);
163 else printf(PASS_STR);
164 }
165
166 MPI_Finalize();
167
168 return nerrs;
169 }
170
171