Skip to content

Commit c6cfe4c

Browse files
committed
WRF-IO: remove setting hints of cb_nodes and nc_num_aggrs_per_node
Also enable command-line options "-r" and "-w" to take a list of file names separated by commas, so it can run multiple write/read benchmarks, each using a different output/input file. For reads, this can avoid file system caching effect. For writes, there should be no caching effect. Using multiple output files simply allows to run the write benchmark multiple times.
1 parent a4fe353 commit c6cfe4c

File tree

1 file changed

+67
-100
lines changed

1 file changed

+67
-100
lines changed

benchmarks/WRF-IO/wrf_io.c

Lines changed: 67 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
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+
*/
942947
static
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-
11621126
err_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

Comments
 (0)