Skip to content

Commit f499a1e

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 f499a1e

File tree

2 files changed

+119
-41
lines changed

2 files changed

+119
-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: 117 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,77 @@ 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 *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+
do {
97+
if (*hint_str == '\0') break; /* done with this line */
98+
99+
key = hint_str;
100+
deli = strchr(hint_str, ';');
101+
if (deli != NULL) {
102+
*deli = '\0'; /* add terminate char */
103+
hint_str = deli + 1;
104+
}
105+
else
106+
hint_str += strlen(hint_str); /* last hint */
107+
108+
/* hint key */
109+
deli = strchr(key, '=');
110+
if (deli == NULL) {
111+
/* expect one token before = */
112+
printf("xxxx %s: '%s'\n", warn_str, key);
113+
break;
114+
}
115+
*deli = '\0'; /* add terminate char */
116+
117+
/* hint value */
118+
val = deli + 1;
119+
120+
/* override previouse set hint or add a new one */
121+
err = MPI_Info_set(cfg->info, key, val);
122+
CHECK_MPIERR
123+
124+
} while (*hint_str != '\0');
125+
126+
err_out:
127+
return err;
128+
}
129+
130+
static inline int set_info(e3sm_io_config *cfg,
131+
char *hint_str)
132+
{
80133
int err;
81134

82135
/* set MPI-IO hints */
83136

137+
err = MPI_Info_create (&(cfg->info));
138+
CHECK_MPIERR
139+
84140
/* collective write */
85141
err = MPI_Info_set (cfg->info, "romio_cb_write", "enable");
86142
CHECK_MPIERR
87143

88144
/* HDF5 may do independent I/O internally */
89145

90146
if (cfg->api == pnetcdf) {
91-
/* no independent MPI-IO */
92-
err = MPI_Info_set (cfg->info, "romio_no_indep_rw", "true");
93-
CHECK_MPIERR
147+
/* set MPI-IO hints here */
148+
// err = MPI_Info_set (cfg->info, "romio_no_indep_rw", "true");
149+
// CHECK_MPIERR
94150

95151
/* set PnetCDF I/O hints */
96152

@@ -121,6 +177,9 @@ static inline int set_info (e3sm_io_config *cfg, e3sm_io_decom *decom) {
121177
/* in-place byte swap */
122178
err = MPI_Info_set (cfg->info, "nc_in_place_swap", "enable");
123179
CHECK_MPIERR
180+
181+
err = parse_hint_line(cfg, hint_str);
182+
if (err == 0) goto err_out;
124183
}
125184

126185
err_out:
@@ -224,7 +283,7 @@ int main (int argc, char **argv) {
224283
CHECK_ERR;
225284
#endif
226285

227-
timing[0] = MPI_Wtime();
286+
timing[1] = MPI_Wtime();
228287

229288
MPI_Comm_rank (MPI_COMM_WORLD, &(cfg.rank));
230289
MPI_Comm_size (MPI_COMM_WORLD, &(cfg.np));
@@ -562,7 +621,7 @@ int main (int argc, char **argv) {
562621
PRINT_MSG (1, "Input data file/folder name = %s\n", cfg.in_path);
563622
PRINT_MSG (1, "Output data file/folder name = %s\n", cfg.out_path);
564623

565-
timing[1] = MPI_Wtime() - timing[0];
624+
timing[1] = MPI_Wtime() - timing[1];
566625
MPI_Barrier(MPI_COMM_WORLD);
567626
timing[2] = MPI_Wtime();
568627

@@ -584,41 +643,68 @@ int main (int argc, char **argv) {
584643
cfg.run_case = unknown;
585644

586645
timing[2] = MPI_Wtime() - timing[2];
587-
MPI_Barrier(MPI_COMM_WORLD);
588-
timing[3] = MPI_Wtime();
589646

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;
647+
/* read I/O hints from file e3sm_io_hints.txt, run e3sm_io_core() one per
648+
* line in the hint file. Each line contains hints as if it is set in the
649+
* environment variable PNETCDF_HINTS.
650+
*/
651+
FILE *fptr = fopen("e3sm_io_hints.txt", "r");
652+
char hint_str[512];
653+
int next_line;
654+
if (fptr == NULL) /* ignore hint file if not exist */
655+
next_line = EOF;
656+
else /* get the first line of the hint file */
657+
next_line = fscanf(fptr, "%s", hint_str);
595658

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

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

604-
/* report timing breakdowns */
605-
if (cfg.rd) {
606-
report_timing_RD(&cfg, &decom);
607-
}
608-
else{
609-
report_timing_WR(&cfg, &decom);
610-
}
663+
/* the core of this benchmark */
664+
MPI_Barrier(MPI_COMM_WORLD);
665+
timing[3] = MPI_Wtime();
666+
667+
/* set MPI-IO and PnetCDF hints */
668+
err = set_info(&cfg, (next_line == EOF) ? NULL : hint_str);
669+
if (err < 0) goto err_out;
670+
671+
err = e3sm_io_core(&cfg, &decom);
672+
CHECK_ERR
673+
674+
timing[3] = MPI_Wtime() - timing[3];
675+
676+
/* report timing breakdowns */
677+
if (cfg.rd)
678+
report_timing_RD(&cfg, &decom);
679+
else
680+
report_timing_WR(&cfg, &decom);
611681

612682
#ifdef E3SM_IO_PROFILING
613-
if (cfg.profiling) e3sm_io_print_profile(&cfg);
683+
if (cfg.profiling) e3sm_io_print_profile(&cfg);
614684
#else
615-
if (cfg.profiling && cfg.rank == 0)
616-
printf("\nWarning: E3SM-IO internal time profiling was disabled at configure time\n\n");
685+
if (cfg.profiling && cfg.rank == 0)
686+
printf("\nWarning: E3SM-IO internal time profiling was disabled at configure time\n\n");
617687
#endif
618688

689+
if (cfg.info != MPI_INFO_NULL) MPI_Info_free (&(cfg.info));
690+
691+
timing[0] = timing[1] + timing[2] + timing[3];
692+
MPI_Reduce(timing, max_t, 4, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
693+
if (cfg.rank == 0) {
694+
printf("init=%.2f read_decomp=%.2f e3sm_io_core=%.2f end-to-end=%.2f\n",
695+
max_t[1],max_t[2],max_t[3],max_t[0]);
696+
printf("-----------------------------------------------------------\n");
697+
printf("\n\n");
698+
}
699+
700+
if (fptr == NULL) break;
701+
702+
next_line = fscanf(fptr, "%s", hint_str);
703+
} while (next_line != EOF);
704+
705+
if (fptr != NULL) fclose(fptr);
706+
619707
err_out:
620-
if (cfg.info != MPI_INFO_NULL)
621-
MPI_Info_free (&(cfg.info));
622708
if (cfg.io_comm != MPI_COMM_WORLD && cfg.io_comm != MPI_COMM_NULL)
623709
MPI_Comm_free (&(cfg.io_comm));
624710
if (cfg.env_log_info != NULL)
@@ -635,16 +721,6 @@ int main (int argc, char **argv) {
635721
}
636722
}
637723

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-
648724
MPI_Finalize ();
649725

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

0 commit comments

Comments
 (0)