Skip to content

Commit 67d4805

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 67d4805

File tree

1 file changed

+66
-100
lines changed

1 file changed

+66
-100
lines changed

benchmarks/WRF-IO/wrf_io.c

Lines changed: 66 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 ----
@@ -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+
*/
942946
static
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-
11621125
err_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

Comments
 (0)