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-2024 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 [ + - ][ + - ]: 23 : 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 : : delete msg; 75 : : mainProxy = thisProxy; 76 [ + - ]: 20 : if (m_cfg.get< tag::quiescence >()) { 77 [ + - ]: 40 : 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 : 19 : 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 : : void finalize() { 97 : 19 : tk::finalize( m_timer, m_timestamp ); 98 : : } 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"