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 ----
@@ -907,6 +907,7 @@ int wrf_r_benchmark(char *in_file,
907907 for (i = 0 ; i < nvars ; i ++ ) {
908908 if (vars [i ].nelems > 0 ) free (vars [i ].buf );
909909 if (vars [i ].name != NULL ) free (vars [i ].name );
910+ if (vars [i ].dimids != NULL ) free (vars [i ].dimids );
910911 }
911912 free (vars );
912913 }
@@ -939,9 +940,13 @@ int wrf_r_benchmark(char *in_file,
939940 return err ;
940941}
941942
943+ /*---- parse_str() >---------------------------------------------------------*/
944+ /* This subroutine parses an input string, in_str, into substring tokens,
945+ * separated by comma, and returns the number of substrings.
946+ */
942947static
943- int parse_str (char * in_str ,
944- int * * int_arr )
948+ int parse_str (char * in_str ,
949+ char * * * str_arr )
945950{
946951 char * token , * str_dup ;
947952 int nelems = 0 ;
@@ -962,16 +967,16 @@ int parse_str(char *in_str,
962967
963968 free (str_dup );
964969
965- /* allocate int_arr */
966- * int_arr = (int * ) malloc (sizeof (int ) * nelems );
970+ /* allocate str_arr */
971+ * str_arr = (char * * ) malloc (sizeof (char * ) * nelems );
967972
968- /* populate int_arr [] */
973+ /* populate str_arr [] */
969974 str_dup = strdup (in_str );
970975 token = strtok (str_dup , "," );
971- (* int_arr )[0 ] = atoi (token );
976+ (* str_arr )[0 ] = strdup (token );
972977 nelems = 1 ;
973978 while ((token = strtok (NULL , "," )) != NULL )
974- (* int_arr )[nelems ++ ] = atoi (token );
979+ (* str_arr )[nelems ++ ] = strdup (token );
975980
976981 free (str_dup );
977982 return nelems ;
@@ -985,12 +990,11 @@ usage(char *argv0)
985990 " [-h] print this help\n"
986991 " [-q] quiet mode\n"
987992 " [-d] debug mode\n"
988- " [-r filename ] benchmark read peformance \n"
989- " [-w filename ] benchmark write peformance \n"
993+ " [-r file1,file2,... ] benchmark read performance \n"
994+ " [-w file1,file2,... ] benchmark write performance \n"
990995 " [-y num] longitude of global 2D grid\n"
991996 " [-x num] latitude of global 2D grid\n"
992997 " [-n num] number of time steps\n"
993- " [-c str] a list of cb_nodes separated by commas\n"
994998 " [-i cdf_file] input text file containing CDL header\n" ;
995999 fprintf (stderr , help , argv0 );
9961000}
@@ -999,11 +1003,9 @@ int main(int argc, char** argv)
9991003{
10001004 extern int optind ;
10011005 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 };
1006+ char * out_files , * in_files , * cdl_file , * * fname ;
1007+ int i , err , nerrs = 0 , nprocs , rank , ntimes , psizes [2 ], hid ;
1008+ int nfiles , do_read , do_write ;
10071009 MPI_Offset longitude , latitude ;
10081010 MPI_Info info = MPI_INFO_NULL ;
10091011
@@ -1012,16 +1014,16 @@ int main(int argc, char** argv)
10121014 MPI_Comm_rank (MPI_COMM_WORLD , & rank );
10131015 MPI_Comm_size (MPI_COMM_WORLD , & nprocs );
10141016
1015- verbose = 1 ;
1016- debug = 0 ;
1017- do_read = 0 ;
1018- do_write = 0 ;
1019- ntimes = 1 ;
1020- cdl_file = NULL ;
1017+ verbose = 1 ;
1018+ debug = 0 ;
1019+ do_read = 0 ;
1020+ do_write = 0 ;
1021+ ntimes = 1 ;
1022+ cdl_file = NULL ;
1023+ in_files = NULL ;
1024+ out_files = NULL ;
10211025 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 ;
1026+ latitude = -1 ; /* default to use south_north from cdl file */
10251027
10261028 while ((i = getopt (argc , argv , "hqdr:w:y:x:n:c:i:" )) != EOF )
10271029 switch (i ) {
@@ -1030,17 +1032,15 @@ int main(int argc, char** argv)
10301032 case 'd' : debug = 1 ;
10311033 break ;
10321034 case 'r' : do_read = 1 ;
1033- snprintf ( in_file , 1024 , "%s" , optarg );
1035+ in_files = strdup ( optarg );
10341036 break ;
10351037 case 'w' : do_write = 1 ;
1036- snprintf ( out_file , 1024 , "%s" , optarg );
1038+ out_files = strdup ( optarg );
10371039 break ;
10381040 case 'y' : longitude = atoll (optarg );
10391041 break ;
10401042 case 'x' : latitude = atoll (optarg );
10411043 break ;
1042- case 'c' : cb_nodes_str = strdup (optarg );
1043- break ;
10441044 case 'n' : ntimes = atoi (optarg );
10451045 break ;
10461046 case 'i' : cdl_file = strdup (optarg );
@@ -1063,104 +1063,71 @@ int main(int argc, char** argv)
10631063
10641064 /* input CDL file is required for write benchmark */
10651065 if (do_write && cdl_file == NULL ) {
1066- if (rank == 0 ) usage (argv [0 ]);
1066+ if (rank == 0 ) {
1067+ fprintf (stderr , "Error: write benchmark requires input CDL file\n" );
1068+ usage (argv [0 ]);
1069+ }
10671070 MPI_Finalize ();
10681071 return 1 ;
10691072 }
10701073
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-
10781074 /* set up the 2D block-block data partitioning pattern */
10791075 psizes [0 ] = psizes [1 ] = 0 ;
10801076 MPI_Dims_create (nprocs , 2 , psizes );
10811077
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-
11001078 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- }
1079+ /* parse CDL header file */
1080+ err = cdl_hdr_open (cdl_file , & hid );
1081+ free (cdl_file );
1082+ if (err != NC_NOERR ) goto err_out ;
11071083
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 );
1084+ if (debug && rank == 0 ) {
1085+ printf ("longitude=%lld latitude=%lld psizes=%d x %d\n" ,
1086+ longitude ,latitude ,psizes [0 ],psizes [1 ]);
1087+ fflush (stdout );
1088+ }
11111089
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- }
1090+ /* Example of out_files: "0.nc,1.nc,2.nc", i.e. 3 output files */
1091+ nfiles = parse_str (out_files , & fname );
11171092
1118- MPI_Barrier (MPI_COMM_WORLD );
1093+ for (i = 0 ; i < nfiles ; i ++ ) {
1094+ MPI_Barrier (MPI_COMM_WORLD );
11191095
1120- err = wrf_w_benchmark (out_file , hid , psizes , longitude , latitude ,
1121- ntimes , info );
1096+ err = wrf_w_benchmark (fname [ i ] , hid , psizes , longitude , latitude ,
1097+ ntimes , info );
11221098
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- }
1099+ if (err != NC_NOERR )
1100+ printf ("%d: Error at %s line=%d: i=%d error=%s\n" ,
1101+ rank , argv [0 ], __LINE__ , i , ncmpi_strerror (err ));
1102+
1103+ free (fname [i ]);
11271104 }
1105+ if (nfiles > 0 ) free (fname );
11281106 }
11291107
11301108 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- }
1109+ /* Example of in_files: "0.nc,1.nc,2.nc", i.e. 3 input files */
1110+ nfiles = parse_str (in_files , & fname );
11371111
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 );
1112+ for (i = 0 ; i < nfiles ; i ++ ) {
1113+ MPI_Barrier (MPI_COMM_WORLD );
11411114
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- }
1115+ err = wrf_r_benchmark (fname [i ], psizes , ntimes , info );
11471116
1148- MPI_Barrier (MPI_COMM_WORLD );
1117+ if (err != NC_NOERR )
1118+ printf ("%d: Error at %s line=%d: i=%d error=%s\n" ,
1119+ rank , argv [0 ], __LINE__ , i , ncmpi_strerror (err ));
11491120
1150- err = wrf_r_benchmark (in_file , psizes , ntimes , info );
1151-
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- }
1121+ free (fname [i ]);
11561122 }
1123+ if (nfiles > 0 ) free (fname );
11571124 }
11581125
1159- MPI_Info_free (& info );
1160- if (cb_nodes != NULL ) free (cb_nodes );
1161-
11621126err_out :
11631127 cdl_hdr_close (hid );
1128+ if (out_files != NULL ) free (out_files );
1129+ if (in_files != NULL ) free (in_files );
1130+ if (info != MPI_INFO_NULL ) MPI_Info_free (& info );
11641131
11651132 MPI_Finalize ();
11661133 return (nerrs > 0 );
0 commit comments