2626 * % mpicc -O2 wrf_io.c -o wrf_io -lpnetcdf
2727 *
2828 * An example of run command:
29- * % mpiexec -n 4 ./wrf_io -w - y 100 -x 100 -n 2 -i wrf_header.txt ./wrf_io.nc
29+ * % mpiexec -n 4 ./wrf_io -y 100 -x 100 -n 2 -i wrf_header.txt -w ./wrf_io.nc
3030 *
3131 * -----------------------------------------------------------
3232 * ---- WRF-IO write benchmark ----
@@ -732,6 +732,10 @@ int wrf_r_benchmark(char *in_file,
732732 err = ncmpi_open (MPI_COMM_WORLD , in_file , NC_NOWRITE , info , & ncid );
733733 CHECK_ERR ("ncmpi_open" )
734734
735+ /* start the timer */
736+ MPI_Barrier (MPI_COMM_WORLD );
737+ timing [0 ] = MPI_Wtime ();
738+
735739 err = ncmpi_inq_dimid (ncid , "south_north" , & dimid );
736740 CHECK_ERR ("ncmpi_inq_dimid" )
737741 err = ncmpi_inq_dimlen (ncid , dimid , & longitude );
@@ -797,10 +801,7 @@ int wrf_r_benchmark(char *in_file,
797801 assert (mem_alloc == buf_size );
798802 }
799803
800- /* start the timer */
801- MPI_Barrier (MPI_COMM_WORLD );
802- timing [0 ] = MPI_Wtime ();
803-
804+ timing [1 ] = MPI_Wtime () - timing [0 ];
804805 timing [2 ] = timing [3 ] = 0 ;
805806
806807 /* ntimes is the number of records */
@@ -880,7 +881,7 @@ int wrf_r_benchmark(char *in_file,
880881 printf (" %.2f GiB\n" , (float )sum_r_size /1073741824 );
881882 double bw = (double )sum_r_size / 1048576 ;
882883 printf ("Max open-to-close time: %.4f sec\n" , max_t [0 ]);
883- printf ("Max define metadata time: %.4f sec\n" , max_t [1 ]);
884+ printf ("Max inquire metadata time: %.4f sec\n" , max_t [1 ]);
884885 printf ("Max iget posting time: %.4f sec\n" , max_t [2 ]);
885886 printf ("Max wait_all time: %.4f sec\n" , max_t [3 ]);
886887 printf ("Read bandwidth: %.2f MiB/s\n" , bw /max_t [0 ]);
@@ -907,6 +908,7 @@ int wrf_r_benchmark(char *in_file,
907908 for (i = 0 ; i < nvars ; i ++ ) {
908909 if (vars [i ].nelems > 0 ) free (vars [i ].buf );
909910 if (vars [i ].name != NULL ) free (vars [i ].name );
911+ if (vars [i ].dimids != NULL ) free (vars [i ].dimids );
910912 }
911913 free (vars );
912914 }
@@ -939,9 +941,13 @@ int wrf_r_benchmark(char *in_file,
939941 return err ;
940942}
941943
944+ /*---- parse_str() >---------------------------------------------------------*/
945+ /* This subroutine parses an input string, in_str, into substring tokens,
946+ * separated by comma, and returns the number of substrings.
947+ */
942948static
943- int parse_str (char * in_str ,
944- int * * int_arr )
949+ int parse_str (char * in_str ,
950+ char * * * str_arr )
945951{
946952 char * token , * str_dup ;
947953 int nelems = 0 ;
@@ -962,16 +968,16 @@ int parse_str(char *in_str,
962968
963969 free (str_dup );
964970
965- /* allocate int_arr */
966- * int_arr = (int * ) malloc (sizeof (int ) * nelems );
971+ /* allocate str_arr */
972+ * str_arr = (char * * ) malloc (sizeof (char * ) * nelems );
967973
968- /* populate int_arr [] */
974+ /* populate str_arr [] */
969975 str_dup = strdup (in_str );
970976 token = strtok (str_dup , "," );
971- (* int_arr )[0 ] = atoi (token );
977+ (* str_arr )[0 ] = strdup (token );
972978 nelems = 1 ;
973979 while ((token = strtok (NULL , "," )) != NULL )
974- (* int_arr )[nelems ++ ] = atoi (token );
980+ (* str_arr )[nelems ++ ] = strdup (token );
975981
976982 free (str_dup );
977983 return nelems ;
@@ -985,12 +991,11 @@ usage(char *argv0)
985991 " [-h] print this help\n"
986992 " [-q] quiet mode\n"
987993 " [-d] debug mode\n"
988- " [-r filename ] benchmark read peformance \n"
989- " [-w filename ] benchmark write peformance \n"
994+ " [-r file1,file2,... ] benchmark read performance \n"
995+ " [-w file1,file2,... ] benchmark write performance \n"
990996 " [-y num] longitude of global 2D grid\n"
991997 " [-x num] latitude of global 2D grid\n"
992998 " [-n num] number of time steps\n"
993- " [-c str] a list of cb_nodes separated by commas\n"
994999 " [-i cdf_file] input text file containing CDL header\n" ;
9951000 fprintf (stderr , help , argv0 );
9961001}
@@ -999,11 +1004,9 @@ int main(int argc, char** argv)
9991004{
10001005 extern int optind ;
10011006 extern char * optarg ;
1002- char out_file [1024 ], in_file [1024 ], int_str [24 ];
1003- char * cdl_file , * cb_nodes_str ;
1004- int i , j , err , nerrs = 0 , nprocs , rank , ntimes , psizes [2 ], hid ;
1005- int num_cb_nodes , num_intra_nodes , * cb_nodes , do_read , do_write ;
1006- int nc_num_aggrs_per_node []= {0 };
1007+ char * out_files , * in_files , * cdl_file , * * fname ;
1008+ int i , err , nerrs = 0 , nprocs , rank , ntimes , psizes [2 ], hid ;
1009+ int nfiles , do_read , do_write ;
10071010 MPI_Offset longitude , latitude ;
10081011 MPI_Info info = MPI_INFO_NULL ;
10091012
@@ -1012,16 +1015,16 @@ int main(int argc, char** argv)
10121015 MPI_Comm_rank (MPI_COMM_WORLD , & rank );
10131016 MPI_Comm_size (MPI_COMM_WORLD , & nprocs );
10141017
1015- verbose = 1 ;
1016- debug = 0 ;
1017- do_read = 0 ;
1018- do_write = 0 ;
1019- ntimes = 1 ;
1020- cdl_file = NULL ;
1018+ verbose = 1 ;
1019+ debug = 0 ;
1020+ do_read = 0 ;
1021+ do_write = 0 ;
1022+ ntimes = 1 ;
1023+ cdl_file = NULL ;
1024+ in_files = NULL ;
1025+ out_files = NULL ;
10211026 longitude = -1 ; /* default to use west_east from cdl file */
1022- latitude = -1 ; /* default to use south_north from cdl file */
1023- cb_nodes = NULL ;
1024- cb_nodes_str = NULL ;
1027+ latitude = -1 ; /* default to use south_north from cdl file */
10251028
10261029 while ((i = getopt (argc , argv , "hqdr:w:y:x:n:c:i:" )) != EOF )
10271030 switch (i ) {
@@ -1030,17 +1033,15 @@ int main(int argc, char** argv)
10301033 case 'd' : debug = 1 ;
10311034 break ;
10321035 case 'r' : do_read = 1 ;
1033- snprintf ( in_file , 1024 , "%s" , optarg );
1036+ in_files = strdup ( optarg );
10341037 break ;
10351038 case 'w' : do_write = 1 ;
1036- snprintf ( out_file , 1024 , "%s" , optarg );
1039+ out_files = strdup ( optarg );
10371040 break ;
10381041 case 'y' : longitude = atoll (optarg );
10391042 break ;
10401043 case 'x' : latitude = atoll (optarg );
10411044 break ;
1042- case 'c' : cb_nodes_str = strdup (optarg );
1043- break ;
10441045 case 'n' : ntimes = atoi (optarg );
10451046 break ;
10461047 case 'i' : cdl_file = strdup (optarg );
@@ -1063,104 +1064,71 @@ int main(int argc, char** argv)
10631064
10641065 /* input CDL file is required for write benchmark */
10651066 if (do_write && cdl_file == NULL ) {
1066- if (rank == 0 ) usage (argv [0 ]);
1067+ if (rank == 0 ) {
1068+ fprintf (stderr , "Error: write benchmark requires input CDL file\n" );
1069+ usage (argv [0 ]);
1070+ }
10671071 MPI_Finalize ();
10681072 return 1 ;
10691073 }
10701074
1071- /* parse CDL header file */
1072- if (do_write ) {
1073- err = cdl_hdr_open (cdl_file , & hid );
1074- free (cdl_file );
1075- if (err != NC_NOERR ) goto err_out ;
1076- }
1077-
10781075 /* set up the 2D block-block data partitioning pattern */
10791076 psizes [0 ] = psizes [1 ] = 0 ;
10801077 MPI_Dims_create (nprocs , 2 , psizes );
10811078
1082- if (debug && do_write && rank == 0 ) {
1083- printf ("longitude=%lld latitude=%lld psizes=%d x %d\n" ,
1084- longitude ,latitude ,psizes [0 ],psizes [1 ]);
1085- fflush (stdout );
1086- }
1087-
1088- if (cb_nodes_str != NULL ) {
1089- num_cb_nodes = parse_str (cb_nodes_str , & cb_nodes );
1090- free (cb_nodes_str );
1091- }
1092- else
1093- num_cb_nodes = 1 ;
1094-
1095- num_intra_nodes = sizeof (nc_num_aggrs_per_node ) / sizeof (int );
1096-
1097- /* set PnetCDF I/O hints */
1098- MPI_Info_create (& info );
1099-
11001079 if (do_write ) {
1101- for (i = 0 ; i < num_cb_nodes ; i ++ ) {
1102- /* set hint cb_nodes */
1103- if (cb_nodes != NULL ) {
1104- sprintf (int_str , "%d" , cb_nodes [i ]);
1105- MPI_Info_set (info , "cb_nodes" , int_str );
1106- }
1080+ /* parse CDL header file */
1081+ err = cdl_hdr_open (cdl_file , & hid );
1082+ free (cdl_file );
1083+ if (err != NC_NOERR ) goto err_out ;
11071084
1108- for (j = 0 ; j < num_intra_nodes ; j ++ ) {
1109- snprintf (int_str , 24 , "%d" , nc_num_aggrs_per_node [j ]);
1110- MPI_Info_set (info , "nc_num_aggrs_per_node" , int_str );
1085+ if (debug && rank == 0 ) {
1086+ printf ("longitude=%lld latitude=%lld psizes=%d x %d\n" ,
1087+ longitude ,latitude ,psizes [0 ],psizes [1 ]);
1088+ fflush (stdout );
1089+ }
11111090
1112- if (debug && rank == 0 ) {
1113- printf ("Info cb_nodes set to %d nc_num_aggrs_per_node set to=%d\n" ,
1114- cb_nodes [i ],nc_num_aggrs_per_node [j ]);
1115- fflush (stdout );
1116- }
1091+ /* Example of out_files: "0.nc,1.nc,2.nc", i.e. 3 output files */
1092+ nfiles = parse_str (out_files , & fname );
11171093
1118- MPI_Barrier (MPI_COMM_WORLD );
1094+ for (i = 0 ; i < nfiles ; i ++ ) {
1095+ MPI_Barrier (MPI_COMM_WORLD );
11191096
1120- err = wrf_w_benchmark (out_file , hid , psizes , longitude , latitude ,
1121- ntimes , info );
1097+ err = wrf_w_benchmark (fname [ i ] , hid , psizes , longitude , latitude ,
1098+ ntimes , info );
11221099
1123- if (err != NC_NOERR )
1124- printf ("%d: Error at %s line=%d: i=%d j=%d error=%s\n" ,
1125- rank , argv [0 ], __LINE__ , i , j , ncmpi_strerror (err ));
1126- }
1100+ if (err != NC_NOERR )
1101+ printf ("%d: Error at %s line=%d: i=%d error=%s\n" ,
1102+ rank , argv [0 ], __LINE__ , i , ncmpi_strerror (err ));
1103+
1104+ free (fname [i ]);
11271105 }
1106+ if (nfiles > 0 ) free (fname );
11281107 }
11291108
11301109 if (do_read ) {
1131- for (i = 0 ; i < num_cb_nodes ; i ++ ) {
1132- /* set hint cb_nodes */
1133- if (cb_nodes != NULL ) {
1134- sprintf (int_str , "%d" , cb_nodes [i ]);
1135- MPI_Info_set (info , "cb_nodes" , int_str );
1136- }
1137-
1138- for (j = 0 ; j < num_intra_nodes ; j ++ ) {
1139- snprintf (int_str , 24 , "%d" , nc_num_aggrs_per_node [j ]);
1140- MPI_Info_set (info , "nc_num_aggrs_per_node" , int_str );
1110+ /* Example of in_files: "0.nc,1.nc,2.nc", i.e. 3 input files */
1111+ nfiles = parse_str (in_files , & fname );
11411112
1142- if (debug && rank == 0 ) {
1143- printf ("Info cb_nodes set to %d nc_num_aggrs_per_node set to=%d\n" ,
1144- cb_nodes [i ],nc_num_aggrs_per_node [j ]);
1145- fflush (stdout );
1146- }
1113+ for (i = 0 ; i < nfiles ; i ++ ) {
1114+ MPI_Barrier (MPI_COMM_WORLD );
11471115
1148- MPI_Barrier ( MPI_COMM_WORLD );
1116+ err = wrf_r_benchmark ( fname [ i ], psizes , ntimes , info );
11491117
1150- err = wrf_r_benchmark (in_file , psizes , ntimes , info );
1118+ if (err != NC_NOERR )
1119+ printf ("%d: Error at %s line=%d: i=%d error=%s\n" ,
1120+ rank , argv [0 ], __LINE__ , i , ncmpi_strerror (err ));
11511121
1152- if (err != NC_NOERR )
1153- printf ("%d: Error at %s line=%d: i=%d j=%d error=%s\n" ,
1154- rank , argv [0 ], __LINE__ , i , j , ncmpi_strerror (err ));
1155- }
1122+ free (fname [i ]);
11561123 }
1124+ if (nfiles > 0 ) free (fname );
11571125 }
11581126
1159- MPI_Info_free (& info );
1160- if (cb_nodes != NULL ) free (cb_nodes );
1161-
11621127err_out :
11631128 cdl_hdr_close (hid );
1129+ if (out_files != NULL ) free (out_files );
1130+ if (in_files != NULL ) free (in_files );
1131+ if (info != MPI_INFO_NULL ) MPI_Info_free (& info );
11641132
11651133 MPI_Finalize ();
11661134 return (nerrs > 0 );
0 commit comments