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