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 ----
@@ -939,9 +939,13 @@ int wrf_r_benchmark(char *in_file,
939939 return err ;
940940}
941941
942+ /*---- parse_str() >---------------------------------------------------------*/
943+ /* This subroutine parses an input string, in_str, into substring tokens,
944+ * separated by comma, and returns the number of substrings.
945+ */
942946static
943- int parse_str (char * in_str ,
944- int * * int_arr )
947+ int parse_str (char * in_str ,
948+ char * * * str_arr )
945949{
946950 char * token , * str_dup ;
947951 int nelems = 0 ;
@@ -962,16 +966,16 @@ int parse_str(char *in_str,
962966
963967 free (str_dup );
964968
965- /* allocate int_arr */
966- * int_arr = (int * ) malloc (sizeof (int ) * nelems );
969+ /* allocate str_arr */
970+ * str_arr = (char * * ) malloc (sizeof (char * ) * nelems );
967971
968- /* populate int_arr [] */
972+ /* populate str_arr [] */
969973 str_dup = strdup (in_str );
970974 token = strtok (str_dup , "," );
971- (* int_arr )[0 ] = atoi (token );
975+ (* str_arr )[0 ] = strdup (token );
972976 nelems = 1 ;
973977 while ((token = strtok (NULL , "," )) != NULL )
974- (* int_arr )[nelems ++ ] = atoi (token );
978+ (* str_arr )[nelems ++ ] = strdup (token );
975979
976980 free (str_dup );
977981 return nelems ;
@@ -985,12 +989,11 @@ usage(char *argv0)
985989 " [-h] print this help\n"
986990 " [-q] quiet mode\n"
987991 " [-d] debug mode\n"
988- " [-r filename ] benchmark read peformance \n"
989- " [-w filename ] benchmark write peformance \n"
992+ " [-r file1,file2,... ] benchmark read performance \n"
993+ " [-w file1,file2,... ] benchmark write performance \n"
990994 " [-y num] longitude of global 2D grid\n"
991995 " [-x num] latitude of global 2D grid\n"
992996 " [-n num] number of time steps\n"
993- " [-c str] a list of cb_nodes separated by commas\n"
994997 " [-i cdf_file] input text file containing CDL header\n" ;
995998 fprintf (stderr , help , argv0 );
996999}
@@ -999,11 +1002,9 @@ int main(int argc, char** argv)
9991002{
10001003 extern int optind ;
10011004 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 };
1005+ char * out_files , * in_files , * cdl_file , * * fname ;
1006+ int i , err , nerrs = 0 , nprocs , rank , ntimes , psizes [2 ], hid ;
1007+ int nfiles , do_read , do_write ;
10071008 MPI_Offset longitude , latitude ;
10081009 MPI_Info info = MPI_INFO_NULL ;
10091010
@@ -1012,16 +1013,16 @@ int main(int argc, char** argv)
10121013 MPI_Comm_rank (MPI_COMM_WORLD , & rank );
10131014 MPI_Comm_size (MPI_COMM_WORLD , & nprocs );
10141015
1015- verbose = 1 ;
1016- debug = 0 ;
1017- do_read = 0 ;
1018- do_write = 0 ;
1019- ntimes = 1 ;
1020- cdl_file = NULL ;
1016+ verbose = 1 ;
1017+ debug = 0 ;
1018+ do_read = 0 ;
1019+ do_write = 0 ;
1020+ ntimes = 1 ;
1021+ cdl_file = NULL ;
1022+ in_files = NULL ;
1023+ out_files = NULL ;
10211024 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 ;
1025+ latitude = -1 ; /* default to use south_north from cdl file */
10251026
10261027 while ((i = getopt (argc , argv , "hqdr:w:y:x:n:c:i:" )) != EOF )
10271028 switch (i ) {
@@ -1030,17 +1031,15 @@ int main(int argc, char** argv)
10301031 case 'd' : debug = 1 ;
10311032 break ;
10321033 case 'r' : do_read = 1 ;
1033- snprintf ( in_file , 1024 , "%s" , optarg );
1034+ in_files = strdup ( optarg );
10341035 break ;
10351036 case 'w' : do_write = 1 ;
1036- snprintf ( out_file , 1024 , "%s" , optarg );
1037+ out_files = strdup ( optarg );
10371038 break ;
10381039 case 'y' : longitude = atoll (optarg );
10391040 break ;
10401041 case 'x' : latitude = atoll (optarg );
10411042 break ;
1042- case 'c' : cb_nodes_str = strdup (optarg );
1043- break ;
10441043 case 'n' : ntimes = atoi (optarg );
10451044 break ;
10461045 case 'i' : cdl_file = strdup (optarg );
@@ -1063,104 +1062,71 @@ int main(int argc, char** argv)
10631062
10641063 /* input CDL file is required for write benchmark */
10651064 if (do_write && cdl_file == NULL ) {
1066- if (rank == 0 ) usage (argv [0 ]);
1065+ if (rank == 0 ) {
1066+ fprintf (stderr , "Error: write benchmark requires input CDL file\n" );
1067+ usage (argv [0 ]);
1068+ }
10671069 MPI_Finalize ();
10681070 return 1 ;
10691071 }
10701072
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-
10781073 /* set up the 2D block-block data partitioning pattern */
10791074 psizes [0 ] = psizes [1 ] = 0 ;
10801075 MPI_Dims_create (nprocs , 2 , psizes );
10811076
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-
11001077 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- }
1078+ /* parse CDL header file */
1079+ err = cdl_hdr_open (cdl_file , & hid );
1080+ free (cdl_file );
1081+ if (err != NC_NOERR ) goto err_out ;
11071082
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 );
1083+ if (debug && rank == 0 ) {
1084+ printf ("longitude=%lld latitude=%lld psizes=%d x %d\n" ,
1085+ longitude ,latitude ,psizes [0 ],psizes [1 ]);
1086+ fflush (stdout );
1087+ }
11111088
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- }
1089+ /* Example of out_files: "0.nc,1.nc,2.nc", i.e. 3 output files */
1090+ nfiles = parse_str (out_files , & fname );
11171091
1118- MPI_Barrier (MPI_COMM_WORLD );
1092+ for (i = 0 ; i < nfiles ; i ++ ) {
1093+ MPI_Barrier (MPI_COMM_WORLD );
11191094
1120- err = wrf_w_benchmark (out_file , hid , psizes , longitude , latitude ,
1121- ntimes , info );
1095+ err = wrf_w_benchmark (fname [ i ] , hid , psizes , longitude , latitude ,
1096+ ntimes , info );
11221097
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- }
1098+ if (err != NC_NOERR )
1099+ printf ("%d: Error at %s line=%d: i=%d error=%s\n" ,
1100+ rank , argv [0 ], __LINE__ , i , ncmpi_strerror (err ));
1101+
1102+ free (fname [i ]);
11271103 }
1104+ if (nfiles > 0 ) free (fname );
11281105 }
11291106
11301107 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- }
1108+ /* Example of in_files: "0.nc,1.nc,2.nc", i.e. 3 input files */
1109+ nfiles = parse_str (in_files , & fname );
11371110
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 );
1111+ for (i = 0 ; i < nfiles ; i ++ ) {
1112+ MPI_Barrier (MPI_COMM_WORLD );
11411113
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- }
1114+ err = wrf_r_benchmark (fname [i ], psizes , ntimes , info );
11471115
1148- MPI_Barrier (MPI_COMM_WORLD );
1116+ if (err != NC_NOERR )
1117+ printf ("%d: Error at %s line=%d: i=%d error=%s\n" ,
1118+ rank , argv [0 ], __LINE__ , i , ncmpi_strerror (err ));
11491119
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- }
1120+ free (fname [i ]);
11561121 }
1122+ if (nfiles > 0 ) free (fname );
11571123 }
11581124
1159- MPI_Info_free (& info );
1160- if (cb_nodes != NULL ) free (cb_nodes );
1161-
11621125err_out :
11631126 cdl_hdr_close (hid );
1127+ if (out_files != NULL ) free (out_files );
1128+ if (in_files != NULL ) free (in_files );
1129+ if (info != MPI_INFO_NULL ) MPI_Info_free (& info );
11641130
11651131 MPI_Finalize ();
11661132 return (nerrs > 0 );
0 commit comments