@@ -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
126185err_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+
619707err_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