LCOV - code coverage report
Current view: top level - ext/amrex/3d-coverage-g++-24.08/include - AMReX_Print.H (source / functions) Hit Total Coverage
Test: coverage_merged.info Lines: 24 30 80.0 %
Date: 2024-11-18 05:28:54 Functions: 22 29 75.9 %

          Line data    Source code
       1             : #ifndef AMREX_PRINT_H_
       2             : #define AMREX_PRINT_H_
       3             : #include <AMReX_Config.H>
       4             : 
       5             : #include <AMReX.H>
       6             : #include <AMReX_ParallelContext.H>
       7             : #include <AMReX_ParallelDescriptor.H>
       8             : #include <AMReX_ANSIEscCode.H>
       9             : 
      10             : #include <sstream>
      11             : #include <fstream>
      12             : #include <iomanip>
      13             : #include <utility>
      14             : 
      15             : namespace amrex
      16             : {
      17             :     template <typename T>
      18             :     std::ostream& operator<< (std::ostream& os, Array<T,AMREX_SPACEDIM> const& a)
      19             :     {
      20             :         os << AMREX_D_TERM( '(' << a[0] , <<
      21             :                             ',' << a[1] , <<
      22             :                             ',' << a[2])  << ')';
      23             :         return os;
      24             :     }
      25             : 
      26             :     template <typename T, typename S>
      27             :     std::ostream& operator<<(std::ostream& os, const std::pair<T, S>& v)
      28             :     {
      29             :         os << "(" << v.first << ", " << v.second << ")";
      30             :         return os;
      31             :     }
      32             : 
      33             :     //! This class provides the user with a few print options
      34             :     class Print
      35             :     {
      36             :     public:
      37             : 
      38             :         static constexpr int AllProcs = -1;
      39             : 
      40             :     /**
      41             :     * \brief Print on I/O Processor of the default communicator
      42             :     * Example: Print() << " x = " << x << '\n';
      43             :     */
      44        5671 :         explicit Print (std::ostream& os_ = amrex::OutStream())
      45        5671 :             : rank(ParallelContext::IOProcessorNumberSub())
      46        5671 :             , comm(ParallelContext::CommunicatorSub())
      47        5671 :             , os(os_)
      48        5671 :             { ss.precision(os.precision()); }
      49             : 
      50             :     /**
      51             :     * \brief Print on all processors of the default communicator
      52             :     * Example: Print(Print::AllProcs) << " x = " << x << '\n';
      53             :     */
      54         300 :         Print (int rank_, std::ostream& os_ = amrex::OutStream())
      55         300 :             : rank(rank_)
      56         300 :             , comm(ParallelContext::CommunicatorSub())
      57         300 :             , os(os_)
      58         300 :             { ss.precision(os.precision()); }
      59             : 
      60             :     /**
      61             :     * \brief Print on process rank_ of communicator comm_
      62             :     * Example: Print(rank_, comm_) << " x = " << x << '\n';
      63             :     */
      64             :         Print (int rank_, MPI_Comm comm_, std::ostream& os_ = amrex::OutStream())
      65             :             : rank(rank_)
      66             :             , comm(comm_)
      67             :             , os(os_)
      68             :             { ss.precision(os.precision()); }
      69             : 
      70        5971 :         ~Print () {
      71        5971 :             if (rank == AllProcs || rank == ParallelContext::MyProcSub()) {
      72        5971 :                 std::ostream * my_os = ParallelContext::OFSPtrSub();
      73        5971 :                 if (my_os) {
      74           0 :                     my_os->flush();
      75           0 :                     (*my_os) << ss.str();
      76           0 :                     my_os->flush();
      77             :                 }
      78        5971 :                 os.flush();
      79        5971 :                 os << ss.str();
      80        5971 :                 os.flush();
      81             :             }
      82        5971 :         }
      83             : 
      84             :         Print (Print const&) = delete;
      85             :         Print (Print &&) = delete;
      86             :         Print& operator= (Print const&) = delete;
      87             :         Print& operator= (Print &&) = delete;
      88             : 
      89             :         Print& SetPrecision(int p) {
      90             :             ss.precision(p);
      91             :             return *this;
      92             :         }
      93             : 
      94             :         template <typename T>
      95       46552 :         Print& operator<< (const T& x) {
      96       46552 :             ss << x;
      97       46552 :             return *this;
      98             :         }
      99             : 
     100           0 :         Print& operator<< (        std::basic_ostream<char, std::char_traits<char> >&
     101             :                            (*func)(std::basic_ostream<char, std::char_traits<char> >&))
     102             :         {
     103           0 :             ss << func;
     104           0 :             return *this;
     105             :         }
     106             : 
     107             :     private:
     108             :         int rank;
     109             :         MPI_Comm comm;
     110             :         std::ostream &os;
     111             :         std::ostringstream ss;
     112             :     };
     113             : 
     114             :     //! Print on all processors of the default communicator
     115             :     class AllPrint
     116             :         : public Print
     117             :     {
     118             :     public:
     119             :         //! Example: AllPrint() << " x = " << x << '\n';
     120         300 :         explicit AllPrint (std::ostream& os_ = amrex::OutStream())
     121         300 :             : Print(Print::AllProcs, os_)
     122         300 :             {}
     123             : 
     124             :     };
     125             : 
     126             :     //! This class prints to a file with a given base name
     127             :     class PrintToFile
     128             :     {
     129             :     public:
     130             : 
     131             :         static constexpr int AllProcs = -1;
     132             : 
     133             :         explicit PrintToFile (std::string file_name_)
     134             :             : file_name(std::move(file_name_))
     135             :             , rank(ParallelContext::IOProcessorNumberSub())
     136             :             , comm(ParallelContext::CommunicatorSub())
     137             :         { Initialize(); }
     138             : 
     139             :         PrintToFile (std::string file_name_, int rank_ )
     140             :             : file_name(std::move(file_name_))
     141             :             , rank(rank_)
     142             :             , comm(ParallelContext::CommunicatorSub())
     143             :         { Initialize(); }
     144             : 
     145             :         PrintToFile (std::string file_name_, int rank_, MPI_Comm comm_)
     146             :             : file_name(std::move(file_name_))
     147             :             , rank(rank_)
     148             :             , comm(comm_)
     149             :         { Initialize(); }
     150             : 
     151             :         ~PrintToFile () {
     152             :             if (rank == AllProcs || rank == ParallelContext::MyProcSub()) {
     153             :                 ofs.flush();
     154             :                 ofs << ss.str();
     155             :                 ofs.flush();
     156             :             }
     157             :         }
     158             : 
     159             :         PrintToFile (PrintToFile const&) = delete;
     160             :         PrintToFile (PrintToFile &&) = delete;
     161             :         PrintToFile& operator= (PrintToFile const&) = delete;
     162             :         PrintToFile& operator= (PrintToFile &&) = delete;
     163             : 
     164             :         PrintToFile& SetPrecision(int p) {
     165             :             ss.precision(p);
     166             :             return *this;
     167             :         }
     168             : 
     169             :         template <typename T>
     170             :         PrintToFile& operator<< (const T& x) {
     171             :             ss << x;
     172             :             return *this;
     173             :         }
     174             : 
     175             :         PrintToFile& operator<< (        std::basic_ostream<char, std::char_traits<char> >&
     176             :                                  (*func)(std::basic_ostream<char, std::char_traits<char> >&))
     177             :         {
     178             :             ss << func;
     179             :             return *this;
     180             :         }
     181             : 
     182             :     private:
     183             : 
     184             :         void Initialize() {
     185             :             int my_proc = ParallelContext::MyProcSub();
     186             :             if (rank == AllProcs || rank == my_proc) {
     187             :                 int my_proc_global = ParallelDescriptor::MyProc();
     188             :                 std::string proc_file_name = file_name + "." + std::to_string(my_proc_global);
     189             : #ifdef AMREX_USE_OMP
     190             :                 proc_file_name += "." + std::to_string(omp_get_thread_num());
     191             : #endif
     192             :                 ofs.open(proc_file_name, std::ios_base::app);
     193             :                 if (!ofs.is_open()) {
     194             :                     amrex::Error("Could not open file for appending in amrex::Print()");
     195             :                 }
     196             :                 ss.precision(ofs.precision());
     197             :             }
     198             :         }
     199             : 
     200             :         std::string file_name;
     201             :         int rank;
     202             :         MPI_Comm comm;
     203             :         std::ofstream ofs;
     204             :         std::ostringstream ss;
     205             :     };
     206             : 
     207             :     //! Print on all processors of the default communicator
     208             :     class AllPrintToFile
     209             :         : public PrintToFile
     210             :     {
     211             :     public:
     212             :         //! Example: AllPrint() << " x = " << x << '\n';
     213             :         explicit AllPrintToFile (std::string file_name_)
     214             :             : PrintToFile(std::move(file_name_), Print::AllProcs)
     215             :             {}
     216             : 
     217             :     };
     218             : }
     219             : 
     220             : #endif

Generated by: LCOV version 1.14