2121 *
2222 * % mpicc -O2 -o flexible_bput flexible_bput.c -lpnetcdf
2323 *
24- * % mpiexec -l -n 4 ./flexible_bput /pvfs2/wkliao/testfile.nc
24+ * % mpiexec -l -n 4 ./flexible_bput -l 4 /pvfs2/wkliao/testfile.nc
2525 *
2626 * % ncmpidump /pvfs2/wkliao/testfile.nc
2727 * netcdf testfile {
4848#include <stdlib.h>
4949#include <string.h> /* strcpy() */
5050#include <libgen.h> /* basename() */
51+ #include <unistd.h> /* getopt() */
5152#include <assert.h>
53+
5254#include <mpi.h>
5355#include <pnetcdf.h>
5456
5557#include <testutils.h>
5658
5759#define NY 6
58- #define NX 4
60+ #define NX 70
5961#define GHOST 2
6062
6163#define INIT_PUT_BUF (buf ) \
7880 printf("Error at line %d in %s: put buffer altered buffer[%d][%d]=%f\n", \
7981 __LINE__,__FILE__,i,j,(double)buf[i][j]); \
8082 nerrs++; \
83+ goto err_out; \
8184 } \
8285 } \
8386 else { \
8487 if (buf[i][j] != (i-GHOST)*array_of_subsizes[1]+(j-GHOST)) { \
8588 printf("Error at line %d in %s: put buffer altered buffer[%d][%d]=%f\n", \
8689 __LINE__,__FILE__,i,j,(double)buf[i][j]); \
8790 nerrs++; \
91+ goto err_out; \
8892 } \
8993 } \
9094 } \
101105 if (i < GHOST || GHOST+array_of_subsizes[0] <= i || \
102106 j < GHOST || GHOST+array_of_subsizes[1] <= j) { \
103107 if (buf[i][j] != -2) { \
104- printf("Error at line %d in %s: unexpected get buffer[%d][%d]= %f\n", \
105- __LINE__,__FILE__,i,j,(double)buf[i][j]); \
108+ printf("Error at line %d in %s: expect buffer[%d][%d] to be %d but got %f\n", \
109+ __LINE__,__FILE__,i,j,-2, (double)buf[i][j]); \
106110 nerrs++; \
111+ goto err_out; \
107112 } \
108113 } \
109114 else { \
110- if (buf[i][j] != (i-GHOST)*array_of_subsizes[1]+(j-GHOST)) { \
111- printf("Error at line %d in %s: unexpected get buffer[%d][%d]=%f\n", \
112- __LINE__,__FILE__,i,j,(double)buf[i][j]); \
115+ int exp = (i-GHOST)*array_of_subsizes[1]+(j-GHOST); \
116+ if (buf[i][j] != exp) { \
117+ printf("Error at line %d in %s: expect buffer[%d][%d] to be %d but got %f\n", \
118+ __LINE__,__FILE__,i,j,exp,(double)buf[i][j]); \
113119 nerrs++; \
120+ goto err_out; \
114121 } \
115122 } \
116123 } \
117124 }
118125
119- int main (int argc , char * * argv )
126+ static
127+ int tst_run (const char * filename , int coll_io , int len )
120128{
121- char filename [256 ];
122129 int i , j , rank , nprocs , err , nerrs = 0 , req , status ;
123130 int ncid , cmode , varid , dimid [2 ];
124131 int array_of_sizes [2 ], array_of_subsizes [2 ], array_of_starts [2 ];
125- int buf_int [ NX + 2 * GHOST ][ NY + 2 * GHOST ] ;
126- double buf_dbl [ NX + 2 * GHOST ][ NY + 2 * GHOST ] ;
132+ int * * buf_int ;
133+ double * * buf_dbl ;
127134 MPI_Offset start [2 ], count [2 ], stride [2 ], imap [2 ];
128135 MPI_Datatype subarray ;
129136
130- MPI_Init (& argc , & argv );
131137 MPI_Comm_rank (MPI_COMM_WORLD , & rank );
132138 MPI_Comm_size (MPI_COMM_WORLD , & nprocs );
133139
134- if (argc > 2 ) {
135- if (!rank ) printf ("Usage: %s [filename]\n" ,argv [0 ]);
136- MPI_Finalize ();
137- return 1 ;
138- }
139- if (argc == 2 ) snprintf (filename , 256 , "%s" , argv [1 ]);
140- else strcpy (filename , "testfile.nc" );
141- MPI_Bcast (filename , 256 , MPI_CHAR , 0 , MPI_COMM_WORLD );
140+ buf_int = (int * * ) malloc (sizeof (int * ) * (len + 2 * GHOST ));
141+ buf_int [0 ] = (int * ) malloc (sizeof (int ) * (len + 2 * GHOST ) * (NY + 2 * GHOST ));
142+ for (i = 1 ; i < (len + 2 * GHOST ); i ++ )
143+ buf_int [i ] = buf_int [i - 1 ] + (NY + 2 * GHOST );
142144
143- if (rank == 0 ) {
144- char * cmd_str = (char * )malloc (strlen (argv [0 ]) + 256 );
145- sprintf (cmd_str , "*** TESTING C %s for flexible bput_varm " , basename (argv [0 ]));
146- printf ("%-66s ------ " , cmd_str );
147- free (cmd_str );
148- }
145+ buf_dbl = (double * * ) malloc (sizeof (double * ) * (len + 2 * GHOST ));
146+ buf_dbl [0 ] = (double * ) malloc (sizeof (double ) * (len + 2 * GHOST ) * (NY + 2 * GHOST ));
147+ for (i = 1 ; i < (len + 2 * GHOST ); i ++ )
148+ buf_dbl [i ] = buf_dbl [i - 1 ] + (NY + 2 * GHOST );
149149
150150 /* create a new file for writing ----------------------------------------*/
151151 cmode = NC_CLOBBER | NC_64BIT_DATA ;
152152 err = ncmpi_create (MPI_COMM_WORLD , filename , cmode , MPI_INFO_NULL , & ncid );
153153 CHECK_ERR
154154
155155 /* define 2 dimensions */
156- err = ncmpi_def_dim (ncid , "Y" , NY , & dimid [0 ]); CHECK_ERR
157- err = ncmpi_def_dim (ncid , "X" , NX * nprocs , & dimid [1 ]); CHECK_ERR
156+ err = ncmpi_def_dim (ncid , "Y" , NY , & dimid [0 ]); CHECK_ERR
157+ err = ncmpi_def_dim (ncid , "X" , len * nprocs , & dimid [1 ]); CHECK_ERR
158158
159- /* define a variable of size NY * (NX * nprocs) */
159+ /* define a variable of size NY * (len * nprocs) */
160160 err = ncmpi_def_var (ncid , "var" , NC_DOUBLE , 2 , dimid , & varid ); CHECK_ERR
161161 err = ncmpi_enddef (ncid ); CHECK_ERR
162162
163- start [0 ] = 0 ; start [1 ] = NX * rank ;
164- count [0 ] = NY ; count [1 ] = NX ;
163+ if (!coll_io ) {
164+ err = ncmpi_begin_indep_data (ncid );
165+ CHECK_ERR
166+ }
167+
168+ start [0 ] = 0 ; start [1 ] = len * rank ;
169+ count [0 ] = NY ; count [1 ] = len ;
165170 stride [0 ] = 1 ; stride [1 ] = 1 ;
166- imap [0 ] = 1 ; imap [1 ] = NY ; /* would be {NX , 1} if not transposing */
171+ imap [0 ] = 1 ; imap [1 ] = NY ; /* would be {len , 1} if not transposing */
167172
168173 /* var is partitioned along X dimension in a matrix transported way */
169- array_of_sizes [0 ] = NX + 2 * GHOST ;
174+ array_of_sizes [0 ] = len + 2 * GHOST ;
170175 array_of_sizes [1 ] = NY + 2 * GHOST ;
171- array_of_subsizes [0 ] = NX ;
176+ array_of_subsizes [0 ] = len ;
172177 array_of_subsizes [1 ] = NY ;
173178 array_of_starts [0 ] = GHOST ;
174179 array_of_starts [1 ] = GHOST ;
@@ -184,13 +189,18 @@ int main(int argc, char** argv)
184189 for (i = 0 ; i < 2 ; i ++ ) bufsize *= count [i ];
185190 err = ncmpi_buffer_attach (ncid , bufsize ); CHECK_ERR
186191
187- err = ncmpi_bput_varm (ncid , varid , start , count , stride , imap , buf_int ,
192+ err = ncmpi_bput_varm (ncid , varid , start , count , stride , imap , buf_int [ 0 ] ,
188193 1 , subarray , & req );
189194 CHECK_ERR
190195 /* check if the contents of put buffer are altered */
191196 CHECK_PUT_BUF (buf_int )
192197
193- err = ncmpi_wait_all (ncid , 1 , & req , & status ); CHECK_ERR
198+ if (coll_io )
199+ err = ncmpi_wait_all (ncid , 1 , & req , & status );
200+ else
201+ err = ncmpi_wait (ncid , 1 , & req , & status );
202+
203+ CHECK_ERR
194204 err = status ; CHECK_ERR
195205
196206 /* check the contents of put buffer are altered */
@@ -202,11 +212,20 @@ int main(int argc, char** argv)
202212 /* initiate get buffer contents */
203213 INIT_GET_BUF (buf_int )
204214
205- /* calling a blocking flexible API */
206- err = ncmpi_get_varm_all (ncid , varid , start , count , stride , imap , buf_int ,
207- 1 , subarray );
215+ if (!coll_io ) {
216+ /* calling a blocking flexible API */
217+ err = ncmpi_end_indep_data (ncid );
218+ CHECK_ERR
219+ }
220+ err = ncmpi_get_varm_all (ncid , varid , start , count , stride , imap ,
221+ buf_int [0 ], 1 , subarray );
208222 CHECK_ERR
209223
224+ if (!coll_io ) {
225+ err = ncmpi_begin_indep_data (ncid );
226+ CHECK_ERR
227+ }
228+
210229 /* check the contents of get buffer */
211230 CHECK_GET_BUF (buf_int )
212231
@@ -224,14 +243,18 @@ int main(int argc, char** argv)
224243
225244 err = ncmpi_buffer_attach (ncid , bufsize ); CHECK_ERR
226245
227- err = ncmpi_bput_varm (ncid , varid , start , count , stride , imap , buf_dbl ,
246+ err = ncmpi_bput_varm (ncid , varid , start , count , stride , imap , buf_dbl [ 0 ] ,
228247 1 , subarray , & req );
229248 CHECK_ERR
230249
231250 /* check the contents of put buffer are altered */
232251 CHECK_PUT_BUF (buf_dbl )
233252
234- err = ncmpi_wait_all (ncid , 1 , & req , & status ); CHECK_ERR
253+ if (coll_io )
254+ err = ncmpi_wait_all (ncid , 1 , & req , & status );
255+ else
256+ err = ncmpi_wait (ncid , 1 , & req , & status );
257+ CHECK_ERR
235258 err = status ; CHECK_ERR
236259
237260 /* check the contents of put buffer are altered */
@@ -244,17 +267,80 @@ int main(int argc, char** argv)
244267 INIT_GET_BUF (buf_dbl )
245268
246269 /* calling a blocking flexible API */
247- err = ncmpi_get_varm_all (ncid , varid , start , count , stride , imap , buf_dbl ,
248- 1 , subarray );
270+ if (coll_io )
271+ err = ncmpi_get_varm_all (ncid , varid , start , count , stride , imap ,
272+ buf_dbl [0 ], 1 , subarray );
273+ else
274+ err = ncmpi_get_varm (ncid , varid , start , count , stride , imap ,
275+ buf_dbl [0 ], 1 , subarray );
249276 CHECK_ERR
250277
251278 /* check the contents of get buffer */
252279 CHECK_GET_BUF (buf_dbl )
253280
281+ err_out :
254282 MPI_Type_free (& subarray );
255283
256284 err = ncmpi_close (ncid ); CHECK_ERR
257285
286+ free (buf_int [0 ]);
287+ free (buf_int );
288+ free (buf_dbl [0 ]);
289+ free (buf_dbl );
290+
291+ return nerrs ;
292+ }
293+
294+ #define FILE_NAME "testfile .nc "
295+
296+ static void
297+ usage (char * argv0 )
298+ {
299+ char * help =
300+ "Usage: %s [OPTIONS]...[filename]\n"
301+ " [-h] Print help\n"
302+ " [-l num]: X dimension size of local array\n"
303+ " [filename]: output netCDF file name (default: %s)\n" ;
304+ fprintf (stderr , help , argv0 , FILE_NAME );
305+ }
306+
307+ int main (int argc , char * * argv )
308+ {
309+ extern int optind ;
310+ extern char * optarg ;
311+ char filename [256 ];
312+ int i , len , rank , nprocs , nerrs = 0 , err = 0 ;
313+
314+ MPI_Init (& argc , & argv );
315+ MPI_Comm_rank (MPI_COMM_WORLD , & rank );
316+ MPI_Comm_size (MPI_COMM_WORLD , & nprocs );
317+
318+ len = NX ;
319+ while ((i = getopt (argc , argv , "hl:" )) != EOF )
320+ switch (i ) {
321+ case 'l' : len = atoi (optarg );
322+ break ;
323+ case 'h' :
324+ default : if (rank == 0 ) usage (argv [0 ]);
325+ MPI_Finalize ();
326+ return 1 ;
327+ }
328+ if (argv [optind ] == NULL ) strcpy (filename , FILE_NAME );
329+ else snprintf (filename , 256 , "%s" , argv [optind ]);
330+
331+ if (rank == 0 ) {
332+ char * cmd_str = (char * )malloc (strlen (argv [0 ]) + 256 );
333+ sprintf (cmd_str , "*** TESTING C %s for flexible bput_varm " , basename (argv [0 ]));
334+ printf ("%-66s ------ " , cmd_str );
335+ free (cmd_str );
336+ }
337+
338+ nerrs = tst_run (filename , 0 , len );
339+ if (nerrs != 0 ) goto err_out ;
340+
341+ nerrs = tst_run (filename , 1 , len );
342+ if (nerrs != 0 ) goto err_out ;
343+
258344 /* check if PnetCDF freed all internal malloc */
259345 MPI_Offset malloc_size , sum_size ;
260346 err = ncmpi_inq_malloc_size (& malloc_size );
@@ -267,6 +353,7 @@ int main(int argc, char** argv)
267353 if (malloc_size > 0 ) ncmpi_inq_malloc_list ();
268354 }
269355
356+ err_out :
270357 MPI_Allreduce (MPI_IN_PLACE , & nerrs , 1 , MPI_INT , MPI_SUM , MPI_COMM_WORLD );
271358 if (rank == 0 ) {
272359 if (nerrs ) printf (FAIL_STR ,nerrs );
0 commit comments