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 : : 2022-2025 J. Bakosi
8 : : All rights reserved. See the LICENSE file for details.
9 : : \brief Mesh file converter Charm++ main chare
10 : : \details Mesh file converter Charm++ main chare. This file contains the
11 : : definition of the Charm++ main chare, equivalent to main() in Charm++-land.
12 : : */
13 : : // *****************************************************************************
14 : :
15 : : #include <vector>
16 : : #include <utility>
17 : : #include <iostream>
18 : :
19 : : #include "Timer.hpp"
20 : : #include "Types.hpp"
21 : : #include "XystConfig.hpp"
22 : : #include "Init.hpp"
23 : : #include "MeshConvDriver.hpp"
24 : : #include "MeshConvConfig.hpp"
25 : : #include "ProcessException.hpp"
26 : :
27 : : #include "NoWarning/charm.hpp"
28 : : #include "NoWarning/meshconv.decl.h"
29 : :
30 : : #if defined(__clang__)
31 : : #pragma clang diagnostic push
32 : : #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
33 : : #endif
34 : :
35 : : //! \brief Charm handle to the main proxy, facilitates call-back to finalize,
36 : : //! etc., must be in global scope, unique per executable
37 : : CProxy_Main mainProxy;
38 : :
39 : : #if defined(__clang__)
40 : : #pragma clang diagnostic pop
41 : : #endif
42 : :
43 : : //! \brief Charm++ main chare for the mesh converter executable, meshconv.
44 : : //! \details Note that this object should not be in a namespace.
45 : : class Main : public CBase_Main {
46 : :
47 : : public:
48 : : //! \brief Constructor
49 : : //! \details MeshConv's main chare constructor is the entry point of the
50 : : //! program, called by the Charm++ runtime system. The constructor does
51 : : //! basic initialization steps, e.g., parser the command-line, prints out
52 : : //! some useful information to screen (in verbose mode), and instantiates
53 : : //! a driver. Since Charm++ is fully asynchronous, the constructor
54 : : //! usually spawns asynchronous objects and immediately exits. Thus in the
55 : : //! body of the main chare constructor we fire up an 'execute' chare,
56 : : //! which then calls back to Main::execute(). Finishing the main chare
57 : : //! constructor the Charm++ runtime system then starts the
58 : : //! network-migration of all global-scope data (if any). The execute chare
59 : : //! calling back to Main::execute() signals the end of the migration of
60 : : //! the global-scope data. Then we are ready to execute the driver which
61 : : //! calls back to Main::finalize() when it finished. Then finalize() exits
62 : : //! by calling Charm++'s CkExit(), shutting down the runtime system.
63 : : //! \see http://charm.cs.illinois.edu/manuals/html/charm++/manual.html
64 : 23 : explicit Main( CkArgMsg* msg )
65 : 23 : try :
66 [ + - ][ + - ]: 69 : m_timer(1)
67 : : {
68 [ + - ]: 23 : tk::setSignalHandlers();
69 : : // Parse command line
70 [ + - ]: 23 : m_cfg.cmdline( msg->argc, msg->argv );
71 [ + - ]: 20 : tk::echoHeader( tk::HeaderType::MESHCONV );
72 [ + - ][ + - ]: 20 : tk::echoBuildEnv( msg->argv[0] );
73 [ + - ]: 20 : tk::echoRunEnv(msg->argc, msg->argv, m_cfg.get< tag::quiescence >());
74 [ + - ][ + - ]: 20 : delete msg;
75 [ + - ]: 20 : mainProxy = thisProxy;
76 [ + - ]: 20 : if (m_cfg.get< tag::quiescence >()) {
77 [ + - ][ + - ]: 20 : CkStartQD( CkCallback( CkIndex_Main::quiescence(), thisProxy ) );
[ + - ]
78 : : }
79 [ + - ]: 20 : m_timer.emplace_back();
80 : : // Fire up an asynchronous execute object, which when created at some
81 : : // future point in time will call back to this->execute(). This is
82 : : // necessary so that this->execute() can access already migrated
83 : : // global-scope data.
84 [ + - ]: 20 : CProxy_execute::ckNew();
85 [ - - ]: 20 : } catch (...) { tk::processExceptionCharm(); }
86 : :
87 : 20 : void execute() {
88 : : try {
89 [ + - ][ + - ]: 20 : m_timestamp.emplace_back("Migrate global-scope data", m_timer[1].hms());
90 [ + + ]: 20 : meshconv::MeshConvDriver().convert( m_cfg.get< tag::input >(),
91 : 20 : m_cfg.get< tag::output >(), m_cfg.get< tag::reorder >() );
92 [ - - ]: 1 : } catch (...) { tk::processExceptionCharm(); }
93 : 19 : }
94 : :
95 : : //! Towards normal exit but collect chare state first (if any)
96 : 19 : void finalize() {
97 : 19 : tk::finalize( m_timer, m_timestamp );
98 : 0 : }
99 : :
100 : : //! Add a time stamp contributing to final timers output
101 : 82 : void timestamp( std::string label, tk::real stamp ) {
102 : : try {
103 [ + - ][ + - ]: 82 : m_timestamp.emplace_back( label, tk::hms( stamp ) );
104 [ - - ]: 0 : } catch (...) { tk::processExceptionCharm(); }
105 : 82 : }
106 : : //! Add multiple time stamps contributing to final timers output
107 : 19 : void timestamp( const std::vector< std::pair< std::string, tk::real > >& s )
108 [ + - ][ + - ]: 101 : { for (const auto& t : s) timestamp( t.first, t.second ); }
[ + + ]
109 : :
110 : : //! Entry method triggered when quiescence is detected
111 [ - - ][ - - ]: 0 : [[noreturn]] void quiescence() { Throw( "Quiescence detected" ); }
[ - - ]
112 : :
113 : : private:
114 : : meshconv::ctr::Config m_cfg; //!< Config parsed from cmdline
115 : : std::vector< tk::Timer > m_timer; //!< Timers
116 : : //! Time stamps in h:m:s with labels
117 : : std::vector< std::pair< std::string, tk::Timer::Watch > > m_timestamp;
118 : : };
119 : :
120 : : //! \brief Charm++ chare execute
121 : : //! \details By the time this object is constructed, the Charm++ runtime system
122 : : //! has finished migrating all global-scoped read-only objects which happens
123 : : //! after the main chare constructor has finished.
124 : : class execute : public CBase_execute {
125 [ + - ]: 20 : public: explicit execute() { mainProxy.execute(); }
126 : : };
127 : :
128 : : #include "NoWarning/meshconv.def.h"
|