Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/Main/MeshConv.cpp
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 Mesh file converter Charm++ main chare
9 : : \details Mesh file converter Charm++ main chare. This file contains the
10 : : definition of the Charm++ main chare, equivalent to main() in Charm++-land.
11 : : */
12 : : // *****************************************************************************
13 : :
14 : : #include <vector>
15 : : #include <utility>
16 : : #include <iostream>
17 : :
18 : : #include "Print.hpp"
19 : : #include "Timer.hpp"
20 : : #include "Types.hpp"
21 : : #include "QuinoaConfig.hpp"
22 : : #include "Init.hpp"
23 : : #include "Tags.hpp"
24 : : #include "MeshConvDriver.hpp"
25 : : #include "MeshConv/CmdLine/CmdLine.hpp"
26 : : #include "MeshConv/CmdLine/Parser.hpp"
27 : : #include "ProcessException.hpp"
28 : : #include "ChareStateCollector.hpp"
29 : :
30 : : #include "NoWarning/charm.hpp"
31 : : #include "NoWarning/meshconv.decl.h"
32 : :
33 : : #if defined(__clang__)
34 : : #pragma clang diagnostic push
35 : : #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
36 : : #endif
37 : :
38 : : //! \brief Charm handle to the main proxy, facilitates call-back to finalize,
39 : : //! etc., must be in global scope, unique per executable
40 : : CProxy_Main mainProxy;
41 : :
42 : : //! Chare state collector Charm++ chare group proxy
43 : : tk::CProxy_ChareStateCollector stateProxy;
44 : :
45 : : //! If true, call and stack traces are to be output with exceptions
46 : : //! \note This is true by default so that the trace is always output between
47 : : //! program start and the Main ctor in which the user-input from command line
48 : : //! setting for this overrides this true setting.
49 : : bool g_trace = true;
50 : :
51 : : #if defined(__clang__)
52 : : #pragma clang diagnostic pop
53 : : #endif
54 : :
55 : : //! \brief Charm++ main chare for the mesh converter executable, meshconv.
56 : : //! \details Note that this object should not be in a namespace.
57 : : // cppcheck-suppress noConstructor
58 : : class Main : public CBase_Main {
59 : :
60 : : public:
61 : : //! \brief Constructor
62 : : //! \details MeshConv's main chare constructor is the entry point of the
63 : : //! program, called by the Charm++ runtime system. The constructor does
64 : : //! basic initialization steps, e.g., parser the command-line, prints out
65 : : //! some useful information to screen (in verbose mode), and instantiates
66 : : //! a driver. Since Charm++ is fully asynchronous, the constructor
67 : : //! usually spawns asynchronous objects and immediately exits. Thus in the
68 : : //! body of the main chare constructor we fire up an 'execute' chare,
69 : : //! which then calls back to Main::execute(). Finishing the main chare
70 : : //! constructor the Charm++ runtime system then starts the
71 : : //! network-migration of all global-scope data (if any). The execute chare
72 : : //! calling back to Main::execute() signals the end of the migration of
73 : : //! the global-scope data. Then we are ready to execute the driver which
74 : : //! calls back to Main::finalize() when it finished. Then finalize() exits
75 : : //! by calling Charm++'s CkExit(), shutting down the runtime system.
76 : : //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
77 : 18 : Main( CkArgMsg* msg )
78 : 18 : try :
79 : 36 : m_signal( tk::setSignalHandlers() ),
80 : : m_cmdline(),
81 : : // Parse command line into m_cmdline using default simple pretty printer
82 [ + - ]: 36 : m_cmdParser( msg->argc, msg->argv, tk::Print(), m_cmdline ),
83 : : // Create MeshConv driver
84 : : m_driver( tk::Main< meshconv::MeshConvDriver >
85 : : ( msg->argc, msg->argv,
86 : 18 : m_cmdline,
87 : : tk::HeaderType::MESHCONV,
88 [ + - ]: 36 : tk::meshconv_executable(),
89 : 18 : m_cmdline.get< tag::io, tag::screen >(),
90 : 18 : m_cmdline.get< tag::io, tag::nrestart >() ) ),
91 : : m_timer(1), // Start new timer measuring the total runtime
92 [ + - ][ + - ]: 90 : m_timestamp()
[ + - ][ + - ]
[ + - ][ + - ]
93 : : {
94 [ + - ][ + - ]: 18 : delete msg;
95 : 18 : g_trace = m_cmdline.get< tag::trace >();
96 [ + - ]: 18 : tk::MainCtor( mainProxy, thisProxy, m_timer, m_cmdline,
97 [ + - ][ + - ]: 36 : CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
98 : : // If quiescence detection is on or user requested it, create chare state
99 : : // collector Charm++ chare group
100 [ + - ][ + - ]: 18 : if ( m_cmdline.get< tag::chare >() || m_cmdline.get< tag::quiescence >() )
[ + - ]
101 [ + - ][ + - ]: 18 : stateProxy = tk::CProxy_ChareStateCollector::ckNew();
102 : : // Fire up an asynchronous execute object, which when created at some
103 : : // future point in time will call back to this->execute(). This is
104 : : // necessary so that this->execute() can access already migrated
105 : : // global-scope data.
106 [ + - ]: 18 : CProxy_execute::ckNew();
107 [ - - ]: 18 : } catch (...) { tk::processExceptionCharm(); }
108 : :
109 : 18 : void execute() {
110 : : try {
111 [ + - ][ + - ]: 18 : m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
112 [ + - ]: 18 : m_driver.execute();
113 [ - - ]: 0 : } catch (...) { tk::processExceptionCharm(); }
114 : 18 : }
115 : :
116 : : //! Towards normal exit but collect chare state first (if any)
117 : 18 : void finalize() {
118 [ + - ]: 18 : tk::finalize( m_cmdline, m_timer, stateProxy, m_timestamp,
119 : 18 : m_cmdline.get< tag::io, tag::screen >(),
120 : 18 : m_cmdline.get< tag::io, tag::nrestart >(),
121 : 36 : CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
122 : 18 : }
123 : :
124 : : //! Add a time stamp contributing to final timers output
125 : 72 : void timestamp( std::string label, tk::real stamp ) {
126 : : try {
127 [ + - ][ + - ]: 72 : m_timestamp.emplace_back( label, tk::hms( stamp ) );
128 [ - - ]: 0 : } catch (...) { tk::processExceptionCharm(); }
129 : 72 : }
130 : : //! Add multiple time stamps contributing to final timers output
131 : 18 : void timestamp( const std::vector< std::pair< std::string, tk::real > >& s )
132 [ + + ][ + - ]: 90 : { for (const auto& t : s) timestamp( t.first, t.second ); }
[ + - ]
133 : :
134 : : //! Entry method triggered when quiescence is detected
135 : 0 : void quiescence() {
136 : : try {
137 [ - - ]: 0 : stateProxy.collect( /* error= */ true,
138 [ - - ][ - - ]: 0 : CkCallback( CkIndex_Main::dumpstate(nullptr), thisProxy ) );
139 [ - - ]: 0 : } catch (...) { tk::processExceptionCharm(); }
140 : 0 : }
141 : :
142 : : //! Dump chare state
143 : 18 : void dumpstate( CkReductionMsg* msg ) {
144 : 18 : tk::dumpstate( m_cmdline,
145 : 18 : m_cmdline.get< tag::io, tag::screen >(),
146 : 18 : m_cmdline.get< tag::io, tag::nrestart >(),
147 : : msg );
148 : 0 : }
149 : :
150 : : private:
151 : : int m_signal; //!< Used to set signal handlers
152 : : meshconv::ctr::CmdLine m_cmdline; //!< Command line
153 : : meshconv::CmdLineParser m_cmdParser; //!< Command line parser
154 : : meshconv::MeshConvDriver m_driver; //!< Driver
155 : : std::vector< tk::Timer > m_timer; //!< Timers
156 : :
157 : : //! Time stamps in h:m:s with labels
158 : : std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
159 : : };
160 : :
161 : : //! \brief Charm++ chare execute
162 : : //! \details By the time this object is constructed, the Charm++ runtime system
163 : : //! has finished migrating all global-scoped read-only objects which happens
164 : : //! after the main chare constructor has finished.
165 : : class execute : public CBase_execute {
166 [ + - ]: 18 : public: execute() { mainProxy.execute(); }
167 : : };
168 : :
169 : : #include "NoWarning/meshconv.def.h"
|