Skip to content

Commit 758f205

Browse files
committed
Enable hint file, run the benchmark once per line in the hint file
hint file name is "e3sm_io_hints.txt"
1 parent 4759892 commit 758f205

File tree

2 files changed

+128
-41
lines changed

2 files changed

+128
-41
lines changed

e3sm_io_hints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
start_iodevice=10;striping_unit=1048576;striping_factor=8;lustre_overstriping_ratio=1;cb_nodes=8
2+
start_iodevice=10;striping_unit=1048576;striping_factor=8;lustre_overstriping_ratio=1;cb_nodes=8;nc_num_aggrs_per_node=32

src/e3sm_io.c

Lines changed: 126 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,86 @@ void check_connector_env(e3sm_io_config *cfg) {
7676
free(env_str);
7777
}
7878

79-
static inline int set_info (e3sm_io_config *cfg, e3sm_io_decom *decom) {
79+
static
80+
int parse_hint_line(e3sm_io_config *cfg,
81+
char *hint_str)
82+
{
83+
char *warn_str="Warning: skip ill-formed hint set in PNETCDF_HINTS";
84+
char *next_hint, *key, *val, *deli;
85+
int err=MPI_SUCCESS;
86+
87+
if (hint_str == NULL) return 1;
88+
89+
/* skip blank lines */
90+
char *hint_saved = strdup(hint_str);
91+
if (strlen(hint_str) == 0 || strtok(hint_saved, " \t") == NULL) {
92+
free(hint_saved);
93+
return 1;
94+
}
95+
96+
next_hint = hint_str;
97+
do {
98+
hint_str = next_hint;
99+
deli = strchr(hint_str, ';');
100+
if (deli != NULL) {
101+
*deli = '\0'; /* add terminate char */
102+
next_hint = deli + 1;
103+
}
104+
else break; /* done with this line */
105+
106+
deli = strchr(hint_str, '=');
107+
if (deli == NULL) { /* ill-formed hint */
108+
printf("%s: '%s'\n", warn_str, hint_str);
109+
continue;
110+
}
111+
*deli = '\0';
112+
113+
/* hint key */
114+
key = strtok(hint_str, "= \t");
115+
if (key == NULL || NULL != strtok(NULL, "= \t")) {
116+
/* expect one token before = */
117+
printf("%s: '%s'\n", warn_str, hint_str);
118+
continue;
119+
}
120+
121+
/* hint value */
122+
val = strtok(deli+1, "= \t");
123+
if (NULL != strtok(NULL, "= \t")) {
124+
/* expect one token before = */
125+
printf("%s: '%s'\n", warn_str, hint_str);
126+
continue;
127+
}
128+
129+
/* override previouse set hint or add a new one */
130+
err = MPI_Info_set(cfg->info, key, val);
131+
CHECK_MPIERR
132+
133+
} while (*next_hint != '\0');
134+
135+
err_out:
136+
return err;
137+
}
138+
139+
static inline int set_info(e3sm_io_config *cfg,
140+
char *hint_str)
141+
{
80142
int err;
81143

82144
/* set MPI-IO hints */
83145

146+
err = MPI_Info_create (&(cfg->info));
147+
CHECK_MPIERR
148+
84149
/* collective write */
85150
err = MPI_Info_set (cfg->info, "romio_cb_write", "enable");
86151
CHECK_MPIERR
87152

88153
/* HDF5 may do independent I/O internally */
89154

90155
if (cfg->api == pnetcdf) {
91-
/* no independent MPI-IO */
92-
err = MPI_Info_set (cfg->info, "romio_no_indep_rw", "true");
93-
CHECK_MPIERR
156+
/* set MPI-IO hints here */
157+
// err = MPI_Info_set (cfg->info, "romio_no_indep_rw", "true");
158+
// CHECK_MPIERR
94159

95160
/* set PnetCDF I/O hints */
96161

@@ -121,6 +186,9 @@ static inline int set_info (e3sm_io_config *cfg, e3sm_io_decom *decom) {
121186
/* in-place byte swap */
122187
err = MPI_Info_set (cfg->info, "nc_in_place_swap", "enable");
123188
CHECK_MPIERR
189+
190+
err = parse_hint_line(cfg, hint_str);
191+
if (err == 0) goto err_out;
124192
}
125193

126194
err_out:
@@ -224,7 +292,7 @@ int main (int argc, char **argv) {
224292
CHECK_ERR;
225293
#endif
226294

227-
timing[0] = MPI_Wtime();
295+
timing[1] = MPI_Wtime();
228296

229297
MPI_Comm_rank (MPI_COMM_WORLD, &(cfg.rank));
230298
MPI_Comm_size (MPI_COMM_WORLD, &(cfg.np));
@@ -562,7 +630,7 @@ int main (int argc, char **argv) {
562630
PRINT_MSG (1, "Input data file/folder name = %s\n", cfg.in_path);
563631
PRINT_MSG (1, "Output data file/folder name = %s\n", cfg.out_path);
564632

565-
timing[1] = MPI_Wtime() - timing[0];
633+
timing[1] = MPI_Wtime() - timing[1];
566634
MPI_Barrier(MPI_COMM_WORLD);
567635
timing[2] = MPI_Wtime();
568636

@@ -584,41 +652,68 @@ int main (int argc, char **argv) {
584652
cfg.run_case = unknown;
585653

586654
timing[2] = MPI_Wtime() - timing[2];
587-
MPI_Barrier(MPI_COMM_WORLD);
588-
timing[3] = MPI_Wtime();
589655

590-
/* set MPI-IO and PnetCDF hints */
591-
err = MPI_Info_create (&(cfg.info));
592-
CHECK_MPIERR
593-
err = set_info (&cfg, &decom);
594-
if (err < 0) goto err_out;
656+
/* read I/O hints from file e3sm_io_hints.txt, run e3sm_io_core() one per
657+
* line in the hint file. Each line contains hints as if it is set in the
658+
* environment variable PNETCDF_HINTS.
659+
*/
660+
FILE *fptr = fopen("e3sm_io_hints.txt", "r");
661+
char hint_str[512];
662+
int next_line;
663+
if (fptr == NULL) /* ignore hint file if not exist */
664+
next_line = EOF;
665+
else /* get the first line of the hint file */
666+
next_line = fscanf(fptr, "%s", hint_str);
595667

596-
/* the core of this benchmark */
597-
err = e3sm_io_core (&cfg, &decom);
598-
CHECK_ERR
668+
do {
599669

600-
timing[3] = MPI_Wtime() - timing[3];
601-
MPI_Barrier(MPI_COMM_WORLD);
602-
timing[4] = MPI_Wtime();
670+
if (cfg.rank == 0) printf("\nHINTS: %s\n\n", (next_line == EOF) ? "" : hint_str);
603671

604-
/* report timing breakdowns */
605-
if (cfg.rd) {
606-
report_timing_RD(&cfg, &decom);
607-
}
608-
else{
609-
report_timing_WR(&cfg, &decom);
610-
}
672+
/* the core of this benchmark */
673+
MPI_Barrier(MPI_COMM_WORLD);
674+
timing[3] = MPI_Wtime();
675+
676+
/* set MPI-IO and PnetCDF hints */
677+
err = set_info(&cfg, (next_line == EOF) ? NULL : hint_str);
678+
if (err < 0) goto err_out;
679+
680+
err = e3sm_io_core(&cfg, &decom);
681+
CHECK_ERR
682+
683+
timing[3] = MPI_Wtime() - timing[3];
684+
685+
/* report timing breakdowns */
686+
if (cfg.rd)
687+
report_timing_RD(&cfg, &decom);
688+
else
689+
report_timing_WR(&cfg, &decom);
611690

612691
#ifdef E3SM_IO_PROFILING
613-
if (cfg.profiling) e3sm_io_print_profile(&cfg);
692+
if (cfg.profiling) e3sm_io_print_profile(&cfg);
614693
#else
615-
if (cfg.profiling && cfg.rank == 0)
616-
printf("\nWarning: E3SM-IO internal time profiling was disabled at configure time\n\n");
694+
if (cfg.profiling && cfg.rank == 0)
695+
printf("\nWarning: E3SM-IO internal time profiling was disabled at configure time\n\n");
617696
#endif
618697

698+
if (cfg.info != MPI_INFO_NULL) MPI_Info_free (&(cfg.info));
699+
700+
timing[0] = timing[1] + timing[2] + timing[3];
701+
MPI_Reduce(timing, max_t, 4, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
702+
if (cfg.rank == 0) {
703+
printf("init=%.2f read_decomp=%.2f e3sm_io_core=%.2f end-to-end=%.2f\n",
704+
max_t[1],max_t[2],max_t[3],max_t[0]);
705+
printf("-----------------------------------------------------------\n");
706+
printf("\n\n");
707+
}
708+
709+
if (fptr == NULL) break;
710+
711+
next_line = fscanf(fptr, "%s", hint_str);
712+
} while (next_line != EOF);
713+
714+
if (fptr != NULL) fclose(fptr);
715+
619716
err_out:
620-
if (cfg.info != MPI_INFO_NULL)
621-
MPI_Info_free (&(cfg.info));
622717
if (cfg.io_comm != MPI_COMM_WORLD && cfg.io_comm != MPI_COMM_NULL)
623718
MPI_Comm_free (&(cfg.io_comm));
624719
if (cfg.env_log_info != NULL)
@@ -635,16 +730,6 @@ int main (int argc, char **argv) {
635730
}
636731
}
637732

638-
timing[4] = MPI_Wtime() - timing[4];
639-
timing[0] = MPI_Wtime() - timing[0];
640-
MPI_Reduce(timing, max_t, 5, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
641-
if (cfg.rank == 0) {
642-
printf("init=%.2f read_decomp=%.2f e3sm_io_core=%.2f final=%.2f end-to-end=%.2f\n",
643-
max_t[1],max_t[2],max_t[3],max_t[4],max_t[0]);
644-
printf("-----------------------------------------------------------\n");
645-
printf("\n\n");
646-
}
647-
648733
MPI_Finalize ();
649734

650735
return (err < 0) ? 1 : 0;

0 commit comments

Comments
 (0)