Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/Main/Init.hpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.
7 : : All rights reserved. See the LICENSE file for details.
8 : : \brief Common initialization routines for main() functions for multiple
9 : : exectuables
10 : : \details Common initialization routines for main() functions for multiple
11 : : exectuables. The functions in this file are used by multiple execitables
12 : : to ensure code-reuse and a uniform screen-output.
13 : : */
14 : : // *****************************************************************************
15 : : #ifndef Init_h
16 : : #define Init_h
17 : :
18 : : #include <string>
19 : : #include <unordered_map>
20 : :
21 : : #include "NoWarning/charm++.hpp"
22 : :
23 : : #include "QuinoaConfig.hpp"
24 : : #include "Exception.hpp"
25 : : #include "Print.hpp"
26 : : #include "ChareStateCollector.hpp"
27 : : #include "ProcessException.hpp"
28 : :
29 : : namespace tk {
30 : :
31 : : //! Executable types for which an ascii logo is available in tk::Print
32 : : enum class HeaderType : uint8_t { INCITER=0,
33 : : RNGTEST,
34 : : UNITTEST,
35 : : MESHCONV,
36 : : FILECONV,
37 : : WALKER };
38 : :
39 : : //! Wrapper for the standard C library's gettimeofday() from
40 : : std::string curtime();
41 : :
42 : : //! Echo program header
43 : : void echoHeader( const Print& print, HeaderType header );
44 : :
45 : : //! Echo build environment
46 : : void echoBuildEnv( const Print& print, const std::string& executable );
47 : :
48 : : //! Echo runtime environment
49 : : void echoRunEnv( const Print& print, int argc, char** argv,
50 : : bool verbose, bool quiescence, bool charestate, bool trace,
51 : : const std::string& screen_log, const std::string& input_log );
52 : :
53 : : //! \brief Generic Main() used for all executables for code-reuse and a uniform
54 : : //! output
55 : : //! \details The template arguments configure this Main class that is
56 : : //! practically used instead of the usual main(). This allows code-reuse and a
57 : : //! unfirom screen-output. The template arguments are:
58 : : //! - Driver, specializaing the driver type to be created, see tk::Driver
59 : : //! - Printer, specializaing the pretty printer type to use, see tk::Print
60 : : //! - CmdLine, specializing the command line object storing data parsed from
61 : : //! the command line
62 : : //! \param[in] argc Number of command-line arguments to executable
63 : : //! \param[in] argv C-style string array to command-line arguments to executable
64 : : //! \param[in] cmdline Command line object storing data parsed from the command
65 : : //! line arguments
66 : : //! \param[in] header Header type enum indicating which executable header to
67 : : //! print
68 : : //! \param[in] executable Name of the executable
69 : : //! \param[in] def Default log file name
70 : : //! \param[in] nrestart Number of times restarted
71 : : //! \return Instantiated driver object which can then be used to execute()
72 : : //! whatever it is intended to drive
73 : : template< class Driver, class CmdLine >
74 : 330 : Driver Main( int argc, char* argv[],
75 : : const CmdLine& cmdline,
76 : : HeaderType header,
77 : : const std::string& executable,
78 : : const std::string& def,
79 : : int nrestart )
80 : : {
81 : : // Create pretty printer
82 : : tk::Print
83 [ + - ][ + - ]: 352 : print( cmdline.logname( def, nrestart ),
[ + - ]
84 : 330 : cmdline.template get< tag::verbose >() ? std::cout : std::clog );
85 : :
86 : : // Echo program header
87 [ + - ]: 330 : echoHeader( print, header );
88 : :
89 : : // Echo environment
90 [ + - ][ + - ]: 330 : print.part( "Environment" );
91 : : // Build environment
92 [ + - ]: 330 : echoBuildEnv( print, executable );
93 : : // Runtime environment
94 [ + - ][ + - ]: 330 : echoRunEnv( print, argc, argv, cmdline.template get< tag::verbose >(),
[ + - ]
95 : : cmdline.template get< tag::quiescence >(),
96 : : cmdline.template get< tag::chare >(),
97 : : cmdline.template get< tag::trace >(),
98 : : cmdline.logname( def, nrestart ),
99 : : executable + "_input.log" );
100 : :
101 : : // Create and return driver
102 [ + - ]: 660 : return Driver( cmdline, nrestart );
103 : : }
104 : :
105 : : //! Generic Main Charm++ module constructor for all executables
106 : : //! \tparam MainProxy Main Charm++ chare proxy for the executable
107 : : //! \tparam CmdLine Executable-specific tagged tuple storing the rusult of the
108 : : //! command line parser
109 : : //! \param[in,out] mp MainProxy to set for the main chare
110 : : //! \param[in] thisProxy 'thisProxy' to set as MainProxy
111 : : //! \param[in,out] timer Vector of timers, held by the main chare, in which to
112 : : //! start the first timer, measuring the migration of global-scope data
113 : : //! \param[in] cmdline Command line grammar stack for the executable (assumed
114 : : //! already parsed)
115 : : //! \param[in] quiescenceTarget Pre-created Charm++ callback to use as the
116 : : //! target function to call if quiescence is detected
117 : : template< class MainProxy, class CmdLine >
118 : 330 : void MainCtor( MainProxy& mp,
119 : : const MainProxy& thisProxy,
120 : : std::vector< tk::Timer >& timer,
121 : : const CmdLine& cmdline,
122 : : const CkCallback& quiescenceTarget )
123 : : {
124 : : // Set Charm++ main proxy
125 : 330 : mp = thisProxy;
126 : :
127 : : // Optionally enable quiscence detection
128 [ + + ]: 330 : if (cmdline.template get< tag::quiescence >()) CkStartQD( quiescenceTarget );
129 : :
130 : : // Start new timer measuring the migration of global-scope data
131 : 330 : timer.emplace_back();
132 : 330 : }
133 : :
134 : : //! Generic function to dump the Charm++ chare state (if collected)
135 : : //! \tparam CmdLine Executable-specific tagged tuple storing the rusult of the
136 : : //! command line parser
137 : : //! \param[in] cmdline Command line grammar stack for the executable
138 : : //! \param[in] def Default log file name
139 : : //! \param[in] nrestart Number of times restarted
140 : : //! \param[in] msg Charm++ reduction message containing the chare state
141 : : //! aggregated from all PEs
142 : : template< class CmdLine >
143 : 280 : void dumpstate( const CmdLine& cmdline,
144 : : const std::string& def,
145 : : int nrestart,
146 : : CkReductionMsg* msg )
147 : : {
148 : : try {
149 : :
150 : : // unpack chare state
151 : 280 : std::unordered_map< int, std::vector< tk::ChareState > > state;
152 : 280 : PUP::fromMem creator( msg->getData() );
153 [ + - ]: 280 : creator | state;
154 [ + - ][ + - ]: 280 : delete msg;
155 : :
156 : : // find out if chare state collection was triggered due to an error
157 [ + - ]: 280 : auto it = state.find( -1 );
158 : 280 : bool error = it != end(state);
159 [ - + ][ - - ]: 280 : if (error) state.erase( it );
160 : :
161 : : // pretty-print collected chare state (only if user requested it or
162 : : // quiescence was detected which is an indication of a logic error)
163 [ + + ][ - + ]: 280 : if (cmdline.template get< tag::chare >() || error) {
[ + + ]
164 [ + - ][ + - ]: 2 : tk::Print print( cmdline.logname( def, nrestart ),
[ + - ]
165 : 1 : cmdline.template get< tag::verbose >() ? std::cout : std::clog,
166 : : std::ios_base::app );
167 [ + - ]: 1 : print.charestate( state );
168 : : }
169 : :
170 : : // exit differently depending on how we were called
171 [ - + ]: 280 : if (error)
172 [ - - ][ - - ]: 0 : Throw( "Quiescence or another error detected" );
[ - - ]
173 : : else
174 [ - - ]: 280 : CkExit(); // tell the Charm++ runtime system to exit with zero exit code
175 : :
176 [ - - ]: 0 : } catch (...) { tk::processExceptionCharm(); }
177 : 0 : }
178 : :
179 : : //! Generic finalize function for different executables
180 : : //! \param[in] cmdline Command line grammar stack for the executable
181 : : //! \param[in] timer Vector of timers, held by the main chare
182 : : //! \param[in,out] state Chare state collector proxy
183 : : //! \param[in,out] timestamp Vector of time stamps in h:m:s with labels
184 : : //! \param[in] dumpstateTarget Pre-created Charm++ callback to use as the
185 : : //! target function for dumping chare state
186 : : //! \param[in] def Default log file name
187 : : //! \param[in] nrestart Number of times restarted
188 : : //! \param[in] clean True if we should exit with a zero exit code, false to
189 : : //! exit with a nonzero exit code
190 : : template< class CmdLine >
191 : 330 : void finalize( const CmdLine& cmdline,
192 : : const std::vector< tk::Timer >& timer,
193 : : tk::CProxy_ChareStateCollector& state,
194 : : std::vector< std::pair< std::string,
195 : : tk::Timer::Watch > >& timestamp,
196 : : const std::string& def,
197 : : int nrestart,
198 : : const CkCallback& dumpstateTarget,
199 : : bool clean = true )
200 : : {
201 : : try {
202 : :
203 [ + - ]: 330 : if (!timer.empty()) {
204 [ + - ][ + - ]: 330 : timestamp.emplace_back( "Total runtime", timer[0].hms() );
205 [ + - ][ + - ]: 660 : tk::Print print( cmdline.logname( def, nrestart ),
[ + - ]
206 : 330 : cmdline.template get< tag::verbose >() ? std::cout : std::clog,
207 : : std::ios_base::app );
208 [ + - ][ + - ]: 330 : print.time( "Timers (h:m:s)", timestamp );
209 [ + - ]: 330 : print.endpart();
210 : : }
211 : :
212 : : // if quiescence detection is on or user requested it, collect chare state
213 [ + + ][ + + ]: 330 : if ( cmdline.template get< tag::chare >() ||
[ + + ]
214 : : cmdline.template get< tag::quiescence >() )
215 : : {
216 [ + - ]: 280 : state.collect( /* error = */ not clean, dumpstateTarget );
217 : : } else { // tell the ++ runtime system to exit with the correct exit code
218 [ + - ][ - - ]: 50 : if (clean) CkExit(); else CkAbort("Failed");
219 : : }
220 : :
221 [ - - ]: 0 : } catch (...) { tk::processExceptionCharm(); }
222 : 280 : }
223 : :
224 : : } // tk::
225 : :
226 : : #endif // Init_h
|