Skip to content

Commit 63e4e18

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 0b2aaec commit 63e4e18

File tree

2 files changed

+75
-105
lines changed

2 files changed

+75
-105
lines changed

benchmarks/WRF-IO/parallel_run.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ for i in ${check_PROGRAMS} ; do
3838
if test "$intra_aggr" = 1 ; then
3939
export PNETCDF_HINTS="${PNETCDF_HINTS};nc_num_aggrs_per_node=2"
4040
fi
41+
# echo "PNETCDF_HINTS=${PNETCDF_HINTS}"
42+
4143
export PNETCDF_SAFE_MODE=$j
4244
# echo "set PNETCDF_SAFE_MODE ${PNETCDF_SAFE_MODE}"
4345

benchmarks/WRF-IO/wrf_io.c

Lines changed: 73 additions & 105 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 ----
@@ -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+
*/
942948
static
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-
11621127
err_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

Comments
 (0)